drm/radeon/kms: fix interlaced modes on dce4+
- set scaler table clears the interleave bit, need to reset it in encoder quirks, this was already done for pre-dce4. - remove the interleave settings from set_base() functions this is now handled in the encoder quirks functions, and isn't technically part of the display base setup. - rename evergreen_do_set_base() to dce4_do_set_base() since it's used on both evergreen and NI asics. Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=28182 Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Cc: stable@kernel.org Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
16f9fdcbcc
commit
c9417bdd4c
2 changed files with 20 additions and 22 deletions
|
@ -995,9 +995,9 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int evergreen_crtc_do_set_base(struct drm_crtc *crtc,
|
static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
|
||||||
struct drm_framebuffer *fb,
|
struct drm_framebuffer *fb,
|
||||||
int x, int y, int atomic)
|
int x, int y, int atomic)
|
||||||
{
|
{
|
||||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||||
struct drm_device *dev = crtc->dev;
|
struct drm_device *dev = crtc->dev;
|
||||||
|
@ -1137,12 +1137,6 @@ static int evergreen_crtc_do_set_base(struct drm_crtc *crtc,
|
||||||
WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
|
WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
|
||||||
(crtc->mode.hdisplay << 16) | crtc->mode.vdisplay);
|
(crtc->mode.hdisplay << 16) | crtc->mode.vdisplay);
|
||||||
|
|
||||||
if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE)
|
|
||||||
WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset,
|
|
||||||
EVERGREEN_INTERLEAVE_EN);
|
|
||||||
else
|
|
||||||
WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0);
|
|
||||||
|
|
||||||
if (!atomic && fb && fb != crtc->fb) {
|
if (!atomic && fb && fb != crtc->fb) {
|
||||||
radeon_fb = to_radeon_framebuffer(fb);
|
radeon_fb = to_radeon_framebuffer(fb);
|
||||||
rbo = radeon_fb->obj->driver_private;
|
rbo = radeon_fb->obj->driver_private;
|
||||||
|
@ -1300,12 +1294,6 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
|
||||||
WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
|
WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
|
||||||
(crtc->mode.hdisplay << 16) | crtc->mode.vdisplay);
|
(crtc->mode.hdisplay << 16) | crtc->mode.vdisplay);
|
||||||
|
|
||||||
if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE)
|
|
||||||
WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset,
|
|
||||||
AVIVO_D1MODE_INTERLEAVE_EN);
|
|
||||||
else
|
|
||||||
WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0);
|
|
||||||
|
|
||||||
if (!atomic && fb && fb != crtc->fb) {
|
if (!atomic && fb && fb != crtc->fb) {
|
||||||
radeon_fb = to_radeon_framebuffer(fb);
|
radeon_fb = to_radeon_framebuffer(fb);
|
||||||
rbo = radeon_fb->obj->driver_private;
|
rbo = radeon_fb->obj->driver_private;
|
||||||
|
@ -1329,7 +1317,7 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
|
||||||
struct radeon_device *rdev = dev->dev_private;
|
struct radeon_device *rdev = dev->dev_private;
|
||||||
|
|
||||||
if (ASIC_IS_DCE4(rdev))
|
if (ASIC_IS_DCE4(rdev))
|
||||||
return evergreen_crtc_do_set_base(crtc, old_fb, x, y, 0);
|
return dce4_crtc_do_set_base(crtc, old_fb, x, y, 0);
|
||||||
else if (ASIC_IS_AVIVO(rdev))
|
else if (ASIC_IS_AVIVO(rdev))
|
||||||
return avivo_crtc_do_set_base(crtc, old_fb, x, y, 0);
|
return avivo_crtc_do_set_base(crtc, old_fb, x, y, 0);
|
||||||
else
|
else
|
||||||
|
@ -1344,7 +1332,7 @@ int atombios_crtc_set_base_atomic(struct drm_crtc *crtc,
|
||||||
struct radeon_device *rdev = dev->dev_private;
|
struct radeon_device *rdev = dev->dev_private;
|
||||||
|
|
||||||
if (ASIC_IS_DCE4(rdev))
|
if (ASIC_IS_DCE4(rdev))
|
||||||
return evergreen_crtc_do_set_base(crtc, fb, x, y, 1);
|
return dce4_crtc_do_set_base(crtc, fb, x, y, 1);
|
||||||
else if (ASIC_IS_AVIVO(rdev))
|
else if (ASIC_IS_AVIVO(rdev))
|
||||||
return avivo_crtc_do_set_base(crtc, fb, x, y, 1);
|
return avivo_crtc_do_set_base(crtc, fb, x, y, 1);
|
||||||
else
|
else
|
||||||
|
|
|
@ -1570,11 +1570,21 @@ atombios_apply_encoder_quirks(struct drm_encoder *encoder,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set scaler clears this on some chips */
|
/* set scaler clears this on some chips */
|
||||||
/* XXX check DCE4 */
|
if (ASIC_IS_AVIVO(rdev) &&
|
||||||
if (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))) {
|
(!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)))) {
|
||||||
if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE))
|
if (ASIC_IS_DCE4(rdev)) {
|
||||||
WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset,
|
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
|
||||||
AVIVO_D1MODE_INTERLEAVE_EN);
|
WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset,
|
||||||
|
EVERGREEN_INTERLEAVE_EN);
|
||||||
|
else
|
||||||
|
WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0);
|
||||||
|
} else {
|
||||||
|
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
|
||||||
|
WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset,
|
||||||
|
AVIVO_D1MODE_INTERLEAVE_EN);
|
||||||
|
else
|
||||||
|
WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue