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 
d76b6b766d4a644d342f62435892d54ebd7192e5..81076349d69c8c13e6c6b4e1c336c2d990ebda6d
 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 
b54c88fb27d57f81306163e699961803ff765bdb..76dd78f5c48ea818a2aa209e0c0c88bc5e8f4e06
 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -1537,21 +1537,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);
 
@@ -2412,6 +2416,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 
d5d1271fce611b60121b36f4b772d6f5e0093d2b..4c7f3c642f6ac0a397ac3b282966d25cd4488d3e
 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
@@ -1586,8 +1586,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);
@@ -1608,15 +1607,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