Commit 8ed49dd1 authored by Victor Lu's avatar Victor Lu Committed by Alex Deucher
Browse files

drm/amdgpu: Add RLCG interface driver implementation for gfx v9.4.3 (v3)



Add RLCG interface support for gfx v9.4.3 and multiple XCCs.
Do not enable it yet.

v2: Fix amdgpu_rlcg_reg_access_ctrl init, add support for multiple XCCs
    in amdgpu_mm_wreg_mmio_rlc

v3: Use GET_INST() when indexing amdgpu_rlcg_reg_access_ctrl

Signed-off-by: default avatarVictor Lu <victorchengchi.lu@amd.com>
Reviewed-by: default avatarZhigang Luo <zhigang.luo@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 4a8e0f95
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1128,7 +1128,7 @@ void amdgpu_device_wreg(struct amdgpu_device *adev,
void amdgpu_device_indirect_wreg_ext(struct amdgpu_device *adev,
				     u64 reg_addr, u32 reg_data);
void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev,
			     uint32_t reg, uint32_t v);
			     uint32_t reg, uint32_t v, uint32_t xcc_id);
void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value);
uint8_t amdgpu_mm_rreg8(struct amdgpu_device *adev, uint32_t offset);

+2 −2
Original line number Diff line number Diff line
@@ -154,7 +154,7 @@ static int amdgpu_debugfs_process_reg_op(bool read, struct file *f,
		} else {
			r = get_user(value, (uint32_t *)buf);
			if (!r)
				amdgpu_mm_wreg_mmio_rlc(adev, *pos >> 2, value);
				amdgpu_mm_wreg_mmio_rlc(adev, *pos >> 2, value, 0);
		}
		if (r) {
			result = r;
@@ -283,7 +283,7 @@ static ssize_t amdgpu_debugfs_regs2_op(struct file *f, char __user *buf, u32 off
		} else {
			r = get_user(value, (uint32_t *)buf);
			if (!r)
				amdgpu_mm_wreg_mmio_rlc(adev, offset >> 2, value);
				amdgpu_mm_wreg_mmio_rlc(adev, offset >> 2, value, rd->id.xcc_id);
		}
		if (r) {
			result = r;
+3 −2
Original line number Diff line number Diff line
@@ -571,7 +571,8 @@ void amdgpu_device_wreg(struct amdgpu_device *adev,
 * this function is invoked only for the debugfs register access
 */
void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev,
			     uint32_t reg, uint32_t v)
			     uint32_t reg, uint32_t v,
			     uint32_t xcc_id)
{
	if (amdgpu_device_skip_hw_access(adev))
		return;
@@ -580,7 +581,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 amdgpu_sriov_wreg(adev, reg, v, 0, 0);
			return amdgpu_sriov_wreg(adev, reg, v, 0, 0, xcc_id);
	} else if ((reg * 4) >= adev->rmmio_size) {
		adev->pcie_wreg(adev, reg * 4, v);
	} else {
+4 −2
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@

#include "clearstate_defs.h"

#define AMDGPU_MAX_RLC_INSTANCES	8

/* firmware ID used in rlc toc */
typedef enum _FIRMWARE_ID_ {
	FIRMWARE_ID_INVALID					= 0,
@@ -201,7 +203,7 @@ struct amdgpu_rlc {
	u32                     cp_table_size;

	/* safe mode for updating CG/PG state */
	bool in_safe_mode[8];
	bool in_safe_mode[AMDGPU_MAX_RLC_INSTANCES];
	const struct amdgpu_rlc_funcs *funcs;

	/* for firmware data */
@@ -257,7 +259,7 @@ struct amdgpu_rlc {

	bool rlcg_reg_access_supported;
	/* registers for rlcg indirect reg access */
	struct amdgpu_rlcg_reg_access_ctrl reg_access_ctrl;
	struct amdgpu_rlcg_reg_access_ctrl reg_access_ctrl[AMDGPU_MAX_RLC_INSTANCES];
};

void amdgpu_gfx_rlc_enter_safe_mode(struct amdgpu_device *adev, int xcc_id);
+11 −6
Original line number Diff line number Diff line
@@ -954,7 +954,7 @@ static bool amdgpu_virt_get_rlcg_reg_access_flag(struct amdgpu_device *adev,
	return ret;
}

static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 flag)
static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 flag, u32 xcc_id)
{
	struct amdgpu_rlcg_reg_access_ctrl *reg_access_ctrl;
	uint32_t timeout = 50000;
@@ -972,7 +972,12 @@ static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v
		return 0;
	}

	reg_access_ctrl = &adev->gfx.rlc.reg_access_ctrl;
	if (adev->gfx.xcc_mask && (((1 << xcc_id) & adev->gfx.xcc_mask) == 0)) {
		dev_err(adev->dev, "invalid xcc\n");
		return 0;
	}

	reg_access_ctrl = &adev->gfx.rlc.reg_access_ctrl[xcc_id];
	scratch_reg0 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg0;
	scratch_reg1 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg1;
	scratch_reg2 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg2;
@@ -1037,13 +1042,13 @@ static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v

void amdgpu_sriov_wreg(struct amdgpu_device *adev,
		       u32 offset, u32 value,
		       u32 acc_flags, u32 hwip)
		       u32 acc_flags, u32 hwip, u32 xcc_id)
{
	u32 rlcg_flag;

	if (!amdgpu_sriov_runtime(adev) &&
		amdgpu_virt_get_rlcg_reg_access_flag(adev, acc_flags, hwip, true, &rlcg_flag)) {
		amdgpu_virt_rlcg_reg_rw(adev, offset, value, rlcg_flag);
		amdgpu_virt_rlcg_reg_rw(adev, offset, value, rlcg_flag, xcc_id);
		return;
	}

@@ -1054,13 +1059,13 @@ void amdgpu_sriov_wreg(struct amdgpu_device *adev,
}

u32 amdgpu_sriov_rreg(struct amdgpu_device *adev,
		      u32 offset, u32 acc_flags, u32 hwip)
		      u32 offset, u32 acc_flags, u32 hwip, u32 xcc_id)
{
	u32 rlcg_flag;

	if (!amdgpu_sriov_runtime(adev) &&
		amdgpu_virt_get_rlcg_reg_access_flag(adev, acc_flags, hwip, false, &rlcg_flag))
		return amdgpu_virt_rlcg_reg_rw(adev, offset, 0, rlcg_flag);
		return amdgpu_virt_rlcg_reg_rw(adev, offset, 0, rlcg_flag, xcc_id);

	if (acc_flags & AMDGPU_REGS_NO_KIQ)
		return RREG32_NO_KIQ(offset);
Loading