Skip to content

Commit d0d7277

Browse files
committed
drm/bridge: ti-sn65dsi83: halve horizontal syncs for dual LVDS output
Dual LVDS output (available on the SN65DSI84) requires HSYNC_PULSE_WIDTH and HORIZONTAL_BACK_PORCH to be divided by two with respect to the values used for single LVDS output. While not clearly stated in the datasheet, this is needed according to the DSI Tuner [0] output. It also makes sense intuitively because in dual LVDS output two pixels at a time are output and so the output clock is half of the pixel clock. Some dual-LVDS panels refuse to show any picture without this fix. Divide by two HORIZONTAL_FRONT_PORCH too, even though this register is used only for test pattern generation which is not currently implemented by this driver. [0] https://www.ti.com/tool/DSI-TUNER Fixes: ceb515b ("drm/bridge: ti-sn65dsi83: Add TI SN65DSI83 and SN65DSI84 driver") Cc: [email protected] Reviewed-by: Marek Vasut <[email protected]> Link: https://patch.msgid.link/20260226-ti-sn65dsi83-dual-lvds-fixes-and-test-pattern-v1-2-2e15f5a9a6a0@bootlin.com Signed-off-by: Luca Ceresoli <[email protected]>
1 parent 2f22702 commit d0d7277

1 file changed

Lines changed: 4 additions & 3 deletions

File tree

drivers/gpu/drm/bridge/ti-sn65dsi83.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
517517
struct drm_atomic_state *state)
518518
{
519519
struct sn65dsi83 *ctx = bridge_to_sn65dsi83(bridge);
520+
const unsigned int dual_factor = ctx->lvds_dual_link ? 2 : 1;
520521
const struct drm_bridge_state *bridge_state;
521522
const struct drm_crtc_state *crtc_state;
522523
const struct drm_display_mode *mode;
@@ -653,18 +654,18 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
653654
/* 32 + 1 pixel clock to ensure proper operation */
654655
le16val = cpu_to_le16(32 + 1);
655656
regmap_bulk_write(ctx->regmap, REG_VID_CHA_SYNC_DELAY_LOW, &le16val, 2);
656-
le16val = cpu_to_le16(mode->hsync_end - mode->hsync_start);
657+
le16val = cpu_to_le16((mode->hsync_end - mode->hsync_start) / dual_factor);
657658
regmap_bulk_write(ctx->regmap, REG_VID_CHA_HSYNC_PULSE_WIDTH_LOW,
658659
&le16val, 2);
659660
le16val = cpu_to_le16(mode->vsync_end - mode->vsync_start);
660661
regmap_bulk_write(ctx->regmap, REG_VID_CHA_VSYNC_PULSE_WIDTH_LOW,
661662
&le16val, 2);
662663
regmap_write(ctx->regmap, REG_VID_CHA_HORIZONTAL_BACK_PORCH,
663-
mode->htotal - mode->hsync_end);
664+
(mode->htotal - mode->hsync_end) / dual_factor);
664665
regmap_write(ctx->regmap, REG_VID_CHA_VERTICAL_BACK_PORCH,
665666
mode->vtotal - mode->vsync_end);
666667
regmap_write(ctx->regmap, REG_VID_CHA_HORIZONTAL_FRONT_PORCH,
667-
mode->hsync_start - mode->hdisplay);
668+
(mode->hsync_start - mode->hdisplay) / dual_factor);
668669
regmap_write(ctx->regmap, REG_VID_CHA_VERTICAL_FRONT_PORCH,
669670
mode->vsync_start - mode->vdisplay);
670671
regmap_write(ctx->regmap, REG_VID_CHA_TEST_PATTERN, 0x00);

0 commit comments

Comments
 (0)