diff options
Diffstat (limited to 'drivers/gpu/drm/msm/adreno/a5xx_gpu.c')
-rw-r--r-- | drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index ce13d49e615b..7a271de9a212 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -902,7 +902,7 @@ static int a5xx_hw_init(struct msm_gpu *gpu) if (!a5xx_gpu->shadow_bo) { a5xx_gpu->shadow = msm_gem_kernel_new(gpu->dev, sizeof(u32) * gpu->nr_rings, - MSM_BO_UNCACHED | MSM_BO_MAP_PRIV, + MSM_BO_WC | MSM_BO_MAP_PRIV, gpu->aspace, &a5xx_gpu->shadow_bo, &a5xx_gpu->shadow_iova); @@ -1075,7 +1075,7 @@ bool a5xx_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring) return true; } -static int a5xx_fault_handler(void *arg, unsigned long iova, int flags) +static int a5xx_fault_handler(void *arg, unsigned long iova, int flags, void *data) { struct msm_gpu *gpu = arg; pr_warn_ratelimited("*** gpu fault: iova=%08lx, flags=%d (%u,%u,%u,%u)\n", @@ -1085,7 +1085,7 @@ static int a5xx_fault_handler(void *arg, unsigned long iova, int flags) gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(6)), gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(7))); - return -EFAULT; + return 0; } static void a5xx_cp_err_irq(struct msm_gpu *gpu) @@ -1200,6 +1200,15 @@ static void a5xx_fault_detect_irq(struct msm_gpu *gpu) struct drm_device *dev = gpu->dev; struct msm_ringbuffer *ring = gpu->funcs->active_ring(gpu); + /* + * If stalled on SMMU fault, we could trip the GPU's hang detection, + * but the fault handler will trigger the devcore dump, and we want + * to otherwise resume normally rather than killing the submit, so + * just bail. + */ + if (gpu_read(gpu, REG_A5XX_RBBM_STATUS3) & BIT(24)) + return; + DRM_DEV_ERROR(dev->dev, "gpu fault ring %d fence %x status %8.8X rb %4.4x/%4.4x ib1 %16.16llX/%4.4x ib2 %16.16llX/%4.4x\n", ring ? ring->id : -1, ring ? ring->seqno : 0, gpu_read(gpu, REG_A5XX_RBBM_STATUS), @@ -1407,7 +1416,7 @@ static int a5xx_crashdumper_init(struct msm_gpu *gpu, struct a5xx_crashdumper *dumper) { dumper->ptr = msm_gem_kernel_new_locked(gpu->dev, - SZ_1M, MSM_BO_UNCACHED, gpu->aspace, + SZ_1M, MSM_BO_WC, gpu->aspace, &dumper->bo, &dumper->iova); if (!IS_ERR(dumper->ptr)) @@ -1523,6 +1532,7 @@ static struct msm_gpu_state *a5xx_gpu_state_get(struct msm_gpu *gpu) { struct a5xx_gpu_state *a5xx_state = kzalloc(sizeof(*a5xx_state), GFP_KERNEL); + bool stalled = !!(gpu_read(gpu, REG_A5XX_RBBM_STATUS3) & BIT(24)); if (!a5xx_state) return ERR_PTR(-ENOMEM); @@ -1535,8 +1545,13 @@ static struct msm_gpu_state *a5xx_gpu_state_get(struct msm_gpu *gpu) a5xx_state->base.rbbm_status = gpu_read(gpu, REG_A5XX_RBBM_STATUS); - /* Get the HLSQ regs with the help of the crashdumper */ - a5xx_gpu_state_get_hlsq_regs(gpu, a5xx_state); + /* + * Get the HLSQ regs with the help of the crashdumper, but only if + * we are not stalled in an iommu fault (in which case the crashdumper + * would not have access to memory) + */ + if (!stalled) + a5xx_gpu_state_get_hlsq_regs(gpu, a5xx_state); a5xx_set_hwcg(gpu, true); @@ -1705,7 +1720,7 @@ static void check_speed_bin(struct device *dev) nvmem_cell_put(cell); } - dev_pm_opp_set_supported_hw(dev, &val, 1); + devm_pm_opp_set_supported_hw(dev, &val, 1); } struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) |