[PATCH 6/8] drm/etnaviv: better track GPU state
Christian Gmeiner
christian.gmeiner at gmail.com
Wed Jun 21 07:33:07 UTC 2023
Hi Lucas
>
> 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 at pengutronix.de>
Reviewed-by: Christian Gmeiner <cgmeiner at igalia.com>
> ---
> drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 25 ++++++++++++++++++-------
> 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 fb07d0e73802..96cbb290b869 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
> @@ -576,7 +576,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);
> @@ -651,8 +651,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,
> @@ -661,6 +659,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);
>
> @@ -670,6 +670,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)
> @@ -705,6 +707,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) {
> @@ -751,6 +756,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)
> @@ -793,6 +800,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");
> @@ -1368,7 +1377,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)
> @@ -1634,7 +1643,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);
> @@ -1647,7 +1656,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;
> @@ -1918,6 +1927,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);
> }
>
> @@ -1931,7 +1942,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 98c6f9c320fc..33ecc1bf84b1 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;
> --
> 2.39.2
>
--
greets
--
Christian Gmeiner, MSc
https://christian-gmeiner.info/privacypolicy
More information about the dri-devel
mailing list