diff options
-rw-r--r-- | drivers/gpu/drm/imx/dpu/dpu-crtc.c | 2 | ||||
-rw-r--r-- | drivers/gpu/imx/dpu/dpu-tcon.c | 40 | ||||
-rw-r--r-- | include/video/dpu.h | 3 |
3 files changed, 33 insertions, 12 deletions
diff --git a/drivers/gpu/drm/imx/dpu/dpu-crtc.c b/drivers/gpu/drm/imx/dpu/dpu-crtc.c index 79bcb78063c9..ae0e661e9429 100644 --- a/drivers/gpu/drm/imx/dpu/dpu-crtc.c +++ b/drivers/gpu/drm/imx/dpu/dpu-crtc.c @@ -525,7 +525,7 @@ static void dpu_crtc_mode_set_nofb(struct drm_crtc *crtc) framegen_panic_displaymode(dpu_crtc->fg, FGDM__TEST); - tcon_cfg_videomode(dpu_crtc->tcon, mode); + tcon_cfg_videomode(dpu_crtc->tcon, mode, false); tcon_set_fmt(dpu_crtc->tcon, imx_crtc_state->bus_format); constframe_framedimensions(dpu_crtc->pa_cf, diff --git a/drivers/gpu/imx/dpu/dpu-tcon.c b/drivers/gpu/imx/dpu/dpu-tcon.c index 199e6e55df15..aa5f45115bc2 100644 --- a/drivers/gpu/imx/dpu/dpu-tcon.c +++ b/drivers/gpu/imx/dpu/dpu-tcon.c @@ -118,11 +118,27 @@ void tcon_set_operation_mode(struct dpu_tcon *tcon) } EXPORT_SYMBOL_GPL(tcon_set_operation_mode); -void tcon_cfg_videomode(struct dpu_tcon *tcon, struct drm_display_mode *m) +void tcon_cfg_videomode(struct dpu_tcon *tcon, + struct drm_display_mode *m, bool side_by_side) { u32 val; + int hdisplay, hsync_start, hsync_end; + int vdisplay, vsync_start, vsync_end; int y; + hdisplay = m->hdisplay; + vdisplay = m->vdisplay; + hsync_start = m->hsync_start; + vsync_start = m->vsync_start; + hsync_end = m->hsync_end; + vsync_end = m->vsync_end; + + if (side_by_side) { + hdisplay /= 2; + hsync_start /= 2; + hsync_end /= 2; + } + /* * TKT320590: * Turn TCON into operation mode later after the first dumb frame is @@ -133,22 +149,20 @@ void tcon_cfg_videomode(struct dpu_tcon *tcon, struct drm_display_mode *m) dpu_tcon_write(tcon, TCON_CTRL, val); /* dsp_control[0]: hsync */ - dpu_tcon_write(tcon, SPGPOSON(0), X(m->hsync_start)); + dpu_tcon_write(tcon, SPGPOSON(0), X(hsync_start)); dpu_tcon_write(tcon, SPGMASKON(0), 0xffff); - dpu_tcon_write(tcon, SPGPOSOFF(0), X(m->hsync_end)); + dpu_tcon_write(tcon, SPGPOSOFF(0), X(hsync_end)); dpu_tcon_write(tcon, SPGMASKOFF(0), 0xffff); dpu_tcon_write(tcon, SMXSIGS(0), 0x2); dpu_tcon_write(tcon, SMXFCTTABLE(0), 0x1); /* dsp_control[1]: vsync */ - dpu_tcon_write(tcon, SPGPOSON(1), - X(m->hsync_start) | Y(m->vsync_start - 1)); + dpu_tcon_write(tcon, SPGPOSON(1), X(hsync_start) | Y(vsync_start - 1)); dpu_tcon_write(tcon, SPGMASKON(1), 0x0); - dpu_tcon_write(tcon, SPGPOSOFF(1), - X(m->hsync_start) | Y(m->vsync_end - 1)); + dpu_tcon_write(tcon, SPGPOSOFF(1), X(hsync_start) | Y(vsync_end - 1)); dpu_tcon_write(tcon, SPGMASKOFF(1), 0x0); dpu_tcon_write(tcon, SMXSIGS(1), 0x3); @@ -159,21 +173,27 @@ void tcon_cfg_videomode(struct dpu_tcon *tcon, struct drm_display_mode *m) dpu_tcon_write(tcon, SPGPOSON(2), 0x0); dpu_tcon_write(tcon, SPGMASKON(2), 0xffff); - dpu_tcon_write(tcon, SPGPOSOFF(2), X(m->hdisplay)); + dpu_tcon_write(tcon, SPGPOSOFF(2), X(hdisplay)); dpu_tcon_write(tcon, SPGMASKOFF(2), 0xffff); /* vertical */ dpu_tcon_write(tcon, SPGPOSON(3), 0x0); dpu_tcon_write(tcon, SPGMASKON(3), 0x7fff0000); - dpu_tcon_write(tcon, SPGPOSOFF(3), Y(m->vdisplay)); + dpu_tcon_write(tcon, SPGPOSOFF(3), Y(vdisplay)); dpu_tcon_write(tcon, SPGMASKOFF(3), 0x7fff0000); dpu_tcon_write(tcon, SMXSIGS(2), 0x2c); dpu_tcon_write(tcon, SMXFCTTABLE(2), 0x8); /* dsp_control[3]: kachuck */ - y = m->vdisplay + 1; + y = vdisplay + 1; + /* + * If sync mode fixup is present, the kachuck signal from slave tcon + * should be one line later than the one from master tcon. + */ + if (side_by_side && tcon_is_slave(tcon)) + y++; dpu_tcon_write(tcon, SPGPOSON(4), X(0x0) | Y(y)); dpu_tcon_write(tcon, SPGMASKON(4), 0x0); diff --git a/include/video/dpu.h b/include/video/dpu.h index ef0d70a591e2..ed9b65cacde7 100644 --- a/include/video/dpu.h +++ b/include/video/dpu.h @@ -553,7 +553,8 @@ void dpu_lb_put(struct dpu_layerblend *lb); struct dpu_tcon; int tcon_set_fmt(struct dpu_tcon *tcon, u32 bus_format); void tcon_set_operation_mode(struct dpu_tcon *tcon); -void tcon_cfg_videomode(struct dpu_tcon *tcon, struct drm_display_mode *m); +void tcon_cfg_videomode(struct dpu_tcon *tcon, + struct drm_display_mode *m, bool side_by_side); bool tcon_is_master(struct dpu_tcon *tcon); bool tcon_is_slave(struct dpu_tcon *tcon); struct dpu_tcon *dpu_tcon_get(struct dpu_soc *dpu, int id); |