Commit a056771b authored by Michael Chen's avatar Michael Chen Committed by Alex Deucher
Browse files

drm/amdgpu: Fix CP_MEC_MDBASE in multi-xcc for gfx v12_1



Need to allocate memory for MEC FW data and program
registers CP_MEC_MDBASE for each XCC respectively.

Signed-off-by: default avatarMichael Chen <michael.chen@amd.com>
Acked-by: default avatarHarish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
Reviewed-by: default avatarShaoyun.liu <Shaoyun.liu@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 8efa1a11
Loading
Loading
Loading
Loading
+98 −94
Original line number Diff line number Diff line
@@ -1887,20 +1887,18 @@ static void gfx_v12_1_xcc_cp_compute_enable(struct amdgpu_device *adev,
}

static int gfx_v12_1_xcc_cp_compute_load_microcode_rs64(struct amdgpu_device *adev,
							int xcc_id)
							uint16_t xcc_mask)
{
	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_ptr, *fw_data_ptr;
	int r;
	int r, xcc_id;

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

	gfx_v12_1_xcc_cp_compute_enable(adev, false, xcc_id);

	mec_hdr = (const struct gfx_firmware_header_v2_0 *)adev->gfx.mec_fw->data;
	amdgpu_ucode_print_gfx_hdr(&mec_hdr->header);

@@ -1925,7 +1923,7 @@ static int gfx_v12_1_xcc_cp_compute_load_microcode_rs64(struct amdgpu_device *ad

	r = amdgpu_bo_create_reserved(adev,
				      ALIGN(fw_data_size, 64 * 1024) *
				      adev->gfx.mec.num_pipe_per_mec,
				      adev->gfx.mec.num_pipe_per_mec * NUM_XCC(xcc_mask),
				      64 * 1024, AMDGPU_GEM_DOMAIN_VRAM,
				      &adev->gfx.mec.mec_fw_data_obj,
				      &adev->gfx.mec.mec_fw_data_gpu_addr,
@@ -1937,8 +1935,12 @@ static int gfx_v12_1_xcc_cp_compute_load_microcode_rs64(struct amdgpu_device *ad
	}

	memcpy(fw_ucode_ptr, fw_ucode, fw_ucode_size);
	for_each_inst(xcc_id, xcc_mask) {
		for (i = 0; i < adev->gfx.mec.num_pipe_per_mec; i++) {
		memcpy(fw_data_ptr + i * ALIGN(fw_data_size, 64 * 1024) / 4, fw_data, fw_data_size);
			u32 offset = (xcc_id * adev->gfx.mec.num_pipe_per_mec + i) *
				     ALIGN(fw_data_size, 64 * 1024) / 4;
			memcpy(fw_data_ptr + offset, fw_data, fw_data_size);
		}
	}

	amdgpu_bo_kunmap(adev->gfx.mec.mec_fw_obj);
@@ -1946,6 +1948,9 @@ static int gfx_v12_1_xcc_cp_compute_load_microcode_rs64(struct amdgpu_device *ad
	amdgpu_bo_unreserve(adev->gfx.mec.mec_fw_obj);
	amdgpu_bo_unreserve(adev->gfx.mec.mec_fw_data_obj);

	for_each_inst(xcc_id, xcc_mask) {
		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);
		tmp = REG_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, VMID, 0);
		tmp = REG_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, EXE_DISABLE, 0);
@@ -1963,10 +1968,12 @@ static int gfx_v12_1_xcc_cp_compute_load_microcode_rs64(struct amdgpu_device *ad

			WREG32_SOC15(GC, GET_INST(GC, xcc_id), regCP_MEC_MDBASE_LO,
					lower_32_bits(adev->gfx.mec.mec_fw_data_gpu_addr +
					   i * ALIGN(fw_data_size, 64 * 1024)));
									(xcc_id * adev->gfx.mec.num_pipe_per_mec + i) *
									ALIGN(fw_data_size, 64 * 1024)));
			WREG32_SOC15(GC, GET_INST(GC, xcc_id), regCP_MEC_MDBASE_HI,
					upper_32_bits(adev->gfx.mec.mec_fw_data_gpu_addr +
					   i * ALIGN(fw_data_size, 64 * 1024)));
									(xcc_id * adev->gfx.mec.num_pipe_per_mec + i) *
									ALIGN(fw_data_size, 64 * 1024)));

			WREG32_SOC15(GC, GET_INST(GC, xcc_id), regCP_CPC_IC_BASE_LO,
					lower_32_bits(adev->gfx.mec.mec_fw_gpu_addr));
@@ -2015,6 +2022,7 @@ 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;
}
@@ -2411,22 +2419,22 @@ static int gfx_v12_1_xcc_kcq_resume(struct amdgpu_device *adev,
	return r;
}

static int gfx_v12_1_xcc_cp_resume(struct amdgpu_device *adev,
				   int xcc_id)
static int gfx_v12_1_xcc_cp_resume(struct amdgpu_device *adev, uint16_t xcc_mask)
{
	int r, i;
	int r, i, xcc_id;
	struct amdgpu_ring *ring;

	if (!(adev->flags & AMD_IS_APU))
		gfx_v12_1_xcc_enable_gui_idle_interrupt(adev, false, xcc_id);

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

	for_each_inst(xcc_id, xcc_mask) {
		if (!(adev->flags & AMD_IS_APU))
			gfx_v12_1_xcc_enable_gui_idle_interrupt(adev, false, xcc_id);

		gfx_v12_1_xcc_cp_set_doorbell_range(adev, xcc_id);

		gfx_v12_1_xcc_cp_compute_enable(adev, true, xcc_id);
@@ -2448,6 +2456,7 @@ static int gfx_v12_1_xcc_cp_resume(struct amdgpu_device *adev,
			if (r)
				return r;
		}
	}

	return 0;
}
@@ -3923,14 +3932,9 @@ static int gfx_v12_1_xcp_resume(void *handle, uint32_t inst_mask)
		}
	}

	tmp_mask = inst_mask;
	for_each_inst(i, tmp_mask) {
		r = gfx_v12_1_xcc_cp_resume(adev, i);
		if (r)
			return r;
	}
	r = gfx_v12_1_xcc_cp_resume(adev, inst_mask);

	return 0;
	return r;
}

static int gfx_v12_1_xcp_suspend(void *handle, uint32_t inst_mask)