aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/msm/adreno_a6xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/msm/adreno_a6xx.c')
-rw-r--r--drivers/gpu/msm/adreno_a6xx.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c
index d1821a7c9076..1a94e7df4e30 100644
--- a/drivers/gpu/msm/adreno_a6xx.c
+++ b/drivers/gpu/msm/adreno_a6xx.c
@@ -1362,6 +1362,29 @@ static void a6xx_cp_callback(struct adreno_device *adreno_dev, int bit)
adreno_dispatcher_schedule(device);
}
+/*
+ * a6xx_gpc_err_int_callback() - Isr for GPC error interrupts
+ * @adreno_dev: Pointer to device
+ * @bit: Interrupt bit
+ */
+static void a6xx_gpc_err_int_callback(struct adreno_device *adreno_dev, int bit)
+{
+ struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
+
+ /*
+ * GPC error is typically the result of mistake SW programming.
+ * Force GPU fault for this interrupt so that we can debug it
+ * with help of register dump.
+ */
+
+ dev_crit_ratelimited(device->dev, "RBBM: GPC error\n");
+ adreno_irqctrl(adreno_dev, 0);
+
+ /* Trigger a fault in the dispatcher - this will effect a restart */
+ adreno_set_gpu_fault(adreno_dev, ADRENO_SOFT_FAULT);
+ adreno_dispatcher_schedule(device);
+}
+
#define A6XX_INT_MASK \
((1 << A6XX_INT_CP_AHB_ERROR) | \
(1 << A6XX_INT_ATB_ASYNCFIFO_OVERFLOW) | \
@@ -1387,7 +1410,7 @@ static struct adreno_irq_funcs a6xx_irq_funcs[32] = {
ADRENO_IRQ_CALLBACK(NULL), /* 5 - UNUSED */
/* 6 - RBBM_ATB_ASYNC_OVERFLOW */
ADRENO_IRQ_CALLBACK(a6xx_err_callback),
- ADRENO_IRQ_CALLBACK(NULL), /* 7 - GPC_ERR */
+ ADRENO_IRQ_CALLBACK(a6xx_gpc_err_int_callback), /* 7 - GPC_ERR */
ADRENO_IRQ_CALLBACK(a6xx_preemption_callback),/* 8 - CP_SW */
ADRENO_IRQ_CALLBACK(a6xx_cp_hw_err_callback), /* 9 - CP_HW_ERROR */
ADRENO_IRQ_CALLBACK(NULL), /* 10 - CP_CCU_FLUSH_DEPTH_TS */