aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2012-04-25 09:38:07 -0400
committerDave Airlie <airlied@redhat.com>2012-04-27 04:24:16 -0400
commitd235e64a4367ad3ff204309490c4325b4f89b25b (patch)
tree33e84fdfc41628f78c5183f04e450d396c1cbc38 /drivers
parentb60bfb6585bcda7bc7abd32ce9a14d4c8a6acc8e (diff)
cdv: continue synching up with updated reference code
In particular clean up the errata handling and correct the crtc masks. We do this a bit differently using our device abstraction for neatness. This doesn't address the ACPI opregion and hotplug plumbing, nor the IRQ related changes that will need. It touches on backlight init but the full backlight support is not in this change set. Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/gma500/cdv_device.c20
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_crt.c20
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_display.c61
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_lvds.c17
-rw-r--r--drivers/gpu/drm/gma500/framebuffer.c13
-rw-r--r--drivers/gpu/drm/gma500/mdfld_device.c2
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_device.c2
-rw-r--r--drivers/gpu/drm/gma500/psb_device.c2
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.h4
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_reg.h4
10 files changed, 89 insertions, 56 deletions
diff --git a/drivers/gpu/drm/gma500/cdv_device.c b/drivers/gpu/drm/gma500/cdv_device.c
index a54cc738926a..5cc06a8fcb7a 100644
--- a/drivers/gpu/drm/gma500/cdv_device.c
+++ b/drivers/gpu/drm/gma500/cdv_device.c
@@ -49,6 +49,9 @@ static void cdv_disable_vga(struct drm_device *dev)
49static int cdv_output_init(struct drm_device *dev) 49static int cdv_output_init(struct drm_device *dev)
50{ 50{
51 struct drm_psb_private *dev_priv = dev->dev_private; 51 struct drm_psb_private *dev_priv = dev->dev_private;
52
53 drm_mode_create_scaling_mode_property(dev);
54
52 cdv_disable_vga(dev); 55 cdv_disable_vga(dev);
53 56
54 cdv_intel_crt_init(dev, &dev_priv->mode_dev); 57 cdv_intel_crt_init(dev, &dev_priv->mode_dev);
@@ -238,6 +241,18 @@ static void cdv_init_pm(struct drm_device *dev)
238 dev_err(dev->dev, "GPU: power management timed out.\n"); 241 dev_err(dev->dev, "GPU: power management timed out.\n");
239} 242}
240 243
244static void cdv_errata(struct drm_device *dev)
245{
246 /* Disable bonus launch.
247 * CPU and GPU competes for memory and display misses updates and flickers.
248 * Worst with dual core, dual displays.
249 *
250 * Fixes were done to Win 7 gfx driver to disable a feature called Bonus
251 * Launch to work around the issue, by degrading performance.
252 */
253 CDV_MSG_WRITE32(3, 0x30, 0x08027108);
254}
255
241/** 256/**
242 * cdv_save_display_registers - save registers lost on suspend 257 * cdv_save_display_registers - save registers lost on suspend
243 * @dev: our DRM device 258 * @dev: our DRM device
@@ -355,7 +370,7 @@ static int cdv_restore_display_registers(struct drm_device *dev)
355 REG_WRITE(PSB_INT_MASK_R, regs->cdv.saveIMR); 370 REG_WRITE(PSB_INT_MASK_R, regs->cdv.saveIMR);
356 371
357 /* Fix arbitration bug */ 372 /* Fix arbitration bug */
358 CDV_MSG_WRITE32(3, 0x30, 0x08027108); 373 cdv_errata(dev);
359 374
360 drm_mode_config_reset(dev); 375 drm_mode_config_reset(dev);
361 376
@@ -464,8 +479,11 @@ const struct psb_ops cdv_chip_ops = {
464 .accel_2d = 0, 479 .accel_2d = 0,
465 .pipes = 2, 480 .pipes = 2,
466 .crtcs = 2, 481 .crtcs = 2,
482 .hdmi_mask = (1 << 0) | (1 << 1),
483 .lvds_mask = (1 << 1),
467 .sgx_offset = MRST_SGX_OFFSET, 484 .sgx_offset = MRST_SGX_OFFSET,
468 .chip_setup = cdv_chip_setup, 485 .chip_setup = cdv_chip_setup,
486 .errata = cdv_errata,
469 487
470 .crtc_helper = &cdv_intel_helper_funcs, 488 .crtc_helper = &cdv_intel_helper_funcs,
471 .crtc_funcs = &cdv_intel_crtc_funcs, 489 .crtc_funcs = &cdv_intel_crtc_funcs,
diff --git a/drivers/gpu/drm/gma500/cdv_intel_crt.c b/drivers/gpu/drm/gma500/cdv_intel_crt.c
index 1a82843b157b..187422018601 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_crt.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_crt.c
@@ -78,9 +78,6 @@ static int cdv_intel_crt_mode_valid(struct drm_connector *connector,
78 if (mode->clock > 355000) 78 if (mode->clock > 355000)
79 return MODE_CLOCK_HIGH; 79 return MODE_CLOCK_HIGH;
80 80
81 if (mode->hdisplay > 1680 || mode->vdisplay > 1050)
82 return MODE_PANEL;
83
84 return MODE_OK; 81 return MODE_OK;
85} 82}
86 83
@@ -148,13 +145,7 @@ static bool cdv_intel_crt_detect_hotplug(struct drm_connector *connector,
148 struct drm_device *dev = connector->dev; 145 struct drm_device *dev = connector->dev;
149 u32 hotplug_en; 146 u32 hotplug_en;
150 int i, tries = 0, ret = false; 147 int i, tries = 0, ret = false;
151 u32 adpa_orig; 148 u32 orig;
152
153 /* disable the DAC when doing the hotplug detection */
154
155 adpa_orig = REG_READ(ADPA);
156
157 REG_WRITE(ADPA, adpa_orig & ~(ADPA_DAC_ENABLE));
158 149
159 /* 150 /*
160 * On a CDV thep, CRT detect sequence need to be done twice 151 * On a CDV thep, CRT detect sequence need to be done twice
@@ -162,7 +153,7 @@ static bool cdv_intel_crt_detect_hotplug(struct drm_connector *connector,
162 */ 153 */
163 tries = 2; 154 tries = 2;
164 155
165 hotplug_en = REG_READ(PORT_HOTPLUG_EN); 156 orig = hotplug_en = REG_READ(PORT_HOTPLUG_EN);
166 hotplug_en &= ~(CRT_HOTPLUG_DETECT_MASK); 157 hotplug_en &= ~(CRT_HOTPLUG_DETECT_MASK);
167 hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; 158 hotplug_en |= CRT_HOTPLUG_FORCE_DETECT;
168 159
@@ -187,8 +178,11 @@ static bool cdv_intel_crt_detect_hotplug(struct drm_connector *connector,
187 CRT_HOTPLUG_MONITOR_NONE) 178 CRT_HOTPLUG_MONITOR_NONE)
188 ret = true; 179 ret = true;
189 180
190 /* Restore the saved ADPA */ 181 /* clear the interrupt we just generated, if any */
191 REG_WRITE(ADPA, adpa_orig); 182 REG_WRITE(PORT_HOTPLUG_STAT, CRT_HOTPLUG_INT_STATUS);
183
184 /* and put the bits back */
185 REG_WRITE(PORT_HOTPLUG_EN, orig);
192 return ret; 186 return ret;
193} 187}
194 188
diff --git a/drivers/gpu/drm/gma500/cdv_intel_display.c b/drivers/gpu/drm/gma500/cdv_intel_display.c
index 07b37f570ad9..2fab77854971 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_display.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_display.c
@@ -226,13 +226,13 @@ cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc,
226 int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; 226 int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
227 int ref_sfr = (pipe == 0) ? SB_REF_DPLLA : SB_REF_DPLLB; 227 int ref_sfr = (pipe == 0) ? SB_REF_DPLLA : SB_REF_DPLLB;
228 u32 ref_value; 228 u32 ref_value;
229 u32 lane_reg, lane_value;
229 230
230 cdv_sb_reset(dev); 231 cdv_sb_reset(dev);
231 232
232 if ((REG_READ(dpll_reg) & DPLL_SYNCLOCK_ENABLE) == 0) { 233 REG_WRITE(dpll_reg, DPLL_SYNCLOCK_ENABLE | DPLL_VGA_MODE_DIS);
233 DRM_ERROR("Attempting to set DPLL with refclk disabled\n"); 234
234 return -EBUSY; 235 udelay(100);
235 }
236 236
237 /* Follow the BIOS and write the REF/SFR Register. Hardcoded value */ 237 /* Follow the BIOS and write the REF/SFR Register. Hardcoded value */
238 ref_value = 0x68A701; 238 ref_value = 0x68A701;
@@ -337,36 +337,29 @@ cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc,
337 if (ret) 337 if (ret)
338 return ret; 338 return ret;
339 339
340 /* always Program the Lane Register for the Pipe A*/ 340 lane_reg = PSB_LANE0;
341/* if (pipe == 0) */ { 341 cdv_sb_read(dev, lane_reg, &lane_value);
342 /* Program the Lane0/1 for HDMI B */ 342 lane_value &= ~(LANE_PLL_MASK);
343 u32 lane_reg, lane_value; 343 lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe);
344 344 cdv_sb_write(dev, lane_reg, lane_value);
345 lane_reg = PSB_LANE0; 345
346 cdv_sb_read(dev, lane_reg, &lane_value); 346 lane_reg = PSB_LANE1;
347 lane_value &= ~(LANE_PLL_MASK); 347 cdv_sb_read(dev, lane_reg, &lane_value);
348 lane_value |= LANE_PLL_ENABLE; 348 lane_value &= ~(LANE_PLL_MASK);
349 cdv_sb_write(dev, lane_reg, lane_value); 349 lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe);
350 350 cdv_sb_write(dev, lane_reg, lane_value);
351 lane_reg = PSB_LANE1; 351
352 cdv_sb_read(dev, lane_reg, &lane_value); 352 lane_reg = PSB_LANE2;
353 lane_value &= ~(LANE_PLL_MASK); 353 cdv_sb_read(dev, lane_reg, &lane_value);
354 lane_value |= LANE_PLL_ENABLE; 354 lane_value &= ~(LANE_PLL_MASK);
355 cdv_sb_write(dev, lane_reg, lane_value); 355 lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe);
356 356 cdv_sb_write(dev, lane_reg, lane_value);
357 /* Program the Lane2/3 for HDMI C */ 357
358 lane_reg = PSB_LANE2; 358 lane_reg = PSB_LANE3;
359 cdv_sb_read(dev, lane_reg, &lane_value); 359 cdv_sb_read(dev, lane_reg, &lane_value);
360 lane_value &= ~(LANE_PLL_MASK); 360 lane_value &= ~(LANE_PLL_MASK);
361 lane_value |= LANE_PLL_ENABLE; 361 lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe);
362 cdv_sb_write(dev, lane_reg, lane_value); 362 cdv_sb_write(dev, lane_reg, lane_value);
363
364 lane_reg = PSB_LANE3;
365 cdv_sb_read(dev, lane_reg, &lane_value);
366 lane_value &= ~(LANE_PLL_MASK);
367 lane_value |= LANE_PLL_ENABLE;
368 cdv_sb_write(dev, lane_reg, lane_value);
369 }
370 363
371 return 0; 364 return 0;
372} 365}
diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
index c87b179eadfd..44a8353d92bf 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
@@ -356,6 +356,8 @@ static void cdv_intel_lvds_mode_set(struct drm_encoder *encoder,
356{ 356{
357 struct drm_device *dev = encoder->dev; 357 struct drm_device *dev = encoder->dev;
358 struct drm_psb_private *dev_priv = dev->dev_private; 358 struct drm_psb_private *dev_priv = dev->dev_private;
359 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(
360 encoder->crtc);
359 u32 pfit_control; 361 u32 pfit_control;
360 362
361 /* 363 /*
@@ -377,6 +379,8 @@ static void cdv_intel_lvds_mode_set(struct drm_encoder *encoder,
377 else 379 else
378 pfit_control = 0; 380 pfit_control = 0;
379 381
382 pfit_control |= psb_intel_crtc->pipe << PFIT_PIPE_SHIFT;
383
380 if (dev_priv->lvds_dither) 384 if (dev_priv->lvds_dither)
381 pfit_control |= PANEL_8TO6_DITHER_ENABLE; 385 pfit_control |= PANEL_8TO6_DITHER_ENABLE;
382 386
@@ -767,6 +771,19 @@ void cdv_intel_lvds_init(struct drm_device *dev,
767 goto failed_find; 771 goto failed_find;
768 } 772 }
769 773
774 /* setup PWM */
775 {
776 u32 pwm;
777
778 pwm = REG_READ(BLC_PWM_CTL2);
779 if (pipe == 1)
780 pwm |= PWM_PIPE_B;
781 else
782 pwm &= ~PWM_PIPE_B;
783 pwm |= PWM_ENABLE;
784 REG_WRITE(BLC_PWM_CTL2, pwm);
785 }
786
770out: 787out:
771 drm_sysfs_connector_add(connector); 788 drm_sysfs_connector_add(connector);
772 return; 789 return;
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index c2cf6bf217dd..c9fe4bdeb681 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -748,10 +748,7 @@ static void psb_setup_outputs(struct drm_device *dev)
748 clone_mask = (1 << INTEL_OUTPUT_SDVO); 748 clone_mask = (1 << INTEL_OUTPUT_SDVO);
749 break; 749 break;
750 case INTEL_OUTPUT_LVDS: 750 case INTEL_OUTPUT_LVDS:
751 if (IS_MRST(dev)) 751 crtc_mask = dev_priv->ops->lvds_mask;
752 crtc_mask = (1 << 0);
753 else
754 crtc_mask = (1 << 1);
755 clone_mask = (1 << INTEL_OUTPUT_LVDS); 752 clone_mask = (1 << INTEL_OUTPUT_LVDS);
756 break; 753 break;
757 case INTEL_OUTPUT_MIPI: 754 case INTEL_OUTPUT_MIPI:
@@ -763,10 +760,7 @@ static void psb_setup_outputs(struct drm_device *dev)
763 clone_mask = (1 << INTEL_OUTPUT_MIPI2); 760 clone_mask = (1 << INTEL_OUTPUT_MIPI2);
764 break; 761 break;
765 case INTEL_OUTPUT_HDMI: 762 case INTEL_OUTPUT_HDMI:
766 if (IS_MFLD(dev)) 763 crtc_mask = dev_priv->ops->hdmi_mask;
767 crtc_mask = (1 << 1);
768 else
769 crtc_mask = (1 << 0);
770 clone_mask = (1 << INTEL_OUTPUT_HDMI); 764 clone_mask = (1 << INTEL_OUTPUT_HDMI);
771 break; 765 break;
772 } 766 }
@@ -802,6 +796,9 @@ void psb_modeset_init(struct drm_device *dev)
802 dev->mode_config.max_height = 2048; 796 dev->mode_config.max_height = 2048;
803 797
804 psb_setup_outputs(dev); 798 psb_setup_outputs(dev);
799
800 if (dev_priv->ops->errata)
801 dev_priv->ops->errata(dev);
805} 802}
806 803
807void psb_modeset_cleanup(struct drm_device *dev) 804void psb_modeset_cleanup(struct drm_device *dev)
diff --git a/drivers/gpu/drm/gma500/mdfld_device.c b/drivers/gpu/drm/gma500/mdfld_device.c
index af656787db0f..a0bd48cd92f4 100644
--- a/drivers/gpu/drm/gma500/mdfld_device.c
+++ b/drivers/gpu/drm/gma500/mdfld_device.c
@@ -672,6 +672,8 @@ const struct psb_ops mdfld_chip_ops = {
672 .accel_2d = 0, 672 .accel_2d = 0,
673 .pipes = 3, 673 .pipes = 3,
674 .crtcs = 3, 674 .crtcs = 3,
675 .lvds_mask = (1 << 1);
676 .hdmi_mask = (1 << 1);
675 .sgx_offset = MRST_SGX_OFFSET, 677 .sgx_offset = MRST_SGX_OFFSET,
676 678
677 .chip_setup = mid_chip_setup, 679 .chip_setup = mid_chip_setup,
diff --git a/drivers/gpu/drm/gma500/oaktrail_device.c b/drivers/gpu/drm/gma500/oaktrail_device.c
index 41d1924ea31e..4c5a1864adf4 100644
--- a/drivers/gpu/drm/gma500/oaktrail_device.c
+++ b/drivers/gpu/drm/gma500/oaktrail_device.c
@@ -487,6 +487,8 @@ const struct psb_ops oaktrail_chip_ops = {
487 .accel_2d = 1, 487 .accel_2d = 1,
488 .pipes = 2, 488 .pipes = 2,
489 .crtcs = 2, 489 .crtcs = 2,
490 .hdmi_mask = (1 << 0),
491 .lvds_mask = (1 << 0),
490 .sgx_offset = MRST_SGX_OFFSET, 492 .sgx_offset = MRST_SGX_OFFSET,
491 493
492 .chip_setup = oaktrail_chip_setup, 494 .chip_setup = oaktrail_chip_setup,
diff --git a/drivers/gpu/drm/gma500/psb_device.c b/drivers/gpu/drm/gma500/psb_device.c
index 95d163e4f1f4..34e6866a73b2 100644
--- a/drivers/gpu/drm/gma500/psb_device.c
+++ b/drivers/gpu/drm/gma500/psb_device.c
@@ -308,6 +308,8 @@ const struct psb_ops psb_chip_ops = {
308 .accel_2d = 1, 308 .accel_2d = 1,
309 .pipes = 2, 309 .pipes = 2,
310 .crtcs = 2, 310 .crtcs = 2,
311 .hdmi_mask = (1 << 0),
312 .lvds_mask = (1 << 1),
311 .sgx_offset = PSB_SGX_OFFSET, 313 .sgx_offset = PSB_SGX_OFFSET,
312 .chip_setup = psb_chip_setup, 314 .chip_setup = psb_chip_setup,
313 .chip_teardown = psb_chip_teardown, 315 .chip_teardown = psb_chip_teardown,
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index 64de248558b2..6235499f39b8 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -688,6 +688,8 @@ struct psb_ops {
688 int pipes; /* Number of output pipes */ 688 int pipes; /* Number of output pipes */
689 int crtcs; /* Number of CRTCs */ 689 int crtcs; /* Number of CRTCs */
690 int sgx_offset; /* Base offset of SGX device */ 690 int sgx_offset; /* Base offset of SGX device */
691 int hdmi_mask; /* Mask of HDMI CRTCs */
692 int lvds_mask; /* Mask of LVDS CRTCs */
691 693
692 /* Sub functions */ 694 /* Sub functions */
693 struct drm_crtc_helper_funcs const *crtc_helper; 695 struct drm_crtc_helper_funcs const *crtc_helper;
@@ -696,6 +698,8 @@ struct psb_ops {
696 /* Setup hooks */ 698 /* Setup hooks */
697 int (*chip_setup)(struct drm_device *dev); 699 int (*chip_setup)(struct drm_device *dev);
698 void (*chip_teardown)(struct drm_device *dev); 700 void (*chip_teardown)(struct drm_device *dev);
701 /* Optional helper caller after modeset */
702 void (*errata)(struct drm_device *dev);
699 703
700 /* Display management hooks */ 704 /* Display management hooks */
701 int (*output_init)(struct drm_device *dev); 705 int (*output_init)(struct drm_device *dev);
diff --git a/drivers/gpu/drm/gma500/psb_intel_reg.h b/drivers/gpu/drm/gma500/psb_intel_reg.h
index 46792fc7d0d0..cbd8aee2b7ed 100644
--- a/drivers/gpu/drm/gma500/psb_intel_reg.h
+++ b/drivers/gpu/drm/gma500/psb_intel_reg.h
@@ -91,6 +91,9 @@
91 91
92#define BLC_PWM_CTL 0x61254 92#define BLC_PWM_CTL 0x61254
93#define BLC_PWM_CTL2 0x61250 93#define BLC_PWM_CTL2 0x61250
94#define PWM_ENABLE (1 << 31)
95#define PWM_LEGACY_MODE (1 << 30)
96#define PWM_PIPE_B (1 << 29)
94#define BLC_PWM_CTL_C 0x62254 97#define BLC_PWM_CTL_C 0x62254
95#define BLC_PWM_CTL2_C 0x62250 98#define BLC_PWM_CTL2_C 0x62250
96#define BACKLIGHT_MODULATION_FREQ_SHIFT (17) 99#define BACKLIGHT_MODULATION_FREQ_SHIFT (17)
@@ -1338,6 +1341,7 @@ No status bits are changed.
1338 1341
1339#define LANE_PLL_MASK (0x7 << 20) 1342#define LANE_PLL_MASK (0x7 << 20)
1340#define LANE_PLL_ENABLE (0x3 << 20) 1343#define LANE_PLL_ENABLE (0x3 << 20)
1344#define LANE_PLL_PIPE(p) (((p) == 0) ? (1 << 21) : (0 << 21))
1341 1345
1342 1346
1343#endif 1347#endif