diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c index 9f657a63b0bb..396f29f289f5 100644 --- a/drivers/gpu/drm/tegra/vic.c +++ b/drivers/gpu/drm/tegra/vic.c @@ -38,6 +38,7 @@ struct vic { struct iommu_domain *domain; struct device *dev; struct clk *clk; + struct reset_control *rst; /* Platform configuration */ const struct vic_config *config; @@ -56,13 +57,37 @@ static void vic_writel(struct vic *vic, u32 value, unsigned int offset) static int vic_runtime_resume(struct device *dev) { struct vic *vic = dev_get_drvdata(dev); + int err; - return clk_prepare_enable(vic->clk); + err = clk_prepare_enable(vic->clk); + if (err < 0) + return err; + + usleep_range(10, 20); + + err = reset_control_deassert(vic->rst); + if (err < 0) + goto disable; + + usleep_range(10, 20); + + return 0; + +disable: + clk_disable_unprepare(vic->clk); + return err; } static int vic_runtime_suspend(struct device *dev) { struct vic *vic = dev_get_drvdata(dev); + int err; + + err = reset_control_assert(vic->rst); + if (err < 0) + return err; + + usleep_range(2000, 4000); clk_disable_unprepare(vic->clk); @@ -323,6 +348,14 @@ static int vic_probe(struct platform_device *pdev) return PTR_ERR(vic->clk); } + if (!dev->pm_domain) { + vic->rst = devm_reset_control_get(dev, "vic"); + if (IS_ERR(vic->rst)) { + dev_err(&pdev->dev, "failed to get reset\n"); + return PTR_ERR(vic->rst); + } + } + vic->falcon.dev = dev; vic->falcon.regs = vic->regs; vic->falcon.ops = &vic_falcon_ops;