Commit 1707add8 authored by Jordan Crouse's avatar Jordan Crouse Committed by Rob Clark

drm/msm/a6xx: Add a6xx gpu state

Add support for gathering and dumping the a6xx GPU state including
registers, GMU registers, indexed registers, shader blocks,
context clusters and debugbus.

v2: Fix bugs discovered by Sharat Masetty
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
Signed-off-by: default avatarRob Clark <robdclark@gmail.com>
parent b9fc2302
...@@ -14,6 +14,7 @@ msm-y := \ ...@@ -14,6 +14,7 @@ msm-y := \
adreno/a6xx_gpu.o \ adreno/a6xx_gpu.o \
adreno/a6xx_gmu.o \ adreno/a6xx_gmu.o \
adreno/a6xx_hfi.o \ adreno/a6xx_hfi.o \
adreno/a6xx_gpu_state.o \
hdmi/hdmi.o \ hdmi/hdmi.o \
hdmi/hdmi_audio.o \ hdmi/hdmi_audio.o \
hdmi/hdmi_bridge.o \ hdmi/hdmi_bridge.o \
......
...@@ -51,10 +51,31 @@ static irqreturn_t a6xx_hfi_irq(int irq, void *data) ...@@ -51,10 +51,31 @@ static irqreturn_t a6xx_hfi_irq(int irq, void *data)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
bool a6xx_gmu_sptprac_is_on(struct a6xx_gmu *gmu)
{
u32 val;
/* This can be called from gpu state code so make sure GMU is valid */
if (IS_ERR_OR_NULL(gmu->mmio))
return false;
val = gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS);
return !(val &
(A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_SPTPRAC_GDSC_POWER_OFF |
A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_SP_CLOCK_OFF));
}
/* Check to see if the GX rail is still powered */ /* Check to see if the GX rail is still powered */
static bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu) bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu)
{ {
u32 val = gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS); u32 val;
/* This can be called from gpu state code so make sure GMU is valid */
if (IS_ERR_OR_NULL(gmu->mmio))
return false;
val = gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS);
return !(val & return !(val &
(A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_GX_HM_GDSC_POWER_OFF | (A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_GX_HM_GDSC_POWER_OFF |
......
...@@ -164,4 +164,7 @@ void a6xx_hfi_init(struct a6xx_gmu *gmu); ...@@ -164,4 +164,7 @@ void a6xx_hfi_init(struct a6xx_gmu *gmu);
int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state); int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state);
void a6xx_hfi_stop(struct a6xx_gmu *gmu); void a6xx_hfi_stop(struct a6xx_gmu *gmu);
bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu);
bool a6xx_gmu_sptprac_is_on(struct a6xx_gmu *gmu);
#endif #endif
...@@ -670,33 +670,6 @@ static const u32 a6xx_register_offsets[REG_ADRENO_REGISTER_MAX] = { ...@@ -670,33 +670,6 @@ static const u32 a6xx_register_offsets[REG_ADRENO_REGISTER_MAX] = {
REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_CNTL, REG_A6XX_CP_RB_CNTL), REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_CNTL, REG_A6XX_CP_RB_CNTL),
}; };
static const u32 a6xx_registers[] = {
0x0000, 0x0002, 0x0010, 0x0010, 0x0012, 0x0012, 0x0018, 0x001b,
0x001e, 0x0032, 0x0038, 0x003c, 0x0042, 0x0042, 0x0044, 0x0044,
0x0047, 0x0047, 0x0056, 0x0056, 0x00ad, 0x00ae, 0x00b0, 0x00fb,
0x0100, 0x011d, 0x0200, 0x020d, 0x0210, 0x0213, 0x0218, 0x023d,
0x0400, 0x04f9, 0x0500, 0x0500, 0x0505, 0x050b, 0x050e, 0x0511,
0x0533, 0x0533, 0x0540, 0x0555, 0x0800, 0x0808, 0x0810, 0x0813,
0x0820, 0x0821, 0x0823, 0x0827, 0x0830, 0x0833, 0x0840, 0x0843,
0x084f, 0x086f, 0x0880, 0x088a, 0x08a0, 0x08ab, 0x08c0, 0x08c4,
0x08d0, 0x08dd, 0x08f0, 0x08f3, 0x0900, 0x0903, 0x0908, 0x0911,
0x0928, 0x093e, 0x0942, 0x094d, 0x0980, 0x0984, 0x098d, 0x0996,
0x0998, 0x099e, 0x09a0, 0x09a6, 0x09a8, 0x09ae, 0x09b0, 0x09b1,
0x09c2, 0x09c8, 0x0a00, 0x0a03, 0x0c00, 0x0c04, 0x0c06, 0x0c06,
0x0c10, 0x0cd9, 0x0e00, 0x0e0e, 0x0e10, 0x0e13, 0x0e17, 0x0e19,
0x0e1c, 0x0e2b, 0x0e30, 0x0e32, 0x0e38, 0x0e39, 0x8600, 0x8601,
0x8610, 0x861b, 0x8620, 0x8620, 0x8628, 0x862b, 0x8630, 0x8637,
0x8e01, 0x8e01, 0x8e04, 0x8e05, 0x8e07, 0x8e08, 0x8e0c, 0x8e0c,
0x8e10, 0x8e1c, 0x8e20, 0x8e25, 0x8e28, 0x8e28, 0x8e2c, 0x8e2f,
0x8e3b, 0x8e3e, 0x8e40, 0x8e43, 0x8e50, 0x8e5e, 0x8e70, 0x8e77,
0x9600, 0x9604, 0x9624, 0x9637, 0x9e00, 0x9e01, 0x9e03, 0x9e0e,
0x9e11, 0x9e16, 0x9e19, 0x9e19, 0x9e1c, 0x9e1c, 0x9e20, 0x9e23,
0x9e30, 0x9e31, 0x9e34, 0x9e34, 0x9e70, 0x9e72, 0x9e78, 0x9e79,
0x9e80, 0x9fff, 0xa600, 0xa601, 0xa603, 0xa603, 0xa60a, 0xa60a,
0xa610, 0xa617, 0xa630, 0xa630,
~0
};
static int a6xx_pm_resume(struct msm_gpu *gpu) static int a6xx_pm_resume(struct msm_gpu *gpu)
{ {
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
...@@ -749,14 +722,6 @@ static int a6xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value) ...@@ -749,14 +722,6 @@ static int a6xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value)
return 0; return 0;
} }
#if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
static void a6xx_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
struct drm_printer *p)
{
adreno_show(gpu, state, p);
}
#endif
static struct msm_ringbuffer *a6xx_active_ring(struct msm_gpu *gpu) static struct msm_ringbuffer *a6xx_active_ring(struct msm_gpu *gpu)
{ {
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
...@@ -821,6 +786,8 @@ static const struct adreno_gpu_funcs funcs = { ...@@ -821,6 +786,8 @@ static const struct adreno_gpu_funcs funcs = {
.gpu_busy = a6xx_gpu_busy, .gpu_busy = a6xx_gpu_busy,
.gpu_get_freq = a6xx_gmu_get_freq, .gpu_get_freq = a6xx_gmu_get_freq,
.gpu_set_freq = a6xx_gmu_set_freq, .gpu_set_freq = a6xx_gmu_set_freq,
.gpu_state_get = a6xx_gpu_state_get,
.gpu_state_put = a6xx_gpu_state_put,
}, },
.get_timestamp = a6xx_get_timestamp, .get_timestamp = a6xx_get_timestamp,
}; };
...@@ -842,7 +809,7 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) ...@@ -842,7 +809,7 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
adreno_gpu = &a6xx_gpu->base; adreno_gpu = &a6xx_gpu->base;
gpu = &adreno_gpu->base; gpu = &adreno_gpu->base;
adreno_gpu->registers = a6xx_registers; adreno_gpu->registers = NULL;
adreno_gpu->reg_offsets = a6xx_register_offsets; adreno_gpu->reg_offsets = a6xx_register_offsets;
ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1); ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1);
......
...@@ -56,6 +56,14 @@ void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state); ...@@ -56,6 +56,14 @@ void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state);
int a6xx_gmu_probe(struct a6xx_gpu *a6xx_gpu, struct device_node *node); int a6xx_gmu_probe(struct a6xx_gpu *a6xx_gpu, struct device_node *node);
void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu); void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu);
void a6xx_gmu_set_freq(struct msm_gpu *gpu, unsigned long freq); void a6xx_gmu_set_freq(struct msm_gpu *gpu, unsigned long freq);
unsigned long a6xx_gmu_get_freq(struct msm_gpu *gpu); unsigned long a6xx_gmu_get_freq(struct msm_gpu *gpu);
void a6xx_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
struct drm_printer *p);
struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu);
int a6xx_gpu_state_put(struct msm_gpu_state *state);
#endif /* __A6XX_GPU_H__ */ #endif /* __A6XX_GPU_H__ */
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment