]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/msm/adreno: Implement gx_is_on() for A8x
authorAkhil P Oommen <akhilpo@oss.qualcomm.com>
Fri, 27 Mar 2026 00:13:54 +0000 (05:43 +0530)
committerRob Clark <robin.clark@oss.qualcomm.com>
Tue, 31 Mar 2026 20:47:29 +0000 (13:47 -0700)
A8x has a diverged enough for a separate implementation of gx_is_on()
check. Add that and move them to the adreno func table.

Fixes: 288a93200892 ("drm/msm/adreno: Introduce A8x GPU Support")
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
Patchwork: https://patchwork.freedesktop.org/patch/714661/
Message-ID: <20260327-a8xx-gpu-batch2-v2-5-2b53c38d2101@oss.qualcomm.com>
Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
drivers/gpu/drm/msm/adreno/a6xx_gmu.c
drivers/gpu/drm/msm/adreno/a6xx_gmu.h
drivers/gpu/drm/msm/adreno/a6xx_gpu.c
drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
drivers/gpu/drm/msm/adreno/adreno_gpu.h

index 690d3e53e27384dac094448f731e0c71f91804bc..b41dbca1ebc63a9b81c8837a68c7167aed3dbe73 100644 (file)
@@ -91,10 +91,10 @@ bool a6xx_gmu_sptprac_is_on(struct a6xx_gmu *gmu)
 }
 
 /* Check to see if the GX rail is still powered */
-bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu)
+bool a6xx_gmu_gx_is_on(struct adreno_gpu *adreno_gpu)
 {
-       struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
-       struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+       struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+       struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
        u32 val;
 
        /* This can be called from gpu state code so make sure GMU is valid */
@@ -117,6 +117,40 @@ bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu)
                A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_GX_HM_CLK_OFF));
 }
 
+bool a7xx_gmu_gx_is_on(struct adreno_gpu *adreno_gpu)
+{
+       struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+       struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
+       u32 val;
+
+       /* This can be called from gpu state code so make sure GMU is valid */
+       if (!gmu->initialized)
+               return false;
+
+       val = gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS);
+
+       return !(val &
+               (A7XX_GMU_SPTPRAC_PWR_CLK_STATUS_GX_HM_GDSC_POWER_OFF |
+               A7XX_GMU_SPTPRAC_PWR_CLK_STATUS_GX_HM_CLK_OFF));
+}
+
+bool a8xx_gmu_gx_is_on(struct adreno_gpu *adreno_gpu)
+{
+       struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+       struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
+       u32 val;
+
+       /* This can be called from gpu state code so make sure GMU is valid */
+       if (!gmu->initialized)
+               return false;
+
+       val = gmu_read(gmu, REG_A8XX_GMU_PWR_CLK_STATUS);
+
+       return !(val &
+               (A8XX_GMU_PWR_CLK_STATUS_GX_HM_GDSC_POWER_OFF |
+                A8XX_GMU_PWR_CLK_STATUS_GX_HM_CLK_OFF));
+}
+
 void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp,
                       bool suspended)
 {
@@ -240,7 +274,7 @@ static bool a6xx_gmu_check_idle_level(struct a6xx_gmu *gmu)
 
        if (val == local) {
                if (gmu->idle_level != GMU_IDLE_STATE_IFPC ||
-                       !a6xx_gmu_gx_is_on(gmu))
+                       !adreno_gpu->funcs->gx_is_on(adreno_gpu))
                        return true;
        }
 
index 2af074c8e8cfa775a7d35a786834dba30395c8c4..9f09daf45ab2b33d3f2b152f803d3fc451c62d2e 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/notifier.h>
 #include <linux/soc/qcom/qcom_aoss.h>
 #include "msm_drv.h"
+#include "adreno_gpu.h"
 #include "a6xx_hfi.h"
 
 struct a6xx_gmu_bo {
@@ -231,7 +232,9 @@ void a6xx_hfi_stop(struct a6xx_gmu *gmu);
 int a6xx_hfi_send_prep_slumber(struct a6xx_gmu *gmu);
 int a6xx_hfi_set_freq(struct a6xx_gmu *gmu, u32 perf_index, u32 bw_index);
 
-bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu);
+bool a6xx_gmu_gx_is_on(struct adreno_gpu *adreno_gpu);
+bool a7xx_gmu_gx_is_on(struct adreno_gpu *adreno_gpu);
+bool a8xx_gmu_gx_is_on(struct adreno_gpu *adreno_gpu);
 bool a6xx_gmu_sptprac_is_on(struct a6xx_gmu *gmu);
 void a6xx_sptprac_disable(struct a6xx_gmu *gmu);
 int a6xx_sptprac_enable(struct a6xx_gmu *gmu);
index ae1d418ed0ab5b85a93c432e5ed3918c7e16a35c..d480c621f911374488e215082d7af4f93e58d306 100644 (file)
@@ -1643,7 +1643,7 @@ static void a6xx_recover(struct msm_gpu *gpu)
 
        adreno_dump_info(gpu);
 
-       if (a6xx_gmu_gx_is_on(&a6xx_gpu->gmu)) {
+       if (adreno_gpu->funcs->gx_is_on(adreno_gpu)) {
                /* Sometimes crashstate capture is skipped, so SQE should be halted here again */
                gpu_write(gpu, REG_A6XX_CP_SQE_CNTL, 3);
 
@@ -2763,6 +2763,7 @@ const struct adreno_gpu_funcs a6xx_gpu_funcs = {
        .get_timestamp = a6xx_gmu_get_timestamp,
        .bus_halt = a6xx_bus_clear_pending_transactions,
        .mmu_fault_handler = a6xx_fault_handler,
+       .gx_is_on = a6xx_gmu_gx_is_on,
 };
 
 const struct adreno_gpu_funcs a6xx_gmuwrapper_funcs = {
@@ -2795,6 +2796,7 @@ const struct adreno_gpu_funcs a6xx_gmuwrapper_funcs = {
        .get_timestamp = a6xx_get_timestamp,
        .bus_halt = a6xx_bus_clear_pending_transactions,
        .mmu_fault_handler = a6xx_fault_handler,
+       .gx_is_on = a6xx_gmu_gx_is_on,
 };
 
 const struct adreno_gpu_funcs a7xx_gpu_funcs = {
@@ -2829,6 +2831,7 @@ const struct adreno_gpu_funcs a7xx_gpu_funcs = {
        .get_timestamp = a6xx_gmu_get_timestamp,
        .bus_halt = a6xx_bus_clear_pending_transactions,
        .mmu_fault_handler = a6xx_fault_handler,
+       .gx_is_on = a7xx_gmu_gx_is_on,
 };
 
 const struct adreno_gpu_funcs a8xx_gpu_funcs = {
@@ -2856,4 +2859,5 @@ const struct adreno_gpu_funcs a8xx_gpu_funcs = {
        .get_timestamp = a8xx_gmu_get_timestamp,
        .bus_halt = a8xx_bus_clear_pending_transactions,
        .mmu_fault_handler = a8xx_fault_handler,
+       .gx_is_on = a8xx_gmu_gx_is_on,
 };
index 6e4950d513b318208dbf6faad7ffd010e0e29618..621f0b71ed11dacf90bb507de4c7dded07c34a05 100644 (file)
@@ -1251,7 +1251,7 @@ static void a6xx_get_gmu_registers(struct msm_gpu *gpu,
                _a6xx_get_gmu_registers(gpu, a6xx_state, &a6xx_gpucc_reg,
                        &a6xx_state->gmu_registers[2], false);
 
-       if (!a6xx_gmu_gx_is_on(&a6xx_gpu->gmu))
+       if (!adreno_gpu->funcs->gx_is_on(adreno_gpu))
                return;
 
        /* Set the fence to ALLOW mode so we can access the registers */
@@ -1608,7 +1608,7 @@ struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu)
        }
 
        /* If GX isn't on the rest of the data isn't going to be accessible */
-       if (!a6xx_gmu_gx_is_on(&a6xx_gpu->gmu))
+       if (!adreno_gpu->funcs->gx_is_on(adreno_gpu))
                return &a6xx_state->base;
 
        /* Halt SQE first */
index 0761cb5270136b11371d1f45419e4744d1ca0505..41b0e376ee31a75f9240c079189af5a891dc96a9 100644 (file)
@@ -78,6 +78,7 @@ struct adreno_gpu_funcs {
        u64 (*get_timestamp)(struct msm_gpu *gpu);
        void (*bus_halt)(struct adreno_gpu *adreno_gpu, bool gx_off);
        int (*mmu_fault_handler)(void *arg, unsigned long iova, int flags, void *data);
+       bool (*gx_is_on)(struct adreno_gpu *adreno_gpu);
 };
 
 struct adreno_reglist {