From: Akhil P Oommen <akhilpo@oss.qualcomm.com>
To: Rob Clark <robin.clark@oss.qualcomm.com>,
Sean Paul <sean@poorly.run>,
Konrad Dybcio <konradybcio@kernel.org>,
Dmitry Baryshkov <lumag@kernel.org>,
Abhinav Kumar <abhinav.kumar@linux.dev>,
Jessica Zhang <jessica.zhang@oss.qualcomm.com>,
Marijn Suijten <marijn.suijten@somainline.org>,
David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>
Cc: linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org,
freedreno@lists.freedesktop.org, linux-kernel@vger.kernel.org,
Akhil P Oommen <akhilpo@oss.qualcomm.com>
Subject: [PATCH 07/17] drm/msm/adreno: Add fenced regwrite support
Date: Sun, 20 Jul 2025 17:46:08 +0530 [thread overview]
Message-ID: <20250720-ifpc-support-v1-7-9347aa5bcbd6@oss.qualcomm.com> (raw)
In-Reply-To: <20250720-ifpc-support-v1-0-9347aa5bcbd6@oss.qualcomm.com>
There are some special registers which are accessible even when GX power
domain is collapsed during an IFPC sleep. Accessing these registers
wakes up GPU from power collapse and allow programming these registers
without additional handshake with GMU. This patch adds support for this
special register write sequence.
Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 63 ++++++++++++++++++++++++++++++-
drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 1 +
drivers/gpu/drm/msm/adreno/a6xx_preempt.c | 20 +++++-----
3 files changed, 73 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index 491fde0083a202bec7c6b3bca88d0e5a717a6560..8c004fc3abd2896d467a9728b34e99e4ed944dc4 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -16,6 +16,67 @@
#define GPU_PAS_ID 13
+static bool fence_status_check(struct msm_gpu *gpu, u32 offset, u32 value, u32 status, u32 mask)
+{
+ /* Success if !writedropped0/1 */
+ if (!(status & mask))
+ return true;
+
+ udelay(10);
+
+ /* Try to update fenced register again */
+ gpu_write(gpu, offset, value);
+ return false;
+}
+
+static int fenced_write(struct a6xx_gpu *a6xx_gpu, u32 offset, u32 value, u32 mask)
+{
+ struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+ struct msm_gpu *gpu = &adreno_gpu->base;
+ struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
+ u32 status;
+
+ gpu_write(gpu, offset, value);
+
+ /* Nothing else to be done in the case of no-GMU */
+ if (adreno_has_gmu_wrapper(adreno_gpu))
+ return 0;
+
+ if (!gmu_poll_timeout(gmu, REG_A6XX_GMU_AHB_FENCE_STATUS, status,
+ fence_status_check(gpu, offset, value, status, mask), 0, 1000))
+ return 0;
+
+ dev_err_ratelimited(gmu->dev, "delay in fenced register write (0x%x)\n",
+ offset);
+
+ /* Try again for another 1ms before failing */
+ gpu_write(gpu, offset, value);
+ if (!gmu_poll_timeout(gmu, REG_A6XX_GMU_AHB_FENCE_STATUS, status,
+ fence_status_check(gpu, offset, value, status, mask), 0, 1000))
+ return 0;
+
+ dev_err_ratelimited(gmu->dev, "fenced register write (0x%x) fail\n",
+ offset);
+
+ return -ETIMEDOUT;
+}
+
+int a6xx_fenced_write(struct a6xx_gpu *a6xx_gpu, u32 offset, u64 value, u32 mask, bool is_64b)
+{
+ int ret;
+
+ ret = fenced_write(a6xx_gpu, offset, lower_32_bits(value), mask);
+ if (ret)
+ return ret;
+
+ if (!is_64b)
+ return 0;
+
+ ret = fenced_write(a6xx_gpu, offset + 1, upper_32_bits(value), mask);
+
+ return ret;
+}
+
static inline bool _a6xx_check_idle(struct msm_gpu *gpu)
{
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
@@ -86,7 +147,7 @@ static void a6xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
/* Update HW if this is the current ring and we are not in preempt*/
if (!a6xx_in_preempt(a6xx_gpu)) {
if (a6xx_gpu->cur_ring == ring)
- gpu_write(gpu, REG_A6XX_CP_RB_WPTR, wptr);
+ a6xx_fenced_write(a6xx_gpu, REG_A6XX_CP_RB_WPTR, wptr, BIT(0), false);
else
ring->restore_wptr = true;
} else {
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
index 9201a53dd341bf432923ffb44947e015208a3d02..2be036a3faca58b4b559c30881e4b31d5929592a 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
@@ -291,5 +291,6 @@ int a6xx_gpu_state_put(struct msm_gpu_state *state);
void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu, bool gx_off);
void a6xx_gpu_sw_reset(struct msm_gpu *gpu, bool assert);
+int a6xx_fenced_write(struct a6xx_gpu *gpu, u32 offset, u64 value, u32 mask, bool is_64b);
#endif /* __A6XX_GPU_H__ */
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_preempt.c b/drivers/gpu/drm/msm/adreno/a6xx_preempt.c
index 3b17fd2dba89115a8e48ba9469e52e4305b0cdbb..5b0fd510ff58d989ab285f1a2497f6f522a6b187 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_preempt.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_preempt.c
@@ -41,7 +41,7 @@ static inline void set_preempt_state(struct a6xx_gpu *gpu,
}
/* Write the most recent wptr for the given ring into the hardware */
-static inline void update_wptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
+static inline void update_wptr(struct a6xx_gpu *a6xx_gpu, struct msm_ringbuffer *ring)
{
unsigned long flags;
uint32_t wptr;
@@ -51,7 +51,7 @@ static inline void update_wptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
if (ring->restore_wptr) {
wptr = get_wptr(ring);
- gpu_write(gpu, REG_A6XX_CP_RB_WPTR, wptr);
+ a6xx_fenced_write(a6xx_gpu, REG_A6XX_CP_RB_WPTR, wptr, BIT(0), false);
ring->restore_wptr = false;
}
@@ -172,7 +172,7 @@ void a6xx_preempt_irq(struct msm_gpu *gpu)
set_preempt_state(a6xx_gpu, PREEMPT_FINISH);
- update_wptr(gpu, a6xx_gpu->cur_ring);
+ update_wptr(a6xx_gpu, a6xx_gpu->cur_ring);
set_preempt_state(a6xx_gpu, PREEMPT_NONE);
@@ -268,7 +268,7 @@ void a6xx_preempt_trigger(struct msm_gpu *gpu)
*/
if (!ring || (a6xx_gpu->cur_ring == ring)) {
set_preempt_state(a6xx_gpu, PREEMPT_FINISH);
- update_wptr(gpu, a6xx_gpu->cur_ring);
+ update_wptr(a6xx_gpu, a6xx_gpu->cur_ring);
set_preempt_state(a6xx_gpu, PREEMPT_NONE);
spin_unlock_irqrestore(&a6xx_gpu->eval_lock, flags);
return;
@@ -302,13 +302,13 @@ void a6xx_preempt_trigger(struct msm_gpu *gpu)
spin_unlock_irqrestore(&ring->preempt_lock, flags);
- gpu_write64(gpu,
- REG_A6XX_CP_CONTEXT_SWITCH_SMMU_INFO,
- a6xx_gpu->preempt_smmu_iova[ring->id]);
+ a6xx_fenced_write(a6xx_gpu,
+ REG_A6XX_CP_CONTEXT_SWITCH_SMMU_INFO, a6xx_gpu->preempt_smmu_iova[ring->id],
+ BIT(1), true);
- gpu_write64(gpu,
+ a6xx_fenced_write(a6xx_gpu,
REG_A6XX_CP_CONTEXT_SWITCH_PRIV_NON_SECURE_RESTORE_ADDR,
- a6xx_gpu->preempt_iova[ring->id]);
+ a6xx_gpu->preempt_iova[ring->id], BIT(1), true);
a6xx_gpu->next_ring = ring;
@@ -328,7 +328,7 @@ void a6xx_preempt_trigger(struct msm_gpu *gpu)
set_preempt_state(a6xx_gpu, PREEMPT_TRIGGERED);
/* Trigger the preemption */
- gpu_write(gpu, REG_A6XX_CP_CONTEXT_SWITCH_CNTL, cntl);
+ a6xx_fenced_write(a6xx_gpu, REG_A6XX_CP_CONTEXT_SWITCH_CNTL, cntl, BIT(1), false);
}
static int preempt_init_ring(struct a6xx_gpu *a6xx_gpu,
--
2.50.1
next prev parent reply other threads:[~2025-07-20 12:17 UTC|newest]
Thread overview: 85+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-20 12:16 [PATCH 00/17] drm/msm: Support for Inter Frame Power Collapse (IFPC) feature Akhil P Oommen
2025-07-20 12:16 ` [PATCH 01/17] drm/msm: Update GMU register xml Akhil P Oommen
2025-07-20 12:16 ` [PATCH 02/17] drm/msm: a6xx: Refactor a6xx_sptprac_enable() Akhil P Oommen
2025-07-22 14:30 ` Konrad Dybcio
2025-07-22 19:47 ` Akhil P Oommen
2025-07-23 10:13 ` Konrad Dybcio
2025-07-23 19:10 ` Akhil P Oommen
2025-07-20 12:16 ` [PATCH 03/17] drm/msm: a6xx: Fix gx_is_on check for a7x family Akhil P Oommen
2025-07-20 18:46 ` Dmitry Baryshkov
2025-07-22 14:33 ` Konrad Dybcio
2025-07-22 19:52 ` Akhil P Oommen
2025-07-23 11:10 ` Dmitry Baryshkov
2025-07-23 19:11 ` Akhil P Oommen
2025-07-20 12:16 ` [PATCH 04/17] drm/msm/a6xx: Poll additional DRV status Akhil P Oommen
2025-07-22 13:31 ` Dmitry Baryshkov
2025-07-22 19:55 ` Akhil P Oommen
2025-07-23 10:01 ` Konrad Dybcio
2025-07-23 19:28 ` Akhil P Oommen
2025-07-24 11:39 ` Konrad Dybcio
2025-07-20 12:16 ` [PATCH 05/17] drm/msm/a6xx: Fix PDC sleep sequence Akhil P Oommen
2025-07-22 13:33 ` Dmitry Baryshkov
2025-07-22 17:26 ` Rob Clark
2025-07-22 21:05 ` Akhil P Oommen
2025-07-23 11:11 ` Dmitry Baryshkov
2025-08-07 13:51 ` Konrad Dybcio
2025-08-08 17:22 ` Akhil P Oommen
2025-08-11 8:40 ` Konrad Dybcio
2025-08-13 21:15 ` Akhil P Oommen
2025-07-20 12:16 ` [PATCH 06/17] drm/msm: Add an ftrace for gpu register access Akhil P Oommen
2025-07-20 12:16 ` Akhil P Oommen [this message]
2025-07-22 13:39 ` [PATCH 07/17] drm/msm/adreno: Add fenced regwrite support Dmitry Baryshkov
2025-07-22 14:52 ` Konrad Dybcio
2025-07-23 21:06 ` Akhil P Oommen
2025-07-24 11:46 ` Konrad Dybcio
2025-07-24 16:54 ` Akhil P Oommen
2025-07-29 13:01 ` Konrad Dybcio
2025-07-29 21:40 ` Akhil P Oommen
2025-07-29 21:49 ` Akhil P Oommen
2025-07-30 7:49 ` Konrad Dybcio
2025-07-23 21:04 ` Akhil P Oommen
2025-07-20 12:16 ` [PATCH 08/17] drm/msm/a6xx: Set Keep-alive votes to block IFPC Akhil P Oommen
2025-07-22 13:44 ` Dmitry Baryshkov
2025-07-22 21:24 ` Akhil P Oommen
2025-07-23 10:05 ` Konrad Dybcio
2025-07-23 21:22 ` Akhil P Oommen
2025-07-23 21:53 ` Dmitry Baryshkov
2025-07-23 11:13 ` Dmitry Baryshkov
2025-07-20 12:16 ` [PATCH 09/17] drm/msm/a6xx: Switch to GMU AO counter Akhil P Oommen
2025-07-23 10:19 ` Konrad Dybcio
2025-07-23 12:15 ` Rob Clark
2025-07-29 13:30 ` Konrad Dybcio
2025-07-20 12:16 ` [PATCH 10/17] drm/msm/a6xx: Poll AHB fence status in GPU IRQ handler Akhil P Oommen
2025-07-23 10:10 ` Konrad Dybcio
2025-07-20 12:16 ` [PATCH 11/17] drm/msm: Add support for IFPC Akhil P Oommen
2025-07-22 13:49 ` Dmitry Baryshkov
2025-07-22 21:27 ` Akhil P Oommen
2025-07-23 10:27 ` Konrad Dybcio
2025-07-23 21:43 ` Akhil P Oommen
2025-07-23 10:22 ` Konrad Dybcio
2025-07-20 12:16 ` [PATCH 12/17] drm/msm: Skip devfreq IDLE when possible Akhil P Oommen
2025-07-21 4:00 ` kernel test robot
2025-07-22 13:50 ` Dmitry Baryshkov
2025-07-22 15:38 ` Rob Clark
2025-07-22 19:23 ` Akhil P Oommen
2025-07-22 20:13 ` Rob Clark
2025-07-23 21:46 ` Akhil P Oommen
2025-07-23 10:28 ` Konrad Dybcio
2025-07-20 12:16 ` [PATCH 13/17] drm/msm/a6xx: Fix hangcheck for IFPC Akhil P Oommen
2025-07-22 13:52 ` Dmitry Baryshkov
2025-07-22 21:33 ` Akhil P Oommen
2025-07-20 12:16 ` [PATCH 14/17] drm/msm/adreno: Disable IFPC when sysprof is active Akhil P Oommen
2025-07-20 12:16 ` [PATCH 15/17] drm/msm/a6xx: Make crashstate capture IFPC safe Akhil P Oommen
2025-07-23 10:32 ` Konrad Dybcio
2025-07-23 21:53 ` Akhil P Oommen
2025-07-20 12:16 ` [PATCH 16/17] drm/msm/a6xx: Enable IFPC on Adreno X1-85 Akhil P Oommen
2025-07-22 13:55 ` Dmitry Baryshkov
2025-07-22 21:37 ` Akhil P Oommen
2025-07-23 10:33 ` Konrad Dybcio
2025-07-23 21:57 ` Akhil P Oommen
2025-07-22 14:55 ` Konrad Dybcio
2025-07-22 21:41 ` Akhil P Oommen
2025-07-29 14:06 ` neil.armstrong
2025-07-29 18:19 ` Akhil P Oommen
2025-07-20 12:16 ` [PATCH 17/17] drm/msm/adreno: Relax devfreq tunings Akhil P Oommen
2025-07-27 0:49 ` Anthony Ruhier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250720-ifpc-support-v1-7-9347aa5bcbd6@oss.qualcomm.com \
--to=akhilpo@oss.qualcomm.com \
--cc=abhinav.kumar@linux.dev \
--cc=airlied@gmail.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=freedreno@lists.freedesktop.org \
--cc=jessica.zhang@oss.qualcomm.com \
--cc=konradybcio@kernel.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lumag@kernel.org \
--cc=marijn.suijten@somainline.org \
--cc=robin.clark@oss.qualcomm.com \
--cc=sean@poorly.run \
--cc=simona@ffwll.ch \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®