diff options
author | Oliver F. Brown <oliver.brown@oss.nxp.com> | 2025-05-01 09:20:05 -0500 |
---|---|---|
committer | Max Krummenacher <max.krummenacher@toradex.com> | 2025-07-28 17:43:13 +0200 |
commit | b1bc67a009612b8db9995bd67a35f106efff56b1 (patch) | |
tree | 93b027aebe3af83690a48bf2f98569f05df10106 | |
parent | 7ff1d327875ee6a8065edabfce2c81fd2d515d2a (diff) |
LF-14666-2: drm/bridge: synopsys: dw-mipi-dsi: Implement fixup for 720p60toradex_6.6-2.2.x-imx
The Synopsys driver needs a mode fixup to support 720p60 for some bridges.
This patch add support to honor the MIPI_DSI_MODE_VIDEO_NO_HFP and
MIPI_DSI_MODE_VIDEO_NO_HBP MIPI DSI mode flags for MIPI sync events mode.
The default behavior for MIPI DSI low power mode with sync pulses is
unchanged.
Also, a timing fixup is implemented to force low power mode for the
horizontal front porch (HFP) for 720p60 with 4 lanes at 24 bit per pixel.
In this mode, the MIPI line has to be rounded up by 2 bytes. This
rounding causes timing errors and corrupts the video for 720p60. By
reducing the horizontal back porch (HBP) by 32 pixels, the Synopsys MIPI
DSI controller will use low power mode for the HFP. By using low power mode
in the HFP the DSI host controller will resynchronize the line timing to
the DPI interface.
Cherry-pick from NXP's lf-6.12.y branch
Upstream-Status: Inappropriate [Other]
Signed-off-by: Oliver F. Brown <oliver.brown@oss.nxp.com>
Acked-by: Liu Ying <victor.liu@nxp.com>
-rw-r--r-- | drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index 4c46b8074393..f00ba0fb6b41 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -85,7 +85,12 @@ #define ENABLE_CMD_MODE BIT(0) #define DSI_VID_MODE_CFG 0x38 -#define ENABLE_LOW_POWER (0x3f << 8) +#define ENABLE_LOW_POWER_HFP (0x20 << 8) +#define ENABLE_LOW_POWER_HBP (0x10 << 8) +#define ENABLE_LOW_POWER_VACT (0x8 << 8) +#define ENABLE_LOW_POWER_VFP (0x4 << 8) +#define ENABLE_LOW_POWER_VBP (0x2 << 8) +#define ENABLE_LOW_POWER_VSA (0x1 << 8) #define ENABLE_LOW_POWER_MASK (0x3f << 8) #define VID_MODE_TYPE_NON_BURST_SYNC_PULSES 0x0 #define VID_MODE_TYPE_NON_BURST_SYNC_EVENTS 0x1 @@ -593,14 +598,21 @@ static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi) * enabling low power is panel-dependent, we should use the * panel configuration here... */ - val = ENABLE_LOW_POWER; + val = ENABLE_LOW_POWER_VACT | ENABLE_LOW_POWER_VFP | ENABLE_LOW_POWER_VSA | + ENABLE_LOW_POWER_VBP; if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) - val |= VID_MODE_TYPE_BURST; - else if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) - val |= VID_MODE_TYPE_NON_BURST_SYNC_PULSES; - else + val |= VID_MODE_TYPE_BURST | ENABLE_LOW_POWER_HFP | ENABLE_LOW_POWER_HBP; + else if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) { + val |= VID_MODE_TYPE_NON_BURST_SYNC_PULSES | ENABLE_LOW_POWER_HFP | + ENABLE_LOW_POWER_HBP; + } else { val |= VID_MODE_TYPE_NON_BURST_SYNC_EVENTS; + if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HFP) + val |= ENABLE_LOW_POWER_HFP; + if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HBP) + val |= ENABLE_LOW_POWER_HBP; + } #ifdef CONFIG_DEBUG_FS if (dsi->vpg_defs.vpg) { @@ -815,6 +827,24 @@ static void dw_mipi_dsi_line_timer_config(struct dw_mipi_dsi *dsi, lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, mode, hsa); dsi_write(dsi, DSI_VID_HSA_TIME, lbcc); + /* + * This timing fixup allows the HFP to go into low power mode for + * 720p60. There is a line size mismatch between DPI and MIPI + * domain for four lanes using 24 bits per pixel. Forcing the HFP + * into low power mode allows the line timer to be reset, thus + * preserving the DPI timing. Without this adjustment, the MIPI + * domain timing drifts from the DPI domain corrupting the video. + * Most other MIPI controllers have workarounds for this mode's + * behavior. + */ + if (mode->htotal == 1650 && mode->vtotal == 750 && + dsi->lanes == 4 && dsi->format == MIPI_DSI_FMT_RGB888 && + (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HFP) && + !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HBP) && + !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) && + !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)) + hbp = hbp - min(32, hbp); + lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, mode, hbp); dsi_write(dsi, DSI_VID_HBP_TIME, lbcc); } |