PageRenderTime 216ms CodeModel.GetById 22ms RepoModel.GetById 4ms app.codeStats 2ms

/drivers/staging/gma500/mrst_lvds.c

https://bitbucket.org/wisechild/galaxy-nexus
C | 371 lines | 251 code | 50 blank | 70 comment | 37 complexity | ddc580da9bc04cc7d06e2812e23d566b MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  1. /*
  2. * Copyright © 2006-2009 Intel Corporation
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms and conditions of the GNU General Public License,
  6. * version 2, as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope it will be useful, but WITHOUT
  9. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  11. * more details.
  12. *
  13. * You should have received a copy of the GNU General Public License along with
  14. * this program; if not, write to the Free Software Foundation, Inc.,
  15. * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  16. *
  17. * Authors:
  18. * Eric Anholt <eric@anholt.net>
  19. * Dave Airlie <airlied@linux.ie>
  20. * Jesse Barnes <jesse.barnes@intel.com>
  21. */
  22. #include <linux/i2c.h>
  23. #include <drm/drmP.h>
  24. #include <asm/mrst.h>
  25. #include "psb_intel_bios.h"
  26. #include "psb_drv.h"
  27. #include "psb_intel_drv.h"
  28. #include "psb_intel_reg.h"
  29. #include "psb_powermgmt.h"
  30. #include <linux/pm_runtime.h>
  31. /* The max/min PWM frequency in BPCR[31:17] - */
  32. /* The smallest number is 1 (not 0) that can fit in the
  33. * 15-bit field of the and then*/
  34. /* shifts to the left by one bit to get the actual 16-bit
  35. * value that the 15-bits correspond to.*/
  36. #define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF
  37. #define BRIGHTNESS_MAX_LEVEL 100
  38. /**
  39. * Sets the power state for the panel.
  40. */
  41. static void mrst_lvds_set_power(struct drm_device *dev,
  42. struct psb_intel_output *output, bool on)
  43. {
  44. u32 pp_status;
  45. DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
  46. PSB_DEBUG_ENTRY("\n");
  47. if (!gma_power_begin(dev, true))
  48. return;
  49. if (on) {
  50. REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
  51. POWER_TARGET_ON);
  52. do {
  53. pp_status = REG_READ(PP_STATUS);
  54. } while ((pp_status & (PP_ON | PP_READY)) == PP_READY);
  55. dev_priv->is_lvds_on = true;
  56. } else {
  57. REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
  58. ~POWER_TARGET_ON);
  59. do {
  60. pp_status = REG_READ(PP_STATUS);
  61. } while (pp_status & PP_ON);
  62. dev_priv->is_lvds_on = false;
  63. pm_request_idle(&dev->pdev->dev);
  64. }
  65. gma_power_end(dev);
  66. }
  67. static void mrst_lvds_dpms(struct drm_encoder *encoder, int mode)
  68. {
  69. struct drm_device *dev = encoder->dev;
  70. struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
  71. PSB_DEBUG_ENTRY("\n");
  72. if (mode == DRM_MODE_DPMS_ON)
  73. mrst_lvds_set_power(dev, output, true);
  74. else
  75. mrst_lvds_set_power(dev, output, false);
  76. /* XXX: We never power down the LVDS pairs. */
  77. }
  78. static void mrst_lvds_mode_set(struct drm_encoder *encoder,
  79. struct drm_display_mode *mode,
  80. struct drm_display_mode *adjusted_mode)
  81. {
  82. struct psb_intel_mode_device *mode_dev =
  83. enc_to_psb_intel_output(encoder)->mode_dev;
  84. struct drm_device *dev = encoder->dev;
  85. u32 lvds_port;
  86. uint64_t v = DRM_MODE_SCALE_FULLSCREEN;
  87. PSB_DEBUG_ENTRY("\n");
  88. if (!gma_power_begin(dev, true))
  89. return;
  90. /*
  91. * The LVDS pin pair will already have been turned on in the
  92. * psb_intel_crtc_mode_set since it has a large impact on the DPLL
  93. * settings.
  94. */
  95. lvds_port = (REG_READ(LVDS) &
  96. (~LVDS_PIPEB_SELECT)) |
  97. LVDS_PORT_EN |
  98. LVDS_BORDER_EN;
  99. if (mode_dev->panel_wants_dither)
  100. lvds_port |= MRST_PANEL_8TO6_DITHER_ENABLE;
  101. REG_WRITE(LVDS, lvds_port);
  102. drm_connector_property_get_value(
  103. &enc_to_psb_intel_output(encoder)->base,
  104. dev->mode_config.scaling_mode_property,
  105. &v);
  106. if (v == DRM_MODE_SCALE_NO_SCALE)
  107. REG_WRITE(PFIT_CONTROL, 0);
  108. else if (v == DRM_MODE_SCALE_ASPECT) {
  109. if ((mode->vdisplay != adjusted_mode->crtc_vdisplay) ||
  110. (mode->hdisplay != adjusted_mode->crtc_hdisplay)) {
  111. if ((adjusted_mode->crtc_hdisplay * mode->vdisplay) ==
  112. (mode->hdisplay * adjusted_mode->crtc_vdisplay))
  113. REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
  114. else if ((adjusted_mode->crtc_hdisplay *
  115. mode->vdisplay) > (mode->hdisplay *
  116. adjusted_mode->crtc_vdisplay))
  117. REG_WRITE(PFIT_CONTROL, PFIT_ENABLE |
  118. PFIT_SCALING_MODE_PILLARBOX);
  119. else
  120. REG_WRITE(PFIT_CONTROL, PFIT_ENABLE |
  121. PFIT_SCALING_MODE_LETTERBOX);
  122. } else
  123. REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
  124. } else /*(v == DRM_MODE_SCALE_FULLSCREEN)*/
  125. REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
  126. gma_power_end(dev);
  127. }
  128. static const struct drm_encoder_helper_funcs mrst_lvds_helper_funcs = {
  129. .dpms = mrst_lvds_dpms,
  130. .mode_fixup = psb_intel_lvds_mode_fixup,
  131. .prepare = psb_intel_lvds_prepare,
  132. .mode_set = mrst_lvds_mode_set,
  133. .commit = psb_intel_lvds_commit,
  134. };
  135. static struct drm_display_mode lvds_configuration_modes[] = {
  136. /* hard coded fixed mode for TPO LTPS LPJ040K001A */
  137. { DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER, 33264, 800, 836,
  138. 846, 1056, 0, 480, 489, 491, 525, 0, 0) },
  139. /* hard coded fixed mode for LVDS 800x480 */
  140. { DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER, 30994, 800, 801,
  141. 802, 1024, 0, 480, 481, 482, 525, 0, 0) },
  142. /* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */
  143. { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 53990, 1024, 1072,
  144. 1104, 1184, 0, 600, 603, 604, 608, 0, 0) },
  145. /* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */
  146. { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 53990, 1024, 1104,
  147. 1136, 1184, 0, 600, 603, 604, 608, 0, 0) },
  148. /* hard coded fixed mode for Sharp wsvga LVDS 1024x600 */
  149. { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 48885, 1024, 1124,
  150. 1204, 1312, 0, 600, 607, 610, 621, 0, 0) },
  151. /* hard coded fixed mode for LVDS 1024x768 */
  152. { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
  153. 1184, 1344, 0, 768, 771, 777, 806, 0, 0) },
  154. /* hard coded fixed mode for LVDS 1366x768 */
  155. { DRM_MODE("1366x768", DRM_MODE_TYPE_DRIVER, 77500, 1366, 1430,
  156. 1558, 1664, 0, 768, 769, 770, 776, 0, 0) },
  157. };
  158. /* Returns the panel fixed mode from configuration. */
  159. static struct drm_display_mode *
  160. mrst_lvds_get_configuration_mode(struct drm_device *dev)
  161. {
  162. struct drm_display_mode *mode = NULL;
  163. struct drm_psb_private *dev_priv = dev->dev_private;
  164. struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
  165. if (dev_priv->vbt_data.size != 0x00) { /*if non-zero, then use vbt*/
  166. mode = kzalloc(sizeof(*mode), GFP_KERNEL);
  167. if (!mode)
  168. return NULL;
  169. mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
  170. mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
  171. mode->hsync_start = mode->hdisplay + \
  172. ((ti->hsync_offset_hi << 8) | \
  173. ti->hsync_offset_lo);
  174. mode->hsync_end = mode->hsync_start + \
  175. ((ti->hsync_pulse_width_hi << 8) | \
  176. ti->hsync_pulse_width_lo);
  177. mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
  178. ti->hblank_lo);
  179. mode->vsync_start = \
  180. mode->vdisplay + ((ti->vsync_offset_hi << 4) | \
  181. ti->vsync_offset_lo);
  182. mode->vsync_end = \
  183. mode->vsync_start + ((ti->vsync_pulse_width_hi << 4) | \
  184. ti->vsync_pulse_width_lo);
  185. mode->vtotal = mode->vdisplay + \
  186. ((ti->vblank_hi << 8) | ti->vblank_lo);
  187. mode->clock = ti->pixel_clock * 10;
  188. #if 0
  189. printk(KERN_INFO "hdisplay is %d\n", mode->hdisplay);
  190. printk(KERN_INFO "vdisplay is %d\n", mode->vdisplay);
  191. printk(KERN_INFO "HSS is %d\n", mode->hsync_start);
  192. printk(KERN_INFO "HSE is %d\n", mode->hsync_end);
  193. printk(KERN_INFO "htotal is %d\n", mode->htotal);
  194. printk(KERN_INFO "VSS is %d\n", mode->vsync_start);
  195. printk(KERN_INFO "VSE is %d\n", mode->vsync_end);
  196. printk(KERN_INFO "vtotal is %d\n", mode->vtotal);
  197. printk(KERN_INFO "clock is %d\n", mode->clock);
  198. #endif
  199. } else
  200. mode = drm_mode_duplicate(dev, &lvds_configuration_modes[2]);
  201. drm_mode_set_name(mode);
  202. drm_mode_set_crtcinfo(mode, 0);
  203. return mode;
  204. }
  205. /**
  206. * mrst_lvds_init - setup LVDS connectors on this device
  207. * @dev: drm device
  208. *
  209. * Create the connector, register the LVDS DDC bus, and try to figure out what
  210. * modes we can display on the LVDS panel (if present).
  211. */
  212. void mrst_lvds_init(struct drm_device *dev,
  213. struct psb_intel_mode_device *mode_dev)
  214. {
  215. struct psb_intel_output *psb_intel_output;
  216. struct drm_connector *connector;
  217. struct drm_encoder *encoder;
  218. struct drm_psb_private *dev_priv =
  219. (struct drm_psb_private *) dev->dev_private;
  220. struct edid *edid;
  221. int ret = 0;
  222. struct i2c_adapter *i2c_adap;
  223. struct drm_display_mode *scan; /* *modes, *bios_mode; */
  224. PSB_DEBUG_ENTRY("\n");
  225. psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL);
  226. if (!psb_intel_output)
  227. return;
  228. psb_intel_output->mode_dev = mode_dev;
  229. connector = &psb_intel_output->base;
  230. encoder = &psb_intel_output->enc;
  231. dev_priv->is_lvds_on = true;
  232. drm_connector_init(dev, &psb_intel_output->base,
  233. &psb_intel_lvds_connector_funcs,
  234. DRM_MODE_CONNECTOR_LVDS);
  235. drm_encoder_init(dev, &psb_intel_output->enc, &psb_intel_lvds_enc_funcs,
  236. DRM_MODE_ENCODER_LVDS);
  237. drm_mode_connector_attach_encoder(&psb_intel_output->base,
  238. &psb_intel_output->enc);
  239. psb_intel_output->type = INTEL_OUTPUT_LVDS;
  240. drm_encoder_helper_add(encoder, &mrst_lvds_helper_funcs);
  241. drm_connector_helper_add(connector,
  242. &psb_intel_lvds_connector_helper_funcs);
  243. connector->display_info.subpixel_order = SubPixelHorizontalRGB;
  244. connector->interlace_allowed = false;
  245. connector->doublescan_allowed = false;
  246. drm_connector_attach_property(connector,
  247. dev->mode_config.scaling_mode_property,
  248. DRM_MODE_SCALE_FULLSCREEN);
  249. drm_connector_attach_property(connector,
  250. dev_priv->backlight_property,
  251. BRIGHTNESS_MAX_LEVEL);
  252. mode_dev->panel_wants_dither = false;
  253. if (dev_priv->vbt_data.size != 0x00)
  254. mode_dev->panel_wants_dither = (dev_priv->gct_data.
  255. Panel_Port_Control & MRST_PANEL_8TO6_DITHER_ENABLE);
  256. /*
  257. * LVDS discovery:
  258. * 1) check for EDID on DDC
  259. * 2) check for VBT data
  260. * 3) check to see if LVDS is already on
  261. * if none of the above, no panel
  262. * 4) make sure lid is open
  263. * if closed, act like it's not there for now
  264. */
  265. /* This ifdef can go once the cpu ident stuff is cleaned up in arch */
  266. #if defined(CONFIG_X86_MRST)
  267. if (mrst_identify_cpu())
  268. i2c_adap = i2c_get_adapter(2);
  269. else /* Oaktrail uses I2C 1 */
  270. #endif
  271. i2c_adap = i2c_get_adapter(1);
  272. if (i2c_adap == NULL)
  273. printk(KERN_ALERT "No ddc adapter available!\n");
  274. /*
  275. * Attempt to get the fixed panel mode from DDC. Assume that the
  276. * preferred mode is the right one.
  277. */
  278. if (i2c_adap) {
  279. edid = drm_get_edid(connector, i2c_adap);
  280. if (edid) {
  281. drm_mode_connector_update_edid_property(connector,
  282. edid);
  283. ret = drm_add_edid_modes(connector, edid);
  284. kfree(edid);
  285. }
  286. list_for_each_entry(scan, &connector->probed_modes, head) {
  287. if (scan->type & DRM_MODE_TYPE_PREFERRED) {
  288. mode_dev->panel_fixed_mode =
  289. drm_mode_duplicate(dev, scan);
  290. goto out; /* FIXME: check for quirks */
  291. }
  292. }
  293. }
  294. /*
  295. * If we didn't get EDID, try geting panel timing
  296. * from configuration data
  297. */
  298. mode_dev->panel_fixed_mode = mrst_lvds_get_configuration_mode(dev);
  299. if (mode_dev->panel_fixed_mode) {
  300. mode_dev->panel_fixed_mode->type |=
  301. DRM_MODE_TYPE_PREFERRED;
  302. goto out; /* FIXME: check for quirks */
  303. }
  304. /* If we still don't have a mode after all that, give up. */
  305. if (!mode_dev->panel_fixed_mode) {
  306. DRM_DEBUG
  307. ("Found no modes on the lvds, ignoring the LVDS\n");
  308. goto failed_find;
  309. }
  310. out:
  311. drm_sysfs_connector_add(connector);
  312. return;
  313. failed_find:
  314. DRM_DEBUG("No LVDS modes found, disabling.\n");
  315. if (psb_intel_output->ddc_bus)
  316. psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
  317. /* failed_ddc: */
  318. drm_encoder_cleanup(encoder);
  319. drm_connector_cleanup(connector);
  320. kfree(connector);
  321. }