Skip to content

Commit f0ce591

Browse files
author
Laurent Pinchart
committed
drm: rcar-du: Fix CRTC timings when CMM is used
When the CMM is enabled, an offset of 25 pixels must be subtracted from the HDS (horizontal display start) and HDE (horizontal display end) registers. Fix the timings calculation, and take this into account in the mode validation. This fixes a visible horizontal offset in the image with VGA monitors. HDMI monitors seem to be generally more tolerant to incorrect timings, but may be affected too. Signed-off-by: Laurent Pinchart <[email protected]>
1 parent 42d95d1 commit f0ce591

File tree

1 file changed

+16
-4
lines changed

1 file changed

+16
-4
lines changed

drivers/gpu/drm/rcar-du/rcar_du_crtc.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
215215
const struct drm_display_mode *mode = &rcrtc->crtc.state->adjusted_mode;
216216
struct rcar_du_device *rcdu = rcrtc->dev;
217217
unsigned long mode_clock = mode->clock * 1000;
218+
unsigned int hdse_offset;
218219
u32 dsmr;
219220
u32 escr;
220221

@@ -298,10 +299,15 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
298299
| DSMR_DIPM_DISP | DSMR_CSPM;
299300
rcar_du_crtc_write(rcrtc, DSMR, dsmr);
300301

302+
hdse_offset = 19;
303+
if (rcrtc->group->cmms_mask & BIT(rcrtc->index % 2))
304+
hdse_offset += 25;
305+
301306
/* Display timings */
302-
rcar_du_crtc_write(rcrtc, HDSR, mode->htotal - mode->hsync_start - 19);
307+
rcar_du_crtc_write(rcrtc, HDSR, mode->htotal - mode->hsync_start -
308+
hdse_offset);
303309
rcar_du_crtc_write(rcrtc, HDER, mode->htotal - mode->hsync_start +
304-
mode->hdisplay - 19);
310+
mode->hdisplay - hdse_offset);
305311
rcar_du_crtc_write(rcrtc, HSWR, mode->hsync_end -
306312
mode->hsync_start - 1);
307313
rcar_du_crtc_write(rcrtc, HCR, mode->htotal - 1);
@@ -836,16 +842,22 @@ rcar_du_crtc_mode_valid(struct drm_crtc *crtc,
836842
struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
837843
struct rcar_du_device *rcdu = rcrtc->dev;
838844
bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
845+
unsigned int min_sync_porch;
839846
unsigned int vbp;
840847

841848
if (interlaced && !rcar_du_has(rcdu, RCAR_DU_FEATURE_INTERLACED))
842849
return MODE_NO_INTERLACE;
843850

844851
/*
845852
* The hardware requires a minimum combined horizontal sync and back
846-
* porch of 20 pixels and a minimum vertical back porch of 3 lines.
853+
* porch of 20 pixels (when CMM isn't used) or 45 pixels (when CMM is
854+
* used), and a minimum vertical back porch of 3 lines.
847855
*/
848-
if (mode->htotal - mode->hsync_start < 20)
856+
min_sync_porch = 20;
857+
if (rcrtc->group->cmms_mask & BIT(rcrtc->index % 2))
858+
min_sync_porch += 25;
859+
860+
if (mode->htotal - mode->hsync_start < min_sync_porch)
849861
return MODE_HBLANK_NARROW;
850862

851863
vbp = (mode->vtotal - mode->vsync_end) / (interlaced ? 2 : 1);

0 commit comments

Comments
 (0)