aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorZhenyu Wang <zhenyuw@linux.intel.com>2009-06-05 03:38:44 -0400
committerEric Anholt <eric@anholt.net>2009-06-05 07:35:49 -0400
commit541998a18b72d2cac48b3369fa4540116ff3f0a8 (patch)
tree0173c46d2a51118583aa46f2854509076ef90ada /drivers/gpu
parent30ad48b7334a2eb2edf22f6c91f7b3f22a22a837 (diff)
drm/i915: Add LVDS support for IGDNG
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com> Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c13
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c127
2 files changed, 114 insertions, 26 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 53cf6efa67b6..05bd97e3e3e0 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1542,6 +1542,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
1542 int pch_fp_reg = (pipe == 0) ? PCH_FPA0 : PCH_FPB0; 1542 int pch_fp_reg = (pipe == 0) ? PCH_FPA0 : PCH_FPB0;
1543 int pch_dpll_reg = (pipe == 0) ? PCH_DPLL_A : PCH_DPLL_B; 1543 int pch_dpll_reg = (pipe == 0) ? PCH_DPLL_A : PCH_DPLL_B;
1544 int fdi_rx_reg = (pipe == 0) ? FDI_RXA_CTL : FDI_RXB_CTL; 1544 int fdi_rx_reg = (pipe == 0) ? FDI_RXA_CTL : FDI_RXB_CTL;
1545 int lvds_reg = LVDS;
1545 u32 temp; 1546 u32 temp;
1546 int sdvo_pixel_multiply; 1547 int sdvo_pixel_multiply;
1547 1548
@@ -1772,8 +1773,12 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
1772 * things on. 1773 * things on.
1773 */ 1774 */
1774 if (is_lvds) { 1775 if (is_lvds) {
1775 u32 lvds = I915_READ(LVDS); 1776 u32 lvds;
1776 1777
1778 if (IS_IGDNG(dev))
1779 lvds_reg = PCH_LVDS;
1780
1781 lvds = I915_READ(lvds_reg);
1777 lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT; 1782 lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT;
1778 /* Set the B0-B3 data pairs corresponding to whether we're going to 1783 /* Set the B0-B3 data pairs corresponding to whether we're going to
1779 * set the DPLLs for dual-channel mode or not. 1784 * set the DPLLs for dual-channel mode or not.
@@ -1788,8 +1793,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
1788 * panels behave in the two modes. 1793 * panels behave in the two modes.
1789 */ 1794 */
1790 1795
1791 I915_WRITE(LVDS, lvds); 1796 I915_WRITE(lvds_reg, lvds);
1792 I915_READ(LVDS); 1797 I915_READ(lvds_reg);
1793 } 1798 }
1794 1799
1795 I915_WRITE(fp_reg, fp); 1800 I915_WRITE(fp_reg, fp);
@@ -2428,7 +2433,7 @@ static void intel_setup_outputs(struct drm_device *dev)
2428 intel_crt_init(dev); 2433 intel_crt_init(dev);
2429 2434
2430 /* Set up integrated LVDS */ 2435 /* Set up integrated LVDS */
2431 if (IS_MOBILE(dev) && !IS_I830(dev) && !IS_IGDNG(dev)) 2436 if (IS_MOBILE(dev) && !IS_I830(dev))
2432 intel_lvds_init(dev); 2437 intel_lvds_init(dev);
2433 2438
2434 if (IS_IGDNG(dev)) { 2439 if (IS_IGDNG(dev)) {
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 53731f0ffcb5..eea3a548b82a 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -45,10 +45,15 @@
45static void intel_lvds_set_backlight(struct drm_device *dev, int level) 45static void intel_lvds_set_backlight(struct drm_device *dev, int level)
46{ 46{
47 struct drm_i915_private *dev_priv = dev->dev_private; 47 struct drm_i915_private *dev_priv = dev->dev_private;
48 u32 blc_pwm_ctl; 48 u32 blc_pwm_ctl, reg;
49 49
50 blc_pwm_ctl = I915_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; 50 if (IS_IGDNG(dev))
51 I915_WRITE(BLC_PWM_CTL, (blc_pwm_ctl | 51 reg = BLC_PWM_CPU_CTL;
52 else
53 reg = BLC_PWM_CTL;
54
55 blc_pwm_ctl = I915_READ(reg) & ~BACKLIGHT_DUTY_CYCLE_MASK;
56 I915_WRITE(reg, (blc_pwm_ctl |
52 (level << BACKLIGHT_DUTY_CYCLE_SHIFT))); 57 (level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
53} 58}
54 59
@@ -58,8 +63,14 @@ static void intel_lvds_set_backlight(struct drm_device *dev, int level)
58static u32 intel_lvds_get_max_backlight(struct drm_device *dev) 63static u32 intel_lvds_get_max_backlight(struct drm_device *dev)
59{ 64{
60 struct drm_i915_private *dev_priv = dev->dev_private; 65 struct drm_i915_private *dev_priv = dev->dev_private;
66 u32 reg;
67
68 if (IS_IGDNG(dev))
69 reg = BLC_PWM_PCH_CTL2;
70 else
71 reg = BLC_PWM_CTL;
61 72
62 return ((I915_READ(BLC_PWM_CTL) & BACKLIGHT_MODULATION_FREQ_MASK) >> 73 return ((I915_READ(reg) & BACKLIGHT_MODULATION_FREQ_MASK) >>
63 BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; 74 BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
64} 75}
65 76
@@ -69,23 +80,31 @@ static u32 intel_lvds_get_max_backlight(struct drm_device *dev)
69static void intel_lvds_set_power(struct drm_device *dev, bool on) 80static void intel_lvds_set_power(struct drm_device *dev, bool on)
70{ 81{
71 struct drm_i915_private *dev_priv = dev->dev_private; 82 struct drm_i915_private *dev_priv = dev->dev_private;
72 u32 pp_status; 83 u32 pp_status, ctl_reg, status_reg;
84
85 if (IS_IGDNG(dev)) {
86 ctl_reg = PCH_PP_CONTROL;
87 status_reg = PCH_PP_STATUS;
88 } else {
89 ctl_reg = PP_CONTROL;
90 status_reg = PP_STATUS;
91 }
73 92
74 if (on) { 93 if (on) {
75 I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | 94 I915_WRITE(ctl_reg, I915_READ(ctl_reg) |
76 POWER_TARGET_ON); 95 POWER_TARGET_ON);
77 do { 96 do {
78 pp_status = I915_READ(PP_STATUS); 97 pp_status = I915_READ(status_reg);
79 } while ((pp_status & PP_ON) == 0); 98 } while ((pp_status & PP_ON) == 0);
80 99
81 intel_lvds_set_backlight(dev, dev_priv->backlight_duty_cycle); 100 intel_lvds_set_backlight(dev, dev_priv->backlight_duty_cycle);
82 } else { 101 } else {
83 intel_lvds_set_backlight(dev, 0); 102 intel_lvds_set_backlight(dev, 0);
84 103
85 I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) & 104 I915_WRITE(ctl_reg, I915_READ(ctl_reg) &
86 ~POWER_TARGET_ON); 105 ~POWER_TARGET_ON);
87 do { 106 do {
88 pp_status = I915_READ(PP_STATUS); 107 pp_status = I915_READ(status_reg);
89 } while (pp_status & PP_ON); 108 } while (pp_status & PP_ON);
90 } 109 }
91} 110}
@@ -106,12 +125,28 @@ static void intel_lvds_save(struct drm_connector *connector)
106{ 125{
107 struct drm_device *dev = connector->dev; 126 struct drm_device *dev = connector->dev;
108 struct drm_i915_private *dev_priv = dev->dev_private; 127 struct drm_i915_private *dev_priv = dev->dev_private;
128 u32 pp_on_reg, pp_off_reg, pp_ctl_reg, pp_div_reg;
129 u32 pwm_ctl_reg;
130
131 if (IS_IGDNG(dev)) {
132 pp_on_reg = PCH_PP_ON_DELAYS;
133 pp_off_reg = PCH_PP_OFF_DELAYS;
134 pp_ctl_reg = PCH_PP_CONTROL;
135 pp_div_reg = PCH_PP_DIVISOR;
136 pwm_ctl_reg = BLC_PWM_CPU_CTL;
137 } else {
138 pp_on_reg = PP_ON_DELAYS;
139 pp_off_reg = PP_OFF_DELAYS;
140 pp_ctl_reg = PP_CONTROL;
141 pp_div_reg = PP_DIVISOR;
142 pwm_ctl_reg = BLC_PWM_CTL;
143 }
109 144
110 dev_priv->savePP_ON = I915_READ(PP_ON_DELAYS); 145 dev_priv->savePP_ON = I915_READ(pp_on_reg);
111 dev_priv->savePP_OFF = I915_READ(PP_OFF_DELAYS); 146 dev_priv->savePP_OFF = I915_READ(pp_off_reg);
112 dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL); 147 dev_priv->savePP_CONTROL = I915_READ(pp_ctl_reg);
113 dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR); 148 dev_priv->savePP_DIVISOR = I915_READ(pp_div_reg);
114 dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); 149 dev_priv->saveBLC_PWM_CTL = I915_READ(pwm_ctl_reg);
115 dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL & 150 dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL &
116 BACKLIGHT_DUTY_CYCLE_MASK); 151 BACKLIGHT_DUTY_CYCLE_MASK);
117 152
@@ -127,12 +162,28 @@ static void intel_lvds_restore(struct drm_connector *connector)
127{ 162{
128 struct drm_device *dev = connector->dev; 163 struct drm_device *dev = connector->dev;
129 struct drm_i915_private *dev_priv = dev->dev_private; 164 struct drm_i915_private *dev_priv = dev->dev_private;
165 u32 pp_on_reg, pp_off_reg, pp_ctl_reg, pp_div_reg;
166 u32 pwm_ctl_reg;
167
168 if (IS_IGDNG(dev)) {
169 pp_on_reg = PCH_PP_ON_DELAYS;
170 pp_off_reg = PCH_PP_OFF_DELAYS;
171 pp_ctl_reg = PCH_PP_CONTROL;
172 pp_div_reg = PCH_PP_DIVISOR;
173 pwm_ctl_reg = BLC_PWM_CPU_CTL;
174 } else {
175 pp_on_reg = PP_ON_DELAYS;
176 pp_off_reg = PP_OFF_DELAYS;
177 pp_ctl_reg = PP_CONTROL;
178 pp_div_reg = PP_DIVISOR;
179 pwm_ctl_reg = BLC_PWM_CTL;
180 }
130 181
131 I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL); 182 I915_WRITE(pwm_ctl_reg, dev_priv->saveBLC_PWM_CTL);
132 I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON); 183 I915_WRITE(pp_on_reg, dev_priv->savePP_ON);
133 I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF); 184 I915_WRITE(pp_off_reg, dev_priv->savePP_OFF);
134 I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR); 185 I915_WRITE(pp_div_reg, dev_priv->savePP_DIVISOR);
135 I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); 186 I915_WRITE(pp_ctl_reg, dev_priv->savePP_CONTROL);
136 if (dev_priv->savePP_CONTROL & POWER_TARGET_ON) 187 if (dev_priv->savePP_CONTROL & POWER_TARGET_ON)
137 intel_lvds_set_power(dev, true); 188 intel_lvds_set_power(dev, true);
138 else 189 else
@@ -216,8 +267,14 @@ static void intel_lvds_prepare(struct drm_encoder *encoder)
216{ 267{
217 struct drm_device *dev = encoder->dev; 268 struct drm_device *dev = encoder->dev;
218 struct drm_i915_private *dev_priv = dev->dev_private; 269 struct drm_i915_private *dev_priv = dev->dev_private;
270 u32 reg;
219 271
220 dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); 272 if (IS_IGDNG(dev))
273 reg = BLC_PWM_CPU_CTL;
274 else
275 reg = BLC_PWM_CTL;
276
277 dev_priv->saveBLC_PWM_CTL = I915_READ(reg);
221 dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL & 278 dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL &
222 BACKLIGHT_DUTY_CYCLE_MASK); 279 BACKLIGHT_DUTY_CYCLE_MASK);
223 280
@@ -251,6 +308,10 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
251 * settings. 308 * settings.
252 */ 309 */
253 310
311 /* No panel fitting yet, fixme */
312 if (IS_IGDNG(dev))
313 return;
314
254 /* 315 /*
255 * Enable automatic panel scaling so that non-native modes fill the 316 * Enable automatic panel scaling so that non-native modes fill the
256 * screen. Should be enabled before the pipe is enabled, according to 317 * screen. Should be enabled before the pipe is enabled, according to
@@ -446,12 +507,18 @@ void intel_lvds_init(struct drm_device *dev)
446 struct drm_display_mode *scan; /* *modes, *bios_mode; */ 507 struct drm_display_mode *scan; /* *modes, *bios_mode; */
447 struct drm_crtc *crtc; 508 struct drm_crtc *crtc;
448 u32 lvds; 509 u32 lvds;
449 int pipe; 510 int pipe, gpio = GPIOC;
450 511
451 /* Skip init on machines we know falsely report LVDS */ 512 /* Skip init on machines we know falsely report LVDS */
452 if (dmi_check_system(intel_no_lvds)) 513 if (dmi_check_system(intel_no_lvds))
453 return; 514 return;
454 515
516 if (IS_IGDNG(dev)) {
517 if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0)
518 return;
519 gpio = PCH_GPIOC;
520 }
521
455 intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); 522 intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
456 if (!intel_output) { 523 if (!intel_output) {
457 return; 524 return;
@@ -486,7 +553,7 @@ void intel_lvds_init(struct drm_device *dev)
486 */ 553 */
487 554
488 /* Set up the DDC bus. */ 555 /* Set up the DDC bus. */
489 intel_output->ddc_bus = intel_i2c_create(dev, GPIOC, "LVDSDDC_C"); 556 intel_output->ddc_bus = intel_i2c_create(dev, gpio, "LVDSDDC_C");
490 if (!intel_output->ddc_bus) { 557 if (!intel_output->ddc_bus) {
491 dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " 558 dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
492 "failed.\n"); 559 "failed.\n");
@@ -528,6 +595,11 @@ void intel_lvds_init(struct drm_device *dev)
528 * on. If so, assume that whatever is currently programmed is the 595 * on. If so, assume that whatever is currently programmed is the
529 * correct mode. 596 * correct mode.
530 */ 597 */
598
599 /* IGDNG: FIXME if still fail, not try pipe mode now */
600 if (IS_IGDNG(dev))
601 goto failed;
602
531 lvds = I915_READ(LVDS); 603 lvds = I915_READ(LVDS);
532 pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0; 604 pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
533 crtc = intel_get_crtc_from_pipe(dev, pipe); 605 crtc = intel_get_crtc_from_pipe(dev, pipe);
@@ -546,6 +618,17 @@ void intel_lvds_init(struct drm_device *dev)
546 goto failed; 618 goto failed;
547 619
548out: 620out:
621 if (IS_IGDNG(dev)) {
622 u32 pwm;
623 /* make sure PWM is enabled */
624 pwm = I915_READ(BLC_PWM_CPU_CTL2);
625 pwm |= (PWM_ENABLE | PWM_PIPE_B);
626 I915_WRITE(BLC_PWM_CPU_CTL2, pwm);
627
628 pwm = I915_READ(BLC_PWM_PCH_CTL1);
629 pwm |= PWM_PCH_ENABLE;
630 I915_WRITE(BLC_PWM_PCH_CTL1, pwm);
631 }
549 drm_sysfs_connector_add(connector); 632 drm_sysfs_connector_add(connector);
550 return; 633 return;
551 634