diff options
author | Patrik Jakobsson <patrik.r.jakobsson@gmail.com> | 2013-11-06 18:14:18 -0500 |
---|---|---|
committer | Patrik Jakobsson <patrik.r.jakobsson@gmail.com> | 2013-11-08 10:22:10 -0500 |
commit | b97b8287a39d1fe6f8aa1b83405f669634ff8401 (patch) | |
tree | f1a5b6dbc33661191e7be47021b5353020a3ec5f /drivers/gpu/drm/gma500/oaktrail_crtc.c | |
parent | ac6113ebb70d4bc7018db4e73f923653347da743 (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.c | 241 |
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 | ||
563 | oaktrail_crtc_mode_set_exit: | 592 | oaktrail_crtc_mode_set_exit: |
564 | gma_power_end(dev); | 593 | gma_power_end(dev); |