drm/amd: Load PSP microcode during early_init
Simplifies the code so that all PSP versions will get the firmware name from `amdgpu_ucode_ip_version_decode` and then use this filename to load microcode as part of the early_init process. Any failures will cause the driver to fail to probe before the firmware framebuffer has been removed. Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Reviewed-by: Lijo Lazar <lijo.lazar@amd.com> Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
93fec4f8c1
commit
2d39c7ae37
@ -123,6 +123,44 @@ static void psp_check_pmfw_centralized_cstate_management(struct psp_context *psp
|
||||
}
|
||||
}
|
||||
|
||||
static int psp_init_sriov_microcode(struct psp_context *psp)
|
||||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
char ucode_prefix[30];
|
||||
int ret = 0;
|
||||
|
||||
amdgpu_ucode_ip_version_decode(adev, MP0_HWIP, ucode_prefix, sizeof(ucode_prefix));
|
||||
|
||||
switch (adev->ip_versions[MP0_HWIP][0]) {
|
||||
case IP_VERSION(9, 0, 0):
|
||||
adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
|
||||
ret = psp_init_cap_microcode(psp, ucode_prefix);
|
||||
break;
|
||||
case IP_VERSION(11, 0, 9):
|
||||
adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
|
||||
ret = psp_init_cap_microcode(psp, ucode_prefix);
|
||||
break;
|
||||
case IP_VERSION(11, 0, 7):
|
||||
adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
|
||||
ret = psp_init_cap_microcode(psp, ucode_prefix);
|
||||
break;
|
||||
case IP_VERSION(13, 0, 2):
|
||||
adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
|
||||
ret = psp_init_cap_microcode(psp, ucode_prefix);
|
||||
ret &= psp_init_ta_microcode(psp, ucode_prefix);
|
||||
break;
|
||||
case IP_VERSION(13, 0, 0):
|
||||
adev->virt.autoload_ucode_id = 0;
|
||||
break;
|
||||
case IP_VERSION(13, 0, 10):
|
||||
adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MES1_DATA;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int psp_early_init(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
@ -193,7 +231,10 @@ static int psp_early_init(void *handle)
|
||||
|
||||
psp_check_pmfw_centralized_cstate_management(psp);
|
||||
|
||||
return 0;
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return psp_init_sriov_microcode(psp);
|
||||
else
|
||||
return psp_init_microcode(psp);
|
||||
}
|
||||
|
||||
void psp_ta_free_shared_buf(struct ta_mem_context *mem_ctx)
|
||||
@ -351,42 +392,6 @@ static bool psp_get_runtime_db_entry(struct amdgpu_device *adev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int psp_init_sriov_microcode(struct psp_context *psp)
|
||||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
int ret = 0;
|
||||
|
||||
switch (adev->ip_versions[MP0_HWIP][0]) {
|
||||
case IP_VERSION(9, 0, 0):
|
||||
adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
|
||||
ret = psp_init_cap_microcode(psp, "vega10");
|
||||
break;
|
||||
case IP_VERSION(11, 0, 9):
|
||||
adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
|
||||
ret = psp_init_cap_microcode(psp, "navi12");
|
||||
break;
|
||||
case IP_VERSION(11, 0, 7):
|
||||
adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
|
||||
ret = psp_init_cap_microcode(psp, "sienna_cichlid");
|
||||
break;
|
||||
case IP_VERSION(13, 0, 2):
|
||||
adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
|
||||
ret = psp_init_cap_microcode(psp, "aldebaran");
|
||||
ret &= psp_init_ta_microcode(psp, "aldebaran");
|
||||
break;
|
||||
case IP_VERSION(13, 0, 0):
|
||||
adev->virt.autoload_ucode_id = 0;
|
||||
break;
|
||||
case IP_VERSION(13, 0, 10):
|
||||
adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MES1_DATA;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int psp_sw_init(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
@ -402,15 +407,6 @@ static int psp_sw_init(void *handle)
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
ret = psp_init_sriov_microcode(psp);
|
||||
else
|
||||
ret = psp_init_microcode(psp);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to load psp firmware!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
adev->psp.xgmi_context.supports_extended_data =
|
||||
!adev->gmc.xgmi.connected_to_cpu &&
|
||||
adev->ip_versions[MP0_HWIP][0] == IP_VERSION(13, 0, 2);
|
||||
@ -2914,19 +2910,13 @@ int psp_ring_cmd_submit(struct psp_context *psp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int psp_init_asd_microcode(struct psp_context *psp,
|
||||
const char *chip_name)
|
||||
int psp_init_asd_microcode(struct psp_context *psp, const char *chip_name)
|
||||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
char fw_name[PSP_FW_NAME_LEN];
|
||||
const struct psp_firmware_header_v1_0 *asd_hdr;
|
||||
int err = 0;
|
||||
|
||||
if (!chip_name) {
|
||||
dev_err(adev->dev, "invalid chip name for asd microcode\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_asd.bin", chip_name);
|
||||
err = request_firmware(&adev->psp.asd_fw, fw_name, adev->dev);
|
||||
if (err)
|
||||
@ -2950,19 +2940,13 @@ out:
|
||||
return err;
|
||||
}
|
||||
|
||||
int psp_init_toc_microcode(struct psp_context *psp,
|
||||
const char *chip_name)
|
||||
int psp_init_toc_microcode(struct psp_context *psp, const char *chip_name)
|
||||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
char fw_name[PSP_FW_NAME_LEN];
|
||||
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)
|
||||
@ -3113,8 +3097,7 @@ static int psp_init_sos_base_fw(struct amdgpu_device *adev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int psp_init_sos_microcode(struct psp_context *psp,
|
||||
const char *chip_name)
|
||||
int psp_init_sos_microcode(struct psp_context *psp, const char *chip_name)
|
||||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
char fw_name[PSP_FW_NAME_LEN];
|
||||
@ -3127,11 +3110,6 @@ int psp_init_sos_microcode(struct psp_context *psp,
|
||||
uint8_t *ucode_array_start_addr;
|
||||
int fw_index = 0;
|
||||
|
||||
if (!chip_name) {
|
||||
dev_err(adev->dev, "invalid chip name for sos microcode\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sos.bin", chip_name);
|
||||
err = request_firmware(&adev->psp.sos_fw, fw_name, adev->dev);
|
||||
if (err)
|
||||
@ -3398,8 +3376,7 @@ int psp_init_ta_microcode(struct psp_context *psp, const char *chip_name)
|
||||
return err;
|
||||
}
|
||||
|
||||
int psp_init_cap_microcode(struct psp_context *psp,
|
||||
const char *chip_name)
|
||||
int psp_init_cap_microcode(struct psp_context *psp, const char *chip_name)
|
||||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
char fw_name[PSP_FW_NAME_LEN];
|
||||
@ -3407,11 +3384,6 @@ int psp_init_cap_microcode(struct psp_context *psp,
|
||||
struct amdgpu_firmware_info *info = NULL;
|
||||
int err = 0;
|
||||
|
||||
if (!chip_name) {
|
||||
dev_err(adev->dev, "invalid chip name for cap microcode\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
dev_err(adev->dev, "cap microcode should only be loaded under SRIOV\n");
|
||||
return -EINVAL;
|
||||
|
@ -47,22 +47,10 @@ MODULE_FIRMWARE("amdgpu/raven_ta.bin");
|
||||
static int psp_v10_0_init_microcode(struct psp_context *psp)
|
||||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
const char *chip_name;
|
||||
char ucode_prefix[30];
|
||||
int err = 0;
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_RAVEN:
|
||||
if (adev->apu_flags & AMD_APU_IS_RAVEN2)
|
||||
chip_name = "raven2";
|
||||
else if (adev->apu_flags & AMD_APU_IS_PICASSO)
|
||||
chip_name = "picasso";
|
||||
else
|
||||
chip_name = "raven";
|
||||
break;
|
||||
default: BUG();
|
||||
}
|
||||
amdgpu_ucode_ip_version_decode(adev, MP0_HWIP, ucode_prefix, sizeof(ucode_prefix));
|
||||
|
||||
err = psp_init_asd_microcode(psp, ucode_prefix);
|
||||
|
@ -88,55 +88,20 @@ MODULE_FIRMWARE("amdgpu/beige_goby_ta.bin");
|
||||
static int psp_v11_0_init_microcode(struct psp_context *psp)
|
||||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
const char *chip_name;
|
||||
char ucode_prefix[30];
|
||||
int err = 0;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
switch (adev->ip_versions[MP0_HWIP][0]) {
|
||||
case IP_VERSION(11, 0, 2):
|
||||
chip_name = "vega20";
|
||||
break;
|
||||
case IP_VERSION(11, 0, 0):
|
||||
chip_name = "navi10";
|
||||
break;
|
||||
case IP_VERSION(11, 0, 5):
|
||||
chip_name = "navi14";
|
||||
break;
|
||||
case IP_VERSION(11, 0, 9):
|
||||
chip_name = "navi12";
|
||||
break;
|
||||
case IP_VERSION(11, 0, 4):
|
||||
chip_name = "arcturus";
|
||||
break;
|
||||
case IP_VERSION(11, 0, 7):
|
||||
chip_name = "sienna_cichlid";
|
||||
break;
|
||||
case IP_VERSION(11, 0, 11):
|
||||
chip_name = "navy_flounder";
|
||||
break;
|
||||
case IP_VERSION(11, 5, 0):
|
||||
chip_name = "vangogh";
|
||||
break;
|
||||
case IP_VERSION(11, 0, 12):
|
||||
chip_name = "dimgrey_cavefish";
|
||||
break;
|
||||
case IP_VERSION(11, 0, 13):
|
||||
chip_name = "beige_goby";
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
amdgpu_ucode_ip_version_decode(adev, MP0_HWIP, ucode_prefix, sizeof(ucode_prefix));
|
||||
|
||||
switch (adev->ip_versions[MP0_HWIP][0]) {
|
||||
case IP_VERSION(11, 0, 2):
|
||||
case IP_VERSION(11, 0, 4):
|
||||
err = psp_init_sos_microcode(psp, chip_name);
|
||||
err = psp_init_sos_microcode(psp, ucode_prefix);
|
||||
if (err)
|
||||
return err;
|
||||
err = psp_init_asd_microcode(psp, chip_name);
|
||||
err = psp_init_asd_microcode(psp, ucode_prefix);
|
||||
if (err)
|
||||
return err;
|
||||
err = psp_init_ta_microcode(psp, ucode_prefix);
|
||||
@ -145,10 +110,10 @@ static int psp_v11_0_init_microcode(struct psp_context *psp)
|
||||
case IP_VERSION(11, 0, 0):
|
||||
case IP_VERSION(11, 0, 5):
|
||||
case IP_VERSION(11, 0, 9):
|
||||
err = psp_init_sos_microcode(psp, chip_name);
|
||||
err = psp_init_sos_microcode(psp, ucode_prefix);
|
||||
if (err)
|
||||
return err;
|
||||
err = psp_init_asd_microcode(psp, chip_name);
|
||||
err = psp_init_asd_microcode(psp, ucode_prefix);
|
||||
if (err)
|
||||
return err;
|
||||
err = psp_init_ta_microcode(psp, ucode_prefix);
|
||||
@ -158,16 +123,16 @@ static int psp_v11_0_init_microcode(struct psp_context *psp)
|
||||
case IP_VERSION(11, 0, 11):
|
||||
case IP_VERSION(11, 0, 12):
|
||||
case IP_VERSION(11, 0, 13):
|
||||
err = psp_init_sos_microcode(psp, chip_name);
|
||||
err = psp_init_sos_microcode(psp, ucode_prefix);
|
||||
if (err)
|
||||
return err;
|
||||
err = psp_init_ta_microcode(psp, chip_name);
|
||||
err = psp_init_ta_microcode(psp, ucode_prefix);
|
||||
break;
|
||||
case IP_VERSION(11, 5, 0):
|
||||
err = psp_init_asd_microcode(psp, chip_name);
|
||||
err = psp_init_asd_microcode(psp, ucode_prefix);
|
||||
if (err)
|
||||
return err;
|
||||
err = psp_init_toc_microcode(psp, chip_name);
|
||||
err = psp_init_toc_microcode(psp, ucode_prefix);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
|
@ -48,24 +48,13 @@ MODULE_FIRMWARE("amdgpu/green_sardine_ta.bin");
|
||||
static int psp_v12_0_init_microcode(struct psp_context *psp)
|
||||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
const char *chip_name;
|
||||
char ucode_prefix[30];
|
||||
int err = 0;
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_RENOIR:
|
||||
if (adev->apu_flags & AMD_APU_IS_RENOIR)
|
||||
chip_name = "renoir";
|
||||
else
|
||||
chip_name = "green_sardine";
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
amdgpu_ucode_ip_version_decode(adev, MP0_HWIP, ucode_prefix, sizeof(ucode_prefix));
|
||||
|
||||
err = psp_init_asd_microcode(psp, chip_name);
|
||||
err = psp_init_asd_microcode(psp, ucode_prefix);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -70,32 +70,19 @@ MODULE_FIRMWARE("amdgpu/psp_13_0_11_ta.bin");
|
||||
static int psp_v13_0_init_microcode(struct psp_context *psp)
|
||||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
const char *chip_name;
|
||||
char ucode_prefix[30];
|
||||
int err = 0;
|
||||
|
||||
switch (adev->ip_versions[MP0_HWIP][0]) {
|
||||
case IP_VERSION(13, 0, 2):
|
||||
chip_name = "aldebaran";
|
||||
break;
|
||||
case IP_VERSION(13, 0, 1):
|
||||
case IP_VERSION(13, 0, 3):
|
||||
chip_name = "yellow_carp";
|
||||
break;
|
||||
default:
|
||||
amdgpu_ucode_ip_version_decode(adev, MP0_HWIP, ucode_prefix, sizeof(ucode_prefix));
|
||||
chip_name = ucode_prefix;
|
||||
break;
|
||||
}
|
||||
amdgpu_ucode_ip_version_decode(adev, MP0_HWIP, ucode_prefix, sizeof(ucode_prefix));
|
||||
|
||||
switch (adev->ip_versions[MP0_HWIP][0]) {
|
||||
case IP_VERSION(13, 0, 2):
|
||||
err = psp_init_sos_microcode(psp, chip_name);
|
||||
err = psp_init_sos_microcode(psp, ucode_prefix);
|
||||
if (err)
|
||||
return err;
|
||||
/* It's not necessary to load ras ta on Guest side */
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
err = psp_init_ta_microcode(&adev->psp, chip_name);
|
||||
err = psp_init_ta_microcode(psp, ucode_prefix);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
@ -105,21 +92,21 @@ static int psp_v13_0_init_microcode(struct psp_context *psp)
|
||||
case IP_VERSION(13, 0, 5):
|
||||
case IP_VERSION(13, 0, 8):
|
||||
case IP_VERSION(13, 0, 11):
|
||||
err = psp_init_toc_microcode(psp, chip_name);
|
||||
err = psp_init_toc_microcode(psp, ucode_prefix);
|
||||
if (err)
|
||||
return err;
|
||||
err = psp_init_ta_microcode(psp, chip_name);
|
||||
err = psp_init_ta_microcode(psp, ucode_prefix);
|
||||
if (err)
|
||||
return err;
|
||||
break;
|
||||
case IP_VERSION(13, 0, 0):
|
||||
case IP_VERSION(13, 0, 7):
|
||||
case IP_VERSION(13, 0, 10):
|
||||
err = psp_init_sos_microcode(psp, chip_name);
|
||||
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, chip_name);
|
||||
err = psp_init_ta_microcode(psp, ucode_prefix);
|
||||
if (err)
|
||||
return err;
|
||||
break;
|
||||
|
@ -35,25 +35,17 @@ MODULE_FIRMWARE("amdgpu/psp_13_0_4_ta.bin");
|
||||
static int psp_v13_0_4_init_microcode(struct psp_context *psp)
|
||||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
const char *chip_name;
|
||||
char ucode_prefix[30];
|
||||
int err = 0;
|
||||
|
||||
switch (adev->ip_versions[MP0_HWIP][0]) {
|
||||
case IP_VERSION(13, 0, 4):
|
||||
amdgpu_ucode_ip_version_decode(adev, MP0_HWIP, ucode_prefix, sizeof(ucode_prefix));
|
||||
chip_name = ucode_prefix;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
amdgpu_ucode_ip_version_decode(adev, MP0_HWIP, ucode_prefix, sizeof(ucode_prefix));
|
||||
|
||||
switch (adev->ip_versions[MP0_HWIP][0]) {
|
||||
case IP_VERSION(13, 0, 4):
|
||||
err = psp_init_toc_microcode(psp, chip_name);
|
||||
err = psp_init_toc_microcode(psp, ucode_prefix);
|
||||
if (err)
|
||||
return err;
|
||||
err = psp_init_ta_microcode(psp, chip_name);
|
||||
err = psp_init_ta_microcode(psp, ucode_prefix);
|
||||
if (err)
|
||||
return err;
|
||||
break;
|
||||
|
@ -57,26 +57,18 @@ static int psp_v3_1_ring_stop(struct psp_context *psp,
|
||||
static int psp_v3_1_init_microcode(struct psp_context *psp)
|
||||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
const char *chip_name;
|
||||
char ucode_prefix[30];
|
||||
int err = 0;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA10:
|
||||
chip_name = "vega10";
|
||||
break;
|
||||
case CHIP_VEGA12:
|
||||
chip_name = "vega12";
|
||||
break;
|
||||
default: BUG();
|
||||
}
|
||||
amdgpu_ucode_ip_version_decode(adev, MP0_HWIP, ucode_prefix, sizeof(ucode_prefix));
|
||||
|
||||
err = psp_init_sos_microcode(psp, chip_name);
|
||||
err = psp_init_sos_microcode(psp, ucode_prefix);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = psp_init_asd_microcode(psp, chip_name);
|
||||
err = psp_init_asd_microcode(psp, ucode_prefix);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user