From 770e4763255ba5bf086ae7b014330651e007bcb7 Mon Sep 17 00:00:00 2001 From: Frieder Schrempf Date: Thu, 13 Jul 2023 11:47:47 +0200 Subject: [PATCH] drm: bridge: samsung-dsim: Fix init during host transfer In case the downstream bridge or panel uses DSI transfers before the DSI host was actually initialized through samsung_dsim_atomic_enable() which clears the stop state (LP11) mode, all transfers will fail. This happens with downstream bridges that are controlled by DSI commands such as the tc358762. To fix this do not enable stop state when the DSI host was initialized through samsung_dsim_host_transfer() which restores the previous behavior. Fixes: 0c14d3130654 ("drm: bridge: samsung-dsim: Fix i.MX8M enable flow to meet spec") Reported-by: Tim Harvey Signed-off-by: Frieder Schrempf --- drivers/gpu/drm/bridge/samsung-dsim.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c index 043b8109e64a..4d371eaa4fa2 100644 --- a/drivers/gpu/drm/bridge/samsung-dsim.c +++ b/drivers/gpu/drm/bridge/samsung-dsim.c @@ -833,7 +833,7 @@ static void samsung_dsim_enable_lane(struct samsung_dsim *dsi, u32 lane) samsung_dsim_write(dsi, DSIM_CONFIG_REG, reg); } -static int samsung_dsim_init_link(struct samsung_dsim *dsi) +static int samsung_dsim_init_link(struct samsung_dsim *dsi, bool force_stop_state) { const struct samsung_dsim_driver_data *driver_data = dsi->driver_data; int timeout; @@ -939,7 +939,7 @@ static int samsung_dsim_init_link(struct samsung_dsim *dsi) reg &= ~DSIM_STOP_STATE_CNT_MASK; reg |= DSIM_STOP_STATE_CNT(driver_data->reg_values[STOP_STATE_CNT]); - if (!samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type)) + if (!samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type) && force_stop_state) reg |= DSIM_FORCE_STOP_STATE; samsung_dsim_write(dsi, DSIM_ESCMODE_REG, reg); @@ -1386,7 +1386,7 @@ static void samsung_dsim_disable_irq(struct samsung_dsim *dsi) disable_irq(dsi->irq); } -static int samsung_dsim_init(struct samsung_dsim *dsi) +static int samsung_dsim_init(struct samsung_dsim *dsi, bool force_stop_state) { const struct samsung_dsim_driver_data *driver_data = dsi->driver_data; @@ -1403,7 +1403,7 @@ static int samsung_dsim_init(struct samsung_dsim *dsi) if (driver_data->wait_for_reset) samsung_dsim_wait_for_reset(dsi); samsung_dsim_set_phy_ctrl(dsi); - samsung_dsim_init_link(dsi); + samsung_dsim_init_link(dsi, force_stop_state); dsi->state |= DSIM_STATE_INITIALIZED; @@ -1432,7 +1432,7 @@ static void samsung_dsim_atomic_pre_enable(struct drm_bridge *bridge, * the host initialization during DSI transfer. */ if (!samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type)) { - ret = samsung_dsim_init(dsi); + ret = samsung_dsim_init(dsi, true); if (ret) return; @@ -1771,7 +1771,7 @@ static ssize_t samsung_dsim_host_transfer(struct mipi_dsi_host *host, if (!(dsi->state & DSIM_STATE_ENABLED)) return -EINVAL; - ret = samsung_dsim_init(dsi); + ret = samsung_dsim_init(dsi, false); if (ret) return ret; -- 2.41.0