Commit 30a46873 authored by Marek Vasut's avatar Marek Vasut Committed by Sam Ravnborg

drm/bridge: ti-sn65dsi83: Optimize reset line toggling

Current code always sets reset line low in .pre_enable callback and
holds it low for 10ms. This is sub-optimal and increases the time
between enablement of the DSI83 and valid LVDS clock.

Rework the reset handling such that the reset line is held low for 10ms
both in probe() of the driver and .disable callback, which guarantees
that the reset line was always held low for more than 10ms and therefore
the reset line timing requirement is satisfied. Furthermore, move the
reset handling into .enable callback so the entire DSI83 initialization
is now in one place.

This reduces DSI83 enablement delay by up to 10ms.
Signed-off-by: default avatarMarek Vasut <marex@denx.de>
Reviewed-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Robert Foss <robert.foss@linaro.org>
Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: default avatarSam Ravnborg <sam@ravnborg.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20211016210402.171595-1-marex@denx.de
parent 40e8c019
......@@ -301,22 +301,6 @@ static void sn65dsi83_detach(struct drm_bridge *bridge)
ctx->dsi = NULL;
}
static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
struct drm_bridge_state *old_bridge_state)
{
struct sn65dsi83 *ctx = bridge_to_sn65dsi83(bridge);
/*
* Reset the chip, pull EN line low for t_reset=10ms,
* then high for t_en=1ms.
*/
regcache_mark_dirty(ctx->regmap);
gpiod_set_value(ctx->enable_gpio, 0);
usleep_range(10000, 11000);
gpiod_set_value(ctx->enable_gpio, 1);
usleep_range(1000, 1100);
}
static u8 sn65dsi83_get_lvds_range(struct sn65dsi83 *ctx,
const struct drm_display_mode *mode)
{
......@@ -394,6 +378,10 @@ static void sn65dsi83_atomic_enable(struct drm_bridge *bridge,
u16 val;
int ret;
/* Deassert reset */
gpiod_set_value(ctx->enable_gpio, 1);
usleep_range(1000, 1100);
/* Get the LVDS format from the bridge state. */
bridge_state = drm_atomic_get_new_bridge_state(state, bridge);
......@@ -540,18 +528,11 @@ static void sn65dsi83_atomic_disable(struct drm_bridge *bridge,
{
struct sn65dsi83 *ctx = bridge_to_sn65dsi83(bridge);
/* Clear reset, disable PLL */
regmap_write(ctx->regmap, REG_RC_RESET, 0x00);
regmap_write(ctx->regmap, REG_RC_PLL_EN, 0x00);
}
static void sn65dsi83_atomic_post_disable(struct drm_bridge *bridge,
struct drm_bridge_state *old_bridge_state)
{
struct sn65dsi83 *ctx = bridge_to_sn65dsi83(bridge);
/* Put the chip in reset, pull EN line low. */
/* Put the chip in reset, pull EN line low, and assure 10ms reset low timing. */
gpiod_set_value(ctx->enable_gpio, 0);
usleep_range(10000, 11000);
regcache_mark_dirty(ctx->regmap);
}
static enum drm_mode_status
......@@ -597,10 +578,8 @@ sn65dsi83_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
static const struct drm_bridge_funcs sn65dsi83_funcs = {
.attach = sn65dsi83_attach,
.detach = sn65dsi83_detach,
.atomic_pre_enable = sn65dsi83_atomic_pre_enable,
.atomic_enable = sn65dsi83_atomic_enable,
.atomic_disable = sn65dsi83_atomic_disable,
.atomic_post_disable = sn65dsi83_atomic_post_disable,
.mode_valid = sn65dsi83_mode_valid,
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
......@@ -685,10 +664,13 @@ static int sn65dsi83_probe(struct i2c_client *client,
model = id->driver_data;
}
/* Put the chip in reset, pull EN line low, and assure 10ms reset low timing. */
ctx->enable_gpio = devm_gpiod_get(ctx->dev, "enable", GPIOD_OUT_LOW);
if (IS_ERR(ctx->enable_gpio))
return PTR_ERR(ctx->enable_gpio);
usleep_range(10000, 11000);
ret = sn65dsi83_parse_dt(ctx, model);
if (ret)
return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment