diff options
Diffstat (limited to 'drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c')
-rw-r--r-- | drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 69 |
1 files changed, 64 insertions, 5 deletions
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c index 4e5d650578c6..91a564a24dbe 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c @@ -882,12 +882,13 @@ static void a6xx_snapshot_gmu_hfi_history(struct msm_gpu *gpu, } } +#define A6XX_REGLIST_SIZE 1 #define A6XX_GBIF_REGLIST_SIZE 1 static void a6xx_get_registers(struct msm_gpu *gpu, struct a6xx_gpu_state *a6xx_state, struct a6xx_crashdumper *dumper) { - int i, count = ARRAY_SIZE(a6xx_ahb_reglist) + + int i, count = A6XX_REGLIST_SIZE + ARRAY_SIZE(a6xx_reglist) + ARRAY_SIZE(a6xx_hlsq_reglist) + A6XX_GBIF_REGLIST_SIZE; int index = 0; @@ -901,12 +902,20 @@ static void a6xx_get_registers(struct msm_gpu *gpu, a6xx_state->nr_registers = count; - for (i = 0; i < ARRAY_SIZE(a6xx_ahb_reglist); i++) + if (adreno_is_a7xx(adreno_gpu)) a6xx_get_ahb_gpu_registers(gpu, - a6xx_state, &a6xx_ahb_reglist[i], + a6xx_state, &a7xx_ahb_reglist, + &a6xx_state->registers[index++]); + else + a6xx_get_ahb_gpu_registers(gpu, + a6xx_state, &a6xx_ahb_reglist, &a6xx_state->registers[index++]); - if (a6xx_has_gbif(adreno_gpu)) + if (adreno_is_a7xx(adreno_gpu)) + a6xx_get_ahb_gpu_registers(gpu, + a6xx_state, &a7xx_gbif_reglist, + &a6xx_state->registers[index++]); + else if (a6xx_has_gbif(adreno_gpu)) a6xx_get_ahb_gpu_registers(gpu, a6xx_state, &a6xx_gbif_reglist, &a6xx_state->registers[index++]); @@ -948,6 +957,18 @@ static u32 a6xx_get_cp_roq_size(struct msm_gpu *gpu) return gpu_read(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2) >> 14; } +static u32 a7xx_get_cp_roq_size(struct msm_gpu *gpu) +{ + /* + * The value at CP_ROQ_THRESHOLDS_2[20:31] is in 4dword units. + * That register however is not directly accessible from APSS on A7xx. + * Program the SQE_UCODE_DBG_ADDR with offset=0x70d3 and read the value. + */ + gpu_write(gpu, REG_A6XX_CP_SQE_UCODE_DBG_ADDR, 0x70d3); + + return 4 * (gpu_read(gpu, REG_A6XX_CP_SQE_UCODE_DBG_DATA) >> 20); +} + /* Read a block of data from an indexed register pair */ static void a6xx_get_indexed_regs(struct msm_gpu *gpu, struct a6xx_gpu_state *a6xx_state, @@ -1019,8 +1040,40 @@ static void a6xx_get_indexed_registers(struct msm_gpu *gpu, /* Restore the size in the hardware */ gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, mempool_size); +} - a6xx_state->nr_indexed_regs = count; +static void a7xx_get_indexed_registers(struct msm_gpu *gpu, + struct a6xx_gpu_state *a6xx_state) +{ + int i, indexed_count, mempool_count; + + indexed_count = ARRAY_SIZE(a7xx_indexed_reglist); + mempool_count = ARRAY_SIZE(a7xx_cp_bv_mempool_indexed); + + a6xx_state->indexed_regs = state_kcalloc(a6xx_state, + indexed_count + mempool_count, + sizeof(*a6xx_state->indexed_regs)); + if (!a6xx_state->indexed_regs) + return; + + a6xx_state->nr_indexed_regs = indexed_count + mempool_count; + + /* First read the common regs */ + for (i = 0; i < indexed_count; i++) + a6xx_get_indexed_regs(gpu, a6xx_state, &a7xx_indexed_reglist[i], + &a6xx_state->indexed_regs[i]); + + gpu_rmw(gpu, REG_A6XX_CP_CHICKEN_DBG, 0, BIT(2)); + gpu_rmw(gpu, REG_A7XX_CP_BV_CHICKEN_DBG, 0, BIT(2)); + + /* Get the contents of the CP_BV mempool */ + for (i = 0; i < mempool_count; i++) + a6xx_get_indexed_regs(gpu, a6xx_state, a7xx_cp_bv_mempool_indexed, + &a6xx_state->indexed_regs[indexed_count - 1 + i]); + + gpu_rmw(gpu, REG_A6XX_CP_CHICKEN_DBG, BIT(2), 0); + gpu_rmw(gpu, REG_A7XX_CP_BV_CHICKEN_DBG, BIT(2), 0); + return; } struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu) @@ -1056,6 +1109,12 @@ struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu) return &a6xx_state->base; /* Get the banks of indexed registers */ + if (adreno_is_a7xx(adreno_gpu)) { + a7xx_get_indexed_registers(gpu, a6xx_state); + /* Further codeflow is untested on A7xx. */ + return &a6xx_state->base; + } + a6xx_get_indexed_registers(gpu, a6xx_state); /* |