Commit 271fca02 authored by Thierry Reding's avatar Thierry Reding

drm/tegra: gr2d: Explicitly control module reset

As of commit 4782c0a5 ("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: 4782c0a5 ("clk: tegra: Don't deassert reset on enabling clocks")
Signed-off-by: default avatarThierry Reding <treding@nvidia.com>
parent 6c7a388b
......@@ -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;
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);
disable_clk:
clk_disable_unprepare(gr2d->clk);
return err;
}
static int gr2d_remove(struct platform_device *pdev)
......@@ -259,6 +282,12 @@ static int gr2d_remove(struct platform_device *pdev)
return err;
}
err = reset_control_assert(gr2d->rst);
if (err < 0)
dev_err(&pdev->dev, "failed to assert reset: %d\n", err);
usleep_range(2000, 4000);
clk_disable_unprepare(gr2d->clk);
return 0;
......
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