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

Commit a9767188 authored by Darren Etheridge's avatar Darren Etheridge Committed by Dave Airlie
Browse files

drm/tilcdc fixup mode to workaround sync for tda998x



Add a fixup function that will flip the hsync priority and
add a hskew value that is used to shift the tda998x to the
right by a variable number of pixels depending on the mode.
This works around an issue with the sync timings that tilcdc
is outputing.

Signed-off-by: default avatarDarren Etheridge <detheridge@ti.com>
Tested-by: default avatarSebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Tested-by: default avatarRussell King <rmk_kernel@arm.linux.org.uk>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 179f1aa4
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -379,7 +379,12 @@ static int tilcdc_crtc_mode_set(struct drm_crtc *crtc,
	else
		tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_SYNC_EDGE);

	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
	/*
	 * use value from adjusted_mode here as this might have been
	 * changed as part of the fixup for slave encoders to solve the
	 * issue where tilcdc timings are not VESA compliant
	 */
	if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
		tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_HSYNC);
	else
		tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_HSYNC);
+26 −1
Original line number Diff line number Diff line
@@ -73,13 +73,38 @@ static void slave_encoder_prepare(struct drm_encoder *encoder)
	tilcdc_crtc_set_panel_info(encoder->crtc, &slave_info);
}

static bool slave_encoder_fixup(struct drm_encoder *encoder,
		const struct drm_display_mode *mode,
		struct drm_display_mode *adjusted_mode)
{
	/*
	 * tilcdc does not generate VESA-complient sync but aligns
	 * VS on the second edge of HS instead of first edge.
	 * We use adjusted_mode, to fixup sync by aligning both rising
	 * edges and add HSKEW offset to let the slave encoder fix it up.
	 */
	adjusted_mode->hskew = mode->hsync_end - mode->hsync_start;
	adjusted_mode->flags |= DRM_MODE_FLAG_HSKEW;

	if (mode->flags & DRM_MODE_FLAG_NHSYNC) {
		adjusted_mode->flags |= DRM_MODE_FLAG_PHSYNC;
		adjusted_mode->flags &= ~DRM_MODE_FLAG_NHSYNC;
	} else {
		adjusted_mode->flags |= DRM_MODE_FLAG_NHSYNC;
		adjusted_mode->flags &= ~DRM_MODE_FLAG_PHSYNC;
	}

	return drm_i2c_encoder_mode_fixup(encoder, mode, adjusted_mode);
}


static const struct drm_encoder_funcs slave_encoder_funcs = {
		.destroy        = slave_encoder_destroy,
};

static const struct drm_encoder_helper_funcs slave_encoder_helper_funcs = {
		.dpms           = drm_i2c_encoder_dpms,
		.mode_fixup     = drm_i2c_encoder_mode_fixup,
		.mode_fixup     = slave_encoder_fixup,
		.prepare        = slave_encoder_prepare,
		.commit         = drm_i2c_encoder_commit,
		.mode_set       = drm_i2c_encoder_mode_set,