[PATCH 1/3] drm/amdgpu: Add RREG64_PCIE_EXT/WREG64_PCIE_EXT functions

Zhang, Hawking Hawking.Zhang at amd.com
Mon Sep 4 07:51:29 UTC 2023


[AMD Official Use Only - General]

Please split the change in amdgpu_device_indirect_rreg|wreg_ext to another patch.

With above addressed, the series is

Reviewed-by: Hawking Zhang <Hawking.Zhang at amd.com>

Regards,
Hawking

-----Original Message-----
From: amd-gfx <amd-gfx-bounces at lists.freedesktop.org> On Behalf Of Candice Li
Sent: Monday, September 4, 2023 15:19
To: amd-gfx at lists.freedesktop.org
Cc: Zhou1, Tao <Tao.Zhou1 at amd.com>; Li, Candice <Candice.Li at amd.com>
Subject: [PATCH 1/3] drm/amdgpu: Add RREG64_PCIE_EXT/WREG64_PCIE_EXT functions

1. Add 64bits register access support on register whose address is greater than 32bits.
2. Update RREG32_PCIE_EXT/WREG32_PCIE_EXT.

Signed-off-by: Candice Li <candice.li at amd.com>
Reviewed-by: Tao Zhou <tao.zhou1 at amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h        |  11 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 119 ++++++++++++++++++++-
 drivers/gpu/drm/amd/amdgpu/soc15.c         |   2 +
 3 files changed, 130 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 45e5db95496906..6ff4289b255bbf 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -653,6 +653,9 @@ 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);

+typedef uint64_t (*amdgpu_rreg64_ext_t)(struct amdgpu_device*,
+uint64_t); typedef void (*amdgpu_wreg64_ext_t)(struct amdgpu_device*,
+uint64_t, uint64_t);
+
 typedef uint32_t (*amdgpu_block_rreg_t)(struct amdgpu_device*, uint32_t, uint32_t);  typedef void (*amdgpu_block_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t, uint32_t);

@@ -867,6 +870,8 @@ struct amdgpu_device {
        amdgpu_wreg_ext_t               pcie_wreg_ext;
        amdgpu_rreg64_t                 pcie_rreg64;
        amdgpu_wreg64_t                 pcie_wreg64;
+       amdgpu_rreg64_ext_t                     pcie_rreg64_ext;
+       amdgpu_wreg64_ext_t                     pcie_wreg64_ext;
        /* protects concurrent UVD register access */
        spinlock_t uvd_ctx_idx_lock;
        amdgpu_rreg_t                   uvd_ctx_rreg;
@@ -1178,10 +1183,14 @@ u32 amdgpu_device_indirect_rreg(struct amdgpu_device *adev,
                                u32 reg_addr);
 u64 amdgpu_device_indirect_rreg64(struct amdgpu_device *adev,
                                  u32 reg_addr);
+u64 amdgpu_device_indirect_rreg64_ext(struct amdgpu_device *adev,
+                                 u64 reg_addr);
 void amdgpu_device_indirect_wreg(struct amdgpu_device *adev,
                                 u32 reg_addr, u32 reg_data);
 void amdgpu_device_indirect_wreg64(struct amdgpu_device *adev,
                                   u32 reg_addr, u64 reg_data);
+void amdgpu_device_indirect_wreg64_ext(struct amdgpu_device *adev,
+                                  u64 reg_addr, u64 reg_data);
 u32 amdgpu_device_get_rev_id(struct amdgpu_device *adev);  bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type);  bool amdgpu_device_has_dc_support(struct amdgpu_device *adev); @@ -1224,6 +1233,8 @@ int emu_soc_asic_init(struct amdgpu_device *adev);  #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 RREG64_PCIE_EXT(reg) adev->pcie_rreg64_ext(adev, (reg)) #define
+WREG64_PCIE_EXT(reg, v) adev->pcie_wreg64_ext(adev, (reg), (v))
 #define RREG32_SMC(reg) adev->smc_rreg(adev, (reg))  #define WREG32_SMC(reg, v) adev->smc_wreg(adev, (reg), (v))  #define RREG32_UVD_CTX(reg) adev->uvd_ctx_rreg(adev, (reg)) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index de9223b5e6fd76..57b24053e1e320 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -574,7 +574,7 @@ u32 amdgpu_device_indirect_rreg_ext(struct amdgpu_device *adev,

        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)
+       if ((reg_addr >> 32) && (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;
@@ -641,6 +641,56 @@ u64 amdgpu_device_indirect_rreg64(struct amdgpu_device *adev,
        return r;
 }

+u64 amdgpu_device_indirect_rreg64_ext(struct amdgpu_device *adev,
+                                 u64 reg_addr)
+{
+       unsigned long flags, pcie_index, pcie_data;
+       unsigned long pcie_index_hi = 0;
+       void __iomem *pcie_index_offset;
+       void __iomem *pcie_index_hi_offset;
+       void __iomem *pcie_data_offset;
+       u64 r;
+
+       pcie_index = adev->nbio.funcs->get_pcie_index_offset(adev);
+       pcie_data = adev->nbio.funcs->get_pcie_data_offset(adev);
+       if ((reg_addr >> 32) && (adev->nbio.funcs->get_pcie_index_hi_offset))
+               pcie_index_hi = adev->nbio.funcs->get_pcie_index_hi_offset(adev);
+
+       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;
+
+       /* read low 32 bits */
+       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);
+       /* read high 32 bits */
+       writel(reg_addr + 4, 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 |= ((u64)readl(pcie_data_offset) << 32);
+
+       /* 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_wreg - write an indirect register address
  *
@@ -680,7 +730,7 @@ void amdgpu_device_indirect_wreg_ext(struct amdgpu_device *adev,

        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)
+       if ((reg_addr >> 32) && (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;
@@ -745,6 +795,55 @@ void amdgpu_device_indirect_wreg64(struct amdgpu_device *adev,
        spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);  }

+void amdgpu_device_indirect_wreg64_ext(struct amdgpu_device *adev,
+                                  u64 reg_addr, u64 reg_data)
+{
+       unsigned long flags, pcie_index, pcie_data;
+       unsigned long pcie_index_hi = 0;
+       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 ((reg_addr >> 32) && (adev->nbio.funcs->get_pcie_index_hi_offset))
+               pcie_index_hi = adev->nbio.funcs->get_pcie_index_hi_offset(adev);
+
+       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;
+
+       /* write low 32 bits */
+       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((u32)(reg_data & 0xffffffffULL), pcie_data_offset);
+       readl(pcie_data_offset);
+       /* write high 32 bits */
+       writel(reg_addr + 4, 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((u32)(reg_data >> 32), 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_get_rev_id - query device rev_id
  *
@@ -822,6 +921,13 @@ static uint64_t amdgpu_invalid_rreg64(struct amdgpu_device *adev, uint32_t reg)
        return 0;
 }

+static uint64_t amdgpu_invalid_rreg64_ext(struct amdgpu_device *adev,
+uint64_t reg) {
+       DRM_ERROR("Invalid callback to read register 0x%llX\n", reg);
+       BUG();
+       return 0;
+}
+
 /**
  * amdgpu_invalid_wreg64 - dummy reg write function
  *
@@ -839,6 +945,13 @@ static void amdgpu_invalid_wreg64(struct amdgpu_device *adev, uint32_t reg, uint
        BUG();
 }

+static void amdgpu_invalid_wreg64_ext(struct amdgpu_device *adev,
+uint64_t reg, uint64_t v) {
+       DRM_ERROR("Invalid callback to write 64 bit register 0x%llX with 0x%08llX\n",
+                 reg, v);
+       BUG();
+}
+
 /**
  * amdgpu_block_invalid_rreg - dummy reg read function
  *
@@ -3583,6 +3696,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
        adev->pciep_wreg = &amdgpu_invalid_wreg;
        adev->pcie_rreg64 = &amdgpu_invalid_rreg64;
        adev->pcie_wreg64 = &amdgpu_invalid_wreg64;
+       adev->pcie_rreg64_ext = &amdgpu_invalid_rreg64_ext;
+       adev->pcie_wreg64_ext = &amdgpu_invalid_wreg64_ext;
        adev->uvd_ctx_rreg = &amdgpu_invalid_rreg;
        adev->uvd_ctx_wreg = &amdgpu_invalid_wreg;
        adev->didt_rreg = &amdgpu_invalid_rreg; diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c
index c45721ca916e40..63dadd72d2ecf4 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15.c
+++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
@@ -919,6 +919,8 @@ static int soc15_common_early_init(void *handle)
        adev->pcie_wreg_ext = &amdgpu_device_indirect_wreg_ext;
        adev->pcie_rreg64 = &amdgpu_device_indirect_rreg64;
        adev->pcie_wreg64 = &amdgpu_device_indirect_wreg64;
+       adev->pcie_rreg64_ext = &amdgpu_device_indirect_rreg64_ext;
+       adev->pcie_wreg64_ext = &amdgpu_device_indirect_wreg64_ext;
        adev->uvd_ctx_rreg = &soc15_uvd_ctx_rreg;
        adev->uvd_ctx_wreg = &soc15_uvd_ctx_wreg;
        adev->didt_rreg = &soc15_didt_rreg;
--
2.25.1



More information about the amd-gfx mailing list