Now with IFPC, GX domain can collapse as soon as GPU becomes IDLE. So
add gx_is_on check before accessing any GX registers during crashstate
capture and recovery.

Signed-off-by: Akhil P Oommen <akhi...@oss.qualcomm.com>
---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c       |  4 ++++
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c       | 27 +++++++++++++++++++--------
 drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 10 +++++++---
 3 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index 
ccdcf5fe4b4f3cd81d765754d00c132960a916a9..c17837013b613b53793db0e34bbc7e65f0eb06e7
 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -101,6 +101,10 @@ bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu)
        if (!gmu->initialized)
                return false;
 
+       /* If GMU is absent, then GX power domain is ON as long as GPU is in 
active state */
+       if (adreno_has_gmu_wrapper(adreno_gpu))
+               return true;
+
        val = gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS);
 
        if (adreno_is_a7xx(adreno_gpu))
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index 
b46fdd222913a46e01b984b90c4e63ae82f54e9f..54decb9908fe526ac7f150465034b03ba688aa6d
 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -1518,21 +1518,25 @@ static void a6xx_recover(struct msm_gpu *gpu)
 
        adreno_dump_info(gpu);
 
-       for (i = 0; i < 8; i++)
-               DRM_DEV_INFO(&gpu->pdev->dev, "CP_SCRATCH_REG%d: %u\n", i,
-                       gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(i)));
+       if (a6xx_gmu_gx_is_on(&a6xx_gpu->gmu)) {
+               /* Sometimes crashstate capture is skipped, so SQE should be 
halted here again */
+               gpu_write(gpu, REG_A6XX_CP_SQE_CNTL, 3);
 
-       if (hang_debug)
-               a6xx_dump(gpu);
+               for (i = 0; i < 8; i++)
+                       DRM_DEV_INFO(&gpu->pdev->dev, "CP_SCRATCH_REG%d: %u\n", 
i,
+                               gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(i)));
+
+               if (hang_debug)
+                       a6xx_dump(gpu);
+
+       }
 
        /*
         * To handle recovery specific sequences during the rpm suspend we are
         * about to trigger
         */
-       a6xx_gpu->hung = true;
 
-       /* Halt SQE first */
-       gpu_write(gpu, REG_A6XX_CP_SQE_CNTL, 3);
+       a6xx_gpu->hung = true;
 
        pm_runtime_dont_use_autosuspend(&gpu->pdev->dev);
 
@@ -2394,6 +2398,13 @@ static uint32_t a6xx_get_rptr(struct msm_gpu *gpu, 
struct msm_ringbuffer *ring)
        if (adreno_gpu->base.hw_apriv || a6xx_gpu->has_whereami)
                return a6xx_gpu->shadow[ring->id];
 
+       /*
+        * This is true only on an A6XX_GEN1 with GMU, has IFPC enabled and a 
super old SQE firmware
+        * without 'whereami' support
+        */
+       WARN_ONCE((to_adreno_gpu(gpu)->info->quirks & ADRENO_QUIRK_IFPC),
+               "Can't read CP_RB_RPTR register reliably\n");
+
        return ring->memptrs->rptr = gpu_read(gpu, REG_A6XX_CP_RB_RPTR);
 }
 
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
index 
341a72a674018258597aadefc9a45269b977e00e..cb846c1548ba4ea31a0ff0f23e98820388cb5ce0
 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
@@ -1569,8 +1569,7 @@ struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu 
*gpu)
        struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
        struct a6xx_gpu_state *a6xx_state = kzalloc(sizeof(*a6xx_state),
                GFP_KERNEL);
-       bool stalled = !!(gpu_read(gpu, REG_A6XX_RBBM_STATUS3) &
-                       A6XX_RBBM_STATUS3_SMMU_STALLED_ON_FAULT);
+       bool stalled;
 
        if (!a6xx_state)
                return ERR_PTR(-ENOMEM);
@@ -1591,15 +1590,20 @@ struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu 
*gpu)
        }
 
        /* If GX isn't on the rest of the data isn't going to be accessible */
-       if (!adreno_has_gmu_wrapper(adreno_gpu) && 
!a6xx_gmu_gx_is_on(&a6xx_gpu->gmu))
+       if (!a6xx_gmu_gx_is_on(&a6xx_gpu->gmu))
                return &a6xx_state->base;
 
+       /* Halt SQE first */
+       gpu_write(gpu, REG_A6XX_CP_SQE_CNTL, 3);
+
        /* Get the banks of indexed registers */
        if (adreno_is_a7xx(adreno_gpu))
                a7xx_get_indexed_registers(gpu, a6xx_state);
        else
                a6xx_get_indexed_registers(gpu, a6xx_state);
 
+       stalled = !!(gpu_read(gpu, REG_A6XX_RBBM_STATUS3) &
+                       A6XX_RBBM_STATUS3_SMMU_STALLED_ON_FAULT);
        /*
         * Try to initialize the crashdumper, if we are not dumping state
         * with the SMMU stalled.  The crashdumper needs memory access to

-- 
2.50.1

Reply via email to