aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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