Commit 5120cb54 authored by Huang Rui's avatar Huang Rui Committed by Alex Deucher
Browse files

drm/amdgpu: add TOC firmware support for apu (v3)



APU needs load toc firmware for gfx10 series on psp front door loading.

v2: rebase against latest code
v3: clarify error message

Signed-off-by: default avatarHuang Rui <ray.huang@amd.com>
Acked-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 6fbcb00c
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -325,6 +325,10 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info,
		fw_info->ver = adev->dm.dmcub_fw_version;
		fw_info->feature = 0;
		break;
	case AMDGPU_INFO_FW_TOC:
		fw_info->ver = adev->psp.toc_fw_version;
		fw_info->feature = adev->psp.toc_feature_version;
		break;
	default:
		return -EINVAL;
	}
@@ -1466,6 +1470,13 @@ static int amdgpu_debugfs_firmware_info(struct seq_file *m, void *data)
	seq_printf(m, "DMCUB feature version: %u, firmware version: 0x%08x\n",
		   fw_info.feature, fw_info.ver);

	/* TOC */
	query_fw.fw_type = AMDGPU_INFO_FW_TOC;
	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
	if (ret)
		return ret;
	seq_printf(m, "TOC feature version: %u, firmware version: 0x%08x\n",
		   fw_info.feature, fw_info.ver);

	seq_printf(m, "VBIOS version: %s\n", ctx->vbios_version);

+36 −0
Original line number Diff line number Diff line
@@ -2415,6 +2415,42 @@ int psp_init_asd_microcode(struct psp_context *psp,
	return err;
}

int psp_init_toc_microcode(struct psp_context *psp,
			   const char *chip_name)
{
	struct amdgpu_device *adev = psp->adev;
	char fw_name[30];
	const struct psp_firmware_header_v1_0 *toc_hdr;
	int err = 0;

	if (!chip_name) {
		dev_err(adev->dev, "invalid chip name for toc microcode\n");
		return -EINVAL;
	}

	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_toc.bin", chip_name);
	err = request_firmware(&adev->psp.toc_fw, fw_name, adev->dev);
	if (err)
		goto out;

	err = amdgpu_ucode_validate(adev->psp.toc_fw);
	if (err)
		goto out;

	toc_hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.toc_fw->data;
	adev->psp.toc_fw_version = le32_to_cpu(toc_hdr->header.ucode_version);
	adev->psp.toc_feature_version = le32_to_cpu(toc_hdr->ucode_feature_version);
	adev->psp.toc_bin_size = le32_to_cpu(toc_hdr->header.ucode_size_bytes);
	adev->psp.toc_start_addr = (uint8_t *)toc_hdr +
				le32_to_cpu(toc_hdr->header.ucode_array_offset_bytes);
	return 0;
out:
	dev_err(adev->dev, "fail to request/validate toc microcode\n");
	release_firmware(adev->psp.toc_fw);
	adev->psp.toc_fw = NULL;
	return err;
}

int psp_init_sos_microcode(struct psp_context *psp,
			   const char *chip_name)
{
+7 −0
Original line number Diff line number Diff line
@@ -253,6 +253,11 @@ struct psp_context
	uint32_t			asd_ucode_size;
	uint8_t				*asd_start_addr;

	/* toc firmware */
	const struct firmware		*toc_fw;
	uint32_t			toc_fw_version;
	uint32_t			toc_feature_version;

	/* fence buffer */
	struct amdgpu_bo		*fence_buf_bo;
	uint64_t			fence_buf_mc_addr;
@@ -386,6 +391,8 @@ int psp_ring_cmd_submit(struct psp_context *psp,
			int index);
int psp_init_asd_microcode(struct psp_context *psp,
			   const char *chip_name);
int psp_init_toc_microcode(struct psp_context *psp,
			   const char *chip_name);
int psp_init_sos_microcode(struct psp_context *psp,
			   const char *chip_name);
int psp_init_ta_microcode(struct psp_context *psp,
+23 −10
Original line number Diff line number Diff line
@@ -109,20 +109,16 @@ static int psp_v11_0_init_microcode(struct psp_context *psp)
		BUG();
	}


	switch (adev->asic_type) {
	case CHIP_VEGA20:
	case CHIP_ARCTURUS:
		err = psp_init_sos_microcode(psp, chip_name);
		if (err)
			return err;

	if (adev->asic_type != CHIP_SIENNA_CICHLID &&
	    adev->asic_type != CHIP_NAVY_FLOUNDER) {
		err = psp_init_asd_microcode(psp, chip_name);
		if (err)
			return err;
	}

	switch (adev->asic_type) {
	case CHIP_VEGA20:
	case CHIP_ARCTURUS:
		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name);
		err = request_firmware(&adev->psp.ta_fw, fw_name, adev->dev);
		if (err) {
@@ -150,6 +146,12 @@ static int psp_v11_0_init_microcode(struct psp_context *psp)
	case CHIP_NAVI10:
	case CHIP_NAVI14:
	case CHIP_NAVI12:
		err = psp_init_sos_microcode(psp, chip_name);
		if (err)
			return err;
		err = psp_init_asd_microcode(psp, chip_name);
		if (err)
			return err;
		if (amdgpu_sriov_vf(adev))
			break;
		snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name);
@@ -180,10 +182,21 @@ static int psp_v11_0_init_microcode(struct psp_context *psp)
		break;
	case CHIP_SIENNA_CICHLID:
	case CHIP_NAVY_FLOUNDER:
		err = psp_init_sos_microcode(psp, chip_name);
		if (err)
			return err;
		err = psp_init_ta_microcode(&adev->psp, chip_name);
		if (err)
			return err;
		break;
	case CHIP_VANGOGH:
		err = psp_init_asd_microcode(psp, chip_name);
		if (err)
			return err;
		err = psp_init_toc_microcode(psp, chip_name);
		if (err)
			return err;
		break;
	default:
		BUG();
	}