Commit 7f8036b7 authored by Rob Clark's avatar Rob Clark

drm/msm: let gpu wire up it's own fault handler

Signed-off-by: default avatarRob Clark <robdclark@gmail.com>
parent 720c3bb8
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
*/ */
#include "msm_gem.h" #include "msm_gem.h"
#include "msm_mmu.h"
#include "a5xx_gpu.h" #include "a5xx_gpu.h"
extern bool hang_debug; extern bool hang_debug;
...@@ -573,6 +574,19 @@ static bool a5xx_idle(struct msm_gpu *gpu) ...@@ -573,6 +574,19 @@ static bool a5xx_idle(struct msm_gpu *gpu)
return true; return true;
} }
static int a5xx_fault_handler(void *arg, unsigned long iova, int flags)
{
struct msm_gpu *gpu = arg;
pr_warn_ratelimited("*** gpu fault: iova=%08lx, flags=%d (%u,%u,%u,%u)\n",
iova, flags,
gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(4)),
gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(5)),
gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(6)),
gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(7)));
return -EFAULT;
}
static void a5xx_cp_err_irq(struct msm_gpu *gpu) static void a5xx_cp_err_irq(struct msm_gpu *gpu)
{ {
u32 status = gpu_read(gpu, REG_A5XX_CP_INTERRUPT_STATUS); u32 status = gpu_read(gpu, REG_A5XX_CP_INTERRUPT_STATUS);
...@@ -884,5 +898,8 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) ...@@ -884,5 +898,8 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
return ERR_PTR(ret); return ERR_PTR(ret);
} }
if (gpu->aspace)
msm_mmu_set_fault_handler(gpu->aspace->mmu, gpu, a5xx_fault_handler);
return gpu; return gpu;
} }
...@@ -24,9 +24,12 @@ struct msm_iommu { ...@@ -24,9 +24,12 @@ struct msm_iommu {
}; };
#define to_msm_iommu(x) container_of(x, struct msm_iommu, base) #define to_msm_iommu(x) container_of(x, struct msm_iommu, base)
static int msm_fault_handler(struct iommu_domain *iommu, struct device *dev, static int msm_fault_handler(struct iommu_domain *domain, struct device *dev,
unsigned long iova, int flags, void *arg) unsigned long iova, int flags, void *arg)
{ {
struct msm_iommu *iommu = arg;
if (iommu->base.handler)
return iommu->base.handler(iommu->base.arg, iova, flags);
pr_warn_ratelimited("*** fault: iova=%08lx, flags=%d\n", iova, flags); pr_warn_ratelimited("*** fault: iova=%08lx, flags=%d\n", iova, flags);
return 0; return 0;
} }
...@@ -136,7 +139,7 @@ struct msm_mmu *msm_iommu_new(struct device *dev, struct iommu_domain *domain) ...@@ -136,7 +139,7 @@ struct msm_mmu *msm_iommu_new(struct device *dev, struct iommu_domain *domain)
iommu->domain = domain; iommu->domain = domain;
msm_mmu_init(&iommu->base, dev, &funcs); msm_mmu_init(&iommu->base, dev, &funcs);
iommu_set_fault_handler(domain, msm_fault_handler, dev); iommu_set_fault_handler(domain, msm_fault_handler, iommu);
return &iommu->base; return &iommu->base;
} }
...@@ -33,6 +33,8 @@ struct msm_mmu_funcs { ...@@ -33,6 +33,8 @@ struct msm_mmu_funcs {
struct msm_mmu { struct msm_mmu {
const struct msm_mmu_funcs *funcs; const struct msm_mmu_funcs *funcs;
struct device *dev; struct device *dev;
int (*handler)(void *arg, unsigned long iova, int flags);
void *arg;
}; };
static inline void msm_mmu_init(struct msm_mmu *mmu, struct device *dev, static inline void msm_mmu_init(struct msm_mmu *mmu, struct device *dev,
...@@ -45,4 +47,11 @@ static inline void msm_mmu_init(struct msm_mmu *mmu, struct device *dev, ...@@ -45,4 +47,11 @@ static inline void msm_mmu_init(struct msm_mmu *mmu, struct device *dev,
struct msm_mmu *msm_iommu_new(struct device *dev, struct iommu_domain *domain); struct msm_mmu *msm_iommu_new(struct device *dev, struct iommu_domain *domain);
struct msm_mmu *msm_gpummu_new(struct device *dev, struct msm_gpu *gpu); struct msm_mmu *msm_gpummu_new(struct device *dev, struct msm_gpu *gpu);
static inline void msm_mmu_set_fault_handler(struct msm_mmu *mmu, void *arg,
int (*handler)(void *arg, unsigned long iova, int flags))
{
mmu->arg = arg;
mmu->handler = handler;
}
#endif /* __MSM_MMU_H__ */ #endif /* __MSM_MMU_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment