diff options
author | Darren Etheridge <detheridge@ti.com> | 2013-08-14 15:43:33 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-08-18 19:10:54 -0400 |
commit | a9767188678725aac99d7990025dd5b822728ba8 (patch) | |
tree | 74fa670bc920f9193882395c8233cfcf157e4b04 | |
parent | 179f1aa407b466c06a94f9e54abc948d1e1146e7 (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.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/tilcdc/tilcdc_slave.c | 27 |
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 | ||
76 | static 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 | |||
76 | static const struct drm_encoder_funcs slave_encoder_funcs = { | 101 | static const struct drm_encoder_funcs slave_encoder_funcs = { |
77 | .destroy = slave_encoder_destroy, | 102 | .destroy = slave_encoder_destroy, |
78 | }; | 103 | }; |
79 | 104 | ||
80 | static const struct drm_encoder_helper_funcs slave_encoder_helper_funcs = { | 105 | static 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, |