[PATCH 2/3] drm/msm/adreno: split a6xx fault handler into generic and a6xx parts
Dmitry Baryshkov
dmitry.baryshkov at linaro.org
Tue Feb 14 12:35:03 UTC 2023
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 at linaro.org>
---
drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 64 +++----------------------
drivers/gpu/drm/msm/adreno/adreno_gpu.c | 60 +++++++++++++++++++++++
drivers/gpu/drm/msm/adreno/adreno_gpu.h | 4 ++
3 files changed, 71 insertions(+), 57 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index aae60cbd9164..faee45135ca8 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -1361,73 +1361,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)
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index a05d48ecae15..9bbc298fe6d6 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -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)
{
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index b4f9b1343d63..f62612a5c70f 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -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);
/*
--
2.30.2
More information about the dri-devel
mailing list