summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliver F. Brown <oliver.brown@oss.nxp.com>2025-05-01 09:20:05 -0500
committerMax Krummenacher <max.krummenacher@toradex.com>2025-07-28 17:43:13 +0200
commitb1bc67a009612b8db9995bd67a35f106efff56b1 (patch)
tree93b027aebe3af83690a48bf2f98569f05df10106
parent7ff1d327875ee6a8065edabfce2c81fd2d515d2a (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.c42
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);
}