[AMD Official Use Only - Internal Distribution Only] Series Reviewed-by: Emily.Deng <Emily.Deng@xxxxxxx> >-----Original Message----- >From: amd-gfx <amd-gfx-bounces@xxxxxxxxxxxxxxxxxxxxx> On Behalf Of Peng >Ju Zhou >Sent: Wednesday, March 31, 2021 1:20 PM >To: amd-gfx@xxxxxxxxxxxxxxxxxxxxx >Cc: Zhao, Jiange <Jiange.Zhao@xxxxxxx> >Subject: [PATCH 4/4] drm/amdgpu: indirect register access for nv12 sriov > >1. expand rlcg interface for gc & mmhub indirect access 2. add rlcg interface >for no kiq > >Signed-off-by: Peng Ju Zhou <PengJu.Zhou@xxxxxxx> >--- > drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- > drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h | 3 +- > drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 131 ++++++++++++++++++--- > drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 2 +- > drivers/gpu/drm/amd/amdgpu/soc15_common.h | 75 ++++++------ > 5 files changed, 150 insertions(+), 63 deletions(-) > >diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c >b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c >index 060d0ae99453..438e2f732377 100644 >--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c >+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c >@@ -490,7 +490,7 @@ void amdgpu_mm_wreg_mmio_rlc(struct >amdgpu_device *adev, > adev->gfx.rlc.funcs && > adev->gfx.rlc.funcs->is_rlcg_access_range) { > if (adev->gfx.rlc.funcs->is_rlcg_access_range(adev, reg)) >-return adev->gfx.rlc.funcs->rlcg_wreg(adev, reg, v); >+return adev->gfx.rlc.funcs->rlcg_wreg(adev, reg, v, 0); > } else { > writel(v, ((void __iomem *)adev->rmmio) + (reg * 4)); > } >diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h >b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h >index aeaaae713c59..4fc2ce8ce8ab 100644 >--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h >+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h >@@ -127,7 +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); >+void (*rlcg_wreg)(struct amdgpu_device *adev, u32 offset, u32 v, u32 >flag); >+u32 (*rlcg_rreg)(struct amdgpu_device *adev, u32 offset, u32 flag); > 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 b4fd0394cd08..85a6a10e048f 100644 >--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c >+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c >@@ -177,6 +177,11 @@ > #define mmGC_THROTTLE_CTRL_Sienna_Cichlid 0x2030 > #define mmGC_THROTTLE_CTRL_Sienna_Cichlid_BASE_IDX 0 > >+#define GFX_RLCG_GC_WRITE_OLD(0x8 << 28) >+#define GFX_RLCG_GC_WRITE(0x0 << 28) >+#define GFX_RLCG_GC_READ(0x1 << 28) >+#define GFX_RLCG_MMHUB_WRITE(0x2 << 28) >+ > MODULE_FIRMWARE("amdgpu/navi10_ce.bin"); > MODULE_FIRMWARE("amdgpu/navi10_pfp.bin"); > MODULE_FIRMWARE("amdgpu/navi10_me.bin"); >@@ -1422,38 +1427,127 @@ static const struct soc15_reg_golden >golden_settings_gc_10_1_2[] = > SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0xffffffff, >0x00800000) }; > >-static void gfx_v10_rlcg_wreg(struct amdgpu_device *adev, u32 offset, u32 v) >+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; >+} >+ >+/* 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 (amdgpu_sriov_reg_indirect_gc(adev)) >+*flag = write ? GFX_RLCG_GC_WRITE : >GFX_RLCG_GC_READ; >+else >+return false; >+} else { >+if (amdgpu_sriov_reg_indirect_mmhub(adev)) >+*flag = GFX_RLCG_MMHUB_WRITE; >+else >+return false; >+} >+ >+return true; >+} >+ >+static u32 gfx_v10_rlcg_rw(struct amdgpu_device *adev, u32 offset, u32 >+v, uint32_t flag) > { > static void *scratch_reg0; > static void *scratch_reg1; >+static void *scratch_reg2; >+static void *scratch_reg3; > static void *spare_int; >+static uint32_t grbm_cntl; >+static uint32_t grbm_idx; > uint32_t i = 0; > uint32_t retries = 50000; >+u32 ret = 0; >+ >+scratch_reg0 = adev->rmmio + >+ (adev- >>reg_offset[GC_HWIP][0][mmSCRATCH_REG0_BASE_IDX] + >mmSCRATCH_REG0) * 4; >+scratch_reg1 = adev->rmmio + >+ (adev- >>reg_offset[GC_HWIP][0][mmSCRATCH_REG1_BASE_IDX] + >mmSCRATCH_REG1) * 4; >+scratch_reg2 = adev->rmmio + >+ (adev- >>reg_offset[GC_HWIP][0][mmSCRATCH_REG0_BASE_IDX] + >mmSCRATCH_REG2) * 4; >+scratch_reg3 = adev->rmmio + >+ (adev- >>reg_offset[GC_HWIP][0][mmSCRATCH_REG1_BASE_IDX] + >mmSCRATCH_REG3) * 4; >+spare_int = adev->rmmio + >+ (adev- >>reg_offset[GC_HWIP][0][mmRLC_SPARE_INT_BASE_IDX] + >+mmRLC_SPARE_INT) * 4; >+ >+grbm_cntl = adev- >>reg_offset[GC_HWIP][0][mmGRBM_GFX_CNTL_BASE_IDX] + >mmGRBM_GFX_CNTL; >+grbm_idx = adev- >>reg_offset[GC_HWIP][0][mmGRBM_GFX_INDEX_BASE_IDX] + >+mmGRBM_GFX_INDEX; >+ >+if (offset == grbm_cntl || offset == grbm_idx) { >+if (offset == grbm_cntl) >+writel(v, scratch_reg2); >+else if (offset == grbm_idx) >+writel(v, scratch_reg3); >+ >+writel(v, ((void __iomem *)adev->rmmio) + (offset * 4)); >+} else { >+writel(v, scratch_reg0); >+writel(offset | flag, scratch_reg1); >+writel(1, spare_int); >+for (i = 0; i < retries; i++) { >+u32 tmp; >+ >+tmp = readl(scratch_reg1); >+if (!(tmp & flag)) >+break; > >-scratch_reg0 = adev->rmmio + (adev- >>reg_offset[GC_HWIP][0][mmSCRATCH_REG0_BASE_IDX] + >mmSCRATCH_REG0)*4; >-scratch_reg1 = adev->rmmio + (adev- >>reg_offset[GC_HWIP][0][mmSCRATCH_REG1_BASE_IDX] + >mmSCRATCH_REG1)*4; >-spare_int = adev->rmmio + (adev- >>reg_offset[GC_HWIP][0][mmRLC_SPARE_INT_BASE_IDX] + >mmRLC_SPARE_INT)*4; >+udelay(10); >+} > >-if (amdgpu_sriov_runtime(adev)) { >-pr_err("shouldn't call rlcg write register during runtime\n"); >-return; >+if (i >= retries) >+pr_err("timeout: rlcg program reg:0x%05x failed !\n", >offset); > } > >-writel(v, scratch_reg0); >-writel(offset | 0x80000000, scratch_reg1); >-writel(1, spare_int); >-for (i = 0; i < retries; i++) { >-u32 tmp; >+ret = readl(scratch_reg0); > >-tmp = readl(scratch_reg1); >-if (!(tmp & 0x80000000)) >-break; >+return ret; >+} > >-udelay(10); >+static void gfx_v10_rlcg_wreg(struct amdgpu_device *adev, u32 offset, >+u32 value, u32 flag) { >+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); >+ >+return; > } >+if (flag & AMDGPU_REGS_NO_KIQ) >+WREG32_NO_KIQ(offset, value); >+else >+WREG32(offset, value); >+} >+ >+static u32 gfx_v10_rlcg_rreg(struct amdgpu_device *adev, u32 offset, >+u32 flag) { >+uint32_t rlcg_flag; > >-if (i >= retries) >-pr_err("timeout: rlcg program reg:0x%05x failed !\n", offset); >+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); >+ >+if (flag & AMDGPU_REGS_NO_KIQ) >+return RREG32_NO_KIQ(offset); >+else >+return RREG32(offset); >+ >+return 0; > } > > static const struct soc15_reg_golden golden_settings_gc_10_1_nv14[] = @@ - >7888,6 +7982,7 @@ static const struct amdgpu_rlc_funcs >gfx_v10_0_rlc_funcs_sriov = { > .start = gfx_v10_0_rlc_start, > .update_spm_vmid = gfx_v10_0_update_spm_vmid, > .rlcg_wreg = gfx_v10_rlcg_wreg, >+.rlcg_rreg = gfx_v10_rlcg_rreg, > .is_rlcg_access_range = gfx_v10_0_is_rlcg_access_range, }; > >diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c >b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c >index 99f58439f3d5..6e49b239087a 100644 >--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c >+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c >@@ -734,7 +734,7 @@ static const u32 >GFX_RLC_SRM_INDEX_CNTL_DATA_OFFSETS[] = > mmRLC_SRM_INDEX_CNTL_DATA_7 - >mmRLC_SRM_INDEX_CNTL_DATA_0, }; > >-static void gfx_v9_0_rlcg_wreg(struct amdgpu_device *adev, u32 offset, u32 v) >+void gfx_v9_0_rlcg_wreg(struct amdgpu_device *adev, u32 offset, u32 v, >+u32 flag) > { > static void *scratch_reg0; > static void *scratch_reg1; >diff --git a/drivers/gpu/drm/amd/amdgpu/soc15_common.h >b/drivers/gpu/drm/amd/amdgpu/soc15_common.h >index 8cdf5d1685cb..14bd794bbea6 100644 >--- a/drivers/gpu/drm/amd/amdgpu/soc15_common.h >+++ b/drivers/gpu/drm/amd/amdgpu/soc15_common.h >@@ -77,27 +77,11 @@ > }) > > #define WREG32_RLC(reg, value) \ >-do {\ >-if (amdgpu_sriov_fullaccess(adev)) { \ >-uint32_t i = 0;\ >-uint32_t retries = 50000;\ >-uint32_t r0 = adev- >>reg_offset[GC_HWIP][0][mmSCRATCH_REG0_BASE_IDX] + >mmSCRATCH_REG0;\ >-uint32_t r1 = adev- >>reg_offset[GC_HWIP][0][mmSCRATCH_REG1_BASE_IDX] + >mmSCRATCH_REG1;\ >-uint32_t spare_int = adev- >>reg_offset[GC_HWIP][0][mmRLC_SPARE_INT_BASE_IDX] + >mmRLC_SPARE_INT;\ >-WREG32(r0, value);\ >-WREG32(r1, (reg | 0x80000000));\ >-WREG32(spare_int, 0x1);\ >-for (i = 0; i < retries; i++) {\ >-u32 tmp = RREG32(r1);\ >-if (!(tmp & 0x80000000))\ >-break;\ >-udelay(10);\ >-}\ >-if (i >= retries)\ >-pr_err("timeout: rlcg program reg:0x%05x >failed !\n", reg);\ >-} else {\ >-WREG32(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) > > #define WREG32_RLC_EX(prefix, reg, value) \ @@ -125,23 +109,24 @@ > } while (0) > > #define WREG32_SOC15_RLC_SHADOW(ip, inst, reg, value) \ >-do {\ >-uint32_t target_reg = adev- >>reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg;\ >-if (amdgpu_sriov_fullaccess(adev)) { \ >-uint32_t r2 = adev- >>reg_offset[GC_HWIP][0][mmSCRATCH_REG1_BASE_IDX] + >mmSCRATCH_REG2;\ >-uint32_t r3 = adev- >>reg_offset[GC_HWIP][0][mmSCRATCH_REG1_BASE_IDX] + >mmSCRATCH_REG3;\ >-uint32_t grbm_cntl = adev- >>reg_offset[GC_HWIP][0][mmGRBM_GFX_CNTL_BASE_IDX] + >mmGRBM_GFX_CNTL; \ >-uint32_t grbm_idx = adev- >>reg_offset[GC_HWIP][0][mmGRBM_GFX_INDEX_BASE_IDX] + >mmGRBM_GFX_INDEX; \ >-if (target_reg == grbm_cntl) \ >-WREG32(r2, value);\ >-else if (target_reg == grbm_idx) \ >-WREG32(r3, value);\ >-WREG32(target_reg, value);\ >-} else {\ >-WREG32(target_reg, value); \ >-}\ >+WREG32_RLC((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + >reg), >+value) >+ >+#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) > >+#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 WREG32_SOC15_RLC_SHADOW_EX(prefix, ip, inst, reg, value) \ > do {\ > uint32_t target_reg = adev- >>reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg;\ @@ -160,10 +145,13 >@@ > }\ > } while (0) > >+#define RREG32_SOC15_RLC(ip, inst, reg) \ >+RREG32_RLC(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + >reg) >+ > #define WREG32_SOC15_RLC(ip, inst, reg, value) \ > do {\ >-uint32_t target_reg = adev- >>reg_offset[GC_HWIP][0][reg##_BASE_IDX] + reg;\ >-WREG32_RLC(target_reg, value); \ >+uint32_t target_reg = adev- >>reg_offset[ip##_HWIP][0][reg##_BASE_IDX] + reg;\ >+WREG32_RLC(target_reg, value); \ > } while (0) > > #define WREG32_SOC15_RLC_EX(prefix, ip, inst, reg, value) \ @@ -173,11 >+161,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(adev->reg_offset[ip##_HWIP][idx][mm##reg##_BASE_IDX] + >mm##reg) \ >- & ~REG_FIELD_MASK(reg, field)) | (val) << REG_FIELD_SHIFT(reg, field)) >+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)) > > #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_RLC(((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + >reg) >++ offset), value) >+ >+#define RREG32_SOC15_OFFSET_RLC(ip, inst, reg, offset) \ >+RREG32_RLC(((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + >reg) >++ offset)) > > #endif >-- >2.17.1 > >_______________________________________________ >amd-gfx mailing list >amd-gfx@xxxxxxxxxxxxxxxxxxxxx >https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.fr >eedesktop.org%2Fmailman%2Flistinfo%2Famd- >gfx&data=04%7C01%7CEmily.Deng%40amd.com%7C5418b86bcb4042c1a >b1c08d8f404c823%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C63 >7527648681476268%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAi >LCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=SIC >r%2FbhwrejJzpuhJmsnJiu6TP%2Fvu075po7%2BJ70Foec%3D&reserved=0 _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx