drivers/gpu/drm/amd/amdgpu/psp_v13_0.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/amdgpu/psp_v13_0.c
Extension
.c
Size
29489 bytes
Lines
983
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!amdgpu_sriov_vf(adev)) {
			err = psp_init_ta_microcode(psp, ucode_prefix);
			if (err)
				return err;
		}
		break;
	case IP_VERSION(13, 0, 1):
	case IP_VERSION(13, 0, 3):
	case IP_VERSION(13, 0, 5):
	case IP_VERSION(13, 0, 8):
	case IP_VERSION(13, 0, 11):
	case IP_VERSION(14, 0, 0):
	case IP_VERSION(14, 0, 1):
	case IP_VERSION(14, 0, 4):
		err = psp_init_toc_microcode(psp, ucode_prefix);
		if (err)
			return err;
		err = psp_init_ta_microcode(psp, ucode_prefix);
		if (err)
			return err;
		break;
	case IP_VERSION(13, 0, 0):
	case IP_VERSION(13, 0, 6):
	case IP_VERSION(13, 0, 7):
	case IP_VERSION(13, 0, 10):
	case IP_VERSION(13, 0, 12):
	case IP_VERSION(13, 0, 14):
	case IP_VERSION(13, 0, 15):
		err = psp_init_sos_microcode(psp, ucode_prefix);
		if (err)
			return err;
		/* It's not necessary to load ras ta on Guest side */
		err = psp_init_ta_microcode(psp, ucode_prefix);
		if (err)
			return err;
		break;
	default:
		BUG();
	}

	return 0;
}

static bool psp_v13_0_is_sos_alive(struct psp_context *psp)
{
	struct amdgpu_device *adev = psp->adev;
	uint32_t sol_reg;

	sol_reg = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_81);

	return sol_reg != 0x0;
}

static void psp_v13_0_bootloader_print_status(struct psp_context *psp,
					      const char *msg)
{
	struct amdgpu_device *adev = psp->adev;
	u32 bl_status_reg;
	char bl_status_msg[PSP13_BL_STATUS_SIZE];
	int i, at;

	if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 6) ||
	    amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 12) ||
	    amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 14) ||
		amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 15)) {
		at = 0;
		for_each_inst(i, adev->aid_mask) {
			bl_status_reg =
				(SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_92)
				 << 2) +
				amdgpu_reg_get_smn_base64(adev, MP0_HWIP, i);
			at += snprintf(bl_status_msg + at,
				       PSP13_BL_STATUS_SIZE - at,
				       " status(%02i): 0x%08x", i,
				       RREG32_PCIE_EXT(bl_status_reg));
		}
		dev_info(adev->dev, "%s - %s", msg, bl_status_msg);
	}
}

static int psp_v13_0_wait_for_vmbx_ready(struct psp_context *psp)
{
	struct amdgpu_device *adev = psp->adev;
	int retry_loop, ret;

	for (retry_loop = 0; retry_loop < PSP_VMBX_POLLING_LIMIT; retry_loop++) {
		/* Wait for bootloader to signify that is
		   ready having bit 31 of C2PMSG_33 set to 1 */
		ret = psp_wait_for(
			psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_33),

Annotation

Implementation Notes