Commit 647d817d authored by Lucas Stach's avatar Lucas Stach

drm/etnaviv: better track GPU state

Instead of only tracking if the FE is running, use a enum to better
describe the various states the GPU can be in. This allows some
additional validation to make sure that functions that expect a
certain GPU state are only called when the GPU is actually in that
state.
Signed-off-by: default avatarLucas Stach <l.stach@pengutronix.de>
Reviewed-by: default avatarChristian Gmeiner <cgmeiner@igalia.com>
parent 448406ea
...@@ -584,7 +584,7 @@ static int etnaviv_hw_reset(struct etnaviv_gpu *gpu) ...@@ -584,7 +584,7 @@ static int etnaviv_hw_reset(struct etnaviv_gpu *gpu)
/* We rely on the GPU running, so program the clock */ /* We rely on the GPU running, so program the clock */
etnaviv_gpu_update_clock(gpu); etnaviv_gpu_update_clock(gpu);
gpu->fe_running = false; gpu->state = ETNA_GPU_STATE_RESET;
gpu->exec_state = -1; gpu->exec_state = -1;
if (gpu->mmu_context) if (gpu->mmu_context)
etnaviv_iommu_context_put(gpu->mmu_context); etnaviv_iommu_context_put(gpu->mmu_context);
...@@ -659,8 +659,6 @@ void etnaviv_gpu_start_fe(struct etnaviv_gpu *gpu, u32 address, u16 prefetch) ...@@ -659,8 +659,6 @@ void etnaviv_gpu_start_fe(struct etnaviv_gpu *gpu, u32 address, u16 prefetch)
VIVS_MMUv2_SEC_COMMAND_CONTROL_ENABLE | VIVS_MMUv2_SEC_COMMAND_CONTROL_ENABLE |
VIVS_MMUv2_SEC_COMMAND_CONTROL_PREFETCH(prefetch)); VIVS_MMUv2_SEC_COMMAND_CONTROL_PREFETCH(prefetch));
} }
gpu->fe_running = true;
} }
static void etnaviv_gpu_start_fe_idleloop(struct etnaviv_gpu *gpu, static void etnaviv_gpu_start_fe_idleloop(struct etnaviv_gpu *gpu,
...@@ -669,6 +667,8 @@ static void etnaviv_gpu_start_fe_idleloop(struct etnaviv_gpu *gpu, ...@@ -669,6 +667,8 @@ static void etnaviv_gpu_start_fe_idleloop(struct etnaviv_gpu *gpu,
u16 prefetch; u16 prefetch;
u32 address; u32 address;
WARN_ON(gpu->state != ETNA_GPU_STATE_INITIALIZED);
/* setup the MMU */ /* setup the MMU */
etnaviv_iommu_restore(gpu, context); etnaviv_iommu_restore(gpu, context);
...@@ -678,6 +678,8 @@ static void etnaviv_gpu_start_fe_idleloop(struct etnaviv_gpu *gpu, ...@@ -678,6 +678,8 @@ static void etnaviv_gpu_start_fe_idleloop(struct etnaviv_gpu *gpu,
&gpu->mmu_context->cmdbuf_mapping); &gpu->mmu_context->cmdbuf_mapping);
etnaviv_gpu_start_fe(gpu, address, prefetch); etnaviv_gpu_start_fe(gpu, address, prefetch);
gpu->state = ETNA_GPU_STATE_RUNNING;
} }
static void etnaviv_gpu_setup_pulse_eater(struct etnaviv_gpu *gpu) static void etnaviv_gpu_setup_pulse_eater(struct etnaviv_gpu *gpu)
...@@ -713,6 +715,9 @@ static void etnaviv_gpu_setup_pulse_eater(struct etnaviv_gpu *gpu) ...@@ -713,6 +715,9 @@ static void etnaviv_gpu_setup_pulse_eater(struct etnaviv_gpu *gpu)
static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu) static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu)
{ {
WARN_ON(!(gpu->state == ETNA_GPU_STATE_IDENTIFIED ||
gpu->state == ETNA_GPU_STATE_RESET));
if ((etnaviv_is_model_rev(gpu, GC320, 0x5007) || if ((etnaviv_is_model_rev(gpu, GC320, 0x5007) ||
etnaviv_is_model_rev(gpu, GC320, 0x5220)) && etnaviv_is_model_rev(gpu, GC320, 0x5220)) &&
gpu_read(gpu, VIVS_HI_CHIP_TIME) != 0x2062400) { gpu_read(gpu, VIVS_HI_CHIP_TIME) != 0x2062400) {
...@@ -759,6 +764,8 @@ static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu) ...@@ -759,6 +764,8 @@ static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu)
etnaviv_gpu_setup_pulse_eater(gpu); etnaviv_gpu_setup_pulse_eater(gpu);
gpu_write(gpu, VIVS_HI_INTR_ENBL, ~0U); gpu_write(gpu, VIVS_HI_INTR_ENBL, ~0U);
gpu->state = ETNA_GPU_STATE_INITIALIZED;
} }
int etnaviv_gpu_init(struct etnaviv_gpu *gpu) int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
...@@ -801,6 +808,8 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu) ...@@ -801,6 +808,8 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
(gpu->identity.minor_features10 & chipMinorFeatures10_SECURITY_AHB)) (gpu->identity.minor_features10 & chipMinorFeatures10_SECURITY_AHB))
gpu->sec_mode = ETNA_SEC_KERNEL; gpu->sec_mode = ETNA_SEC_KERNEL;
gpu->state = ETNA_GPU_STATE_IDENTIFIED;
ret = etnaviv_hw_reset(gpu); ret = etnaviv_hw_reset(gpu);
if (ret) { if (ret) {
dev_err(gpu->dev, "GPU reset failed\n"); dev_err(gpu->dev, "GPU reset failed\n");
...@@ -1376,7 +1385,7 @@ struct dma_fence *etnaviv_gpu_submit(struct etnaviv_gem_submit *submit) ...@@ -1376,7 +1385,7 @@ struct dma_fence *etnaviv_gpu_submit(struct etnaviv_gem_submit *submit)
goto out_unlock; goto out_unlock;
} }
if (!gpu->fe_running) if (gpu->state == ETNA_GPU_STATE_INITIALIZED)
etnaviv_gpu_start_fe_idleloop(gpu, submit->mmu_context); etnaviv_gpu_start_fe_idleloop(gpu, submit->mmu_context);
if (submit->prev_mmu_context) if (submit->prev_mmu_context)
...@@ -1642,7 +1651,7 @@ int etnaviv_gpu_wait_idle(struct etnaviv_gpu *gpu, unsigned int timeout_ms) ...@@ -1642,7 +1651,7 @@ int etnaviv_gpu_wait_idle(struct etnaviv_gpu *gpu, unsigned int timeout_ms)
static void etnaviv_gpu_hw_suspend(struct etnaviv_gpu *gpu) static void etnaviv_gpu_hw_suspend(struct etnaviv_gpu *gpu)
{ {
if (gpu->initialized && gpu->fe_running) { if (gpu->state == ETNA_GPU_STATE_RUNNING) {
/* Replace the last WAIT with END */ /* Replace the last WAIT with END */
mutex_lock(&gpu->lock); mutex_lock(&gpu->lock);
etnaviv_buffer_end(gpu); etnaviv_buffer_end(gpu);
...@@ -1655,7 +1664,7 @@ static void etnaviv_gpu_hw_suspend(struct etnaviv_gpu *gpu) ...@@ -1655,7 +1664,7 @@ static void etnaviv_gpu_hw_suspend(struct etnaviv_gpu *gpu)
*/ */
etnaviv_gpu_wait_idle(gpu, 100); etnaviv_gpu_wait_idle(gpu, 100);
gpu->fe_running = false; gpu->state = ETNA_GPU_STATE_INITIALIZED;
} }
gpu->exec_state = -1; gpu->exec_state = -1;
...@@ -1926,6 +1935,8 @@ static int etnaviv_gpu_rpm_suspend(struct device *dev) ...@@ -1926,6 +1935,8 @@ static int etnaviv_gpu_rpm_suspend(struct device *dev)
etnaviv_gpu_hw_suspend(gpu); etnaviv_gpu_hw_suspend(gpu);
gpu->state = ETNA_GPU_STATE_IDENTIFIED;
return etnaviv_gpu_clk_disable(gpu); return etnaviv_gpu_clk_disable(gpu);
} }
...@@ -1939,7 +1950,7 @@ static int etnaviv_gpu_rpm_resume(struct device *dev) ...@@ -1939,7 +1950,7 @@ static int etnaviv_gpu_rpm_resume(struct device *dev)
return ret; return ret;
/* Re-initialise the basic hardware state */ /* Re-initialise the basic hardware state */
if (gpu->initialized) { if (gpu->state == ETNA_GPU_STATE_IDENTIFIED) {
ret = etnaviv_gpu_hw_resume(gpu); ret = etnaviv_gpu_hw_resume(gpu);
if (ret) { if (ret) {
etnaviv_gpu_clk_disable(gpu); etnaviv_gpu_clk_disable(gpu);
......
...@@ -95,6 +95,14 @@ struct clk; ...@@ -95,6 +95,14 @@ struct clk;
#define ETNA_NR_EVENTS 30 #define ETNA_NR_EVENTS 30
enum etnaviv_gpu_state {
ETNA_GPU_STATE_UNKNOWN = 0,
ETNA_GPU_STATE_IDENTIFIED,
ETNA_GPU_STATE_RESET,
ETNA_GPU_STATE_INITIALIZED,
ETNA_GPU_STATE_RUNNING,
};
struct etnaviv_gpu { struct etnaviv_gpu {
struct drm_device *drm; struct drm_device *drm;
struct thermal_cooling_device *cooling; struct thermal_cooling_device *cooling;
...@@ -105,8 +113,8 @@ struct etnaviv_gpu { ...@@ -105,8 +113,8 @@ struct etnaviv_gpu {
struct workqueue_struct *wq; struct workqueue_struct *wq;
struct mutex sched_lock; struct mutex sched_lock;
struct drm_gpu_scheduler sched; struct drm_gpu_scheduler sched;
enum etnaviv_gpu_state state;
bool initialized; bool initialized;
bool fe_running;
/* 'ring'-buffer: */ /* 'ring'-buffer: */
struct etnaviv_cmdbuf buffer; struct etnaviv_cmdbuf buffer;
......
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