]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/msm/a6xx: Allow IFPC with perfcntr stream
authorRob Clark <robin.clark@oss.qualcomm.com>
Tue, 26 May 2026 14:50:50 +0000 (07:50 -0700)
committerRob Clark <robin.clark@oss.qualcomm.com>
Fri, 29 May 2026 14:07:30 +0000 (07:07 -0700)
Now that the dynamic pwrup reglist has SEL reg values to restore
appended, so that SEL regs are restored on IFPC exit, we can stop
completely disabling IFPC while global counter sampling is active.

To accomplish this, we re-use sysprof_setup() with a force_on param
to inhibit IFPC specifically while the counter regs are being read,
while leaving IFPC enabled the rest of the time.

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/728219/
Message-ID: <20260526145137.160554-17-robin.clark@oss.qualcomm.com>

drivers/gpu/drm/msm/adreno/a6xx_gmu.c
drivers/gpu/drm/msm/adreno/a6xx_gpu.h
drivers/gpu/drm/msm/msm_gpu.h
drivers/gpu/drm/msm/msm_perfcntr.c
drivers/gpu/drm/msm/msm_submitqueue.c

index d26f8733672dd9c07e8c78043c1da18a2511e1f7..47b5702e1b40d216d9039cec74e549d086b8f02b 100644 (file)
@@ -2078,9 +2078,9 @@ static int a6xx_gmu_get_irq(struct a6xx_gmu *gmu, struct platform_device *pdev,
        return irq;
 }
 
-void a6xx_gmu_sysprof_setup(struct msm_gpu *gpu)
+void a6xx_gmu_sysprof_setup(struct msm_gpu *gpu, bool force_on)
 {
-       bool sysprof = msm_gpu_sysprof_no_ifpc(gpu);
+       bool sysprof = msm_gpu_sysprof_no_ifpc(gpu) || force_on;
        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;
index b72fb58bf223470cc2288b4f2f90aee310f249eb..f60a0801a62d7c38c8699fc7b8ec918e32f9fc96 100644 (file)
@@ -281,7 +281,7 @@ void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state);
 int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node);
 int a6xx_gmu_wrapper_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node);
 void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu);
-void a6xx_gmu_sysprof_setup(struct msm_gpu *gpu);
+void a6xx_gmu_sysprof_setup(struct msm_gpu *gpu, bool force_on);
 
 void a6xx_preempt_init(struct msm_gpu *gpu);
 void a6xx_preempt_hw_init(struct msm_gpu *gpu);
index c9c9a3b75b682c8c54bcb845583f45f229166ea4..6c83b8cbbb904a6a1515f49bbf94fc153376e159 100644 (file)
@@ -93,7 +93,7 @@ struct msm_gpu_funcs {
         * for cmdstream that is buffered in this FIFO upstream of the CP fw.
         */
        bool (*progress)(struct msm_gpu *gpu, struct msm_ringbuffer *ring);
-       void (*sysprof_setup)(struct msm_gpu *gpu);
+       void (*sysprof_setup)(struct msm_gpu *gpu, bool force_on);
 
        /* Configure perfcntr SELect regs: */
        void (*perfcntr_configure)(struct msm_gpu *gpu, struct msm_ringbuffer *ring,
@@ -378,13 +378,7 @@ msm_gpu_sysprof_no_perfcntr_zap(struct msm_gpu *gpu)
 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);
+       return refcount_read(&gpu->sysprof_active) > 1;
 }
 
 /*
index 0a6f8039f6106dc45e6ea76ead7b3ab7f2b41515..ce65b1160955e21dc18292a2d6f417b2bd6c0840 100644 (file)
@@ -258,6 +258,10 @@ sample_worker(struct kthread_work *work)
                return;
        }
 
+       /* Inhibit IFPC while accessing registers: */
+       if (gpu->funcs->sysprof_setup)
+               gpu->funcs->sysprof_setup(gpu, true);
+
        if (gpu->funcs->perfcntr_flush)
                gpu->funcs->perfcntr_flush(gpu);
 
@@ -292,6 +296,10 @@ sample_worker(struct kthread_work *work)
                }
        }
 
+       /* Re-enable IFPC: */
+       if (gpu->funcs->sysprof_setup)
+               gpu->funcs->sysprof_setup(gpu, false);
+
        smp_store_release(&stream->fifo.head, head);
        wake_up_all(&stream->poll_wq);
 }
index a58fe41602c6ae838427369722278fbbd7230fc5..1a5a77b28016315a45c1ce3833d74853bbb2e1b2 100644 (file)
@@ -42,7 +42,7 @@ int msm_context_set_sysprof(struct msm_context *ctx, struct msm_gpu *gpu, int sy
 
        /* Some gpu families require additional setup for sysprof */
        if (gpu->funcs->sysprof_setup)
-               gpu->funcs->sysprof_setup(gpu);
+               gpu->funcs->sysprof_setup(gpu, false);
 
        ctx->sysprof = sysprof;