Commit 6b1ff3dd authored by Trigger Huang's avatar Trigger Huang Committed by Alex Deucher
Browse files

drm/amdgpu: add basic func for RLC program reg



New feature for RLC, some registers can be programmed by
RLC interface under SR-IOV VF:

WREG32_SOC15_RLC_SHADOW:
	1, for GRBM_GFX_CNTL, firstly the new register value should be be
		programmed to SCRATCH_REG2
	1, for GRBM_GFX_INDEX, firstly the new register value should be be
		programmed to SCRATCH_REG3

WREG32_RLC:
	for registers supported to be programmed by RLC interface, the
	following sequence should be used:
		1, write the value to SCRATCH_REG0
		2, write reg | 0x80000000 to SCRATCH_REG1
		3, write 0x1 to RLC_SPARE_INT to notify RLC
		4, polling SCRATCH_REG1 to check if finished

Signed-off-by: default avatarTrigger Huang <Trigger.Huang@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 98cad2de
Loading
Loading
Loading
Loading
+56 −1
Original line number Diff line number Diff line
@@ -89,6 +89,61 @@
			(sram_sel << UVD_DPG_LMA_CTL__SRAM_SEL__SHIFT)); \
	} while (0)

#endif

#define WREG32_RLC(reg, value) \
	do {							\
		if (amdgpu_virt_support_rlc_prg_reg(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); \
		}	\
	} 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_virt_support_rlc_prg_reg(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); \
		}	\
	} while (0)

#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); \
	} 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))

#define WREG32_SOC15_OFFSET_RLC(ip, inst, reg, offset, value) \
    WREG32_RLC(((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset), value)

#endif