Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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



Signed-off-by: default avatarRob Clark <robdclark@gmail.com>
parent 720c3bb8
Loading
Loading
Loading
Loading
+17 −0
Original line number Original line Diff line number Diff line
@@ -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)
	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)
		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;
}
}
+5 −2
Original line number Original line Diff line number Diff line
@@ -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)


	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;
}
}
+9 −0
Original line number Original line Diff line number Diff line
@@ -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,
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__ */