diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2010-03-31 00:33:27 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-03-31 00:54:47 -0400 |
commit | f46c01208da1881591e3f55ca77d37f54469f8e4 (patch) | |
tree | 39b9169c70da504b80440b85b5ef2ffa4394d25f /drivers/gpu/drm/radeon/rs690.c | |
parent | 3b01a1191fe76bd11e5743eceed7c25d8157239e (diff) |
drm/radeon/kms: display watermark updates (v2)
- Add module option to force the display priority
0 = auto, 1 = normal, 2 = high
- Default to high on r3xx/r4xx/rv515 chips
Fixes flickering problems during heavy acceleration
due to underflow to the display controllers
- Fill in minimal support for RS600
v2 - update display priority when bandwidth is updated
so the user can change the parameter at runtime and it
will take affect on the next modeset.
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/rs690.c')
-rw-r--r-- | drivers/gpu/drm/radeon/rs690.c | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index f758d5cc116..bbf3da790fd 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c | |||
@@ -400,10 +400,12 @@ void rs690_bandwidth_update(struct radeon_device *rdev) | |||
400 | struct drm_display_mode *mode1 = NULL; | 400 | struct drm_display_mode *mode1 = NULL; |
401 | struct rs690_watermark wm0; | 401 | struct rs690_watermark wm0; |
402 | struct rs690_watermark wm1; | 402 | struct rs690_watermark wm1; |
403 | u32 tmp; | 403 | u32 tmp, d1mode_priority_a_cnt, d2mode_priority_a_cnt; |
404 | fixed20_12 priority_mark02, priority_mark12, fill_rate; | 404 | fixed20_12 priority_mark02, priority_mark12, fill_rate; |
405 | fixed20_12 a, b; | 405 | fixed20_12 a, b; |
406 | 406 | ||
407 | radeon_update_display_priority(rdev); | ||
408 | |||
407 | if (rdev->mode_info.crtcs[0]->base.enabled) | 409 | if (rdev->mode_info.crtcs[0]->base.enabled) |
408 | mode0 = &rdev->mode_info.crtcs[0]->base.mode; | 410 | mode0 = &rdev->mode_info.crtcs[0]->base.mode; |
409 | if (rdev->mode_info.crtcs[1]->base.enabled) | 411 | if (rdev->mode_info.crtcs[1]->base.enabled) |
@@ -413,7 +415,8 @@ void rs690_bandwidth_update(struct radeon_device *rdev) | |||
413 | * modes if the user specifies HIGH for displaypriority | 415 | * modes if the user specifies HIGH for displaypriority |
414 | * option. | 416 | * option. |
415 | */ | 417 | */ |
416 | if (rdev->disp_priority == 2) { | 418 | if ((rdev->disp_priority == 2) && |
419 | ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740))) { | ||
417 | tmp = RREG32_MC(R_000104_MC_INIT_MISC_LAT_TIMER); | 420 | tmp = RREG32_MC(R_000104_MC_INIT_MISC_LAT_TIMER); |
418 | tmp &= C_000104_MC_DISP0R_INIT_LAT; | 421 | tmp &= C_000104_MC_DISP0R_INIT_LAT; |
419 | tmp &= C_000104_MC_DISP1R_INIT_LAT; | 422 | tmp &= C_000104_MC_DISP1R_INIT_LAT; |
@@ -488,10 +491,16 @@ void rs690_bandwidth_update(struct radeon_device *rdev) | |||
488 | priority_mark12.full = 0; | 491 | priority_mark12.full = 0; |
489 | if (wm1.priority_mark_max.full > priority_mark12.full) | 492 | if (wm1.priority_mark_max.full > priority_mark12.full) |
490 | priority_mark12.full = wm1.priority_mark_max.full; | 493 | priority_mark12.full = wm1.priority_mark_max.full; |
491 | WREG32(R_006548_D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02)); | 494 | d1mode_priority_a_cnt = rfixed_trunc(priority_mark02); |
492 | WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02)); | 495 | d2mode_priority_a_cnt = rfixed_trunc(priority_mark12); |
493 | WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12)); | 496 | if (rdev->disp_priority == 2) { |
494 | WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12)); | 497 | d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1); |
498 | d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1); | ||
499 | } | ||
500 | WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); | ||
501 | WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); | ||
502 | WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); | ||
503 | WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); | ||
495 | } else if (mode0) { | 504 | } else if (mode0) { |
496 | if (rfixed_trunc(wm0.dbpp) > 64) | 505 | if (rfixed_trunc(wm0.dbpp) > 64) |
497 | a.full = rfixed_mul(wm0.dbpp, wm0.num_line_pair); | 506 | a.full = rfixed_mul(wm0.dbpp, wm0.num_line_pair); |
@@ -518,8 +527,11 @@ void rs690_bandwidth_update(struct radeon_device *rdev) | |||
518 | priority_mark02.full = 0; | 527 | priority_mark02.full = 0; |
519 | if (wm0.priority_mark_max.full > priority_mark02.full) | 528 | if (wm0.priority_mark_max.full > priority_mark02.full) |
520 | priority_mark02.full = wm0.priority_mark_max.full; | 529 | priority_mark02.full = wm0.priority_mark_max.full; |
521 | WREG32(R_006548_D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02)); | 530 | d1mode_priority_a_cnt = rfixed_trunc(priority_mark02); |
522 | WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02)); | 531 | if (rdev->disp_priority == 2) |
532 | d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1); | ||
533 | WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); | ||
534 | WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); | ||
523 | WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, | 535 | WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, |
524 | S_006D48_D2MODE_PRIORITY_A_OFF(1)); | 536 | S_006D48_D2MODE_PRIORITY_A_OFF(1)); |
525 | WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, | 537 | WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, |
@@ -550,12 +562,15 @@ void rs690_bandwidth_update(struct radeon_device *rdev) | |||
550 | priority_mark12.full = 0; | 562 | priority_mark12.full = 0; |
551 | if (wm1.priority_mark_max.full > priority_mark12.full) | 563 | if (wm1.priority_mark_max.full > priority_mark12.full) |
552 | priority_mark12.full = wm1.priority_mark_max.full; | 564 | priority_mark12.full = wm1.priority_mark_max.full; |
565 | d2mode_priority_a_cnt = rfixed_trunc(priority_mark12); | ||
566 | if (rdev->disp_priority == 2) | ||
567 | d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1); | ||
553 | WREG32(R_006548_D1MODE_PRIORITY_A_CNT, | 568 | WREG32(R_006548_D1MODE_PRIORITY_A_CNT, |
554 | S_006548_D1MODE_PRIORITY_A_OFF(1)); | 569 | S_006548_D1MODE_PRIORITY_A_OFF(1)); |
555 | WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, | 570 | WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, |
556 | S_00654C_D1MODE_PRIORITY_B_OFF(1)); | 571 | S_00654C_D1MODE_PRIORITY_B_OFF(1)); |
557 | WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12)); | 572 | WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); |
558 | WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12)); | 573 | WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); |
559 | } | 574 | } |
560 | } | 575 | } |
561 | 576 | ||