diff options
author | Jerome Glisse <jglisse@redhat.com> | 2009-07-13 15:04:08 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-07-29 01:45:09 -0400 |
commit | c93bb85b5cba3e3a06f2cad8e9bc5c23d3d10aac (patch) | |
tree | 3168bee69e08dcb1f0f509b03ea1693a688d34ef /drivers/gpu/drm/radeon/radeon_display.c | |
parent | e024e11070a0a0dc7163ce1ec2da354a638bdbed (diff) |
drm/radeon/kms: fix bandwidth computation on avivo hardware
Fix bandwidth computation and crtc priority in memory controller
so that crtc memory request are fullfill in time to avoid display
artifact.
Signed-off-by: Jerome Glisse <jglisse@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_display.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_display.c | 68 |
1 files changed, 42 insertions, 26 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index bc312f3d9a0..a8fa1bb84cf 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -187,6 +187,7 @@ static void radeon_crtc_init(struct drm_device *dev, int index) | |||
187 | 187 | ||
188 | drm_mode_crtc_set_gamma_size(&radeon_crtc->base, 256); | 188 | drm_mode_crtc_set_gamma_size(&radeon_crtc->base, 256); |
189 | radeon_crtc->crtc_id = index; | 189 | radeon_crtc->crtc_id = index; |
190 | rdev->mode_info.crtcs[index] = radeon_crtc; | ||
190 | 191 | ||
191 | radeon_crtc->mode_set.crtc = &radeon_crtc->base; | 192 | radeon_crtc->mode_set.crtc = &radeon_crtc->base; |
192 | radeon_crtc->mode_set.connectors = (struct drm_connector **)(radeon_crtc + 1); | 193 | radeon_crtc->mode_set.connectors = (struct drm_connector **)(radeon_crtc + 1); |
@@ -661,36 +662,51 @@ void radeon_modeset_fini(struct radeon_device *rdev) | |||
661 | } | 662 | } |
662 | } | 663 | } |
663 | 664 | ||
664 | void radeon_init_disp_bandwidth(struct drm_device *dev) | 665 | bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, |
666 | struct drm_display_mode *mode, | ||
667 | struct drm_display_mode *adjusted_mode) | ||
665 | { | 668 | { |
666 | struct radeon_device *rdev = dev->dev_private; | 669 | struct drm_device *dev = crtc->dev; |
667 | struct drm_display_mode *modes[2]; | 670 | struct drm_encoder *encoder; |
668 | int pixel_bytes[2]; | 671 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
669 | struct drm_crtc *crtc; | 672 | struct radeon_encoder *radeon_encoder; |
670 | 673 | bool first = true; | |
671 | pixel_bytes[0] = pixel_bytes[1] = 0; | ||
672 | modes[0] = modes[1] = NULL; | ||
673 | |||
674 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
675 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
676 | 674 | ||
677 | if (crtc->enabled && crtc->fb) { | 675 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
678 | modes[radeon_crtc->crtc_id] = &crtc->mode; | 676 | radeon_encoder = to_radeon_encoder(encoder); |
679 | pixel_bytes[radeon_crtc->crtc_id] = crtc->fb->bits_per_pixel / 8; | 677 | if (encoder->crtc != crtc) |
678 | continue; | ||
679 | if (first) { | ||
680 | radeon_crtc->rmx_type = radeon_encoder->rmx_type; | ||
681 | radeon_crtc->devices = radeon_encoder->devices; | ||
682 | memcpy(&radeon_crtc->native_mode, | ||
683 | &radeon_encoder->native_mode, | ||
684 | sizeof(struct radeon_native_mode)); | ||
685 | first = false; | ||
686 | } else { | ||
687 | if (radeon_crtc->rmx_type != radeon_encoder->rmx_type) { | ||
688 | /* WARNING: Right now this can't happen but | ||
689 | * in the future we need to check that scaling | ||
690 | * are consistent accross different encoder | ||
691 | * (ie all encoder can work with the same | ||
692 | * scaling). | ||
693 | */ | ||
694 | DRM_ERROR("Scaling not consistent accross encoder.\n"); | ||
695 | return false; | ||
696 | } | ||
680 | } | 697 | } |
681 | } | 698 | } |
682 | 699 | if (radeon_crtc->rmx_type != RMX_OFF) { | |
683 | if (ASIC_IS_AVIVO(rdev)) { | 700 | fixed20_12 a, b; |
684 | radeon_init_disp_bw_avivo(dev, | 701 | a.full = rfixed_const(crtc->mode.vdisplay); |
685 | modes[0], | 702 | b.full = rfixed_const(radeon_crtc->native_mode.panel_xres); |
686 | pixel_bytes[0], | 703 | radeon_crtc->vsc.full = rfixed_div(a, b); |
687 | modes[1], | 704 | a.full = rfixed_const(crtc->mode.hdisplay); |
688 | pixel_bytes[1]); | 705 | b.full = rfixed_const(radeon_crtc->native_mode.panel_yres); |
706 | radeon_crtc->hsc.full = rfixed_div(a, b); | ||
689 | } else { | 707 | } else { |
690 | radeon_init_disp_bw_legacy(dev, | 708 | radeon_crtc->vsc.full = rfixed_const(1); |
691 | modes[0], | 709 | radeon_crtc->hsc.full = rfixed_const(1); |
692 | pixel_bytes[0], | ||
693 | modes[1], | ||
694 | pixel_bytes[1]); | ||
695 | } | 710 | } |
711 | return true; | ||
696 | } | 712 | } |