Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c9417bdd authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie
Browse files

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: default avatarAlex Deucher <alexdeucher@gmail.com>
Cc: stable@kernel.org
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 16f9fdcb
Loading
Loading
Loading
Loading
+5 −17
Original line number Diff line number Diff line
@@ -995,7 +995,7 @@ 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,
				 int x, int y, int atomic)
{
@@ -1137,12 +1137,6 @@ static int evergreen_crtc_do_set_base(struct drm_crtc *crtc,
	WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
	       (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) {
		radeon_fb = to_radeon_framebuffer(fb);
		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,
	       (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) {
		radeon_fb = to_radeon_framebuffer(fb);
		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;

	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))
		return avivo_crtc_do_set_base(crtc, old_fb, x, y, 0);
	else
@@ -1344,7 +1332,7 @@ int atombios_crtc_set_base_atomic(struct drm_crtc *crtc,
       struct radeon_device *rdev = dev->dev_private;

	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))
		return avivo_crtc_do_set_base(crtc, fb, x, y, 1);
	else
+15 −5
Original line number Diff line number Diff line
@@ -1570,11 +1570,21 @@ atombios_apply_encoder_quirks(struct drm_encoder *encoder,
	}

	/* set scaler clears this on some chips */
	/* XXX check DCE4 */
	if (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))) {
		if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE))
	if (ASIC_IS_AVIVO(rdev) &&
	    (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)))) {
		if (ASIC_IS_DCE4(rdev)) {
			if (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);
		} 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);
		}
	}
}