drm/msm/adreno: split a6xx fault handler into generic and a6xx parts
authorDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Tue, 14 Feb 2023 12:35:03 +0000 (15:35 +0300)
committerRob Clark <robdclark@chromium.org>
Tue, 28 Mar 2023 22:49:09 +0000 (15:49 -0700)
Split the a6xx_fault_handler() into the generic adreno_fault_handler()
and platform-specific parts. The adreno_fault_handler() can further be
used by a5xx and hopefully by a4xx (at some point).

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Patchwork: https://patchwork.freedesktop.org/patch/522722/
Link: https://lore.kernel.org/r/20230214123504.3729522-3-dmitry.baryshkov@linaro.org
Signed-off-by: Rob Clark <robdclark@chromium.org>
drivers/gpu/drm/msm/adreno/a6xx_gpu.c
drivers/gpu/drm/msm/adreno/adreno_gpu.c
drivers/gpu/drm/msm/adreno/adreno_gpu.h

index 0f6ed7a..07f360e 100644 (file)
@@ -1362,73 +1362,23 @@ static const char *a6xx_fault_block(struct msm_gpu *gpu, u32 id)
        return a6xx_uche_fault_block(gpu, id);
 }
 
-#define ARM_SMMU_FSR_TF                 BIT(1)
-#define ARM_SMMU_FSR_PF                        BIT(3)
-#define ARM_SMMU_FSR_EF                        BIT(4)
-
 static int a6xx_fault_handler(void *arg, unsigned long iova, int flags, void *data)
 {
        struct msm_gpu *gpu = arg;
        struct adreno_smmu_fault_info *info = data;
-       const char *type = "UNKNOWN";
-       const char *block;
-       bool do_devcoredump = info && !READ_ONCE(gpu->crashstate);
-
-       /*
-        * If we aren't going to be resuming later from fault_worker, then do
-        * it now.
-        */
-       if (!do_devcoredump) {
-               gpu->aspace->mmu->funcs->resume_translation(gpu->aspace->mmu);
-       }
+       const char *block = "unknown";
 
-       /*
-        * Print a default message if we couldn't get the data from the
-        * adreno-smmu-priv
-        */
-       if (!info) {
-               pr_warn_ratelimited("*** gpu fault: iova=%.16lx flags=%d (%u,%u,%u,%u)\n",
-                       iova, flags,
+       u32 scratch[] = {
                        gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(4)),
                        gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(5)),
                        gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(6)),
-                       gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(7)));
-
-               return 0;
-       }
-
-       if (info->fsr & ARM_SMMU_FSR_TF)
-               type = "TRANSLATION";
-       else if (info->fsr & ARM_SMMU_FSR_PF)
-               type = "PERMISSION";
-       else if (info->fsr & ARM_SMMU_FSR_EF)
-               type = "EXTERNAL";
-
-       block = a6xx_fault_block(gpu, info->fsynr1 & 0xff);
-
-       pr_warn_ratelimited("*** gpu fault: ttbr0=%.16llx iova=%.16lx dir=%s type=%s source=%s (%u,%u,%u,%u)\n",
-                       info->ttbr0, iova,
-                       flags & IOMMU_FAULT_WRITE ? "WRITE" : "READ",
-                       type, block,
-                       gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(4)),
-                       gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(5)),
-                       gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(6)),
-                       gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(7)));
-
-       if (do_devcoredump) {
-               /* Turn off the hangcheck timer to keep it from bothering us */
-               del_timer(&gpu->hangcheck_timer);
+                       gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(7)),
+       };
 
-               gpu->fault_info.ttbr0 = info->ttbr0;
-               gpu->fault_info.iova  = iova;
-               gpu->fault_info.flags = flags;
-               gpu->fault_info.type  = type;
-               gpu->fault_info.block = block;
+       if (info)
+               block = a6xx_fault_block(gpu, info->fsynr1 & 0xff);
 
-               kthread_queue_work(gpu->worker, &gpu->fault_work);
-       }
-
-       return 0;
+       return adreno_fault_handler(gpu, iova, flags, info, block, scratch);
 }
 
 static void a6xx_cp_hw_err_irq(struct msm_gpu *gpu)
index adbfe73..bb38e72 100644 (file)
@@ -246,6 +246,66 @@ u64 adreno_private_address_space_size(struct msm_gpu *gpu)
        return SZ_4G;
 }
 
+#define ARM_SMMU_FSR_TF                 BIT(1)
+#define ARM_SMMU_FSR_PF                        BIT(3)
+#define ARM_SMMU_FSR_EF                        BIT(4)
+
+int adreno_fault_handler(struct msm_gpu *gpu, unsigned long iova, int flags,
+                        struct adreno_smmu_fault_info *info, const char *block,
+                        u32 scratch[4])
+{
+       const char *type = "UNKNOWN";
+       bool do_devcoredump = info && !READ_ONCE(gpu->crashstate);
+
+       /*
+        * If we aren't going to be resuming later from fault_worker, then do
+        * it now.
+        */
+       if (!do_devcoredump) {
+               gpu->aspace->mmu->funcs->resume_translation(gpu->aspace->mmu);
+       }
+
+       /*
+        * Print a default message if we couldn't get the data from the
+        * adreno-smmu-priv
+        */
+       if (!info) {
+               pr_warn_ratelimited("*** gpu fault: iova=%.16lx flags=%d (%u,%u,%u,%u)\n",
+                       iova, flags,
+                       scratch[0], scratch[1], scratch[2], scratch[3]);
+
+               return 0;
+       }
+
+       if (info->fsr & ARM_SMMU_FSR_TF)
+               type = "TRANSLATION";
+       else if (info->fsr & ARM_SMMU_FSR_PF)
+               type = "PERMISSION";
+       else if (info->fsr & ARM_SMMU_FSR_EF)
+               type = "EXTERNAL";
+
+       pr_warn_ratelimited("*** gpu fault: ttbr0=%.16llx iova=%.16lx dir=%s type=%s source=%s (%u,%u,%u,%u)\n",
+                       info->ttbr0, iova,
+                       flags & IOMMU_FAULT_WRITE ? "WRITE" : "READ",
+                       type, block,
+                       scratch[0], scratch[1], scratch[2], scratch[3]);
+
+       if (do_devcoredump) {
+               /* Turn off the hangcheck timer to keep it from bothering us */
+               del_timer(&gpu->hangcheck_timer);
+
+               gpu->fault_info.ttbr0 = info->ttbr0;
+               gpu->fault_info.iova  = iova;
+               gpu->fault_info.flags = flags;
+               gpu->fault_info.type  = type;
+               gpu->fault_info.block = block;
+
+               kthread_queue_work(gpu->worker, &gpu->fault_work);
+       }
+
+       return 0;
+}
+
 int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx,
                     uint32_t param, uint64_t *value, uint32_t *len)
 {
index b4f9b13..f62612a 100644 (file)
@@ -341,6 +341,10 @@ adreno_iommu_create_address_space(struct msm_gpu *gpu,
                                  struct platform_device *pdev,
                                  unsigned long quirks);
 
+int adreno_fault_handler(struct msm_gpu *gpu, unsigned long iova, int flags,
+                        struct adreno_smmu_fault_info *info, const char *block,
+                        u32 scratch[4]);
+
 int adreno_read_speedbin(struct device *dev, u32 *speedbin);
 
 /*