intel_lvds.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  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. return 0;
  298. }
  299. static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = {
  300. .dpms = intel_lvds_dpms,
  301. .mode_fixup = intel_lvds_mode_fixup,
  302. .prepare = intel_lvds_prepare,
  303. .mode_set = intel_lvds_mode_set,
  304. .commit = intel_lvds_commit,
  305. };
  306. static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = {
  307. .get_modes = intel_lvds_get_modes,
  308. .mode_valid = intel_lvds_mode_valid,
  309. .best_encoder = intel_best_encoder,
  310. };
  311. static const struct drm_connector_funcs intel_lvds_connector_funcs = {
  312. .dpms = drm_helper_connector_dpms,
  313. .save = intel_lvds_save,
  314. .restore = intel_lvds_restore,
  315. .detect = intel_lvds_detect,
  316. .fill_modes = drm_helper_probe_single_connector_modes,
  317. .set_property = intel_lvds_set_property,
  318. .destroy = intel_lvds_destroy,
  319. };
  320. static void intel_lvds_enc_destroy(struct drm_encoder *encoder)
  321. {
  322. drm_encoder_cleanup(encoder);
  323. }
  324. static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
  325. .destroy = intel_lvds_enc_destroy,
  326. };
  327. static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id)
  328. {
  329. DRM_DEBUG("Skipping LVDS initialization for %s\n", id->ident);
  330. return 1;
  331. }
  332. /* These systems claim to have LVDS, but really don't */
  333. static const struct dmi_system_id intel_no_lvds[] = {
  334. {
  335. .callback = intel_no_lvds_dmi_callback,
  336. .ident = "Apple Mac Mini (Core series)",
  337. .matches = {
  338. DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
  339. DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"),
  340. },
  341. },
  342. {
  343. .callback = intel_no_lvds_dmi_callback,
  344. .ident = "Apple Mac Mini (Core 2 series)",
  345. .matches = {
  346. DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
  347. DMI_MATCH(DMI_PRODUCT_NAME, "Macmini2,1"),
  348. },
  349. },
  350. {
  351. .callback = intel_no_lvds_dmi_callback,
  352. .ident = "MSI IM-945GSE-A",
  353. .matches = {
  354. DMI_MATCH(DMI_SYS_VENDOR, "MSI"),
  355. DMI_MATCH(DMI_PRODUCT_NAME, "A9830IMS"),
  356. },
  357. },
  358. {
  359. .callback = intel_no_lvds_dmi_callback,
  360. .ident = "Dell Studio Hybrid",
  361. .matches = {
  362. DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
  363. DMI_MATCH(DMI_PRODUCT_NAME, "Studio Hybrid 140g"),
  364. },
  365. },
  366. /* FIXME: add a check for the Aopen Mini PC */
  367. { } /* terminating entry */
  368. };
  369. /**
  370. * intel_lvds_init - setup LVDS connectors on this device
  371. * @dev: drm device
  372. *
  373. * Create the connector, register the LVDS DDC bus, and try to figure out what
  374. * modes we can display on the LVDS panel (if present).
  375. */
  376. void intel_lvds_init(struct drm_device *dev)
  377. {
  378. struct drm_i915_private *dev_priv = dev->dev_private;
  379. struct intel_output *intel_output;
  380. struct drm_connector *connector;
  381. struct drm_encoder *encoder;
  382. struct drm_display_mode *scan; /* *modes, *bios_mode; */
  383. struct drm_crtc *crtc;
  384. u32 lvds;
  385. int pipe;
  386. /* Skip init on machines we know falsely report LVDS */
  387. if (dmi_check_system(intel_no_lvds))
  388. return;
  389. intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
  390. if (!intel_output) {
  391. return;
  392. }
  393. connector = &intel_output->base;
  394. encoder = &intel_output->enc;
  395. drm_connector_init(dev, &intel_output->base, &intel_lvds_connector_funcs,
  396. DRM_MODE_CONNECTOR_LVDS);
  397. drm_encoder_init(dev, &intel_output->enc, &intel_lvds_enc_funcs,
  398. DRM_MODE_ENCODER_LVDS);
  399. drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
  400. intel_output->type = INTEL_OUTPUT_LVDS;
  401. drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);
  402. drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
  403. connector->display_info.subpixel_order = SubPixelHorizontalRGB;
  404. connector->interlace_allowed = false;
  405. connector->doublescan_allowed = false;
  406. /*
  407. * LVDS discovery:
  408. * 1) check for EDID on DDC
  409. * 2) check for VBT data
  410. * 3) check to see if LVDS is already on
  411. * if none of the above, no panel
  412. * 4) make sure lid is open
  413. * if closed, act like it's not there for now
  414. */
  415. /* Set up the DDC bus. */
  416. intel_output->ddc_bus = intel_i2c_create(dev, GPIOC, "LVDSDDC_C");
  417. if (!intel_output->ddc_bus) {
  418. dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
  419. "failed.\n");
  420. goto failed;
  421. }
  422. /*
  423. * Attempt to get the fixed panel mode from DDC. Assume that the
  424. * preferred mode is the right one.
  425. */
  426. intel_ddc_get_modes(intel_output);
  427. list_for_each_entry(scan, &connector->probed_modes, head) {
  428. mutex_lock(&dev->mode_config.mutex);
  429. if (scan->type & DRM_MODE_TYPE_PREFERRED) {
  430. dev_priv->panel_fixed_mode =
  431. drm_mode_duplicate(dev, scan);
  432. mutex_unlock(&dev->mode_config.mutex);
  433. goto out;
  434. }
  435. mutex_unlock(&dev->mode_config.mutex);
  436. }
  437. /* Failed to get EDID, what about VBT? */
  438. if (dev_priv->lfp_lvds_vbt_mode) {
  439. mutex_lock(&dev->mode_config.mutex);
  440. dev_priv->panel_fixed_mode =
  441. drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode);
  442. mutex_unlock(&dev->mode_config.mutex);
  443. if (dev_priv->panel_fixed_mode) {
  444. dev_priv->panel_fixed_mode->type |=
  445. DRM_MODE_TYPE_PREFERRED;
  446. goto out;
  447. }
  448. }
  449. /*
  450. * If we didn't get EDID, try checking if the panel is already turned
  451. * on. If so, assume that whatever is currently programmed is the
  452. * correct mode.
  453. */
  454. lvds = I915_READ(LVDS);
  455. pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
  456. crtc = intel_get_crtc_from_pipe(dev, pipe);
  457. if (crtc && (lvds & LVDS_PORT_EN)) {
  458. dev_priv->panel_fixed_mode = intel_crtc_mode_get(dev, crtc);
  459. if (dev_priv->panel_fixed_mode) {
  460. dev_priv->panel_fixed_mode->type |=
  461. DRM_MODE_TYPE_PREFERRED;
  462. goto out;
  463. }
  464. }
  465. /* If we still don't have a mode after all that, give up. */
  466. if (!dev_priv->panel_fixed_mode)
  467. goto failed;
  468. out:
  469. drm_sysfs_connector_add(connector);
  470. return;
  471. failed:
  472. DRM_DEBUG("No LVDS modes found, disabling.\n");
  473. if (intel_output->ddc_bus)
  474. intel_i2c_destroy(intel_output->ddc_bus);
  475. drm_connector_cleanup(connector);
  476. kfree(connector);
  477. }