From: Le Ma <[email protected]>

On multiple AIDs platform, bit[34:32] in SMD address is leveraged to access
nonAID0 register smn address and new PCI_INDEX_HI register is introduced
to access the higher bits.

v2: rebase on latest register accessors (Alex)

Signed-off-by: Le Ma <[email protected]>
Acked-by: Felix Kuehling <[email protected]>
Reviewed-by: Lijo Lazar <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h        | 11 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 98 ++++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h   |  1 +
 drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c     |  6 ++
 drivers/gpu/drm/amd/amdgpu/soc15.c         |  2 +
 5 files changed, 118 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index ca9c4d31e352..5ad7ac75cc0f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -629,6 +629,9 @@ void amdgpu_cgs_destroy_device(struct cgs_device 
*cgs_device);
 typedef uint32_t (*amdgpu_rreg_t)(struct amdgpu_device*, uint32_t);
 typedef void (*amdgpu_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t);
 
+typedef uint32_t (*amdgpu_rreg_ext_t)(struct amdgpu_device*, uint64_t);
+typedef void (*amdgpu_wreg_ext_t)(struct amdgpu_device*, uint64_t, uint32_t);
+
 typedef uint64_t (*amdgpu_rreg64_t)(struct amdgpu_device*, uint32_t);
 typedef void (*amdgpu_wreg64_t)(struct amdgpu_device*, uint32_t, uint64_t);
 
@@ -819,6 +822,8 @@ struct amdgpu_device {
        amdgpu_wreg_t                   pcie_wreg;
        amdgpu_rreg_t                   pciep_rreg;
        amdgpu_wreg_t                   pciep_wreg;
+       amdgpu_rreg_ext_t               pcie_rreg_ext;
+       amdgpu_wreg_ext_t               pcie_wreg_ext;
        amdgpu_rreg64_t                 pcie_rreg64;
        amdgpu_wreg64_t                 pcie_wreg64;
        /* protects concurrent UVD register access */
@@ -1109,9 +1114,13 @@ uint32_t amdgpu_device_wait_on_rreg(struct amdgpu_device 
*adev,
                            uint32_t expected_value, uint32_t mask);
 uint32_t amdgpu_device_rreg(struct amdgpu_device *adev,
                            uint32_t reg, uint32_t acc_flags);
+u32 amdgpu_device_indirect_rreg_ext(struct amdgpu_device *adev,
+                                   u64 reg_addr);
 void amdgpu_device_wreg(struct amdgpu_device *adev,
                        uint32_t reg, uint32_t v,
                        uint32_t acc_flags);
+void amdgpu_device_indirect_wreg_ext(struct amdgpu_device *adev,
+                                    u64 reg_addr, u32 reg_data);
 void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev,
                             uint32_t reg, uint32_t v);
 void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t 
value);
@@ -1163,6 +1172,8 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
 #define WREG32_PCIE(reg, v) adev->pcie_wreg(adev, (reg), (v))
 #define RREG32_PCIE_PORT(reg) adev->pciep_rreg(adev, (reg))
 #define WREG32_PCIE_PORT(reg, v) adev->pciep_wreg(adev, (reg), (v))
+#define RREG32_PCIE_EXT(reg) adev->pcie_rreg_ext(adev, (reg))
+#define WREG32_PCIE_EXT(reg, v) adev->pcie_wreg_ext(adev, (reg), (v))
 #define RREG64_PCIE(reg) adev->pcie_rreg64(adev, (reg))
 #define WREG64_PCIE(reg, v) adev->pcie_wreg64(adev, (reg), (v))
 #define RREG32_SMC(reg) adev->smc_rreg(adev, (reg))
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 518e89a7d9ae..c0ab1a57dcbc 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -706,6 +706,48 @@ u32 amdgpu_device_indirect_rreg(struct amdgpu_device *adev,
        return r;
 }
 
+u32 amdgpu_device_indirect_rreg_ext(struct amdgpu_device *adev,
+                                   u64 reg_addr)
+{
+       unsigned long flags, pcie_index, pcie_index_hi, pcie_data;
+       u32 r;
+       void __iomem *pcie_index_offset;
+       void __iomem *pcie_index_hi_offset;
+       void __iomem *pcie_data_offset;
+
+       pcie_index = adev->nbio.funcs->get_pcie_index_offset(adev);
+       pcie_data = adev->nbio.funcs->get_pcie_data_offset(adev);
+       if (adev->nbio.funcs->get_pcie_index_hi_offset)
+               pcie_index_hi = 
adev->nbio.funcs->get_pcie_index_hi_offset(adev);
+       else
+               pcie_index_hi = 0;
+
+       spin_lock_irqsave(&adev->pcie_idx_lock, flags);
+       pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
+       pcie_data_offset = (void __iomem *)adev->rmmio + pcie_data * 4;
+       if (pcie_index_hi != 0)
+               pcie_index_hi_offset = (void __iomem *)adev->rmmio +
+                               pcie_index_hi * 4;
+
+       writel(reg_addr, pcie_index_offset);
+       readl(pcie_index_offset);
+       if (pcie_index_hi != 0) {
+               writel((reg_addr >> 32) & 0xff, pcie_index_hi_offset);
+               readl(pcie_index_hi_offset);
+       }
+       r = readl(pcie_data_offset);
+
+       /* clear the high bits */
+       if (pcie_index_hi != 0) {
+               writel(0, pcie_index_hi_offset);
+               readl(pcie_index_hi_offset);
+       }
+
+       spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
+
+       return r;
+}
+
 /**
  * amdgpu_device_indirect_rreg64 - read a 64bits indirect register
  *
@@ -773,6 +815,46 @@ void amdgpu_device_indirect_wreg(struct amdgpu_device 
*adev,
        spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
 }
 
+void amdgpu_device_indirect_wreg_ext(struct amdgpu_device *adev,
+                                    u64 reg_addr, u32 reg_data)
+{
+       unsigned long flags, pcie_index, pcie_index_hi, pcie_data;
+       void __iomem *pcie_index_offset;
+       void __iomem *pcie_index_hi_offset;
+       void __iomem *pcie_data_offset;
+
+       pcie_index = adev->nbio.funcs->get_pcie_index_offset(adev);
+       pcie_data = adev->nbio.funcs->get_pcie_data_offset(adev);
+       if (adev->nbio.funcs->get_pcie_index_hi_offset)
+               pcie_index_hi = 
adev->nbio.funcs->get_pcie_index_hi_offset(adev);
+       else
+               pcie_index_hi = 0;
+
+       spin_lock_irqsave(&adev->pcie_idx_lock, flags);
+       pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
+       pcie_data_offset = (void __iomem *)adev->rmmio + pcie_data * 4;
+       if (pcie_index_hi != 0)
+               pcie_index_hi_offset = (void __iomem *)adev->rmmio +
+                               pcie_index_hi * 4;
+
+       writel(reg_addr, pcie_index_offset);
+       readl(pcie_index_offset);
+       if (pcie_index_hi != 0) {
+               writel((reg_addr >> 32) & 0xff, pcie_index_hi_offset);
+               readl(pcie_index_hi_offset);
+       }
+       writel(reg_data, pcie_data_offset);
+       readl(pcie_data_offset);
+
+       /* clear the high bits */
+       if (pcie_index_hi != 0) {
+               writel(0, pcie_index_hi_offset);
+               readl(pcie_index_hi_offset);
+       }
+
+       spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
+}
+
 /**
  * amdgpu_device_indirect_wreg64 - write a 64bits indirect register address
  *
@@ -839,6 +921,13 @@ static uint32_t amdgpu_invalid_rreg(struct amdgpu_device 
*adev, uint32_t reg)
        return 0;
 }
 
+static uint32_t amdgpu_invalid_rreg_ext(struct amdgpu_device *adev, uint64_t 
reg)
+{
+       DRM_ERROR("Invalid callback to read register 0x%llX\n", reg);
+       BUG();
+       return 0;
+}
+
 /**
  * amdgpu_invalid_wreg - dummy reg write function
  *
@@ -856,6 +945,13 @@ static void amdgpu_invalid_wreg(struct amdgpu_device 
*adev, uint32_t reg, uint32
        BUG();
 }
 
+static void amdgpu_invalid_wreg_ext(struct amdgpu_device *adev, uint64_t reg, 
uint32_t v)
+{
+       DRM_ERROR("Invalid callback to write register 0x%llX with 0x%08X\n",
+                 reg, v);
+       BUG();
+}
+
 /**
  * amdgpu_invalid_rreg64 - dummy 64 bit reg read function
  *
@@ -3607,6 +3703,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
        adev->smc_wreg = &amdgpu_invalid_wreg;
        adev->pcie_rreg = &amdgpu_invalid_rreg;
        adev->pcie_wreg = &amdgpu_invalid_wreg;
+       adev->pcie_rreg_ext = &amdgpu_invalid_rreg_ext;
+       adev->pcie_wreg_ext = &amdgpu_invalid_wreg_ext;
        adev->pciep_rreg = &amdgpu_invalid_rreg;
        adev->pciep_wreg = &amdgpu_invalid_wreg;
        adev->pcie_rreg64 = &amdgpu_invalid_rreg64;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h
index 6a636c34b717..8fa3a1f3b181 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h
@@ -61,6 +61,7 @@ struct amdgpu_nbio_funcs {
        u32 (*get_hdp_flush_done_offset)(struct amdgpu_device *adev);
        u32 (*get_pcie_index_offset)(struct amdgpu_device *adev);
        u32 (*get_pcie_data_offset)(struct amdgpu_device *adev);
+       u32 (*get_pcie_index_hi_offset)(struct amdgpu_device *adev);
        u32 (*get_pcie_port_index_offset)(struct amdgpu_device *adev);
        u32 (*get_pcie_port_data_offset)(struct amdgpu_device *adev);
        u32 (*get_rev_id)(struct amdgpu_device *adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c 
b/drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c
index 40e694932a20..cd576b767912 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c
@@ -319,6 +319,11 @@ static u32 nbio_v7_9_get_pcie_data_offset(struct 
amdgpu_device *adev)
        return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX0_PCIE_DATA2);
 }
 
+static u32 nbio_v7_9_get_pcie_index_hi_offset(struct amdgpu_device *adev)
+{
+       return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX0_PCIE_INDEX2_HI);
+}
+
 const struct nbio_hdp_flush_reg nbio_v7_9_hdp_flush_reg = {
        .ref_and_mask_cp0 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP0_MASK,
        .ref_and_mask_cp1 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP1_MASK,
@@ -382,6 +387,7 @@ const struct amdgpu_nbio_funcs nbio_v7_9_funcs = {
        .get_hdp_flush_done_offset = nbio_v7_9_get_hdp_flush_done_offset,
        .get_pcie_index_offset = nbio_v7_9_get_pcie_index_offset,
        .get_pcie_data_offset = nbio_v7_9_get_pcie_data_offset,
+       .get_pcie_index_hi_offset = nbio_v7_9_get_pcie_index_hi_offset,
        .get_rev_id = nbio_v7_9_get_rev_id,
        .mc_access_enable = nbio_v7_9_mc_access_enable,
        .get_memsize = nbio_v7_9_get_memsize,
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c 
b/drivers/gpu/drm/amd/amdgpu/soc15.c
index 81c2150eb374..af47fafd2e77 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15.c
+++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
@@ -874,6 +874,8 @@ static int soc15_common_early_init(void *handle)
        adev->smc_wreg = NULL;
        adev->pcie_rreg = &amdgpu_device_indirect_rreg;
        adev->pcie_wreg = &amdgpu_device_indirect_wreg;
+       adev->pcie_rreg_ext = &amdgpu_device_indirect_rreg_ext;
+       adev->pcie_wreg_ext = &amdgpu_device_indirect_wreg_ext;
        adev->pcie_rreg64 = &amdgpu_device_indirect_rreg64;
        adev->pcie_wreg64 = &amdgpu_device_indirect_wreg64;
        adev->uvd_ctx_rreg = &soc15_uvd_ctx_rreg;
-- 
2.39.2

Reply via email to