intel_lvds.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. /*
  2. * Copyright © 2006-2007 Intel Corporation
  3. * Copyright (c) 2006 Dave Airlie <airlied@linux.ie>
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a
  6. * copy of this software and associated documentation files (the "Software"),
  7. * to deal in the Software without restriction, including without limitation
  8. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9. * and/or sell copies of the Software, and to permit persons to whom the
  10. * Software is furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice (including the next
  13. * paragraph) shall be included in all copies or substantial portions of the
  14. * Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22. * DEALINGS IN THE SOFTWARE.
  23. *
  24. * Authors:
  25. * Eric Anholt <eric@anholt.net>
  26. * Dave Airlie <airlied@linux.ie>
  27. * Jesse Barnes <jesse.barnes@intel.com>
  28. */
  29. #include <linux/dmi.h>
  30. #include <linux/i2c.h>
  31. #include "drmP.h"
  32. #include "drm.h"
  33. #include "drm_crtc.h"
  34. #include "drm_edid.h"
  35. #include "intel_drv.h"
  36. #include "i915_drm.h"
  37. #include "i915_drv.h"
  38. /**
  39. * Sets the backlight level.
  40. *
  41. * \param level backlight level, from 0 to intel_lvds_get_max_backlight().
  42. */
  43. static void intel_lvds_set_backlight(struct drm_device *dev, int level)
  44. {
  45. struct drm_i915_private *dev_priv = dev->dev_private;
  46. u32 blc_pwm_ctl;
  47. blc_pwm_ctl = I915_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
  48. I915_WRITE(BLC_PWM_CTL, (blc_pwm_ctl |
  49. (level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
  50. }
  51. /**
  52. * Returns the maximum level of the backlight duty cycle field.
  53. */
  54. static u32 intel_lvds_get_max_backlight(struct drm_device *dev)
  55. {
  56. struct drm_i915_private *dev_priv = dev->dev_private;
  57. return ((I915_READ(BLC_PWM_CTL) & BACKLIGHT_MODULATION_FREQ_MASK) >>
  58. BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
  59. }
  60. /**
  61. * Sets the power state for the panel.
  62. */
  63. static void intel_lvds_set_power(struct drm_device *dev, bool on)
  64. {
  65. struct drm_i915_private *dev_priv = dev->dev_private;
  66. u32 pp_status;
  67. if (on) {
  68. I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) |
  69. POWER_TARGET_ON);
  70. do {
  71. pp_status = I915_READ(PP_STATUS);
  72. } while ((pp_status & PP_ON) == 0);
  73. intel_lvds_set_backlight(dev, dev_priv->backlight_duty_cycle);
  74. } else {
  75. intel_lvds_set_backlight(dev, 0);
  76. I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) &
  77. ~POWER_TARGET_ON);
  78. do {
  79. pp_status = I915_READ(PP_STATUS);
  80. } while (pp_status & PP_ON);
  81. }
  82. }
  83. static void intel_lvds_dpms(struct drm_encoder *encoder, int mode)
  84. {
  85. struct drm_device *dev = encoder->dev;
  86. if (mode == DRM_MODE_DPMS_ON)
  87. intel_lvds_set_power(dev, true);
  88. else
  89. intel_lvds_set_power(dev, false);
  90. /* XXX: We never power down the LVDS pairs. */
  91. }
  92. static void intel_lvds_save(struct drm_connector *connector)
  93. {
  94. struct drm_device *dev = connector->dev;
  95. struct drm_i915_private *dev_priv = dev->dev_private;
  96. dev_priv->savePP_ON = I915_READ(PP_ON_DELAYS);
  97. dev_priv->savePP_OFF = I915_READ(PP_OFF_DELAYS);
  98. dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL);
  99. dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR);
  100. dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
  101. dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL &
  102. BACKLIGHT_DUTY_CYCLE_MASK);
  103. /*
  104. * If the light is off at server startup, just make it full brightness
  105. */
  106. if (dev_priv->backlight_duty_cycle == 0)
  107. dev_priv->backlight_duty_cycle =
  108. intel_lvds_get_max_backlight(dev);
  109. }
  110. static void intel_lvds_restore(struct drm_connector *connector)
  111. {
  112. struct drm_device *dev = connector->dev;
  113. struct drm_i915_private *dev_priv = dev->dev_private;
  114. I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
  115. I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON);
  116. I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF);
  117. I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR);
  118. I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
  119. if (dev_priv->savePP_CONTROL & POWER_TARGET_ON)
  120. intel_lvds_set_power(dev, true);
  121. else
  122. intel_lvds_set_power(dev, false);
  123. }
  124. static int intel_lvds_mode_valid(struct drm_connector *connector,
  125. struct drm_display_mode *mode)
  126. {
  127. struct drm_device *dev = connector->dev;
  128. struct drm_i915_private *dev_priv = dev->dev_private;
  129. struct drm_display_mode *fixed_mode = dev_priv->panel_fixed_mode;
  130. if (fixed_mode) {
  131. if (mode->hdisplay > fixed_mode->hdisplay)
  132. return MODE_PANEL;
  133. if (mode->vdisplay > fixed_mode->vdisplay)
  134. return MODE_PANEL;
  135. }
  136. return MODE_OK;
  137. }
  138. static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
  139. struct drm_display_mode *mode,
  140. struct drm_display_mode *adjusted_mode)
  141. {
  142. struct drm_device *dev = encoder->dev;
  143. struct drm_i915_private *dev_priv = dev->dev_private;
  144. struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
  145. struct drm_encoder *tmp_encoder;
  146. /* Should never happen!! */
  147. if (!IS_I965G(dev) && intel_crtc->pipe == 0) {
  148. printk(KERN_ERR "Can't support LVDS on pipe A\n");
  149. return false;
  150. }
  151. /* Should never happen!! */
  152. list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, head) {
  153. if (tmp_encoder != encoder && tmp_encoder->crtc == encoder->crtc) {
  154. printk(KERN_ERR "Can't enable LVDS and another "
  155. "encoder on the same pipe\n");
  156. return false;
  157. }
  158. }
  159. /*
  160. * If we have timings from the BIOS for the panel, put them in
  161. * to the adjusted mode. The CRTC will be set up for this mode,
  162. * with the panel scaling set up to source from the H/VDisplay
  163. * of the original mode.
  164. */
  165. if (dev_priv->panel_fixed_mode != NULL) {
  166. adjusted_mode->hdisplay = dev_priv->panel_fixed_mode->hdisplay;
  167. adjusted_mode->hsync_start =
  168. dev_priv->panel_fixed_mode->hsync_start;
  169. adjusted_mode->hsync_end =
  170. dev_priv->panel_fixed_mode->hsync_end;
  171. adjusted_mode->htotal = dev_priv->panel_fixed_mode->htotal;
  172. adjusted_mode->vdisplay = dev_priv->panel_fixed_mode->vdisplay;
  173. adjusted_mode->vsync_start =
  174. dev_priv->panel_fixed_mode->vsync_start;
  175. adjusted_mode->vsync_end =
  176. dev_priv->panel_fixed_mode->vsync_end;
  177. adjusted_mode->vtotal = dev_priv->panel_fixed_mode->vtotal;
  178. adjusted_mode->clock = dev_priv->panel_fixed_mode->clock;
  179. drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
  180. }
  181. /*
  182. * XXX: It would be nice to support lower refresh rates on the
  183. * panels to reduce power consumption, and perhaps match the
  184. * user's requested refresh rate.
  185. */
  186. return true;
  187. }
  188. static void intel_lvds_prepare(struct drm_encoder *encoder)
  189. {
  190. struct drm_device *dev = encoder->dev;
  191. struct drm_i915_private *dev_priv = dev->dev_private;
  192. dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
  193. dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL &
  194. BACKLIGHT_DUTY_CYCLE_MASK);
  195. intel_lvds_set_power(dev, false);
  196. }
  197. static void intel_lvds_commit( struct drm_encoder *encoder)
  198. {
  199. struct drm_device *dev = encoder->dev;
  200. struct drm_i915_private *dev_priv = dev->dev_private;
  201. if (dev_priv->backlight_duty_cycle == 0)
  202. dev_priv->backlight_duty_cycle =
  203. intel_lvds_get_max_backlight(dev);
  204. intel_lvds_set_power(dev, true);
  205. }
  206. static void intel_lvds_mode_set(struct drm_encoder *encoder,
  207. struct drm_display_mode *mode,
  208. struct drm_display_mode *adjusted_mode)
  209. {
  210. struct drm_device *dev = encoder->dev;
  211. struct drm_i915_private *dev_priv = dev->dev_private;
  212. struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
  213. u32 pfit_control;
  214. /*
  215. * The LVDS pin pair will already have been turned on in the
  216. * intel_crtc_mode_set since it has a large impact on the DPLL
  217. * settings.
  218. */
  219. /*
  220. * Enable automatic panel scaling so that non-native modes fill the
  221. * screen. Should be enabled before the pipe is enabled, according to
  222. * register description and PRM.
  223. */
  224. if (mode->hdisplay != adjusted_mode->hdisplay ||
  225. mode->vdisplay != adjusted_mode->vdisplay)
  226. pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE |
  227. HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR |
  228. HORIZ_INTERP_BILINEAR);
  229. else
  230. pfit_control = 0;
  231. if (!IS_I965G(dev)) {
  232. if (dev_priv->panel_wants_dither || dev_priv->lvds_dither)
  233. pfit_control |= PANEL_8TO6_DITHER_ENABLE;
  234. }
  235. else
  236. pfit_control |= intel_crtc->pipe << PFIT_PIPE_SHIFT;
  237. I915_WRITE(PFIT_CONTROL, pfit_control);
  238. }
  239. /**
  240. * Detect the LVDS connection.
  241. *
  242. * This always returns CONNECTOR_STATUS_CONNECTED. This connector should only have
  243. * been set up if the LVDS was actually connected anyway.
  244. */
  245. static enum drm_connector_status intel_lvds_detect(struct drm_connector *connector)
  246. {
  247. return connector_status_connected;
  248. }
  249. /**
  250. * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
  251. */
  252. static int intel_lvds_get_modes(struct drm_connector *connector)
  253. {
  254. struct drm_device *dev = connector->dev;
  255. struct intel_output *intel_output = to_intel_output(connector);
  256. struct drm_i915_private *dev_priv = dev->dev_private;
  257. int ret = 0;
  258. ret = intel_ddc_get_modes(intel_output);
  259. if (ret)
  260. return ret;
  261. /* Didn't get an EDID, so
  262. * Set wide sync ranges so we get all modes
  263. * handed to valid_mode for checking
  264. */
  265. connector->display_info.min_vfreq = 0;
  266. connector->display_info.max_vfreq = 200;
  267. connector->display_info.min_hfreq = 0;
  268. connector->display_info.max_hfreq = 200;
  269. if (dev_priv->panel_fixed_mode != NULL) {
  270. struct drm_display_mode *mode;
  271. mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode);
  272. drm_mode_probed_add(connector, mode);
  273. return 1;
  274. }
  275. return 0;
  276. }
  277. /**
  278. * intel_lvds_destroy - unregister and free LVDS structures
  279. * @connector: connector to free
  280. *
  281. * Unregister the DDC bus for this connector then free the driver private
  282. * structure.
  283. */
  284. static void intel_lvds_destroy(struct drm_connector *connector)
  285. {
  286. struct intel_output *intel_output = to_intel_output(connector);
  287. if (intel_output->ddc_bus)
  288. intel_i2c_destroy(intel_output->ddc_bus);
  289. drm_sysfs_connector_remove(connector);
  290. drm_connector_cleanup(connector);
  291. kfree(connector);
  292. }
  293. static int intel_lvds_set_property(struct drm_connector *connector,
  294. struct drm_property *property,
  295. uint64_t value)
  296. {
  297. struct drm_device *dev = connector->dev;
  298. if (property == dev->mode_config.dpms_property && connector->encoder)
  299. intel_lvds_dpms(connector->encoder, (uint32_t)(value & 0xf));
  300. return 0;
  301. }
  302. static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = {
  303. .dpms = intel_lvds_dpms,
  304. .mode_fixup = intel_lvds_mode_fixup,
  305. .prepare = intel_lvds_prepare,
  306. .mode_set = intel_lvds_mode_set,
  307. .commit = intel_lvds_commit,
  308. };
  309. static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = {
  310. .get_modes = intel_lvds_get_modes,
  311. .mode_valid = intel_lvds_mode_valid,
  312. .best_encoder = intel_best_encoder,
  313. };
  314. static const struct drm_connector_funcs intel_lvds_connector_funcs = {
  315. .save = intel_lvds_save,
  316. .restore = intel_lvds_restore,
  317. .detect = intel_lvds_detect,
  318. .fill_modes = drm_helper_probe_single_connector_modes,
  319. .set_property = intel_lvds_set_property,
  320. .destroy = intel_lvds_destroy,
  321. };
  322. static void intel_lvds_enc_destroy(struct drm_encoder *encoder)
  323. {
  324. drm_encoder_cleanup(encoder);
  325. }
  326. static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
  327. .destroy = intel_lvds_enc_destroy,
  328. };
  329. static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id)
  330. {
  331. DRM_DEBUG("Skipping LVDS initialization for %s\n", id->ident);
  332. return 1;
  333. }
  334. /* These systems claim to have LVDS, but really don't */
  335. static const struct dmi_system_id __initdata intel_no_lvds[] = {
  336. {
  337. .callback = intel_no_lvds_dmi_callback,
  338. .ident = "Apple Mac Mini (Core series)",
  339. .matches = {
  340. DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
  341. DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"),
  342. },
  343. },
  344. {
  345. .callback = intel_no_lvds_dmi_callback,
  346. .ident = "Apple Mac Mini (Core 2 series)",
  347. .matches = {
  348. DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
  349. DMI_MATCH(DMI_PRODUCT_NAME, "Macmini2,1"),
  350. },
  351. },
  352. {
  353. .callback = intel_no_lvds_dmi_callback,
  354. .ident = "MSI IM-945GSE-A",
  355. .matches = {
  356. DMI_MATCH(DMI_SYS_VENDOR, "MSI"),
  357. DMI_MATCH(DMI_PRODUCT_NAME, "A9830IMS"),
  358. },
  359. },
  360. {
  361. .callback = intel_no_lvds_dmi_callback,
  362. .ident = "Dell Studio Hybrid",
  363. .matches = {
  364. DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
  365. DMI_MATCH(DMI_PRODUCT_NAME, "Studio Hybrid 140g"),
  366. },
  367. },
  368. /* FIXME: add a check for the Aopen Mini PC */
  369. { } /* terminating entry */
  370. };
  371. /**
  372. * intel_lvds_init - setup LVDS connectors on this device
  373. * @dev: drm device
  374. *
  375. * Create the connector, register the LVDS DDC bus, and try to figure out what
  376. * modes we can display on the LVDS panel (if present).
  377. */
  378. void intel_lvds_init(struct drm_device *dev)
  379. {
  380. struct drm_i915_private *dev_priv = dev->dev_private;
  381. struct intel_output *intel_output;
  382. struct drm_connector *connector;
  383. struct drm_encoder *encoder;
  384. struct drm_display_mode *scan; /* *modes, *bios_mode; */
  385. struct drm_crtc *crtc;
  386. u32 lvds;
  387. int pipe;
  388. /* Skip init on machines we know falsely report LVDS */
  389. if (dmi_check_system(intel_no_lvds))
  390. return;
  391. intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
  392. if (!intel_output) {
  393. return;
  394. }
  395. connector = &intel_output->base;
  396. encoder = &intel_output->enc;
  397. drm_connector_init(dev, &intel_output->base, &intel_lvds_connector_funcs,
  398. DRM_MODE_CONNECTOR_LVDS);
  399. drm_encoder_init(dev, &intel_output->enc, &intel_lvds_enc_funcs,
  400. DRM_MODE_ENCODER_LVDS);
  401. drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
  402. intel_output->type = INTEL_OUTPUT_LVDS;
  403. drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);
  404. drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
  405. connector->display_info.subpixel_order = SubPixelHorizontalRGB;
  406. connector->interlace_allowed = false;
  407. connector->doublescan_allowed = false;
  408. /*
  409. * LVDS discovery:
  410. * 1) check for EDID on DDC
  411. * 2) check for VBT data
  412. * 3) check to see if LVDS is already on
  413. * if none of the above, no panel
  414. * 4) make sure lid is open
  415. * if closed, act like it's not there for now
  416. */
  417. /* Set up the DDC bus. */
  418. intel_output->ddc_bus = intel_i2c_create(dev, GPIOC, "LVDSDDC_C");
  419. if (!intel_output->ddc_bus) {
  420. dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
  421. "failed.\n");
  422. goto failed;
  423. }
  424. /*
  425. * Attempt to get the fixed panel mode from DDC. Assume that the
  426. * preferred mode is the right one.
  427. */
  428. intel_ddc_get_modes(intel_output);
  429. list_for_each_entry(scan, &connector->probed_modes, head) {
  430. mutex_lock(&dev->mode_config.mutex);
  431. if (scan->type & DRM_MODE_TYPE_PREFERRED) {
  432. dev_priv->panel_fixed_mode =
  433. drm_mode_duplicate(dev, scan);
  434. mutex_unlock(&dev->mode_config.mutex);
  435. goto out;
  436. }
  437. mutex_unlock(&dev->mode_config.mutex);
  438. }
  439. /* Failed to get EDID, what about VBT? */
  440. if (dev_priv->vbt_mode) {
  441. mutex_lock(&dev->mode_config.mutex);
  442. dev_priv->panel_fixed_mode =
  443. drm_mode_duplicate(dev, dev_priv->vbt_mode);
  444. mutex_unlock(&dev->mode_config.mutex);
  445. if (dev_priv->panel_fixed_mode) {
  446. dev_priv->panel_fixed_mode->type |=
  447. DRM_MODE_TYPE_PREFERRED;
  448. goto out;
  449. }
  450. }
  451. /*
  452. * If we didn't get EDID, try checking if the panel is already turned
  453. * on. If so, assume that whatever is currently programmed is the
  454. * correct mode.
  455. */
  456. lvds = I915_READ(LVDS);
  457. pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
  458. crtc = intel_get_crtc_from_pipe(dev, pipe);
  459. if (crtc && (lvds & LVDS_PORT_EN)) {
  460. dev_priv->panel_fixed_mode = intel_crtc_mode_get(dev, crtc);
  461. if (dev_priv->panel_fixed_mode) {
  462. dev_priv->panel_fixed_mode->type |=
  463. DRM_MODE_TYPE_PREFERRED;
  464. goto out;
  465. }
  466. }
  467. /* If we still don't have a mode after all that, give up. */
  468. if (!dev_priv->panel_fixed_mode)
  469. goto failed;
  470. out:
  471. drm_sysfs_connector_add(connector);
  472. return;
  473. failed:
  474. DRM_DEBUG("No LVDS modes found, disabling.\n");
  475. if (intel_output->ddc_bus)
  476. intel_i2c_destroy(intel_output->ddc_bus);
  477. drm_connector_cleanup(connector);
  478. kfree(connector);
  479. }