Commit a5504e9a authored by Peng Ju Zhou's avatar Peng Ju Zhou Committed by Alex Deucher
Browse files

drm/amdgpu: Indirect register access for Navi12 sriov



This patch series are used for GC/MMHUB(part)/IH_RB_CNTL
indirect access in the SRIOV environment.

There are 4 bits, controlled by host, to control
if GC/MMHUB(part)/IH_RB_CNTL indirect access enabled.
(one bit is master bit controls other 3 bits)

For GC registers, changing all the register access from MMIO to
RLC and use RLC as the default access method in the full access time.

For partial MMHUB registers, changing their access from MMIO to
RLC in the full access time, the remaining registers
keep the original access method.

For IH_RB_CNTL register, changing it's access from MMIO to PSP.

Signed-off-by: default avatarPeng Ju Zhou <PengJu.Zhou@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 9256e542
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1144,6 +1144,7 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
 * Registers read & write functions.
 */
#define AMDGPU_REGS_NO_KIQ    (1<<1)
#define AMDGPU_REGS_RLC	(1<<2)

#define RREG32_NO_KIQ(reg) amdgpu_device_rreg(adev, (reg), AMDGPU_REGS_NO_KIQ)
#define WREG32_NO_KIQ(reg, v) amdgpu_device_wreg(adev, (reg), (v), AMDGPU_REGS_NO_KIQ)
+1 −1
Original line number Diff line number Diff line
@@ -491,7 +491,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, 0);
			return adev->gfx.rlc.funcs->rlcg_wreg(adev, reg, v, 0, 0);
	} else {
		writel(v, ((void __iomem *)adev->rmmio) + (reg * 4));
	}
+2 −2
Original line number Diff line number Diff line
@@ -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 acc_flags, u32 hwip);
	u32 (*rlcg_rreg)(struct amdgpu_device *adev, u32 offset, u32 acc_flags, u32 hwip);
	bool (*is_rlcg_access_range)(struct amdgpu_device *adev, uint32_t reg);
};

+37 −41
Original line number Diff line number Diff line
@@ -1432,40 +1432,38 @@ static const struct soc15_reg_golden golden_settings_gc_10_1_2[] =
	SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0xffffffff, 0x00c00000)
};

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;
static bool gfx_v10_get_rlcg_flag(struct amdgpu_device *adev, u32 acc_flags, u32 hwip,
				 int write, u32 *rlcg_flag)
{
	switch (hwip) {
	case GC_HWIP:
		if (amdgpu_sriov_reg_indirect_gc(adev)) {
			*rlcg_flag = write ? GFX_RLCG_GC_WRITE : GFX_RLCG_GC_READ;

			return true;
	}
		/* only in new version, AMDGPU_REGS_NO_KIQ and AMDGPU_REGS_RLC enabled simultaneously */
		} else if ((acc_flags & AMDGPU_REGS_RLC) && !(acc_flags & AMDGPU_REGS_NO_KIQ)) {
			*rlcg_flag = GFX_RLCG_GC_WRITE_OLD;

	/* 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;
		}

		break;
	case MMHUB_HWIP:
		if (amdgpu_sriov_reg_indirect_mmhub(adev) &&
		    (acc_flags & AMDGPU_REGS_RLC) && write) {
			*rlcg_flag = GFX_RLCG_MMHUB_WRITE;
			return true;
		}

		break;
	default:
		DRM_DEBUG("Not program register by RLCG\n");
	}

	return false;
}

static u32 gfx_v10_rlcg_rw(struct amdgpu_device *adev, u32 offset, u32 v, uint32_t flag)
{
	static void *scratch_reg0;
@@ -1523,36 +1521,34 @@ 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 acc_flags, u32 hwip)
{
	uint32_t rlcg_flag;
	u32 rlcg_flag;

	if (amdgpu_sriov_fullaccess(adev) &&
	    gfx_v10_is_rlcg_rw(adev, offset, &rlcg_flag, 1)) {
	if (!amdgpu_sriov_runtime(adev) &&
	    gfx_v10_get_rlcg_flag(adev, acc_flags, hwip, 1, &rlcg_flag)) {
		gfx_v10_rlcg_rw(adev, offset, value, rlcg_flag);

		return;
	}
	if (flag & AMDGPU_REGS_NO_KIQ)

	if (acc_flags & 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)
static u32 gfx_v10_rlcg_rreg(struct amdgpu_device *adev, u32 offset, u32 acc_flags, u32 hwip)
{
	uint32_t rlcg_flag;
	u32 rlcg_flag;

	if (amdgpu_sriov_fullaccess(adev) &&
	    gfx_v10_is_rlcg_rw(adev, offset, &rlcg_flag, 0))
	if (!amdgpu_sriov_runtime(adev) &&
	    gfx_v10_get_rlcg_flag(adev, acc_flags, hwip, 0, &rlcg_flag))
		return gfx_v10_rlcg_rw(adev, offset, 0, rlcg_flag);

	if (flag & AMDGPU_REGS_NO_KIQ)
	if (acc_flags & 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[] =
+5 −4
Original line number Diff line number Diff line
@@ -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_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 flag)
static void gfx_v9_0_rlcg_w(struct amdgpu_device *adev, u32 offset, u32 v, u32 flag)
{
	static void *scratch_reg0;
	static void *scratch_reg1;
@@ -787,15 +787,16 @@ static void gfx_v9_0_rlcg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32

}

static void gfx_v9_0_rlcg_wreg(struct amdgpu_device *adev, u32 offset, u32 v, u32 flag)
static void gfx_v9_0_rlcg_wreg(struct amdgpu_device *adev, u32 offset,
			       u32 v, u32 acc_flags, u32 hwip)
{
	if (amdgpu_sriov_fullaccess(adev)) {
		gfx_v9_0_rlcg_rw(adev, offset, v, flag);
		gfx_v9_0_rlcg_w(adev, offset, v, acc_flags);

		return;
	}

	if (flag & AMDGPU_REGS_NO_KIQ)
	if (acc_flags & AMDGPU_REGS_NO_KIQ)
		WREG32_NO_KIQ(offset, v);
	else
		WREG32(offset, v);
Loading