Locking PLL requires the DSI HS clock to be running, which it might not be in probe(), but should be in atomic_enable().
This resolves issues like this: sn65dsi83 1-002c: failed to lock PLL, ret=-110 sn65dsi83 1-002c: Unexpected link status 0x01 sn65dsi83 1-002c: Unexpected link status 0x01 sn65dsi83 1-002c: reset the pipe as seen with nwl-dsi bridge and others. This is the same issue as addressed in the patch by Gary Bisson [1], but changing the ti-sn65dsi83 driver instead, so we don't have to change all other drivers that could potentially be used with this chip. [1] https://lore.kernel.org/all/[email protected]/ Signed-off-by: Esben Haabendal <[email protected]> --- drivers/gpu/drm/bridge/ti-sn65dsi83.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c index 32e9eadd7452..e87bed3a6640 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c @@ -532,7 +532,6 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge, bool test_pattern = sn65dsi83_test_pattern; bool lvds_format_24bpp; bool lvds_format_jeida; - unsigned int pval; __le16 le16val; u16 val; int ret; @@ -682,26 +681,12 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge, regmap_write(ctx->regmap, REG_VID_CHA_TEST_PATTERN, test_pattern ? REG_VID_CHA_TEST_PATTERN_EN : 0); - /* Enable PLL */ - regmap_write(ctx->regmap, REG_RC_PLL_EN, REG_RC_PLL_EN_PLL_EN); - usleep_range(3000, 4000); - ret = regmap_read_poll_timeout(ctx->regmap, REG_RC_LVDS_PLL, pval, - pval & REG_RC_LVDS_PLL_PLL_EN_STAT, - 1000, 100000); - if (ret) { - dev_err(ctx->dev, "failed to lock PLL, ret=%i\n", ret); - /* On failure, disable PLL again and exit. */ - regmap_write(ctx->regmap, REG_RC_PLL_EN, 0x00); - goto err_add_action; - } - /* Trigger reset after CSR register update. */ regmap_write(ctx->regmap, REG_RC_RESET, REG_RC_RESET_SOFT_RESET); /* Wait for 10ms after soft reset as specified in datasheet */ usleep_range(10000, 12000); -err_add_action: devm_add_action(ctx->dev, sn65dsi83_release_resources, ctx); err_exit: drm_bridge_exit(idx); @@ -712,11 +697,24 @@ static void sn65dsi83_atomic_enable(struct drm_bridge *bridge, { struct sn65dsi83 *ctx = bridge_to_sn65dsi83(bridge); unsigned int pval; - int idx; + int idx, ret; if (!drm_bridge_enter(bridge, &idx)) return; + /* Enable PLL */ + regmap_write(ctx->regmap, REG_RC_PLL_EN, REG_RC_PLL_EN_PLL_EN); + usleep_range(3000, 4000); + ret = regmap_read_poll_timeout(ctx->regmap, REG_RC_LVDS_PLL, pval, + pval & REG_RC_LVDS_PLL_PLL_EN_STAT, + 1000, 100000); + if (ret) { + dev_err(ctx->dev, "failed to lock PLL, ret=%i\n", ret); + /* On failure, disable PLL again and exit. */ + regmap_write(ctx->regmap, REG_RC_PLL_EN, 0x00); + return; + } + /* Clear all errors that got asserted during initialization. */ regmap_read(ctx->regmap, REG_IRQ_STAT, &pval); regmap_write(ctx->regmap, REG_IRQ_STAT, pval); -- 2.55.0
