Skip to content

Commit 62cd0fa

Browse files
akhilpo-qcomRob Clark
authored andcommitted
drm/msm/adreno: Disable IFPC when sysprof is active
Moving to IFPC state clears the 'Perfcounter Select' register setup by the userspace. So, lets block the IFPC when sysprof is active by using the perfcounter oob signal to the GMU. Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com> Patchwork: https://patchwork.freedesktop.org/patch/673380/ Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
1 parent a242ef4 commit 62cd0fa

6 files changed

Lines changed: 47 additions & 0 deletions

File tree

drivers/gpu/drm/msm/adreno/a6xx_gmu.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,11 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)
11571157
/* Set the GPU to the current freq */
11581158
a6xx_gmu_set_initial_freq(gpu, gmu);
11591159

1160+
if (refcount_read(&gpu->sysprof_active) > 1) {
1161+
ret = a6xx_gmu_set_oob(gmu, GMU_OOB_PERFCOUNTER_SET);
1162+
if (!ret)
1163+
set_bit(GMU_STATUS_OOB_PERF_SET, &gmu->status);
1164+
}
11601165
out:
11611166
/* On failure, shut down the GMU to leave it in a good state */
11621167
if (ret) {
@@ -1204,6 +1209,9 @@ static void a6xx_gmu_shutdown(struct a6xx_gmu *gmu)
12041209
a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_GPU_SET);
12051210
}
12061211

1212+
if (test_and_clear_bit(GMU_STATUS_OOB_PERF_SET, &gmu->status))
1213+
a6xx_gmu_clear_oob(gmu, GMU_OOB_PERFCOUNTER_SET);
1214+
12071215
ret = a6xx_gmu_wait_for_idle(gmu);
12081216

12091217
/* If the GMU isn't responding assume it is hung */
@@ -1817,6 +1825,35 @@ static int a6xx_gmu_get_irq(struct a6xx_gmu *gmu, struct platform_device *pdev,
18171825
return irq;
18181826
}
18191827

1828+
void a6xx_gmu_sysprof_setup(struct msm_gpu *gpu)
1829+
{
1830+
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
1831+
struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
1832+
struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
1833+
unsigned int sysprof_active;
1834+
1835+
/* Nothing to do if GPU is suspended. We will handle this during GMU resume */
1836+
if (!pm_runtime_get_if_active(&gpu->pdev->dev))
1837+
return;
1838+
1839+
mutex_lock(&gmu->lock);
1840+
1841+
sysprof_active = refcount_read(&gpu->sysprof_active);
1842+
1843+
/*
1844+
* 'Perfcounter select' register values are lost during IFPC collapse. To avoid that,
1845+
* use the currently unused perfcounter oob vote to block IFPC when sysprof is active
1846+
*/
1847+
if ((sysprof_active > 1) && !test_and_set_bit(GMU_STATUS_OOB_PERF_SET, &gmu->status))
1848+
a6xx_gmu_set_oob(gmu, GMU_OOB_PERFCOUNTER_SET);
1849+
else if ((sysprof_active == 1) && test_and_clear_bit(GMU_STATUS_OOB_PERF_SET, &gmu->status))
1850+
a6xx_gmu_clear_oob(gmu, GMU_OOB_PERFCOUNTER_SET);
1851+
1852+
mutex_unlock(&gmu->lock);
1853+
1854+
pm_runtime_put(&gpu->pdev->dev);
1855+
}
1856+
18201857
void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu)
18211858
{
18221859
struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;

drivers/gpu/drm/msm/adreno/a6xx_gmu.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ struct a6xx_gmu {
125125
#define GMU_STATUS_FW_START 0
126126
/* To track if PDC sleep seq was done */
127127
#define GMU_STATUS_PDC_SLEEP 1
128+
/* To track Perfcounter OOB set status */
129+
#define GMU_STATUS_OOB_PERF_SET 2
128130
unsigned long status;
129131
};
130132

drivers/gpu/drm/msm/adreno/a6xx_gpu.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2536,6 +2536,7 @@ static const struct adreno_gpu_funcs funcs = {
25362536
.create_private_vm = a6xx_create_private_vm,
25372537
.get_rptr = a6xx_get_rptr,
25382538
.progress = a6xx_progress,
2539+
.sysprof_setup = a6xx_gmu_sysprof_setup,
25392540
},
25402541
.get_timestamp = a6xx_gmu_get_timestamp,
25412542
};
@@ -2596,6 +2597,7 @@ static const struct adreno_gpu_funcs funcs_a7xx = {
25962597
.create_private_vm = a6xx_create_private_vm,
25972598
.get_rptr = a6xx_get_rptr,
25982599
.progress = a6xx_progress,
2600+
.sysprof_setup = a6xx_gmu_sysprof_setup,
25992601
},
26002602
.get_timestamp = a6xx_gmu_get_timestamp,
26012603
};

drivers/gpu/drm/msm/adreno/a6xx_gpu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state);
254254
int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node);
255255
int a6xx_gmu_wrapper_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node);
256256
void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu);
257+
void a6xx_gmu_sysprof_setup(struct msm_gpu *gpu);
257258

258259
void a6xx_preempt_init(struct msm_gpu *gpu);
259260
void a6xx_preempt_hw_init(struct msm_gpu *gpu);

drivers/gpu/drm/msm/msm_gpu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ struct msm_gpu_funcs {
9292
* for cmdstream that is buffered in this FIFO upstream of the CP fw.
9393
*/
9494
bool (*progress)(struct msm_gpu *gpu, struct msm_ringbuffer *ring);
95+
void (*sysprof_setup)(struct msm_gpu *gpu);
9596
};
9697

9798
/* Additional state for iommu faults: */

drivers/gpu/drm/msm/msm_submitqueue.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ int msm_context_set_sysprof(struct msm_context *ctx, struct msm_gpu *gpu, int sy
4040
break;
4141
}
4242

43+
/* Some gpu families require additional setup for sysprof */
44+
if (gpu->funcs->sysprof_setup)
45+
gpu->funcs->sysprof_setup(gpu);
46+
4347
ctx->sysprof = sysprof;
4448

4549
return 0;

0 commit comments

Comments
 (0)