diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/psp_v3_1.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/psp_v3_1.c | 262 |
1 files changed, 25 insertions, 237 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c index 735c43c7daab..f2e725f72d2f 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c @@ -50,9 +50,6 @@ MODULE_FIRMWARE("amdgpu/vega12_asd.bin"); #define smnMP1_FIRMWARE_FLAGS 0x3010028 -static uint32_t sos_old_versions[] = {1517616, 1510592, 1448594, 1446554}; - -static bool psp_v3_1_support_vmr_ring(struct psp_context *psp); static int psp_v3_1_ring_stop(struct psp_context *psp, enum psp_ring_type ring_type); @@ -60,9 +57,7 @@ static int psp_v3_1_init_microcode(struct psp_context *psp) { struct amdgpu_device *adev = psp->adev; const char *chip_name; - char fw_name[30]; int err = 0; - const struct psp_firmware_header_v1_0 *hdr; DRM_DEBUG("\n"); @@ -76,55 +71,15 @@ static int psp_v3_1_init_microcode(struct psp_context *psp) default: BUG(); } - 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) - goto out; - - err = amdgpu_ucode_validate(adev->psp.sos_fw); + err = psp_init_sos_microcode(psp, chip_name); if (err) - goto out; - - hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.sos_fw->data; - adev->psp.sos_fw_version = le32_to_cpu(hdr->header.ucode_version); - adev->psp.sos_feature_version = le32_to_cpu(hdr->ucode_feature_version); - adev->psp.sos_bin_size = le32_to_cpu(hdr->sos_size_bytes); - adev->psp.sys_bin_size = le32_to_cpu(hdr->header.ucode_size_bytes) - - le32_to_cpu(hdr->sos_size_bytes); - adev->psp.sys_start_addr = (uint8_t *)hdr + - le32_to_cpu(hdr->header.ucode_array_offset_bytes); - adev->psp.sos_start_addr = (uint8_t *)adev->psp.sys_start_addr + - le32_to_cpu(hdr->sos_offset_bytes); - - 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) - goto out; + return err; - err = amdgpu_ucode_validate(adev->psp.asd_fw); + err = psp_init_asd_microcode(psp, chip_name); if (err) - goto out; - - hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.asd_fw->data; - adev->psp.asd_fw_version = le32_to_cpu(hdr->header.ucode_version); - adev->psp.asd_feature_version = le32_to_cpu(hdr->ucode_feature_version); - adev->psp.asd_ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes); - adev->psp.asd_start_addr = (uint8_t *)hdr + - le32_to_cpu(hdr->header.ucode_array_offset_bytes); + return err; return 0; -out: - if (err) { - dev_err(adev->dev, - "psp v3.1: Failed to load firmware \"%s\"\n", - fw_name); - release_firmware(adev->psp.sos_fw); - adev->psp.sos_fw = NULL; - release_firmware(adev->psp.asd_fw); - adev->psp.asd_fw = NULL; - } - - return err; } static int psp_v3_1_bootloader_load_sysdrv(struct psp_context *psp) @@ -168,41 +123,19 @@ static int psp_v3_1_bootloader_load_sysdrv(struct psp_context *psp) return ret; } -static bool psp_v3_1_match_version(struct amdgpu_device *adev, uint32_t ver) -{ - int i; - - if (ver == adev->psp.sos_fw_version) - return true; - - /* - * Double check if the latest four legacy versions. - * If yes, it is still the right version. - */ - for (i = 0; i < ARRAY_SIZE(sos_old_versions); i++) { - if (sos_old_versions[i] == adev->psp.sos_fw_version) - return true; - } - - return false; -} - static int psp_v3_1_bootloader_load_sos(struct psp_context *psp) { int ret; unsigned int psp_gfxdrv_command_reg = 0; struct amdgpu_device *adev = psp->adev; - uint32_t sol_reg, ver; + uint32_t sol_reg; /* Check sOS sign of life register to confirm sys driver and sOS * are already been loaded. */ sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); - if (sol_reg) { - psp->sos_fw_version = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_58); - printk("sos fw version = 0x%x.\n", psp->sos_fw_version); + if (sol_reg) return 0; - } /* Wait for bootloader to signify that is ready having bit 31 of C2PMSG_35 set to 1 */ ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_35), @@ -227,11 +160,6 @@ static int psp_v3_1_bootloader_load_sos(struct psp_context *psp) ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_81), RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81), 0, true); - - ver = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_58); - if (!psp_v3_1_match_version(adev, ver)) - DRM_WARN("SOS version doesn't match\n"); - return ret; } @@ -302,7 +230,7 @@ static int psp_v3_1_ring_create(struct psp_context *psp, psp_v3_1_reroute_ih(psp); - if (psp_v3_1_support_vmr_ring(psp)) { + if (amdgpu_sriov_vf(adev)) { ret = psp_v3_1_ring_stop(psp, ring_type); if (ret) { DRM_ERROR("psp_v3_1_ring_stop_sriov failed!\n"); @@ -360,34 +288,26 @@ static int psp_v3_1_ring_stop(struct psp_context *psp, enum psp_ring_type ring_type) { int ret = 0; - unsigned int psp_ring_reg = 0; struct amdgpu_device *adev = psp->adev; - if (psp_v3_1_support_vmr_ring(psp)) { - /* Write the Destroy GPCOM ring command to C2PMSG_101 */ - psp_ring_reg = GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING; - WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101, psp_ring_reg); - - /* there might be handshake issue which needs delay */ - mdelay(20); - - /* Wait for response flag (bit 31) in C2PMSG_101 */ - ret = psp_wait_for(psp, - SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_101), - 0x80000000, 0x80000000, false); - } else { - /* Write the ring destroy command to C2PMSG_64 */ - psp_ring_reg = 3 << 16; - WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64, psp_ring_reg); + /* Write the ring destroy command*/ + if (amdgpu_sriov_vf(adev)) + WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101, + GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING); + else + WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64, + GFX_CTRL_CMD_ID_DESTROY_RINGS); - /* there might be handshake issue which needs delay */ - mdelay(20); + /* there might be handshake issue with hardware which needs delay */ + mdelay(20); - /* Wait for response flag (bit 31) in C2PMSG_64 */ - ret = psp_wait_for(psp, - SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64), - 0x80000000, 0x80000000, false); - } + /* Wait for response flag (bit 31) */ + if (amdgpu_sriov_vf(adev)) + ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_101), + 0x80000000, 0x80000000, false); + else + ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64), + 0x80000000, 0x80000000, false); return ret; } @@ -410,128 +330,6 @@ static int psp_v3_1_ring_destroy(struct psp_context *psp, return ret; } -static int -psp_v3_1_sram_map(struct amdgpu_device *adev, - unsigned int *sram_offset, unsigned int *sram_addr_reg_offset, - unsigned int *sram_data_reg_offset, - enum AMDGPU_UCODE_ID ucode_id) -{ - int ret = 0; - - switch(ucode_id) { -/* TODO: needs to confirm */ -#if 0 - case AMDGPU_UCODE_ID_SMC: - *sram_offset = 0; - *sram_addr_reg_offset = 0; - *sram_data_reg_offset = 0; - break; -#endif - - case AMDGPU_UCODE_ID_CP_CE: - *sram_offset = 0x0; - *sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_CE_UCODE_ADDR); - *sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_CE_UCODE_DATA); - break; - - case AMDGPU_UCODE_ID_CP_PFP: - *sram_offset = 0x0; - *sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_PFP_UCODE_ADDR); - *sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_PFP_UCODE_DATA); - break; - - case AMDGPU_UCODE_ID_CP_ME: - *sram_offset = 0x0; - *sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_ME_UCODE_ADDR); - *sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_ME_UCODE_DATA); - break; - - case AMDGPU_UCODE_ID_CP_MEC1: - *sram_offset = 0x10000; - *sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_MEC_ME1_UCODE_ADDR); - *sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_MEC_ME1_UCODE_DATA); - break; - - case AMDGPU_UCODE_ID_CP_MEC2: - *sram_offset = 0x10000; - *sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_MEC2_UCODE_ADDR); - *sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_MEC2_UCODE_DATA); - break; - - case AMDGPU_UCODE_ID_RLC_G: - *sram_offset = 0x2000; - *sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_UCODE_ADDR); - *sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_UCODE_DATA); - break; - - case AMDGPU_UCODE_ID_SDMA0: - *sram_offset = 0x0; - *sram_addr_reg_offset = SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_UCODE_ADDR); - *sram_data_reg_offset = SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_UCODE_DATA); - break; - -/* TODO: needs to confirm */ -#if 0 - case AMDGPU_UCODE_ID_SDMA1: - *sram_offset = ; - *sram_addr_reg_offset = ; - break; - - case AMDGPU_UCODE_ID_UVD: - *sram_offset = ; - *sram_addr_reg_offset = ; - break; - - case AMDGPU_UCODE_ID_VCE: - *sram_offset = ; - *sram_addr_reg_offset = ; - break; -#endif - - case AMDGPU_UCODE_ID_MAXIMUM: - default: - ret = -EINVAL; - break; - } - - return ret; -} - -static bool psp_v3_1_compare_sram_data(struct psp_context *psp, - struct amdgpu_firmware_info *ucode, - enum AMDGPU_UCODE_ID ucode_type) -{ - int err = 0; - unsigned int fw_sram_reg_val = 0; - unsigned int fw_sram_addr_reg_offset = 0; - unsigned int fw_sram_data_reg_offset = 0; - unsigned int ucode_size; - uint32_t *ucode_mem = NULL; - struct amdgpu_device *adev = psp->adev; - - err = psp_v3_1_sram_map(adev, &fw_sram_reg_val, &fw_sram_addr_reg_offset, - &fw_sram_data_reg_offset, ucode_type); - if (err) - return false; - - WREG32(fw_sram_addr_reg_offset, fw_sram_reg_val); - - ucode_size = ucode->ucode_size; - ucode_mem = (uint32_t *)ucode->kaddr; - while (ucode_size) { - fw_sram_reg_val = RREG32(fw_sram_data_reg_offset); - - if (*ucode_mem != fw_sram_reg_val) - return false; - - ucode_mem++; - /* 4 bytes */ - ucode_size -= 4; - } - - return true; -} - static bool psp_v3_1_smu_reload_quirk(struct psp_context *psp) { struct amdgpu_device *adev = psp->adev; @@ -575,20 +373,12 @@ static int psp_v3_1_mode1_reset(struct psp_context *psp) return 0; } -static bool psp_v3_1_support_vmr_ring(struct psp_context *psp) -{ - if (amdgpu_sriov_vf(psp->adev)) - return true; - - return false; -} - static uint32_t psp_v3_1_ring_get_wptr(struct psp_context *psp) { uint32_t data; struct amdgpu_device *adev = psp->adev; - if (psp_v3_1_support_vmr_ring(psp)) + if (amdgpu_sriov_vf(adev)) data = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102); else data = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67); @@ -599,7 +389,7 @@ static void psp_v3_1_ring_set_wptr(struct psp_context *psp, uint32_t value) { struct amdgpu_device *adev = psp->adev; - if (psp_v3_1_support_vmr_ring(psp)) { + if (amdgpu_sriov_vf(adev)) { WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102, value); /* send interrupt to PSP for SRIOV ring write pointer update */ WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101, @@ -616,10 +406,8 @@ static const struct psp_funcs psp_v3_1_funcs = { .ring_create = psp_v3_1_ring_create, .ring_stop = psp_v3_1_ring_stop, .ring_destroy = psp_v3_1_ring_destroy, - .compare_sram_data = psp_v3_1_compare_sram_data, .smu_reload_quirk = psp_v3_1_smu_reload_quirk, .mode1_reset = psp_v3_1_mode1_reset, - .support_vmr_ring = psp_v3_1_support_vmr_ring, .ring_get_wptr = psp_v3_1_ring_get_wptr, .ring_set_wptr = psp_v3_1_ring_set_wptr, }; |