aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarren Etheridge <detheridge@ti.com>2013-08-14 15:43:33 -0400
committerDave Airlie <airlied@redhat.com>2013-08-18 19:10:54 -0400
commita9767188678725aac99d7990025dd5b822728ba8 (patch)
tree74fa670bc920f9193882395c8233cfcf157e4b04
parent179f1aa407b466c06a94f9e54abc948d1e1146e7 (diff)
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: Darren Etheridge <detheridge@ti.com> Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Tested-by: Russell King <rmk_kernel@arm.linux.org.uk> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_crtc.c7
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_slave.c27
2 files changed, 32 insertions, 2 deletions
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index 7418dcd986d3..6d0524095fe3 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -379,7 +379,12 @@ static int tilcdc_crtc_mode_set(struct drm_crtc *crtc,
379 else 379 else
380 tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_SYNC_EDGE); 380 tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_SYNC_EDGE);
381 381
382 if (mode->flags & DRM_MODE_FLAG_NHSYNC) 382 /*
383 * use value from adjusted_mode here as this might have been
384 * changed as part of the fixup for slave encoders to solve the
385 * issue where tilcdc timings are not VESA compliant
386 */
387 if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
383 tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_HSYNC); 388 tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_HSYNC);
384 else 389 else
385 tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_HSYNC); 390 tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_HSYNC);
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_slave.c b/drivers/gpu/drm/tilcdc/tilcdc_slave.c
index dfffaf014022..23b3203d8241 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_slave.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_slave.c
@@ -73,13 +73,38 @@ static void slave_encoder_prepare(struct drm_encoder *encoder)
73 tilcdc_crtc_set_panel_info(encoder->crtc, &slave_info); 73 tilcdc_crtc_set_panel_info(encoder->crtc, &slave_info);
74} 74}
75 75
76static bool slave_encoder_fixup(struct drm_encoder *encoder,
77 const struct drm_display_mode *mode,
78 struct drm_display_mode *adjusted_mode)
79{
80 /*
81 * tilcdc does not generate VESA-complient sync but aligns
82 * VS on the second edge of HS instead of first edge.
83 * We use adjusted_mode, to fixup sync by aligning both rising
84 * edges and add HSKEW offset to let the slave encoder fix it up.
85 */
86 adjusted_mode->hskew = mode->hsync_end - mode->hsync_start;
87 adjusted_mode->flags |= DRM_MODE_FLAG_HSKEW;
88
89 if (mode->flags & DRM_MODE_FLAG_NHSYNC) {
90 adjusted_mode->flags |= DRM_MODE_FLAG_PHSYNC;
91 adjusted_mode->flags &= ~DRM_MODE_FLAG_NHSYNC;
92 } else {
93 adjusted_mode->flags |= DRM_MODE_FLAG_NHSYNC;
94 adjusted_mode->flags &= ~DRM_MODE_FLAG_PHSYNC;
95 }
96
97 return drm_i2c_encoder_mode_fixup(encoder, mode, adjusted_mode);
98}
99
100
76static const struct drm_encoder_funcs slave_encoder_funcs = { 101static const struct drm_encoder_funcs slave_encoder_funcs = {
77 .destroy = slave_encoder_destroy, 102 .destroy = slave_encoder_destroy,
78}; 103};
79 104
80static const struct drm_encoder_helper_funcs slave_encoder_helper_funcs = { 105static const struct drm_encoder_helper_funcs slave_encoder_helper_funcs = {
81 .dpms = drm_i2c_encoder_dpms, 106 .dpms = drm_i2c_encoder_dpms,
82 .mode_fixup = drm_i2c_encoder_mode_fixup, 107 .mode_fixup = slave_encoder_fixup,
83 .prepare = slave_encoder_prepare, 108 .prepare = slave_encoder_prepare,
84 .commit = drm_i2c_encoder_commit, 109 .commit = drm_i2c_encoder_commit,
85 .mode_set = drm_i2c_encoder_mode_set, 110 .mode_set = drm_i2c_encoder_mode_set,