Am Donnerstag, dem 19.05.2022 um 13:47 +0200 schrieb Marek Vasut:
> The Refclk may be supplied by SoC clock output instead of crystal
> oscillator, make sure the clock are enabled before any other action
> is performed with the bridge chip, otherwise it may either fail to
> operate at all, or miss reset GPIO toggle.
>
> Fixes: 7caff0fc4296e ("drm/bridge: tc358767: Add DPI to eDP bridge driver")
> Signed-off-by: Marek Vasut <[email protected]>
Reviewed-by: Lucas Stach <[email protected]>
> Cc: Jonas Karlman <[email protected]>
> Cc: Laurent Pinchart <[email protected]>
> Cc: Lucas Stach <[email protected]>
> Cc: Marek Vasut <[email protected]>
> Cc: Maxime Ripard <[email protected]>
> Cc: Neil Armstrong <[email protected]>
> Cc: Robert Foss <[email protected]>
> Cc: Sam Ravnborg <[email protected]>
> ---
> V2: Use devm_add_action_or_reset() to add clock disable hook instead
> of wall of failpath
> ---
> drivers/gpu/drm/bridge/tc358767.c | 30 +++++++++++++++++++++++-------
> 1 file changed, 23 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/tc358767.c
> b/drivers/gpu/drm/bridge/tc358767.c
> index 45ea829d56601..b2ef01303be23 100644
> --- a/drivers/gpu/drm/bridge/tc358767.c
> +++ b/drivers/gpu/drm/bridge/tc358767.c
> @@ -2033,6 +2033,13 @@ static int tc_probe_bridge_endpoint(struct tc_data *tc)
> return -EINVAL;
> }
>
> +static void tc_clk_disable(void *data)
> +{
> + struct clk *refclk = data;
> +
> + clk_disable_unprepare(refclk);
> +}
> +
> static int tc_probe(struct i2c_client *client, const struct i2c_device_id
> *id)
> {
> struct device *dev = &client->dev;
> @@ -2049,6 +2056,22 @@ static int tc_probe(struct i2c_client *client, const
> struct i2c_device_id *id)
> if (ret)
> return ret;
>
> + tc->refclk = devm_clk_get(dev, "ref");
> + if (IS_ERR(tc->refclk)) {
> + ret = PTR_ERR(tc->refclk);
> + dev_err(dev, "Failed to get refclk: %d\n", ret);
> + return ret;
> + }
> +
> + ret = devm_add_action_or_reset(dev, tc_clk_disable, tc->refclk);
> + if (ret)
> + return ret;
> +
> + clk_prepare_enable(tc->refclk);
> +
> + /* tRSTW = 100 cycles , at 13 MHz that is ~7.69 us */
> + usleep_range(10, 15);
> +
> /* Shut down GPIO is optional */
> tc->sd_gpio = devm_gpiod_get_optional(dev, "shutdown", GPIOD_OUT_HIGH);
> if (IS_ERR(tc->sd_gpio))
> @@ -2069,13 +2092,6 @@ static int tc_probe(struct i2c_client *client, const
> struct i2c_device_id *id)
> usleep_range(5000, 10000);
> }
>
> - tc->refclk = devm_clk_get(dev, "ref");
> - if (IS_ERR(tc->refclk)) {
> - ret = PTR_ERR(tc->refclk);
> - dev_err(dev, "Failed to get refclk: %d\n", ret);
> - return ret;
> - }
> -
> tc->regmap = devm_regmap_init_i2c(client, &tc_regmap_config);
> if (IS_ERR(tc->regmap)) {
> ret = PTR_ERR(tc->regmap);