drm/tegra: gr2d: Explicitly control module reset
[ Upstream commit271fca025a
] As of commit4782c0a5dd
("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:4782c0a5dd
("clk: tegra: Don't deassert reset on enabling clocks") Signed-off-by: Thierry Reding <treding@nvidia.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
3b90135b03
commit
0dbb2617c7
@ -4,9 +4,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
#include <linux/iommu.h>
|
#include <linux/iommu.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
|
#include <linux/reset.h>
|
||||||
|
|
||||||
#include "drm.h"
|
#include "drm.h"
|
||||||
#include "gem.h"
|
#include "gem.h"
|
||||||
@ -19,6 +21,7 @@ struct gr2d_soc {
|
|||||||
struct gr2d {
|
struct gr2d {
|
||||||
struct tegra_drm_client client;
|
struct tegra_drm_client client;
|
||||||
struct host1x_channel *channel;
|
struct host1x_channel *channel;
|
||||||
|
struct reset_control *rst;
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
|
|
||||||
const struct gr2d_soc *soc;
|
const struct gr2d_soc *soc;
|
||||||
@ -208,6 +211,12 @@ static int gr2d_probe(struct platform_device *pdev)
|
|||||||
if (!syncpts)
|
if (!syncpts)
|
||||||
return -ENOMEM;
|
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);
|
gr2d->clk = devm_clk_get(dev, NULL);
|
||||||
if (IS_ERR(gr2d->clk)) {
|
if (IS_ERR(gr2d->clk)) {
|
||||||
dev_err(dev, "cannot get clock\n");
|
dev_err(dev, "cannot get clock\n");
|
||||||
@ -220,6 +229,14 @@ static int gr2d_probe(struct platform_device *pdev)
|
|||||||
return err;
|
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);
|
INIT_LIST_HEAD(&gr2d->client.base.list);
|
||||||
gr2d->client.base.ops = &gr2d_client_ops;
|
gr2d->client.base.ops = &gr2d_client_ops;
|
||||||
gr2d->client.base.dev = dev;
|
gr2d->client.base.dev = dev;
|
||||||
@ -234,8 +251,7 @@ static int gr2d_probe(struct platform_device *pdev)
|
|||||||
err = host1x_client_register(&gr2d->client.base);
|
err = host1x_client_register(&gr2d->client.base);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
dev_err(dev, "failed to register host1x client: %d\n", err);
|
dev_err(dev, "failed to register host1x client: %d\n", err);
|
||||||
clk_disable_unprepare(gr2d->clk);
|
goto assert_rst;
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initialize address register map */
|
/* initialize address register map */
|
||||||
@ -245,6 +261,13 @@ static int gr2d_probe(struct platform_device *pdev)
|
|||||||
platform_set_drvdata(pdev, gr2d);
|
platform_set_drvdata(pdev, gr2d);
|
||||||
|
|
||||||
return 0;
|
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)
|
static int gr2d_remove(struct platform_device *pdev)
|
||||||
@ -259,6 +282,12 @@ static int gr2d_remove(struct platform_device *pdev)
|
|||||||
return err;
|
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);
|
clk_disable_unprepare(gr2d->clk);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Reference in New Issue
Block a user