Some NBIO generations expose doorbell control register
instances through global SMN addresses. Extend the common
doorbell entry description and programming helper to
select this access path

The IP-specific mapping records the target register
instance while callers remain responsible for invoking
their doorbell callback for each required instance.

Signed-off-by: Hawking Zhang <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.c | 24 ++++++++++++++++--------
 drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h |  9 +++++++++
 2 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.c
index 70b63fd3656f..55049a8635bd 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.c
@@ -221,18 +221,26 @@ void amdgpu_nbio_program_doorbell_entry(
        if (WARN_ON_ONCE(!entry->ctrl_reg))
                return;
 
-       /* A NULL CTRL disables and clears the entry. */
-       if (!ctrl) {
-               WREG32_SOC15_IP(NBIO, entry->ctrl_reg, 0);
-               if (entry->ctrl1_reg)
-                       WREG32_SOC15_IP(NBIO, entry->ctrl1_reg, 0);
+       if (entry->use_ext) {
+               /* CTRL1 programming is not needed when use_ext is set. */
+               if (WARN_ON_ONCE(entry->ctrl1_reg || ctrl1))
+                       return;
+
+               WREG32_PCIE_EXT(
+                       (adev->reg_offset[NBIO_HWIP][entry->reg_inst]
+                        [entry->ctrl_reg_base_idx] + entry->ctrl_reg) * 4 +
+                       amdgpu_reg_get_smn_base64(
+                               adev, NBIO_HWIP, entry->reg_inst),
+                       ctrl ? *ctrl : 0);
                return;
        }
 
        if (WARN_ON_ONCE(ctrl1 && !entry->ctrl1_reg))
                return;
 
-       WREG32_SOC15_IP(NBIO, entry->ctrl_reg, *ctrl);
-       if (ctrl1)
-               WREG32_SOC15_IP(NBIO, entry->ctrl1_reg, *ctrl1);
+       /* A NULL CTRL disables and clears the entry. */
+       WREG32_SOC15_IP(NBIO, entry->ctrl_reg, ctrl ? *ctrl : 0);
+       if (entry->ctrl1_reg && (!ctrl || ctrl1))
+               WREG32_SOC15_IP(NBIO, entry->ctrl1_reg,
+                                   ctrl ? *ctrl1 : 0);
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h
index 2ac392934169..18418a331517 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h
@@ -114,6 +114,15 @@ struct amdgpu_nbio_doorbell_entry {
        u32 port;
        u32 ctrl_reg;
        u32 ctrl1_reg;
+       /*
+        * Some NBIO generations expose each register instance through a global
+        * SMN address. The caller invokes the doorbell callback for each 
required
+        * instance across the die; reg_inst identifies the instance represented
+        * by this entry. Extended entries only support a CTRL register.
+        */
+       bool use_ext;
+       u32 reg_inst;
+       u32 ctrl_reg_base_idx;
 };
 
 struct amdgpu_nbio_doorbell_entries {
-- 
2.17.1

Reply via email to