diff --git a/drivers/gpu/msm/a3xx_reg.h b/drivers/gpu/msm/a3xx_reg.h index 05c79679398..6a010a98653 100644 --- a/drivers/gpu/msm/a3xx_reg.h +++ b/drivers/gpu/msm/a3xx_reg.h @@ -65,13 +65,17 @@ #define A3XX_RBBM_INT_CLEAR_CMD 0x061 #define A3XX_RBBM_INT_0_MASK 0x063 #define A3XX_RBBM_INT_0_STATUS 0x064 +#define A3XX_RBBM_PERFCTR_CTL 0x80 #define A3XX_RBBM_GPU_BUSY_MASKED 0x88 +#define A3XX_RBBM_PERFCTR_SP_7_LO 0xE0 +#define A3XX_RBBM_PERFCTR_SP_7_HI 0xE1 #define A3XX_RBBM_RBBM_CTL 0x100 #define A3XX_RBBM_RBBM_CTL 0x100 #define A3XX_RBBM_PERFCTR_PWR_1_LO 0x0EC #define A3XX_RBBM_PERFCTR_PWR_1_HI 0x0ED #define A3XX_RBBM_DEBUG_BUS_CTL 0x111 #define A3XX_RBBM_DEBUG_BUS_DATA_STATUS 0x112 + /* Following two are same as on A2XX, just in a different place */ #define A3XX_CP_PFP_UCODE_ADDR 0x1C9 #define A3XX_CP_PFP_UCODE_DATA 0x1CA @@ -160,6 +164,7 @@ #define A3XX_VPC_VPC_DEBUG_RAM_READ 0xE62 #define A3XX_UCHE_CACHE_MODE_CONTROL_REG 0xE82 #define A3XX_UCHE_CACHE_INVALIDATE0_REG 0xEA0 +#define A3XX_SP_PERFCOUNTER7_SELECT 0xECB #define A3XX_GRAS_CL_CLIP_CNTL 0x2040 #define A3XX_GRAS_CL_GB_CLIP_ADJ 0x2044 #define A3XX_GRAS_CL_VPORT_XOFFSET 0x2048 @@ -528,4 +533,7 @@ /* RBBM_CLOCK_CTL default value */ #define A3XX_RBBM_CLOCK_CTL_DEFAULT 0xBFFFFFFF +/* COUNTABLE FOR SP PERFCOUNTER */ +#define SP_FS_FULL_ALU_INSTRUCTIONS 0x0E + #endif diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 71bd4a22b36..f3944220514 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -127,6 +127,8 @@ unsigned int hang_detect_regs[] = { REG_CP_IB1_BUFSZ, REG_CP_IB2_BASE, REG_CP_IB2_BUFSZ, + 0, + 0 }; const unsigned int hang_detect_regs_count = ARRAY_SIZE(hang_detect_regs); @@ -1299,6 +1301,12 @@ static int adreno_start(struct kgsl_device *device, unsigned int init_ram) */ hang_detect_regs[0] = adreno_dev->gpudev->reg_rbbm_status; + /* Add A3XX specific registers for hang detection */ + if (adreno_is_a3xx(adreno_dev)) { + hang_detect_regs[6] = A3XX_RBBM_PERFCTR_SP_7_LO; + hang_detect_regs[7] = A3XX_RBBM_PERFCTR_SP_7_HI; + } + status = kgsl_mmu_start(device); if (status) goto error_clk_off; @@ -2222,6 +2230,10 @@ unsigned int adreno_hang_detect(struct kgsl_device *device, return 0; for (i = 0; i < hang_detect_regs_count; i++) { + + if (hang_detect_regs[i] == 0) + continue; + adreno_regread(device, hang_detect_regs[i], &curr_reg_val[i]); if (curr_reg_val[i] != prev_reg_val[i]) { diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c index f7ae5b88f5b..f53bcb960de 100644 --- a/drivers/gpu/msm/adreno_a3xx.c +++ b/drivers/gpu/msm/adreno_a3xx.c @@ -2831,6 +2831,17 @@ static void a3xx_start(struct adreno_device *adreno_dev) adreno_regwrite(device, A3XX_RB_GMEM_BASE_ADDR, (unsigned int)(adreno_dev->ocmem_base >> 14)); } + + /* Turn on performance counters */ + adreno_regwrite(device, A3XX_RBBM_PERFCTR_CTL, 0x01); + + /* + * Set SP perfcounter 7 to count SP_FS_FULL_ALU_INSTRUCTIONS + * we will use this to augment our hang detection + */ + + adreno_regwrite(device, A3XX_SP_PERFCOUNTER7_SELECT, + SP_FS_FULL_ALU_INSTRUCTIONS); } /* Defined in adreno_a3xx_snapshot.c */