08.07.2021 17:37, Thierry Reding пишет: > From: Thierry Reding <treding@xxxxxxxxxx> > > As of commit 4782c0a5dd88 ("clk: tegra: Don't deassert reset on enabling > clocks"), module resets are no longer automatically deasserted when the > module clock is enabled. To make sure that the gr2d module continues to > work, we need to explicitly control the module reset. > > Fixes: 4782c0a5dd88 ("clk: tegra: Don't deassert reset on enabling clocks") > Signed-off-by: Thierry Reding <treding@xxxxxxxxxx> On which board do see this problem? TRM says that 2d should be in reset by default, but somehow it's not a problem on devices that use fastboot.. why would it touch the 2d reset? > --- > drivers/gpu/drm/tegra/gr2d.c | 33 +++++++++++++++++++++++++++++++-- > 1 file changed, 31 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/tegra/gr2d.c b/drivers/gpu/drm/tegra/gr2d.c > index de288cba3905..ba3722f1b865 100644 > --- a/drivers/gpu/drm/tegra/gr2d.c > +++ b/drivers/gpu/drm/tegra/gr2d.c > @@ -4,9 +4,11 @@ > */ > > #include <linux/clk.h> > +#include <linux/delay.h> > #include <linux/iommu.h> > #include <linux/module.h> > #include <linux/of_device.h> > +#include <linux/reset.h> > > #include "drm.h" > #include "gem.h" > @@ -19,6 +21,7 @@ struct gr2d_soc { > struct gr2d { > struct tegra_drm_client client; > struct host1x_channel *channel; > + struct reset_control *rst; Unused variable? > struct clk *clk; > > const struct gr2d_soc *soc; > @@ -208,6 +211,12 @@ static int gr2d_probe(struct platform_device *pdev) > if (!syncpts) > return -ENOMEM; > > + gr2d->rst = devm_reset_control_get(dev, NULL); > + if (IS_ERR(gr2d->rst)) { > + dev_err(dev, "cannot get reset\n"); > + return PTR_ERR(gr2d->rst); > + } > + > gr2d->clk = devm_clk_get(dev, NULL); > if (IS_ERR(gr2d->clk)) { > dev_err(dev, "cannot get clock\n"); > @@ -220,6 +229,14 @@ static int gr2d_probe(struct platform_device *pdev) > return err; > } > > + usleep_range(2000, 4000); > + > + err = reset_control_deassert(gr2d->rst); > + if (err < 0) { > + dev_err(dev, "failed to deassert reset: %d\n", err); > + goto disable_clk; > + } > + > INIT_LIST_HEAD(&gr2d->client.base.list); > gr2d->client.base.ops = &gr2d_client_ops; > gr2d->client.base.dev = dev; > @@ -234,8 +251,7 @@ static int gr2d_probe(struct platform_device *pdev) > err = host1x_client_register(&gr2d->client.base); > if (err < 0) { > dev_err(dev, "failed to register host1x client: %d\n", err); > - clk_disable_unprepare(gr2d->clk); > - return err; > + goto assert_rst; > } > > /* initialize address register map */ > @@ -245,6 +261,13 @@ static int gr2d_probe(struct platform_device *pdev) > platform_set_drvdata(pdev, gr2d); > > return 0; > + > +assert_rst: > + (void)reset_control_assert(gr2d->rst); (void)?