Commit 1a856863 authored by Likun Gao's avatar Likun Gao Committed by Alex Deucher
Browse files

drm/amdgpu: adjust xcc_cp_resume function for gfx_v12_1



Adjust gfx_v12_1_xcc_cp_resume function to program
cp resume per xcc_id (logic xcc number) to fix for
xcp_resume.
V2: Allocate compute microcode bo when sw init

Signed-off-by: default avatarLikun Gao <Likun.Gao@amd.com>
Reviewed-by: default avatarLijo Lazar <lijo.lazar@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent bf93f1fe
Loading
Loading
Loading
Loading
+135 −109
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ static void gfx_v12_1_update_perf_clk(struct amdgpu_device *adev,
				      bool enable);
static void gfx_v12_1_xcc_update_perf_clk(struct amdgpu_device *adev,
					 bool enable, int xcc_id);
static int gfx_v12_1_init_cp_compute_microcode_bo(struct amdgpu_device *adev);

static void gfx_v12_1_kiq_set_resources(struct amdgpu_ring *kiq_ring,
					uint64_t queue_mask)
@@ -1245,6 +1246,10 @@ static int gfx_v12_1_sw_init(struct amdgpu_ip_block *ip_block)
		r = gfx_v12_1_rlc_autoload_buffer_init(adev);
		if (r)
			return r;
	} else if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) {
		r = gfx_v12_1_init_cp_compute_microcode_bo(adev);
		if (r)
			return r;
	}

	r = gfx_v12_1_gpu_early_init(adev);
@@ -1919,15 +1924,13 @@ static void gfx_v12_1_xcc_cp_compute_enable(struct amdgpu_device *adev,
	udelay(50);
}

static int gfx_v12_1_xcc_cp_compute_load_microcode_rs64(struct amdgpu_device *adev,
							uint16_t xcc_mask)
static int gfx_v12_1_init_cp_compute_microcode_bo(struct amdgpu_device *adev)
{
	const struct gfx_firmware_header_v2_0 *mec_hdr;
	const __le32 *fw_ucode, *fw_data;
	u32 tmp, fw_ucode_size, fw_data_size;
	u32 i, usec_timeout = 50000; /* Wait for 50 ms */
	u32 fw_ucode_size, fw_data_size;
	u32 *fw_ucode_ptr, *fw_data_ptr;
	int r, xcc_id;
	int i, r, xcc_id;

	if (!adev->gfx.mec_fw)
		return -EINVAL;
@@ -1943,6 +1946,7 @@ static int gfx_v12_1_xcc_cp_compute_load_microcode_rs64(struct amdgpu_device *ad
				le32_to_cpu(mec_hdr->data_offset_bytes));
	fw_data_size = le32_to_cpu(mec_hdr->data_size_bytes);

	if (adev->gfx.mec.mec_fw_obj == NULL) {
		r = amdgpu_bo_create_reserved(adev, fw_ucode_size,
					      64 * 1024, AMDGPU_GEM_DOMAIN_VRAM,
					      &adev->gfx.mec.mec_fw_obj,
@@ -1954,21 +1958,27 @@ static int gfx_v12_1_xcc_cp_compute_load_microcode_rs64(struct amdgpu_device *ad
			return r;
		}

		memcpy(fw_ucode_ptr, fw_ucode, fw_ucode_size);

		amdgpu_bo_kunmap(adev->gfx.mec.mec_fw_obj);
		amdgpu_bo_unreserve(adev->gfx.mec.mec_fw_obj);
	}

	if (adev->gfx.mec.mec_fw_data_obj == NULL) {
		r = amdgpu_bo_create_reserved(adev,
					      ALIGN(fw_data_size, 64 * 1024) *
				      adev->gfx.mec.num_pipe_per_mec * NUM_XCC(xcc_mask),
					      adev->gfx.mec.num_pipe_per_mec * NUM_XCC(adev->gfx.xcc_mask),
					      64 * 1024, AMDGPU_GEM_DOMAIN_VRAM,
					      &adev->gfx.mec.mec_fw_data_obj,
					      &adev->gfx.mec.mec_fw_data_gpu_addr,
					      (void **)&fw_data_ptr);
		if (r) {
		dev_err(adev->dev, "(%d) failed to create mec fw ucode bo\n", r);
			dev_err(adev->dev, "(%d) failed to create mec fw data bo\n", r);
			gfx_v12_1_mec_fini(adev);
			return r;
		}

	memcpy(fw_ucode_ptr, fw_ucode, fw_ucode_size);
	for (xcc_id = 0; xcc_id < NUM_XCC(xcc_mask); xcc_id++) {
		for (xcc_id = 0; xcc_id < NUM_XCC(adev->gfx.xcc_mask); xcc_id++) {
			for (i = 0; i < adev->gfx.mec.num_pipe_per_mec; i++) {
				u32 offset = (xcc_id * adev->gfx.mec.num_pipe_per_mec + i) *
					     ALIGN(fw_data_size, 64 * 1024) / 4;
@@ -1976,12 +1986,26 @@ static int gfx_v12_1_xcc_cp_compute_load_microcode_rs64(struct amdgpu_device *ad
			}
		}

	amdgpu_bo_kunmap(adev->gfx.mec.mec_fw_obj);
		amdgpu_bo_kunmap(adev->gfx.mec.mec_fw_data_obj);
	amdgpu_bo_unreserve(adev->gfx.mec.mec_fw_obj);
		amdgpu_bo_unreserve(adev->gfx.mec.mec_fw_data_obj);
	}

	return 0;
}

static int gfx_v12_1_xcc_cp_compute_load_microcode_rs64(struct amdgpu_device *adev,
							int xcc_id)
{
	const struct gfx_firmware_header_v2_0 *mec_hdr;
	u32 fw_data_size;
	u32 tmp, i, usec_timeout = 50000; /* Wait for 50 ms */

	if (!adev->gfx.mec_fw)
		return -EINVAL;

	mec_hdr = (const struct gfx_firmware_header_v2_0 *)adev->gfx.mec_fw->data;
	fw_data_size = le32_to_cpu(mec_hdr->data_size_bytes);

	for (xcc_id = 0; xcc_id < NUM_XCC(xcc_mask); xcc_id++) {
	gfx_v12_1_xcc_cp_compute_enable(adev, false, xcc_id);

	tmp = RREG32_SOC15(GC, GET_INST(GC, xcc_id), regCP_CPC_IC_BASE_CNTL);
@@ -2031,7 +2055,7 @@ static int gfx_v12_1_xcc_cp_compute_load_microcode_rs64(struct amdgpu_device *ad
	}

	if (i >= usec_timeout) {
			dev_err(adev->dev, "failed to invalidate instruction cache\n");
		dev_err(adev->dev, "failed to invalidate data cache\n");
		return -EINVAL;
	}

@@ -2055,7 +2079,6 @@ static int gfx_v12_1_xcc_cp_compute_load_microcode_rs64(struct amdgpu_device *ad
	}

	gfx_v12_1_xcc_set_mec_ucode_start_addr(adev, xcc_id);
	}

	return 0;
}
@@ -2460,14 +2483,14 @@ static int gfx_v12_1_xcc_cp_resume(struct amdgpu_device *adev, uint16_t xcc_mask
	int r, i, xcc_id;
	struct amdgpu_ring *ring;

	for_each_inst(xcc_id, xcc_mask) {
		if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) {
			/* legacy firmware loading */
		r = gfx_v12_1_xcc_cp_compute_load_microcode_rs64(adev, xcc_mask);
			r = gfx_v12_1_xcc_cp_compute_load_microcode_rs64(adev, xcc_id);
			if (r)
				return r;
		}

	for (xcc_id = 0; xcc_id < NUM_XCC(xcc_mask); xcc_id++) {
		if (!(adev->flags & AMD_IS_APU))
			gfx_v12_1_xcc_enable_gui_idle_interrupt(adev, false, xcc_id);

@@ -2500,6 +2523,7 @@ static int gfx_v12_1_xcc_cp_resume(struct amdgpu_device *adev, uint16_t xcc_mask
static int gfx_v12_1_cp_resume(struct amdgpu_device *adev)
{
	int num_xcc, num_xcp, num_xcc_per_xcp;
	uint16_t xcc_mask;
	int r = 0;

	num_xcc = NUM_XCC(adev->gfx.xcc_mask);
@@ -2531,7 +2555,9 @@ static int gfx_v12_1_cp_resume(struct amdgpu_device *adev)
	if (r)
		return r;

	return gfx_v12_1_xcc_cp_resume(adev, adev->gfx.xcc_mask);
	xcc_mask = GENMASK(NUM_XCC(adev->gfx.xcc_mask) - 1, 0);

	return gfx_v12_1_xcc_cp_resume(adev, xcc_mask);
}

static int gfx_v12_1_gfxhub_enable(struct amdgpu_device *adev)