This patch series introduces the IFPC feature to the DRM-MSM driver for Adreno GPUs. IFPC enables GMU to quickly transition GPU into a low power state when idle and quickly resume gpu to active state upon workload submission, hence the name 'Inter Frame Power Collapse'. Since the KMD is unaware of these transitions, it must perform a handshake with the hardware (eg: fenced_write, OOB signaling etc) before accessing registers in the GX power domain.
Initial patches address a few existing issues that were not exposed in the absence of IFPC. Rest of the patches are additional changes required for IFPC. This series adds the necessary restore register list for X1-85/A750 GPUs and enables IFPC support for them.
To: Rob Clark robin.clark@oss.qualcomm.com To: Sean Paul sean@poorly.run To: Konrad Dybcio konradybcio@kernel.org To: Dmitry Baryshkov lumag@kernel.org To: Abhinav Kumar abhinav.kumar@linux.dev To: Jessica Zhang jessica.zhang@oss.qualcomm.com To: Marijn Suijten marijn.suijten@somainline.org To: David Airlie airlied@gmail.com To: Simona Vetter simona@ffwll.ch To: Antonino Maniscalco antomani103@gmail.com To: Neil Armstrong neil.armstrong@linaro.org Cc: linux-arm-msm@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: freedreno@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org Cc: Antonino Maniscalco antomani103@gmail.com Cc: Neil Armstrong neil.armstrong@linaro.org
Signed-off-by: Akhil P Oommen akhilpo@oss.qualcomm.com --- Changes in v2: - Elaborate commit text and add Fixes tags (Dmitry/Konrad) - Document GMU_IDLE_STATE_RESERVED (Konrad) - Add a memory barrier in fenced_write - Move an error print in fenced_write to after polling - %s/set_keepalive_vote/a6xx[gpu|preempt]_keepalive_vote (Dmitry) - Add an "unlikely()" to read_gmu_ao_counter() (Konrad/Rob) - Define IFPC_LONG_HYST to document a magic number - Add a new patch to enable IFPC on A750 GPU (Neil/Antonino) - Drop patch 12 & 17 from v1 revision - Link to v1: https://lore.kernel.org/r/20250720-ifpc-support-v1-0-9347aa5bcbd6@oss.qualco...
--- Akhil P Oommen (16): drm/msm: Update GMU register xml drm/msm: a6xx: Fix gx_is_on check for a7x family drm/msm/a6xx: Poll additional DRV status drm/msm/a6xx: Fix PDC sleep sequence drm/msm: a6xx: Refactor a6xx_sptprac_enable() drm/msm: Add an ftrace for gpu register access drm/msm/adreno: Add fenced regwrite support drm/msm/a6xx: Set Keep-alive votes to block IFPC drm/msm/a6xx: Switch to GMU AO counter drm/msm/a6xx: Poll AHB fence status in GPU IRQ handler drm/msm: Add support for IFPC drm/msm/a6xx: Fix hangcheck for IFPC drm/msm/adreno: Disable IFPC when sysprof is active drm/msm/a6xx: Make crashstate capture IFPC safe drm/msm/a6xx: Enable IFPC on Adreno X1-85 drm/msm/a6xx: Enable IFPC on A750 GPU
drivers/gpu/drm/msm/adreno/a6xx_catalog.c | 71 ++++++- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 105 ++++++++-- drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 14 ++ drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 221 ++++++++++++++++++---- drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 3 + drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 10 +- drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 34 +++- drivers/gpu/drm/msm/adreno/a6xx_preempt.c | 40 +++- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 1 + drivers/gpu/drm/msm/msm_gpu.h | 9 + drivers/gpu/drm/msm/msm_gpu_trace.h | 12 ++ drivers/gpu/drm/msm/msm_submitqueue.c | 4 + drivers/gpu/drm/msm/registers/adreno/a6xx_gmu.xml | 11 ++ 13 files changed, 459 insertions(+), 76 deletions(-) --- base-commit: 5cc61f86dff464a63b6a6e4758f26557fda4d494 change-id: 20241216-ifpc-support-3b80167b3532
Best regards,
Since the PDC resides out of the GPU subsystem and cannot be reset in case it enters bad state, utmost care must be taken to trigger the PDC wake/sleep routines in the correct order.
The PDC wake sequence can be exercised only after a PDC sleep sequence. Additionally, GMU firmware should initialize a few registers before the KMD can trigger a PDC sleep sequence. So PDC sleep can't be done if the GMU firmware has not initialized. Track these dependencies using a new status variable and trigger PDC sleep/wake sequences appropriately.
Cc: stable@vger.kernel.org Fixes: 4b565ca5a2cb ("drm/msm: Add A6XX device support") Signed-off-by: Akhil P Oommen akhilpo@oss.qualcomm.com --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 28 +++++++++++++++++----------- drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 6 ++++++ 2 files changed, 23 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 06870f6596a7cb045deecaff3c95fba32ee84d52..ba593ccfe3c6a2f3a2ea0db3a1435d0668ed7bf2 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -279,6 +279,8 @@ static int a6xx_gmu_start(struct a6xx_gmu *gmu) if (ret) DRM_DEV_ERROR(gmu->dev, "GMU firmware initialization timed out\n");
+ set_bit(GMU_STATUS_FW_START, &gmu->status); + return ret; }
@@ -525,6 +527,9 @@ static int a6xx_rpmh_start(struct a6xx_gmu *gmu) int ret; u32 val;
+ if (!test_and_clear_bit(GMU_STATUS_PDC_SLEEP, &gmu->status)) + return 0; + gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, BIT(1));
ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_RSCC_CONTROL_ACK, val, @@ -552,6 +557,9 @@ static void a6xx_rpmh_stop(struct a6xx_gmu *gmu) int ret; u32 val;
+ if (test_and_clear_bit(GMU_STATUS_FW_START, &gmu->status)) + return; + gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, 1);
ret = gmu_poll_timeout_rscc(gmu, REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0, @@ -560,6 +568,8 @@ static void a6xx_rpmh_stop(struct a6xx_gmu *gmu) DRM_DEV_ERROR(gmu->dev, "Unable to power off the GPU RSC\n");
gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, 0); + + set_bit(GMU_STATUS_PDC_SLEEP, &gmu->status); }
static inline void pdc_write(void __iomem *ptr, u32 offset, u32 value) @@ -688,8 +698,6 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu) /* ensure no writes happen before the uCode is fully written */ wmb();
- a6xx_rpmh_stop(gmu); - err: if (!IS_ERR_OR_NULL(pdcptr)) iounmap(pdcptr); @@ -849,19 +857,15 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state) else gmu_write(gmu, REG_A6XX_GMU_GENERAL_7, 1);
- if (state == GMU_WARM_BOOT) { - ret = a6xx_rpmh_start(gmu); - if (ret) - return ret; - } else { + ret = a6xx_rpmh_start(gmu); + if (ret) + return ret; + + if (state == GMU_COLD_BOOT) { if (WARN(!adreno_gpu->fw[ADRENO_FW_GMU], "GMU firmware is not loaded\n")) return -ENOENT;
- ret = a6xx_rpmh_start(gmu); - if (ret) - return ret; - ret = a6xx_gmu_fw_load(gmu); if (ret) return ret; @@ -1046,6 +1050,8 @@ static void a6xx_gmu_force_off(struct a6xx_gmu *gmu)
/* Reset GPU core blocks */ a6xx_gpu_sw_reset(gpu, true); + + a6xx_rpmh_stop(gmu); }
static void a6xx_gmu_set_initial_freq(struct msm_gpu *gpu, struct a6xx_gmu *gmu) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h index d1ce11131ba6746056b3314dccdc3612cf982306..069a8c9474e8beb4ebe84d1609a8d38b44314125 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h @@ -117,6 +117,12 @@ struct a6xx_gmu {
struct qmp *qmp; struct a6xx_hfi_msg_bw_table *bw_table; + +/* To check if we can trigger sleep seq at PDC. Cleared in a6xx_rpmh_stop() */ +#define GMU_STATUS_FW_START 0 +/* To track if PDC sleep seq was done */ +#define GMU_STATUS_PDC_SLEEP 1 + unsigned long status; };
static inline u32 gmu_read(struct a6xx_gmu *gmu, u32 offset)
On 08/09/2025 10:26, Akhil P Oommen wrote:
This patch series introduces the IFPC feature to the DRM-MSM driver for Adreno GPUs. IFPC enables GMU to quickly transition GPU into a low power state when idle and quickly resume gpu to active state upon workload submission, hence the name 'Inter Frame Power Collapse'. Since the KMD is unaware of these transitions, it must perform a handshake with the hardware (eg: fenced_write, OOB signaling etc) before accessing registers in the GX power domain.
Initial patches address a few existing issues that were not exposed in the absence of IFPC. Rest of the patches are additional changes required for IFPC. This series adds the necessary restore register list for X1-85/A750 GPUs and enables IFPC support for them.
To: Rob Clark robin.clark@oss.qualcomm.com To: Sean Paul sean@poorly.run To: Konrad Dybcio konradybcio@kernel.org To: Dmitry Baryshkov lumag@kernel.org To: Abhinav Kumar abhinav.kumar@linux.dev To: Jessica Zhang jessica.zhang@oss.qualcomm.com To: Marijn Suijten marijn.suijten@somainline.org To: David Airlie airlied@gmail.com To: Simona Vetter simona@ffwll.ch To: Antonino Maniscalco antomani103@gmail.com To: Neil Armstrong neil.armstrong@linaro.org Cc: linux-arm-msm@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: freedreno@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org Cc: Antonino Maniscalco antomani103@gmail.com Cc: Neil Armstrong neil.armstrong@linaro.org
Signed-off-by: Akhil P Oommen akhilpo@oss.qualcomm.com
Changes in v2:
- Elaborate commit text and add Fixes tags (Dmitry/Konrad)
- Document GMU_IDLE_STATE_RESERVED (Konrad)
- Add a memory barrier in fenced_write
- Move an error print in fenced_write to after polling
- %s/set_keepalive_vote/a6xx[gpu|preempt]_keepalive_vote (Dmitry)
- Add an "unlikely()" to read_gmu_ao_counter() (Konrad/Rob)
- Define IFPC_LONG_HYST to document a magic number
- Add a new patch to enable IFPC on A750 GPU (Neil/Antonino)
- Drop patch 12 & 17 from v1 revision
- Link to v1: https://lore.kernel.org/r/20250720-ifpc-support-v1-0-9347aa5bcbd6@oss.qualco...
Akhil P Oommen (16): drm/msm: Update GMU register xml drm/msm: a6xx: Fix gx_is_on check for a7x family drm/msm/a6xx: Poll additional DRV status drm/msm/a6xx: Fix PDC sleep sequence drm/msm: a6xx: Refactor a6xx_sptprac_enable() drm/msm: Add an ftrace for gpu register access drm/msm/adreno: Add fenced regwrite support drm/msm/a6xx: Set Keep-alive votes to block IFPC drm/msm/a6xx: Switch to GMU AO counter drm/msm/a6xx: Poll AHB fence status in GPU IRQ handler drm/msm: Add support for IFPC drm/msm/a6xx: Fix hangcheck for IFPC drm/msm/adreno: Disable IFPC when sysprof is active drm/msm/a6xx: Make crashstate capture IFPC safe drm/msm/a6xx: Enable IFPC on Adreno X1-85 drm/msm/a6xx: Enable IFPC on A750 GPU
drivers/gpu/drm/msm/adreno/a6xx_catalog.c | 71 ++++++- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 105 ++++++++-- drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 14 ++ drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 221 ++++++++++++++++++---- drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 3 + drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 10 +- drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 34 +++- drivers/gpu/drm/msm/adreno/a6xx_preempt.c | 40 +++- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 1 + drivers/gpu/drm/msm/msm_gpu.h | 9 + drivers/gpu/drm/msm/msm_gpu_trace.h | 12 ++ drivers/gpu/drm/msm/msm_submitqueue.c | 4 + drivers/gpu/drm/msm/registers/adreno/a6xx_gmu.xml | 11 ++ 13 files changed, 459 insertions(+), 76 deletions(-)
base-commit: 5cc61f86dff464a63b6a6e4758f26557fda4d494 change-id: 20241216-ifpc-support-3b80167b3532
Best regards,
Tested-by: Neil Armstrong neil.armstrong@linaro.org # on SM8650-HDK
Thanks, Neil
linux-stable-mirror@lists.linaro.org