Skip to content

Commit

Permalink
drm/sun4i: Fix TCON clock and regmap initialization sequence
Browse files Browse the repository at this point in the history
The TCON driver calls sun4i_tcon_init_regmap and sun4i_tcon_init_clocks
in its bind function. The former creates a regmap and writes to several
register to clear its configuration to a known default. The latter
initializes various clocks. This includes enabling the bus clock for
register access and creating the dotclock.

In order for the first step's writes to work, the bus clock must be
enabled which is done in the second step. but the dotclock's ops use
the regmap created in the first step.

Rearrange the function calls such that the clocks are initialized before
the regmap, and split out the dot clock creation to after the regmap is
initialized.

Fixes: 9026e0d ("drm: Add Allwinner A10 Display Engine support")
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
  • Loading branch information
Chen-Yu Tsai authored and Maxime Ripard committed Mar 9, 2017
1 parent 596afb6 commit 4c7f16d
Showing 1 changed file with 15 additions and 7 deletions.
22 changes: 15 additions & 7 deletions drivers/gpu/drm/sun4i/sun4i_tcon.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,12 +335,11 @@ static int sun4i_tcon_init_clocks(struct device *dev,
}
}

return sun4i_dclk_create(dev, tcon);
return 0;
}

static void sun4i_tcon_free_clocks(struct sun4i_tcon *tcon)
{
sun4i_dclk_free(tcon);
clk_disable_unprepare(tcon->clk);
}

Expand Down Expand Up @@ -505,22 +504,28 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
return ret;
}

ret = sun4i_tcon_init_clocks(dev, tcon);
if (ret) {
dev_err(dev, "Couldn't init our TCON clocks\n");
goto err_assert_reset;
}

ret = sun4i_tcon_init_regmap(dev, tcon);
if (ret) {
dev_err(dev, "Couldn't init our TCON regmap\n");
goto err_assert_reset;
goto err_free_clocks;
}

ret = sun4i_tcon_init_clocks(dev, tcon);
ret = sun4i_dclk_create(dev, tcon);
if (ret) {
dev_err(dev, "Couldn't init our TCON clocks\n");
goto err_assert_reset;
dev_err(dev, "Couldn't create our TCON dot clock\n");
goto err_free_clocks;
}

ret = sun4i_tcon_init_irq(dev, tcon);
if (ret) {
dev_err(dev, "Couldn't init our TCON interrupts\n");
goto err_free_clocks;
goto err_free_dotclock;
}

tcon->crtc = sun4i_crtc_init(drm);
Expand All @@ -536,6 +541,8 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,

return 0;

err_free_dotclock:
sun4i_dclk_free(tcon);
err_free_clocks:
sun4i_tcon_free_clocks(tcon);
err_assert_reset:
Expand All @@ -548,6 +555,7 @@ static void sun4i_tcon_unbind(struct device *dev, struct device *master,
{
struct sun4i_tcon *tcon = dev_get_drvdata(dev);

sun4i_dclk_free(tcon);
sun4i_tcon_free_clocks(tcon);
}

Expand Down

0 comments on commit 4c7f16d

Please sign in to comment.