Skip to content

Commit 20c8276

Browse files
fschrempfsuperna9999
authored andcommitted
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. As documented in [1] DSI hosts are expected to allow transfers outside the normal bridge enable/disable flow. To fix this make sure that stop state is cleared in samsung_dsim_host_transfer() which restores the previous behavior. We also factor out the common code to enable/disable stop state to samsung_dsim_set_stop_state(). [1] https://docs.kernel.org/gpu/drm-kms-helpers.html#mipi-dsi-bridge-operation Fixes: 0c14d31 ("drm: bridge: samsung-dsim: Fix i.MX8M enable flow to meet spec") Reported-by: Tim Harvey <tharvey@gateworks.com> Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Tested-by: Tim Harvey <tharvey@gateworks.com> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20230724151640.555490-1-frieder@fris.de
1 parent 50b6f2c commit 20c8276

File tree

1 file changed

+17
-10
lines changed

1 file changed

+17
-10
lines changed

drivers/gpu/drm/bridge/samsung-dsim.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,6 +1386,18 @@ static void samsung_dsim_disable_irq(struct samsung_dsim *dsi)
13861386
disable_irq(dsi->irq);
13871387
}
13881388

1389+
static void samsung_dsim_set_stop_state(struct samsung_dsim *dsi, bool enable)
1390+
{
1391+
u32 reg = samsung_dsim_read(dsi, DSIM_ESCMODE_REG);
1392+
1393+
if (enable)
1394+
reg |= DSIM_FORCE_STOP_STATE;
1395+
else
1396+
reg &= ~DSIM_FORCE_STOP_STATE;
1397+
1398+
samsung_dsim_write(dsi, DSIM_ESCMODE_REG, reg);
1399+
}
1400+
13891401
static int samsung_dsim_init(struct samsung_dsim *dsi)
13901402
{
13911403
const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;
@@ -1445,15 +1457,12 @@ static void samsung_dsim_atomic_enable(struct drm_bridge *bridge,
14451457
struct drm_bridge_state *old_bridge_state)
14461458
{
14471459
struct samsung_dsim *dsi = bridge_to_dsi(bridge);
1448-
u32 reg;
14491460

14501461
if (samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type)) {
14511462
samsung_dsim_set_display_mode(dsi);
14521463
samsung_dsim_set_display_enable(dsi, true);
14531464
} else {
1454-
reg = samsung_dsim_read(dsi, DSIM_ESCMODE_REG);
1455-
reg &= ~DSIM_FORCE_STOP_STATE;
1456-
samsung_dsim_write(dsi, DSIM_ESCMODE_REG, reg);
1465+
samsung_dsim_set_stop_state(dsi, false);
14571466
}
14581467

14591468
dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;
@@ -1463,16 +1472,12 @@ static void samsung_dsim_atomic_disable(struct drm_bridge *bridge,
14631472
struct drm_bridge_state *old_bridge_state)
14641473
{
14651474
struct samsung_dsim *dsi = bridge_to_dsi(bridge);
1466-
u32 reg;
14671475

14681476
if (!(dsi->state & DSIM_STATE_ENABLED))
14691477
return;
14701478

1471-
if (!samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type)) {
1472-
reg = samsung_dsim_read(dsi, DSIM_ESCMODE_REG);
1473-
reg |= DSIM_FORCE_STOP_STATE;
1474-
samsung_dsim_write(dsi, DSIM_ESCMODE_REG, reg);
1475-
}
1479+
if (!samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type))
1480+
samsung_dsim_set_stop_state(dsi, true);
14761481

14771482
dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;
14781483
}
@@ -1775,6 +1780,8 @@ static ssize_t samsung_dsim_host_transfer(struct mipi_dsi_host *host,
17751780
if (ret)
17761781
return ret;
17771782

1783+
samsung_dsim_set_stop_state(dsi, false);
1784+
17781785
ret = mipi_dsi_create_packet(&xfer.packet, msg);
17791786
if (ret < 0)
17801787
return ret;

0 commit comments

Comments
 (0)