diff options
author | Lucas Stach <l.stach@pengutronix.de> | 2023-06-07 15:02:21 +0200 |
---|---|---|
committer | Lucas Stach <l.stach@pengutronix.de> | 2023-07-17 11:32:27 +0200 |
commit | 647d817d807127cfff6dacc85992e52ab7779e94 (patch) | |
tree | 676400bf14a8a40d2b6b4d5964e26e8a4bc0f400 /drivers | |
parent | 448406eaf6c2a1f9941af1027dc610fd7461f0dc (diff) |
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: Lucas Stach <l.stach@pengutronix.de>
Reviewed-by: Christian Gmeiner <cgmeiner@igalia.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 25 | ||||
-rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_gpu.h | 10 |
2 files changed, 27 insertions, 8 deletions
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index d3187ca9e1a3..a024f5422df2 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -584,7 +584,7 @@ static int etnaviv_hw_reset(struct etnaviv_gpu *gpu) /* We rely on the GPU running, so program the clock */ etnaviv_gpu_update_clock(gpu); - gpu->fe_running = false; + gpu->state = ETNA_GPU_STATE_RESET; gpu->exec_state = -1; if (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) VIVS_MMUv2_SEC_COMMAND_CONTROL_ENABLE | VIVS_MMUv2_SEC_COMMAND_CONTROL_PREFETCH(prefetch)); } - - gpu->fe_running = true; } 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; u32 address; + WARN_ON(gpu->state != ETNA_GPU_STATE_INITIALIZED); + /* setup the MMU */ etnaviv_iommu_restore(gpu, context); @@ -678,6 +678,8 @@ static void etnaviv_gpu_start_fe_idleloop(struct etnaviv_gpu *gpu, &gpu->mmu_context->cmdbuf_mapping); etnaviv_gpu_start_fe(gpu, address, prefetch); + + gpu->state = ETNA_GPU_STATE_RUNNING; } 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) { + WARN_ON(!(gpu->state == ETNA_GPU_STATE_IDENTIFIED || + gpu->state == ETNA_GPU_STATE_RESET)); + if ((etnaviv_is_model_rev(gpu, GC320, 0x5007) || etnaviv_is_model_rev(gpu, GC320, 0x5220)) && gpu_read(gpu, VIVS_HI_CHIP_TIME) != 0x2062400) { @@ -759,6 +764,8 @@ static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu) etnaviv_gpu_setup_pulse_eater(gpu); gpu_write(gpu, VIVS_HI_INTR_ENBL, ~0U); + + gpu->state = ETNA_GPU_STATE_INITIALIZED; } 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->sec_mode = ETNA_SEC_KERNEL; + gpu->state = ETNA_GPU_STATE_IDENTIFIED; + ret = etnaviv_hw_reset(gpu); if (ret) { dev_err(gpu->dev, "GPU reset failed\n"); @@ -1376,7 +1385,7 @@ struct dma_fence *etnaviv_gpu_submit(struct etnaviv_gem_submit *submit) goto out_unlock; } - if (!gpu->fe_running) + if (gpu->state == ETNA_GPU_STATE_INITIALIZED) etnaviv_gpu_start_fe_idleloop(gpu, submit->mmu_context); if (submit->prev_mmu_context) @@ -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) { - if (gpu->initialized && gpu->fe_running) { + if (gpu->state == ETNA_GPU_STATE_RUNNING) { /* Replace the last WAIT with END */ mutex_lock(&gpu->lock); etnaviv_buffer_end(gpu); @@ -1655,7 +1664,7 @@ static void etnaviv_gpu_hw_suspend(struct etnaviv_gpu *gpu) */ etnaviv_gpu_wait_idle(gpu, 100); - gpu->fe_running = false; + gpu->state = ETNA_GPU_STATE_INITIALIZED; } gpu->exec_state = -1; @@ -1926,6 +1935,8 @@ static int etnaviv_gpu_rpm_suspend(struct device *dev) etnaviv_gpu_hw_suspend(gpu); + gpu->state = ETNA_GPU_STATE_IDENTIFIED; + return etnaviv_gpu_clk_disable(gpu); } @@ -1939,7 +1950,7 @@ static int etnaviv_gpu_rpm_resume(struct device *dev) return ret; /* Re-initialise the basic hardware state */ - if (gpu->initialized) { + if (gpu->state == ETNA_GPU_STATE_IDENTIFIED) { ret = etnaviv_gpu_hw_resume(gpu); if (ret) { etnaviv_gpu_clk_disable(gpu); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h index e1e1de59c38d..b4e545dce947 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h @@ -95,6 +95,14 @@ struct clk; #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 drm_device *drm; struct thermal_cooling_device *cooling; @@ -105,8 +113,8 @@ struct etnaviv_gpu { struct workqueue_struct *wq; struct mutex sched_lock; struct drm_gpu_scheduler sched; + enum etnaviv_gpu_state state; bool initialized; - bool fe_running; /* 'ring'-buffer: */ struct etnaviv_cmdbuf buffer; |