[PATCH v2 01/12] drm/amdgpu: Indirect register access for Navi12 sriov
Peng Ju Zhou
PengJu.Zhou at amd.com
Thu Apr 29 10:26:33 UTC 2021
Change RLCG/SOC15 register access interface to triage
GC/MMHUB access from MMIO to RLCG.
Signed-off-by: Peng Ju Zhou <PengJu.Zhou at amd.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h | 4 +-
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 68 ++++----------
drivers/gpu/drm/amd/amdgpu/soc15_common.h | 109 +++++++++++++++-------
3 files changed, 95 insertions(+), 86 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h
index 4fc2ce8ce8ab..8193bd04b4b9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h
@@ -127,8 +127,8 @@ struct amdgpu_rlc_funcs {
void (*reset)(struct amdgpu_device *adev);
void (*start)(struct amdgpu_device *adev);
void (*update_spm_vmid)(struct amdgpu_device *adev, unsigned vmid);
- void (*rlcg_wreg)(struct amdgpu_device *adev, u32 offset, u32 v, u32 flag);
- u32 (*rlcg_rreg)(struct amdgpu_device *adev, u32 offset, u32 flag);
+ void (*rlcg_wreg)(struct amdgpu_device *adev, u32 offset, u32 v, u32 hwip);
+ u32 (*rlcg_rreg)(struct amdgpu_device *adev, u32 offset, u32 hwip);
bool (*is_rlcg_access_range)(struct amdgpu_device *adev, uint32_t reg);
};
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
index 49fd10a15707..9320d44a67bc 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
@@ -1427,38 +1427,25 @@ static const struct soc15_reg_golden golden_settings_gc_10_1_2[] =
SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0xffffffff, 0x00800000)
};
-static bool gfx_v10_is_rlcg_rw(struct amdgpu_device *adev, u32 offset, uint32_t *flag, bool write)
-{
- /* always programed by rlcg, only for gc */
- if (offset == SOC15_REG_OFFSET(GC, 0, mmRLC_CSIB_ADDR_HI) ||
- offset == SOC15_REG_OFFSET(GC, 0, mmRLC_CSIB_ADDR_LO) ||
- offset == SOC15_REG_OFFSET(GC, 0, mmRLC_CSIB_LENGTH) ||
- offset == SOC15_REG_OFFSET(GC, 0, mmGRBM_GFX_CNTL) ||
- offset == SOC15_REG_OFFSET(GC, 0, mmGRBM_GFX_INDEX) ||
- offset == SOC15_REG_OFFSET(GC, 0, mmCP_ME_CNTL)) {
- if (!amdgpu_sriov_reg_indirect_gc(adev))
- *flag = GFX_RLCG_GC_WRITE_OLD;
- else
- *flag = write ? GFX_RLCG_GC_WRITE : GFX_RLCG_GC_READ;
-
- return true;
- }
+static u32 gfx_v10_get_rlcg_flag(struct amdgpu_device *adev, u32 hwip, int write)
+{
+ u32 flag = -1;
- /* currently support gc read/write, mmhub write */
- if (offset >= SOC15_REG_OFFSET(GC, 0, mmSDMA0_DEC_START) &&
- offset <= SOC15_REG_OFFSET(GC, 0, mmRLC_GTS_OFFSET_MSB)) {
+ if (hwip == GC_HWIP) {
if (amdgpu_sriov_reg_indirect_gc(adev))
- *flag = write ? GFX_RLCG_GC_WRITE : GFX_RLCG_GC_READ;
+ flag = write ? GFX_RLCG_GC_WRITE : GFX_RLCG_GC_READ;
else
- return false;
+ flag = GFX_RLCG_GC_WRITE_OLD;
} else {
+ ASSERT(write);
if (amdgpu_sriov_reg_indirect_mmhub(adev))
- *flag = GFX_RLCG_MMHUB_WRITE;
- else
- return false;
+ flag = GFX_RLCG_MMHUB_WRITE;
}
- return true;
+ if (flag == -1)
+ DRM_ERROR("amdgpu: failed to get RLCG flag, IP 0x%x\n", hwip);
+
+ return flag;
}
static u32 gfx_v10_rlcg_rw(struct amdgpu_device *adev, u32 offset, u32 v, uint32_t flag)
@@ -1518,36 +1505,21 @@ static u32 gfx_v10_rlcg_rw(struct amdgpu_device *adev, u32 offset, u32 v, uint32
return ret;
}
-static void gfx_v10_rlcg_wreg(struct amdgpu_device *adev, u32 offset, u32 value, u32 flag)
+static void gfx_v10_rlcg_wreg(struct amdgpu_device *adev, u32 offset, u32 value, u32 hwip)
{
- uint32_t rlcg_flag;
-
- if (amdgpu_sriov_fullaccess(adev) &&
- gfx_v10_is_rlcg_rw(adev, offset, &rlcg_flag, 1)) {
- gfx_v10_rlcg_rw(adev, offset, value, rlcg_flag);
+ u32 rlcg_flag;
- return;
- }
- if (flag & AMDGPU_REGS_NO_KIQ)
- WREG32_NO_KIQ(offset, value);
- else
- WREG32(offset, value);
+ rlcg_flag = gfx_v10_get_rlcg_flag(adev, hwip, 1);
+ gfx_v10_rlcg_rw(adev, offset, value, rlcg_flag);
}
-static u32 gfx_v10_rlcg_rreg(struct amdgpu_device *adev, u32 offset, u32 flag)
+static u32 gfx_v10_rlcg_rreg(struct amdgpu_device *adev, u32 offset, u32 hwip)
{
- uint32_t rlcg_flag;
-
- if (amdgpu_sriov_fullaccess(adev) &&
- gfx_v10_is_rlcg_rw(adev, offset, &rlcg_flag, 0))
- return gfx_v10_rlcg_rw(adev, offset, 0, rlcg_flag);
+ u32 rlcg_flag;
- if (flag & AMDGPU_REGS_NO_KIQ)
- return RREG32_NO_KIQ(offset);
- else
- return RREG32(offset);
+ rlcg_flag = gfx_v10_get_rlcg_flag(adev, hwip, 0);
- return 0;
+ return gfx_v10_rlcg_rw(adev, offset, 0, rlcg_flag);
}
static const struct soc15_reg_golden golden_settings_gc_10_1_nv14[] =
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15_common.h b/drivers/gpu/drm/amd/amdgpu/soc15_common.h
index 14bd794bbea6..16b659596dd6 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15_common.h
+++ b/drivers/gpu/drm/amd/amdgpu/soc15_common.h
@@ -27,28 +27,73 @@
/* Register Access Macros */
#define SOC15_REG_OFFSET(ip, inst, reg) (adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg)
+#define RLC_GC_EN(hwip) \
+ (amdgpu_sriov_fullaccess(adev) && \
+ (amdgpu_sriov_reg_indirect_gc(adev) && (hwip == GC_HWIP)))
+
+#define RLC_MMHUB_EN(hwip, write) \
+ (amdgpu_sriov_fullaccess(adev) && \
+ (amdgpu_sriov_reg_indirect_mmhub(adev) && \
+ (hwip == MMHUB_HWIP) && \
+ (write)))
+
+#define __WREG32_SOC15_RLC__(reg, value, hwip) \
+ ((((hwip == GC_HWIP) || ((hwip == MMHUB_HWIP) && RLC_MMHUB_EN(hwip, 1))) && \
+ amdgpu_sriov_vf(adev) && adev->gfx.rlc.funcs->rlcg_wreg) ? \
+ adev->gfx.rlc.funcs->rlcg_wreg(adev, reg, value, hwip) : \
+ WREG32(reg, value))
+
+#define __RREG32_SOC15_RLC__(reg, hwip) \
+ ((amdgpu_sriov_vf(adev) && adev->gfx.rlc.funcs->rlcg_rreg) ? \
+ adev->gfx.rlc.funcs->rlcg_rreg(adev, reg, hwip) : \
+ RREG32(reg))
+
+#define __WREG32_SOC15__(reg, value, hwip) \
+ (RLC_GC_EN(hwip) ? \
+ __WREG32_SOC15_RLC__(reg, value, hwip) : \
+ WREG32(reg, value))
+
+#define __RREG32_SOC15__(reg, hwip) \
+ (RLC_GC_EN(hwip) ? \
+ __RREG32_SOC15_RLC__(reg, hwip) : \
+ RREG32(reg))
+
#define WREG32_FIELD15(ip, idx, reg, field, val) \
- WREG32(adev->reg_offset[ip##_HWIP][idx][mm##reg##_BASE_IDX] + mm##reg, \
- (RREG32(adev->reg_offset[ip##_HWIP][idx][mm##reg##_BASE_IDX] + mm##reg) \
- & ~REG_FIELD_MASK(reg, field)) | (val) << REG_FIELD_SHIFT(reg, field))
+ __WREG32_SOC15__(adev->reg_offset[ip##_HWIP][idx][mm##reg##_BASE_IDX] + mm##reg, \
+ (__RREG32_SOC15__( \
+ adev->reg_offset[ip##_HWIP][idx][mm##reg##_BASE_IDX] + mm##reg, \
+ ip##_HWIP) & \
+ ~REG_FIELD_MASK(reg, field)) | (val) << REG_FIELD_SHIFT(reg, field), \
+ ip##_HWIP)
#define RREG32_SOC15(ip, inst, reg) \
- RREG32(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg)
+ __RREG32_SOC15__(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg, ip##_HWIP)
+
+#define RREG32_SOC15_IP(ip, reg) __RREG32_SOC15__(reg, ip##_HWIP)
#define RREG32_SOC15_NO_KIQ(ip, inst, reg) \
- RREG32_NO_KIQ(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg)
+ ((RLC_GC_EN(ip##_HWIP) && adev->gfx.rlc.funcs->rlcg_rreg) ? \
+ adev->gfx.rlc.funcs->rlcg_rreg(adev, reg, ip##_HWIP) : \
+ RREG32_NO_KIQ(reg, value))
#define RREG32_SOC15_OFFSET(ip, inst, reg, offset) \
- RREG32((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset)
+ __RREG32_SOC15__((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset, ip##_HWIP)
#define WREG32_SOC15(ip, inst, reg, value) \
- WREG32((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg), value)
+ __WREG32_SOC15__((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg), \
+ value, ip##_HWIP)
+
+#define WREG32_SOC15_IP(ip, reg, value) \
+ __WREG32_SOC15__(reg, value, ip##_HWIP)
#define WREG32_SOC15_NO_KIQ(ip, inst, reg, value) \
- WREG32_NO_KIQ((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg), value)
+ ((RLC_GC_EN(ip##_HWIP) && adev->gfx.rlc.funcs->rlcg_wreg) ? \
+ adev->gfx.rlc.funcs->rlcg_wreg(adev, reg, value, ip##_HWIP) : \
+ WREG32_NO_KIQ(reg, value))
#define WREG32_SOC15_OFFSET(ip, inst, reg, offset, value) \
- WREG32((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset, value)
+ __WREG32_SOC15__((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset, \
+ value, ip##_HWIP)
#define SOC15_WAIT_ON_RREG(ip, inst, reg, expected_value, mask) \
({ int ret = 0; \
@@ -77,12 +122,7 @@
})
#define WREG32_RLC(reg, value) \
- do { \
- if (adev->gfx.rlc.funcs->rlcg_wreg) \
- adev->gfx.rlc.funcs->rlcg_wreg(adev, reg, value, 0); \
- else \
- WREG32(reg, value); \
- } while (0)
+ __WREG32_SOC15_RLC__(reg, value, GC_HWIP)
#define WREG32_RLC_EX(prefix, reg, value) \
do { \
@@ -108,24 +148,21 @@
} \
} while (0)
+/* shadow the registers in the callback function */
#define WREG32_SOC15_RLC_SHADOW(ip, inst, reg, value) \
- WREG32_RLC((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg), value)
+ __WREG32_SOC15_RLC__((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg), value, GC_HWIP)
+/* for GC only */
#define RREG32_RLC(reg) \
- (adev->gfx.rlc.funcs->rlcg_rreg ? \
- adev->gfx.rlc.funcs->rlcg_rreg(adev, reg, 0) : RREG32(reg))
-
-#define WREG32_RLC_NO_KIQ(reg, value) \
- do { \
- if (adev->gfx.rlc.funcs->rlcg_wreg) \
- adev->gfx.rlc.funcs->rlcg_wreg(adev, reg, value, AMDGPU_REGS_NO_KIQ); \
- else \
- WREG32_NO_KIQ(reg, value); \
- } while (0)
+ __RREG32_SOC15_RLC__(reg, GC_HWIP)
+
+#define WREG32_RLC_NO_KIQ(reg, value, hwip) \
+ (((RLC_GC_EN(hwip) || RLC_MMHUB_EN(hwip, 1)) && adev->gfx.rlc.funcs->rlcg_wreg) ? \
+ adev->gfx.rlc.funcs->rlcg_wreg(adev, reg, value, hwip) : WREG32_NO_KIQ(reg, value))
-#define RREG32_RLC_NO_KIQ(reg) \
- (adev->gfx.rlc.funcs->rlcg_rreg ? \
- adev->gfx.rlc.funcs->rlcg_rreg(adev, reg, AMDGPU_REGS_NO_KIQ) : RREG32_NO_KIQ(reg))
+#define RREG32_RLC_NO_KIQ(reg, hwip) \
+ (((RLC_GC_EN(hwip) || RLC_MMHUB_EN(hwip, 0)) && adev->gfx.rlc.funcs->rlcg_rreg) ? \
+ adev->gfx.rlc.funcs->rlcg_rreg(adev, reg, hwip) : RREG32_NO_KIQ(reg))
#define WREG32_SOC15_RLC_SHADOW_EX(prefix, ip, inst, reg, value) \
do { \
@@ -146,12 +183,12 @@
} while (0)
#define RREG32_SOC15_RLC(ip, inst, reg) \
- RREG32_RLC(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg)
+ __RREG32_SOC15_RLC__(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg, ip##_HWIP)
#define WREG32_SOC15_RLC(ip, inst, reg, value) \
do { \
uint32_t target_reg = adev->reg_offset[ip##_HWIP][0][reg##_BASE_IDX] + reg;\
- WREG32_RLC(target_reg, value); \
+ __WREG32_SOC15_RLC__(target_reg, value, ip##_HWIP); \
} while (0)
#define WREG32_SOC15_RLC_EX(prefix, ip, inst, reg, value) \
@@ -161,14 +198,14 @@
} while (0)
#define WREG32_FIELD15_RLC(ip, idx, reg, field, val) \
- WREG32_RLC((adev->reg_offset[ip##_HWIP][idx][mm##reg##_BASE_IDX] + mm##reg), \
- (RREG32_RLC(adev->reg_offset[ip##_HWIP][idx][mm##reg##_BASE_IDX] + mm##reg) \
- & ~REG_FIELD_MASK(reg, field)) | (val) << REG_FIELD_SHIFT(reg, field))
+ __WREG32_SOC15_RLC__((adev->reg_offset[ip##_HWIP][idx][mm##reg##_BASE_IDX] + mm##reg), \
+ (__RREG32_SOC15_RLC__(adev->reg_offset[ip##_HWIP][idx][mm##reg##_BASE_IDX] + mm##reg, ip##_HWIP) \
+ & ~REG_FIELD_MASK(reg, field)) | (val) << REG_FIELD_SHIFT(reg, field), ip##_HWIP)
#define WREG32_SOC15_OFFSET_RLC(ip, inst, reg, offset, value) \
- WREG32_RLC(((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset), value)
+ __WREG32_SOC15_RLC__((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset, value, ip##_HWIP)
#define RREG32_SOC15_OFFSET_RLC(ip, inst, reg, offset) \
- RREG32_RLC(((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset))
+ __RREG32_SOC15_RLC__((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset, ip##_HWIP)
#endif
--
2.17.1
More information about the amd-gfx
mailing list