aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_crtc.c241
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.h27
2 files changed, 162 insertions, 106 deletions
diff --git a/drivers/gpu/drm/gma500/oaktrail_crtc.c b/drivers/gpu/drm/gma500/oaktrail_crtc.c
index bde3065f7422..ef4f0766a385 100644
--- a/drivers/gpu/drm/gma500/oaktrail_crtc.c
+++ b/drivers/gpu/drm/gma500/oaktrail_crtc.c
@@ -227,6 +227,8 @@ static void oaktrail_crtc_dpms(struct drm_crtc *crtc, int mode)
227 int pipe = gma_crtc->pipe; 227 int pipe = gma_crtc->pipe;
228 const struct psb_offset *map = &dev_priv->regmap[pipe]; 228 const struct psb_offset *map = &dev_priv->regmap[pipe];
229 u32 temp; 229 u32 temp;
230 int i;
231 int need_aux = gma_pipe_has_type(crtc, INTEL_OUTPUT_SDVO) ? 1 : 0;
230 232
231 if (pipe == 1) { 233 if (pipe == 1) {
232 oaktrail_crtc_hdmi_dpms(crtc, mode); 234 oaktrail_crtc_hdmi_dpms(crtc, mode);
@@ -243,35 +245,45 @@ static void oaktrail_crtc_dpms(struct drm_crtc *crtc, int mode)
243 case DRM_MODE_DPMS_ON: 245 case DRM_MODE_DPMS_ON:
244 case DRM_MODE_DPMS_STANDBY: 246 case DRM_MODE_DPMS_STANDBY:
245 case DRM_MODE_DPMS_SUSPEND: 247 case DRM_MODE_DPMS_SUSPEND:
246 /* Enable the DPLL */ 248 for (i = 0; i <= need_aux; i++) {
247 temp = REG_READ(map->dpll); 249 /* Enable the DPLL */
248 if ((temp & DPLL_VCO_ENABLE) == 0) { 250 temp = REG_READ_WITH_AUX(map->dpll, i);
249 REG_WRITE(map->dpll, temp); 251 if ((temp & DPLL_VCO_ENABLE) == 0) {
250 REG_READ(map->dpll); 252 REG_WRITE_WITH_AUX(map->dpll, temp, i);
251 /* Wait for the clocks to stabilize. */ 253 REG_READ_WITH_AUX(map->dpll, i);
252 udelay(150); 254 /* Wait for the clocks to stabilize. */
253 REG_WRITE(map->dpll, temp | DPLL_VCO_ENABLE); 255 udelay(150);
254 REG_READ(map->dpll); 256 REG_WRITE_WITH_AUX(map->dpll,
255 /* Wait for the clocks to stabilize. */ 257 temp | DPLL_VCO_ENABLE, i);
256 udelay(150); 258 REG_READ_WITH_AUX(map->dpll, i);
257 REG_WRITE(map->dpll, temp | DPLL_VCO_ENABLE); 259 /* Wait for the clocks to stabilize. */
258 REG_READ(map->dpll); 260 udelay(150);
259 /* Wait for the clocks to stabilize. */ 261 REG_WRITE_WITH_AUX(map->dpll,
260 udelay(150); 262 temp | DPLL_VCO_ENABLE, i);
261 } 263 REG_READ_WITH_AUX(map->dpll, i);
262 /* Enable the pipe */ 264 /* Wait for the clocks to stabilize. */
263 temp = REG_READ(map->conf); 265 udelay(150);
264 if ((temp & PIPEACONF_ENABLE) == 0) 266 }
265 REG_WRITE(map->conf, temp | PIPEACONF_ENABLE); 267
266 /* Enable the plane */ 268 /* Enable the pipe */
267 temp = REG_READ(map->cntr); 269 temp = REG_READ_WITH_AUX(map->conf, i);
268 if ((temp & DISPLAY_PLANE_ENABLE) == 0) { 270 if ((temp & PIPEACONF_ENABLE) == 0) {
269 REG_WRITE(map->cntr, 271 REG_WRITE_WITH_AUX(map->conf,
270 temp | DISPLAY_PLANE_ENABLE); 272 temp | PIPEACONF_ENABLE, i);
271 /* Flush the plane changes */ 273 }
272 REG_WRITE(map->base, REG_READ(map->base));
273 }
274 274
275 /* Enable the plane */
276 temp = REG_READ_WITH_AUX(map->cntr, i);
277 if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
278 REG_WRITE_WITH_AUX(map->cntr,
279 temp | DISPLAY_PLANE_ENABLE,
280 i);
281 /* Flush the plane changes */
282 REG_WRITE_WITH_AUX(map->base,
283 REG_READ_WITH_AUX(map->base, i), i);
284 }
285
286 }
275 gma_crtc_load_lut(crtc); 287 gma_crtc_load_lut(crtc);
276 288
277 /* Give the overlay scaler a chance to enable 289 /* Give the overlay scaler a chance to enable
@@ -283,35 +295,40 @@ static void oaktrail_crtc_dpms(struct drm_crtc *crtc, int mode)
283 * if it's on this pipe */ 295 * if it's on this pipe */
284 /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */ 296 /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
285 297
286 /* Disable the VGA plane that we never use */ 298 for (i = 0; i <= need_aux; i++) {
287 REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); 299 /* Disable the VGA plane that we never use */
288 /* Disable display plane */ 300 REG_WRITE_WITH_AUX(VGACNTRL, VGA_DISP_DISABLE, i);
289 temp = REG_READ(map->cntr); 301 /* Disable display plane */
290 if ((temp & DISPLAY_PLANE_ENABLE) != 0) { 302 temp = REG_READ_WITH_AUX(map->cntr, i);
291 REG_WRITE(map->cntr, 303 if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
292 temp & ~DISPLAY_PLANE_ENABLE); 304 REG_WRITE_WITH_AUX(map->cntr,
293 /* Flush the plane changes */ 305 temp & ~DISPLAY_PLANE_ENABLE, i);
294 REG_WRITE(map->base, REG_READ(map->base)); 306 /* Flush the plane changes */
295 REG_READ(map->base); 307 REG_WRITE_WITH_AUX(map->base,
296 } 308 REG_READ(map->base), i);
309 REG_READ_WITH_AUX(map->base, i);
310 }
297 311
298 /* Next, disable display pipes */ 312 /* Next, disable display pipes */
299 temp = REG_READ(map->conf); 313 temp = REG_READ_WITH_AUX(map->conf, i);
300 if ((temp & PIPEACONF_ENABLE) != 0) { 314 if ((temp & PIPEACONF_ENABLE) != 0) {
301 REG_WRITE(map->conf, temp & ~PIPEACONF_ENABLE); 315 REG_WRITE_WITH_AUX(map->conf,
302 REG_READ(map->conf); 316 temp & ~PIPEACONF_ENABLE, i);
303 } 317 REG_READ_WITH_AUX(map->conf, i);
304 /* Wait for for the pipe disable to take effect. */ 318 }
305 gma_wait_for_vblank(dev); 319 /* Wait for for the pipe disable to take effect. */
320 gma_wait_for_vblank(dev);
321
322 temp = REG_READ_WITH_AUX(map->dpll, i);
323 if ((temp & DPLL_VCO_ENABLE) != 0) {
324 REG_WRITE_WITH_AUX(map->dpll,
325 temp & ~DPLL_VCO_ENABLE, i);
326 REG_READ_WITH_AUX(map->dpll, i);
327 }
306 328
307 temp = REG_READ(map->dpll); 329 /* Wait for the clocks to turn off. */
308 if ((temp & DPLL_VCO_ENABLE) != 0) { 330 udelay(150);
309 REG_WRITE(map->dpll, temp & ~DPLL_VCO_ENABLE);
310 REG_READ(map->dpll);
311 } 331 }
312
313 /* Wait for the clocks to turn off. */
314 udelay(150);
315 break; 332 break;
316 } 333 }
317 334
@@ -367,6 +384,8 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc,
367 struct gma_encoder *gma_encoder = NULL; 384 struct gma_encoder *gma_encoder = NULL;
368 uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN; 385 uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN;
369 struct drm_connector *connector; 386 struct drm_connector *connector;
387 int i;
388 int need_aux = gma_pipe_has_type(crtc, INTEL_OUTPUT_SDVO) ? 1 : 0;
370 389
371 if (pipe == 1) 390 if (pipe == 1)
372 return oaktrail_crtc_hdmi_mode_set(crtc, mode, adjusted_mode, x, y, old_fb); 391 return oaktrail_crtc_hdmi_mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
@@ -401,15 +420,17 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc,
401 } 420 }
402 421
403 /* Disable the VGA plane that we never use */ 422 /* Disable the VGA plane that we never use */
404 REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); 423 for (i = 0; i <= need_aux; i++)
424 REG_WRITE_WITH_AUX(VGACNTRL, VGA_DISP_DISABLE, i);
405 425
406 /* Disable the panel fitter if it was on our pipe */ 426 /* Disable the panel fitter if it was on our pipe */
407 if (oaktrail_panel_fitter_pipe(dev) == pipe) 427 if (oaktrail_panel_fitter_pipe(dev) == pipe)
408 REG_WRITE(PFIT_CONTROL, 0); 428 REG_WRITE(PFIT_CONTROL, 0);
409 429
410 REG_WRITE(map->src, 430 for (i = 0; i <= need_aux; i++) {
411 ((mode->crtc_hdisplay - 1) << 16) | 431 REG_WRITE_WITH_AUX(map->src, ((mode->crtc_hdisplay - 1) << 16) |
412 (mode->crtc_vdisplay - 1)); 432 (mode->crtc_vdisplay - 1), i);
433 }
413 434
414 if (gma_encoder) 435 if (gma_encoder)
415 drm_object_property_get_value(&connector->base, 436 drm_object_property_get_value(&connector->base,
@@ -426,35 +447,39 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc,
426 offsetY = (adjusted_mode->crtc_vdisplay - 447 offsetY = (adjusted_mode->crtc_vdisplay -
427 mode->crtc_vdisplay) / 2; 448 mode->crtc_vdisplay) / 2;
428 449
429 REG_WRITE(map->htotal, (mode->crtc_hdisplay - 1) | 450 for (i = 0; i <= need_aux; i++) {
430 ((adjusted_mode->crtc_htotal - 1) << 16)); 451 REG_WRITE_WITH_AUX(map->htotal, (mode->crtc_hdisplay - 1) |
431 REG_WRITE(map->vtotal, (mode->crtc_vdisplay - 1) | 452 ((adjusted_mode->crtc_htotal - 1) << 16), i);
432 ((adjusted_mode->crtc_vtotal - 1) << 16)); 453 REG_WRITE_WITH_AUX(map->vtotal, (mode->crtc_vdisplay - 1) |
433 REG_WRITE(map->hblank, 454 ((adjusted_mode->crtc_vtotal - 1) << 16), i);
434 (adjusted_mode->crtc_hblank_start - offsetX - 1) | 455 REG_WRITE_WITH_AUX(map->hblank,
435 ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16)); 456 (adjusted_mode->crtc_hblank_start - offsetX - 1) |
436 REG_WRITE(map->hsync, 457 ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16), i);
437 (adjusted_mode->crtc_hsync_start - offsetX - 1) | 458 REG_WRITE_WITH_AUX(map->hsync,
438 ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16)); 459 (adjusted_mode->crtc_hsync_start - offsetX - 1) |
439 REG_WRITE(map->vblank, 460 ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16), i);
440 (adjusted_mode->crtc_vblank_start - offsetY - 1) | 461 REG_WRITE_WITH_AUX(map->vblank,
441 ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16)); 462 (adjusted_mode->crtc_vblank_start - offsetY - 1) |
442 REG_WRITE(map->vsync, 463 ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16), i);
443 (adjusted_mode->crtc_vsync_start - offsetY - 1) | 464 REG_WRITE_WITH_AUX(map->vsync,
444 ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16)); 465 (adjusted_mode->crtc_vsync_start - offsetY - 1) |
466 ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16), i);
467 }
445 } else { 468 } else {
446 REG_WRITE(map->htotal, (adjusted_mode->crtc_hdisplay - 1) | 469 for (i = 0; i <= need_aux; i++) {
447 ((adjusted_mode->crtc_htotal - 1) << 16)); 470 REG_WRITE_WITH_AUX(map->htotal, (adjusted_mode->crtc_hdisplay - 1) |
448 REG_WRITE(map->vtotal, (adjusted_mode->crtc_vdisplay - 1) | 471 ((adjusted_mode->crtc_htotal - 1) << 16), i);
449 ((adjusted_mode->crtc_vtotal - 1) << 16)); 472 REG_WRITE_WITH_AUX(map->vtotal, (adjusted_mode->crtc_vdisplay - 1) |
450 REG_WRITE(map->hblank, (adjusted_mode->crtc_hblank_start - 1) | 473 ((adjusted_mode->crtc_vtotal - 1) << 16), i);
451 ((adjusted_mode->crtc_hblank_end - 1) << 16)); 474 REG_WRITE_WITH_AUX(map->hblank, (adjusted_mode->crtc_hblank_start - 1) |
452 REG_WRITE(map->hsync, (adjusted_mode->crtc_hsync_start - 1) | 475 ((adjusted_mode->crtc_hblank_end - 1) << 16), i);
453 ((adjusted_mode->crtc_hsync_end - 1) << 16)); 476 REG_WRITE_WITH_AUX(map->hsync, (adjusted_mode->crtc_hsync_start - 1) |
454 REG_WRITE(map->vblank, (adjusted_mode->crtc_vblank_start - 1) | 477 ((adjusted_mode->crtc_hsync_end - 1) << 16), i);
455 ((adjusted_mode->crtc_vblank_end - 1) << 16)); 478 REG_WRITE_WITH_AUX(map->vblank, (adjusted_mode->crtc_vblank_start - 1) |
456 REG_WRITE(map->vsync, (adjusted_mode->crtc_vsync_start - 1) | 479 ((adjusted_mode->crtc_vblank_end - 1) << 16), i);
457 ((adjusted_mode->crtc_vsync_end - 1) << 16)); 480 REG_WRITE_WITH_AUX(map->vsync, (adjusted_mode->crtc_vsync_start - 1) |
481 ((adjusted_mode->crtc_vsync_end - 1) << 16), i);
482 }
458 } 483 }
459 484
460 /* Flush the plane changes */ 485 /* Flush the plane changes */
@@ -534,31 +559,35 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc,
534 dpll |= DPLL_VCO_ENABLE; 559 dpll |= DPLL_VCO_ENABLE;
535 560
536 if (dpll & DPLL_VCO_ENABLE) { 561 if (dpll & DPLL_VCO_ENABLE) {
537 REG_WRITE(map->fp0, fp); 562 for (i = 0; i <= need_aux; i++) {
538 REG_WRITE(map->dpll, dpll & ~DPLL_VCO_ENABLE); 563 REG_WRITE_WITH_AUX(map->fp0, fp, i);
539 REG_READ(map->dpll); 564 REG_WRITE_WITH_AUX(map->dpll, dpll & ~DPLL_VCO_ENABLE, i);
540 /* Check the DPLLA lock bit PIPEACONF[29] */ 565 REG_READ_WITH_AUX(map->dpll, i);
541 udelay(150); 566 /* Check the DPLLA lock bit PIPEACONF[29] */
567 udelay(150);
568 }
542 } 569 }
543 570
544 REG_WRITE(map->fp0, fp); 571 for (i = 0; i <= need_aux; i++) {
545 REG_WRITE(map->dpll, dpll); 572 REG_WRITE_WITH_AUX(map->fp0, fp, i);
546 REG_READ(map->dpll); 573 REG_WRITE_WITH_AUX(map->dpll, dpll, i);
547 /* Wait for the clocks to stabilize. */ 574 REG_READ_WITH_AUX(map->dpll, i);
548 udelay(150); 575 /* Wait for the clocks to stabilize. */
576 udelay(150);
549 577
550 /* write it again -- the BIOS does, after all */ 578 /* write it again -- the BIOS does, after all */
551 REG_WRITE(map->dpll, dpll); 579 REG_WRITE_WITH_AUX(map->dpll, dpll, i);
552 REG_READ(map->dpll); 580 REG_READ_WITH_AUX(map->dpll, i);
553 /* Wait for the clocks to stabilize. */ 581 /* Wait for the clocks to stabilize. */
554 udelay(150); 582 udelay(150);
555 583
556 REG_WRITE(map->conf, pipeconf); 584 REG_WRITE_WITH_AUX(map->conf, pipeconf, i);
557 REG_READ(map->conf); 585 REG_READ_WITH_AUX(map->conf, i);
558 gma_wait_for_vblank(dev); 586 gma_wait_for_vblank(dev);
559 587
560 REG_WRITE(map->cntr, dspcntr); 588 REG_WRITE_WITH_AUX(map->cntr, dspcntr, i);
561 gma_wait_for_vblank(dev); 589 gma_wait_for_vblank(dev);
590 }
562 591
563oaktrail_crtc_mode_set_exit: 592oaktrail_crtc_mode_set_exit:
564 gma_power_end(dev); 593 gma_power_end(dev);
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index dc7a8dec68e5..b59e6588c343 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -941,6 +941,22 @@ static inline uint32_t REGISTER_READ_AUX(struct drm_device *dev, uint32_t reg)
941#define REG_READ(reg) REGISTER_READ(dev, (reg)) 941#define REG_READ(reg) REGISTER_READ(dev, (reg))
942#define REG_READ_AUX(reg) REGISTER_READ_AUX(dev, (reg)) 942#define REG_READ_AUX(reg) REGISTER_READ_AUX(dev, (reg))
943 943
944/* Useful for post reads */
945static inline uint32_t REGISTER_READ_WITH_AUX(struct drm_device *dev,
946 uint32_t reg, int aux)
947{
948 uint32_t val;
949
950 if (aux)
951 val = REG_READ_AUX(reg);
952 else
953 val = REG_READ(reg);
954
955 return val;
956}
957
958#define REG_READ_WITH_AUX(reg, aux) REGISTER_READ_WITH_AUX(dev, (reg), (aux))
959
944static inline void REGISTER_WRITE(struct drm_device *dev, uint32_t reg, 960static inline void REGISTER_WRITE(struct drm_device *dev, uint32_t reg,
945 uint32_t val) 961 uint32_t val)
946{ 962{
@@ -958,6 +974,17 @@ static inline void REGISTER_WRITE_AUX(struct drm_device *dev, uint32_t reg,
958#define REG_WRITE(reg, val) REGISTER_WRITE(dev, (reg), (val)) 974#define REG_WRITE(reg, val) REGISTER_WRITE(dev, (reg), (val))
959#define REG_WRITE_AUX(reg, val) REGISTER_WRITE_AUX(dev, (reg), (val)) 975#define REG_WRITE_AUX(reg, val) REGISTER_WRITE_AUX(dev, (reg), (val))
960 976
977static inline void REGISTER_WRITE_WITH_AUX(struct drm_device *dev, uint32_t reg,
978 uint32_t val, int aux)
979{
980 if (aux)
981 REG_WRITE_AUX(reg, val);
982 else
983 REG_WRITE(reg, val);
984}
985
986#define REG_WRITE_WITH_AUX(reg, val, aux) REGISTER_WRITE_WITH_AUX(dev, (reg), (val), (aux))
987
961static inline void REGISTER_WRITE16(struct drm_device *dev, 988static inline void REGISTER_WRITE16(struct drm_device *dev,
962 uint32_t reg, uint32_t val) 989 uint32_t reg, uint32_t val)
963{ 990{