Skip to content

Commit 647d817

Browse files
committed
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>
1 parent 448406e commit 647d817

File tree

2 files changed

+27
-8
lines changed

2 files changed

+27
-8
lines changed

drivers/gpu/drm/etnaviv/etnaviv_gpu.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ static int etnaviv_hw_reset(struct etnaviv_gpu *gpu)
584584
/* We rely on the GPU running, so program the clock */
585585
etnaviv_gpu_update_clock(gpu);
586586

587-
gpu->fe_running = false;
587+
gpu->state = ETNA_GPU_STATE_RESET;
588588
gpu->exec_state = -1;
589589
if (gpu->mmu_context)
590590
etnaviv_iommu_context_put(gpu->mmu_context);
@@ -659,8 +659,6 @@ void etnaviv_gpu_start_fe(struct etnaviv_gpu *gpu, u32 address, u16 prefetch)
659659
VIVS_MMUv2_SEC_COMMAND_CONTROL_ENABLE |
660660
VIVS_MMUv2_SEC_COMMAND_CONTROL_PREFETCH(prefetch));
661661
}
662-
663-
gpu->fe_running = true;
664662
}
665663

666664
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,
669667
u16 prefetch;
670668
u32 address;
671669

670+
WARN_ON(gpu->state != ETNA_GPU_STATE_INITIALIZED);
671+
672672
/* setup the MMU */
673673
etnaviv_iommu_restore(gpu, context);
674674

@@ -678,6 +678,8 @@ static void etnaviv_gpu_start_fe_idleloop(struct etnaviv_gpu *gpu,
678678
&gpu->mmu_context->cmdbuf_mapping);
679679

680680
etnaviv_gpu_start_fe(gpu, address, prefetch);
681+
682+
gpu->state = ETNA_GPU_STATE_RUNNING;
681683
}
682684

683685
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)
713715

714716
static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu)
715717
{
718+
WARN_ON(!(gpu->state == ETNA_GPU_STATE_IDENTIFIED ||
719+
gpu->state == ETNA_GPU_STATE_RESET));
720+
716721
if ((etnaviv_is_model_rev(gpu, GC320, 0x5007) ||
717722
etnaviv_is_model_rev(gpu, GC320, 0x5220)) &&
718723
gpu_read(gpu, VIVS_HI_CHIP_TIME) != 0x2062400) {
@@ -759,6 +764,8 @@ static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu)
759764
etnaviv_gpu_setup_pulse_eater(gpu);
760765

761766
gpu_write(gpu, VIVS_HI_INTR_ENBL, ~0U);
767+
768+
gpu->state = ETNA_GPU_STATE_INITIALIZED;
762769
}
763770

764771
int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
@@ -801,6 +808,8 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
801808
(gpu->identity.minor_features10 & chipMinorFeatures10_SECURITY_AHB))
802809
gpu->sec_mode = ETNA_SEC_KERNEL;
803810

811+
gpu->state = ETNA_GPU_STATE_IDENTIFIED;
812+
804813
ret = etnaviv_hw_reset(gpu);
805814
if (ret) {
806815
dev_err(gpu->dev, "GPU reset failed\n");
@@ -1376,7 +1385,7 @@ struct dma_fence *etnaviv_gpu_submit(struct etnaviv_gem_submit *submit)
13761385
goto out_unlock;
13771386
}
13781387

1379-
if (!gpu->fe_running)
1388+
if (gpu->state == ETNA_GPU_STATE_INITIALIZED)
13801389
etnaviv_gpu_start_fe_idleloop(gpu, submit->mmu_context);
13811390

13821391
if (submit->prev_mmu_context)
@@ -1642,7 +1651,7 @@ int etnaviv_gpu_wait_idle(struct etnaviv_gpu *gpu, unsigned int timeout_ms)
16421651

16431652
static void etnaviv_gpu_hw_suspend(struct etnaviv_gpu *gpu)
16441653
{
1645-
if (gpu->initialized && gpu->fe_running) {
1654+
if (gpu->state == ETNA_GPU_STATE_RUNNING) {
16461655
/* Replace the last WAIT with END */
16471656
mutex_lock(&gpu->lock);
16481657
etnaviv_buffer_end(gpu);
@@ -1655,7 +1664,7 @@ static void etnaviv_gpu_hw_suspend(struct etnaviv_gpu *gpu)
16551664
*/
16561665
etnaviv_gpu_wait_idle(gpu, 100);
16571666

1658-
gpu->fe_running = false;
1667+
gpu->state = ETNA_GPU_STATE_INITIALIZED;
16591668
}
16601669

16611670
gpu->exec_state = -1;
@@ -1926,6 +1935,8 @@ static int etnaviv_gpu_rpm_suspend(struct device *dev)
19261935

19271936
etnaviv_gpu_hw_suspend(gpu);
19281937

1938+
gpu->state = ETNA_GPU_STATE_IDENTIFIED;
1939+
19291940
return etnaviv_gpu_clk_disable(gpu);
19301941
}
19311942

@@ -1939,7 +1950,7 @@ static int etnaviv_gpu_rpm_resume(struct device *dev)
19391950
return ret;
19401951

19411952
/* Re-initialise the basic hardware state */
1942-
if (gpu->initialized) {
1953+
if (gpu->state == ETNA_GPU_STATE_IDENTIFIED) {
19431954
ret = etnaviv_gpu_hw_resume(gpu);
19441955
if (ret) {
19451956
etnaviv_gpu_clk_disable(gpu);

drivers/gpu/drm/etnaviv/etnaviv_gpu.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,14 @@ struct clk;
9595

9696
#define ETNA_NR_EVENTS 30
9797

98+
enum etnaviv_gpu_state {
99+
ETNA_GPU_STATE_UNKNOWN = 0,
100+
ETNA_GPU_STATE_IDENTIFIED,
101+
ETNA_GPU_STATE_RESET,
102+
ETNA_GPU_STATE_INITIALIZED,
103+
ETNA_GPU_STATE_RUNNING,
104+
};
105+
98106
struct etnaviv_gpu {
99107
struct drm_device *drm;
100108
struct thermal_cooling_device *cooling;
@@ -105,8 +113,8 @@ struct etnaviv_gpu {
105113
struct workqueue_struct *wq;
106114
struct mutex sched_lock;
107115
struct drm_gpu_scheduler sched;
116+
enum etnaviv_gpu_state state;
108117
bool initialized;
109-
bool fe_running;
110118

111119
/* 'ring'-buffer: */
112120
struct etnaviv_cmdbuf buffer;

0 commit comments

Comments
 (0)