aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/gma500/oaktrail_crtc.c
diff options
context:
space:
mode:
authorPatrik Jakobsson <patrik.r.jakobsson@gmail.com>2013-11-06 18:14:18 -0500
committerPatrik Jakobsson <patrik.r.jakobsson@gmail.com>2013-11-08 10:22:10 -0500
commitb97b8287a39d1fe6f8aa1b83405f669634ff8401 (patch)
treef1a5b6dbc33661191e7be47021b5353020a3ec5f /drivers/gpu/drm/gma500/oaktrail_crtc.c
parentac6113ebb70d4bc7018db4e73f923653347da743 (diff)
drm/gma500/mrst: Add aux register writes when programming pipe
On SDVO pipes (always Pipe B on mrst) we have to sequentially write the aux vdc. We might be able to skip programming the primary vdc in some/most places but we don't care about that now. Signed-off-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/gma500/oaktrail_crtc.c')
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_crtc.c241
1 files changed, 135 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);