| From 66a90160ce772121814fe1124b6605ea80045e65 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 17 Jul 2020 20:04:18 +0530 |
| Subject: drm: msm: a6xx: fix gpu failure after system resume |
| |
| From: Akhil P Oommen <akhilpo@codeaurora.org> |
| |
| [ Upstream commit 57c0bd517c06b088106b0236ed604056c8e06da5 ] |
| |
| On targets where GMU is available, GMU takes over the ownership of GX GDSC |
| during its initialization. So, move the refcount-get on GX PD before we |
| initialize the GMU. This ensures that nobody can collapse the GX GDSC |
| once GMU owns the GX GDSC. This patch fixes some GMU OOB errors seen |
| during GPU wake up during a system resume. |
| |
| Reported-by: Matthias Kaehlcke <mka@chromium.org> |
| Signed-off-by: Akhil P Oommen <akhilpo@codeaurora.org> |
| Tested-by: Matthias Kaehlcke <mka@chromium.org> |
| Reviewed-by: Jordan Crouse <jcrouse@codeaurora.org> |
| Signed-off-by: Rob Clark <robdclark@chromium.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 18 ++++++++++-------- |
| 1 file changed, 10 insertions(+), 8 deletions(-) |
| |
| diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c |
| index 34607a98cc7c8..9a7a18951dc2b 100644 |
| --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c |
| +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c |
| @@ -732,10 +732,19 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu) |
| /* Turn on the resources */ |
| pm_runtime_get_sync(gmu->dev); |
| |
| + /* |
| + * "enable" the GX power domain which won't actually do anything but it |
| + * will make sure that the refcounting is correct in case we need to |
| + * bring down the GX after a GMU failure |
| + */ |
| + if (!IS_ERR_OR_NULL(gmu->gxpd)) |
| + pm_runtime_get_sync(gmu->gxpd); |
| + |
| /* Use a known rate to bring up the GMU */ |
| clk_set_rate(gmu->core_clk, 200000000); |
| ret = clk_bulk_prepare_enable(gmu->nr_clocks, gmu->clocks); |
| if (ret) { |
| + pm_runtime_put(gmu->gxpd); |
| pm_runtime_put(gmu->dev); |
| return ret; |
| } |
| @@ -771,19 +780,12 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu) |
| /* Set the GPU to the current freq */ |
| __a6xx_gmu_set_freq(gmu, gmu->current_perf_index); |
| |
| - /* |
| - * "enable" the GX power domain which won't actually do anything but it |
| - * will make sure that the refcounting is correct in case we need to |
| - * bring down the GX after a GMU failure |
| - */ |
| - if (!IS_ERR_OR_NULL(gmu->gxpd)) |
| - pm_runtime_get(gmu->gxpd); |
| - |
| out: |
| /* On failure, shut down the GMU to leave it in a good state */ |
| if (ret) { |
| disable_irq(gmu->gmu_irq); |
| a6xx_rpmh_stop(gmu); |
| + pm_runtime_put(gmu->gxpd); |
| pm_runtime_put(gmu->dev); |
| } |
| |
| -- |
| 2.25.1 |
| |