Commit 2d39c7ae authored by Mario Limonciello's avatar Mario Limonciello Committed by Alex Deucher

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: default avatarAlex Deucher <alexander.deucher@amd.com>
Reviewed-by: default avatarLijo Lazar <lijo.lazar@amd.com>
Signed-off-by: default avatarMario Limonciello <mario.limonciello@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 93fec4f8
......@@ -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 @@ int psp_init_asd_microcode(struct psp_context *psp,
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;
}
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();
}
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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment