diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c index 7705aa34a5277ce90cea0bdaea0a33f1f887cb29..897865ecb8da0788ae45f604e11fb9654c7249ad 100644 --- a/drivers/gpu/drm/panfrost/panfrost_device.c +++ b/drivers/gpu/drm/panfrost/panfrost_device.c @@ -3,6 +3,7 @@ /* Copyright 2019 Linaro, Ltd, Rob Herring <robh@kernel.org> */ #include <linux/clk.h> +#include <linux/reset.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/regulator/consumer.h> @@ -14,6 +15,28 @@ #include "panfrost_job.h" #include "panfrost_mmu.h" +static int panfrost_reset_init(struct panfrost_device *pfdev) +{ + int err; + + pfdev->rstc = devm_reset_control_array_get(pfdev->dev, false, true); + if (IS_ERR(pfdev->rstc)) { + dev_err(pfdev->dev, "get reset failed %ld\n", PTR_ERR(pfdev->clock)); + return PTR_ERR(pfdev->rstc); + } + + err = reset_control_deassert(pfdev->rstc); + if (err) + return err; + + return 0; +} + +static void panfrost_reset_fini(struct panfrost_device *pfdev) +{ + reset_control_assert(pfdev->rstc); +} + static int panfrost_clk_init(struct panfrost_device *pfdev) { int err; @@ -91,25 +114,31 @@ int panfrost_device_init(struct panfrost_device *pfdev) goto err_out0; } + err = panfrost_reset_init(pfdev); + if (err) { + dev_err(pfdev->dev, "reset init failed %d\n", err); + goto err_out1; + } + res = platform_get_resource(pfdev->pdev, IORESOURCE_MEM, 0); pfdev->iomem = devm_ioremap_resource(pfdev->dev, res); if (IS_ERR(pfdev->iomem)) { dev_err(pfdev->dev, "failed to ioremap iomem\n"); err = PTR_ERR(pfdev->iomem); - goto err_out1; + goto err_out2; } err = panfrost_gpu_init(pfdev); if (err) - goto err_out1; + goto err_out2; err = panfrost_mmu_init(pfdev); if (err) - goto err_out2; + goto err_out3; err = panfrost_job_init(pfdev); if (err) - goto err_out3; + goto err_out4; /* runtime PM will wake us up later */ panfrost_gpu_power_off(pfdev); @@ -120,10 +149,12 @@ int panfrost_device_init(struct panfrost_device *pfdev) pm_runtime_put_autosuspend(pfdev->dev); return 0; -err_out3: +err_out4: panfrost_mmu_fini(pfdev); -err_out2: +err_out3: panfrost_gpu_fini(pfdev); +err_out2: + panfrost_reset_fini(pfdev); err_out1: panfrost_regulator_fini(pfdev); err_out0: diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h index f92011d05cc09d32b08c27e736fdda32dcd59a35..a9295d4d85eb27a8eb32a8bafe1f63b538ef11c8 100644 --- a/drivers/gpu/drm/panfrost/panfrost_device.h +++ b/drivers/gpu/drm/panfrost/panfrost_device.h @@ -60,6 +60,7 @@ struct panfrost_device { void __iomem *iomem; struct clk *clock; struct regulator *regulator; + struct reset_control *rstc; struct panfrost_features features;