drm/msm: Add sysprof accessors

Currently the sysprof param serves two functions, (a) disabling perfcntr
clearing on context switch/preemption, and (b) disabling IFPC.  In the
future, with kernel side global perfcntr collection/stream, the decision
about disabling IFPC will change.

To prepare for this, split out two helpers/accessors for the two
different cases.  For now, they are the same thing, but this will
change.

Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
Reviewed-by: Anna Maniscalco <anna.maniscalco2000@gmail.com>
Reviewed-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
Patchwork: https://patchwork.freedesktop.org/patch/728214/
Message-ID: <20260526145137.160554-8-robin.clark@oss.qualcomm.com>
This commit is contained in:
Rob Clark 2026-05-26 07:50:41 -07:00
parent c897d550f0
commit 4250923945
6 changed files with 27 additions and 10 deletions

View File

@ -2080,10 +2080,10 @@ static int a6xx_gmu_get_irq(struct a6xx_gmu *gmu, struct platform_device *pdev,
void a6xx_gmu_sysprof_setup(struct msm_gpu *gpu)
{
bool sysprof = msm_gpu_sysprof_no_ifpc(gpu);
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
unsigned int sysprof_active;
/* Nothing to do if GPU is suspended. We will handle this during GMU resume */
if (!pm_runtime_get_if_active(&gpu->pdev->dev))
@ -2091,15 +2091,13 @@ void a6xx_gmu_sysprof_setup(struct msm_gpu *gpu)
mutex_lock(&gmu->lock);
sysprof_active = refcount_read(&gpu->sysprof_active);
/*
* 'Perfcounter select' register values are lost during IFPC collapse. To avoid that,
* use the currently unused perfcounter oob vote to block IFPC when sysprof is active
*/
if ((sysprof_active > 1) && !test_and_set_bit(GMU_STATUS_OOB_PERF_SET, &gmu->status))
if (sysprof && !test_and_set_bit(GMU_STATUS_OOB_PERF_SET, &gmu->status))
a6xx_gmu_set_oob(gmu, GMU_OOB_PERFCOUNTER_SET);
else if ((sysprof_active == 1) && test_and_clear_bit(GMU_STATUS_OOB_PERF_SET, &gmu->status))
else if (!sysprof && test_and_clear_bit(GMU_STATUS_OOB_PERF_SET, &gmu->status))
a6xx_gmu_clear_oob(gmu, GMU_OOB_PERFCOUNTER_SET);
mutex_unlock(&gmu->lock);

View File

@ -203,7 +203,7 @@ static void get_stats_counter(struct msm_ringbuffer *ring, u32 counter,
static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu,
struct msm_ringbuffer *ring, struct msm_gem_submit *submit)
{
bool sysprof = refcount_read(&a6xx_gpu->base.base.sysprof_active) > 1;
bool sysprof = msm_gpu_sysprof_no_perfcntr_zap(&a6xx_gpu->base.base);
struct msm_context *ctx = submit->queue->ctx;
struct drm_gpuvm *vm = msm_context_vm(submit->dev, ctx);
struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
@ -1531,7 +1531,7 @@ static int hw_init(struct msm_gpu *gpu)
a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_BOOT_SLUMBER);
}
if (!ret && (refcount_read(&gpu->sysprof_active) > 1)) {
if (!ret && msm_gpu_sysprof_no_ifpc(gpu)) {
ret = a6xx_gmu_set_oob(gmu, GMU_OOB_PERFCOUNTER_SET);
if (!ret)
set_bit(GMU_STATUS_OOB_PERF_SET, &gmu->status);
@ -2776,6 +2776,7 @@ const struct adreno_gpu_funcs a8xx_gpu_funcs = {
.create_private_vm = a6xx_create_private_vm,
.get_rptr = a6xx_get_rptr,
.progress = a8xx_progress,
.sysprof_setup = a6xx_gmu_sysprof_setup,
},
.init = a6xx_gpu_init,
.get_timestamp = a8xx_gmu_get_timestamp,

View File

@ -261,7 +261,7 @@ void a6xx_preempt_trigger(struct msm_gpu *gpu)
mod_timer(&a6xx_gpu->preempt_timer, jiffies + msecs_to_jiffies(10000));
/* Enable or disable postamble as needed */
sysprof = refcount_read(&a6xx_gpu->base.base.sysprof_active) > 1;
sysprof = msm_gpu_sysprof_no_perfcntr_zap(gpu);
if (!sysprof && !a6xx_gpu->postamble_enabled)
preempt_prepare_postamble(a6xx_gpu);

View File

@ -845,7 +845,7 @@ static int hw_init(struct msm_gpu *gpu)
*/
a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_GPU_SET);
if (!ret && (refcount_read(&gpu->sysprof_active) > 1)) {
if (!ret && msm_gpu_sysprof_no_perfcntr_zap(gpu)) {
ret = a6xx_gmu_set_oob(gmu, GMU_OOB_PERFCOUNTER_SET);
if (!ret)
set_bit(GMU_STATUS_OOB_PERF_SET, &gmu->status);

View File

@ -242,7 +242,7 @@ void a8xx_preempt_trigger(struct msm_gpu *gpu)
mod_timer(&a6xx_gpu->preempt_timer, jiffies + msecs_to_jiffies(10000));
/* Enable or disable postamble as needed */
sysprof = refcount_read(&a6xx_gpu->base.base.sysprof_active) > 1;
sysprof = msm_gpu_sysprof_no_perfcntr_zap(gpu);
if (!sysprof && !a6xx_gpu->postamble_enabled)
preempt_prepare_postamble(a6xx_gpu);

View File

@ -311,6 +311,24 @@ static inline bool msm_gpu_active(struct msm_gpu *gpu)
return false;
}
static inline bool
msm_gpu_sysprof_no_perfcntr_zap(struct msm_gpu *gpu)
{
return refcount_read(&gpu->sysprof_active) > 1;
}
static inline bool
msm_gpu_sysprof_no_ifpc(struct msm_gpu *gpu)
{
/*
* For now, this is the same condition as disabling perfcntr clears
* on context switch. But once kernel perfcntr IFPC support is in
* place, we will only need to disable IFPC for legacy userspace
* setting SYSPROF param.
*/
return msm_gpu_sysprof_no_perfcntr_zap(gpu);
}
/*
* The number of priority levels provided by drm gpu scheduler. The
* DRM_SCHED_PRIORITY_KERNEL priority level is treated specially in some