]> Git Repo - linux.git/blobdiff - drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
Merge tag 'rpmsg-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/andersson...
[linux.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_psp.c
index a6dbe4b83533f7888a2e60bf36350d5951247062..523d22db094b6bdd34e2506b1ece238eea37ede0 100644 (file)
@@ -100,6 +100,8 @@ static int psp_early_init(void *handle)
        case CHIP_NAVI12:
        case CHIP_SIENNA_CICHLID:
        case CHIP_NAVY_FLOUNDER:
+       case CHIP_VANGOGH:
+       case CHIP_DIMGREY_CAVEFISH:
                psp_v11_0_set_psp_funcs(psp);
                psp->autoload_supported = true;
                break;
@@ -288,6 +290,8 @@ psp_cmd_submit_buf(struct psp_context *psp,
        skip_unsupport = (psp->cmd_buf_mem->resp.status == TEE_ERROR_NOT_SUPPORTED ||
                psp->cmd_buf_mem->resp.status == PSP_ERR_UNKNOWN_COMMAND) && amdgpu_sriov_vf(psp->adev);
 
+       memcpy((void*)&cmd->resp, (void*)&psp->cmd_buf_mem->resp, sizeof(struct psp_gfx_resp));
+
        /* In some cases, psp response status is not 0 even there is no
         * problem while the command is submitted. Some version of PSP FW
         * doesn't write 0 to that field.
@@ -308,9 +312,6 @@ psp_cmd_submit_buf(struct psp_context *psp,
                }
        }
 
-       /* get xGMI session id from response buffer */
-       cmd->resp.session_id = psp->cmd_buf_mem->resp.session_id;
-
        if (ucode) {
                ucode->tmr_mc_addr_lo = psp->cmd_buf_mem->resp.fw_addr_lo;
                ucode->tmr_mc_addr_hi = psp->cmd_buf_mem->resp.fw_addr_hi;
@@ -509,6 +510,37 @@ static int psp_tmr_terminate(struct psp_context *psp)
        return 0;
 }
 
+int psp_get_fw_attestation_records_addr(struct psp_context *psp,
+                                       uint64_t *output_ptr)
+{
+       int ret;
+       struct psp_gfx_cmd_resp *cmd;
+
+       if (!output_ptr)
+               return -EINVAL;
+
+       if (amdgpu_sriov_vf(psp->adev))
+               return 0;
+
+       cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
+       if (!cmd)
+               return -ENOMEM;
+
+       cmd->cmd_id = GFX_CMD_ID_GET_FW_ATTESTATION;
+
+       ret = psp_cmd_submit_buf(psp, NULL, cmd,
+                                psp->fence_buf_mc_addr);
+
+       if (!ret) {
+               *output_ptr = ((uint64_t)cmd->resp.uresp.fwar_db_info.fwar_db_addr_lo) +
+                             ((uint64_t)cmd->resp.uresp.fwar_db_info.fwar_db_addr_hi << 32);
+       }
+
+       kfree(cmd);
+
+       return ret;
+}
+
 static void psp_prep_asd_load_cmd_buf(struct psp_gfx_cmd_resp *cmd,
                                uint64_t asd_mc, uint32_t size)
 {
@@ -624,14 +656,14 @@ static void psp_prep_ta_load_cmd_buf(struct psp_gfx_cmd_resp *cmd,
                                     uint64_t ta_shared_mc,
                                     uint32_t ta_shared_size)
 {
-       cmd->cmd_id                             = GFX_CMD_ID_LOAD_TA;
+       cmd->cmd_id                             = GFX_CMD_ID_LOAD_TA;
        cmd->cmd.cmd_load_ta.app_phy_addr_lo    = lower_32_bits(ta_bin_mc);
-       cmd->cmd.cmd_load_ta.app_phy_addr_hi    = upper_32_bits(ta_bin_mc);
-       cmd->cmd.cmd_load_ta.app_len            = ta_bin_size;
+       cmd->cmd.cmd_load_ta.app_phy_addr_hi    = upper_32_bits(ta_bin_mc);
+       cmd->cmd.cmd_load_ta.app_len            = ta_bin_size;
 
        cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo = lower_32_bits(ta_shared_mc);
        cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi = upper_32_bits(ta_shared_mc);
-       cmd->cmd.cmd_load_ta.cmd_buf_len         = ta_shared_size;
+       cmd->cmd.cmd_load_ta.cmd_buf_len         = ta_shared_size;
 }
 
 static int psp_xgmi_init_shared_buf(struct psp_context *psp)
@@ -655,9 +687,9 @@ static void psp_prep_ta_invoke_cmd_buf(struct psp_gfx_cmd_resp *cmd,
                                       uint32_t ta_cmd_id,
                                       uint32_t session_id)
 {
-       cmd->cmd_id                             = GFX_CMD_ID_INVOKE_CMD;
-       cmd->cmd.cmd_invoke_cmd.session_id      = session_id;
-       cmd->cmd.cmd_invoke_cmd.ta_cmd_id       = ta_cmd_id;
+       cmd->cmd_id                             = GFX_CMD_ID_INVOKE_CMD;
+       cmd->cmd.cmd_invoke_cmd.session_id      = session_id;
+       cmd->cmd.cmd_invoke_cmd.ta_cmd_id       = ta_cmd_id;
 }
 
 static int psp_ta_invoke(struct psp_context *psp,
@@ -806,7 +838,7 @@ int psp_xgmi_get_hive_id(struct psp_context *psp, uint64_t *hive_id)
        struct ta_xgmi_shared_memory *xgmi_cmd;
        int ret;
 
-       xgmi_cmd = (struct ta_xgmi_shared_memory*)psp->xgmi_context.xgmi_shared_buf;
+       xgmi_cmd = (struct ta_xgmi_shared_memory *)psp->xgmi_context.xgmi_shared_buf;
        memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory));
 
        xgmi_cmd->cmd_id = TA_COMMAND_XGMI__GET_HIVE_ID;
@@ -826,7 +858,7 @@ int psp_xgmi_get_node_id(struct psp_context *psp, uint64_t *node_id)
        struct ta_xgmi_shared_memory *xgmi_cmd;
        int ret;
 
-       xgmi_cmd = (struct ta_xgmi_shared_memory*)psp->xgmi_context.xgmi_shared_buf;
+       xgmi_cmd = (struct ta_xgmi_shared_memory *)psp->xgmi_context.xgmi_shared_buf;
        memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory));
 
        xgmi_cmd->cmd_id = TA_COMMAND_XGMI__GET_NODE_ID;
@@ -854,7 +886,7 @@ int psp_xgmi_get_topology_info(struct psp_context *psp,
        if (!topology || topology->num_nodes > TA_XGMI__MAX_CONNECTED_NODES)
                return -EINVAL;
 
-       xgmi_cmd = (struct ta_xgmi_shared_memory*)psp->xgmi_context.xgmi_shared_buf;
+       xgmi_cmd = (struct ta_xgmi_shared_memory *)psp->xgmi_context.xgmi_shared_buf;
        memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory));
 
        /* Fill in the shared memory with topology information as input */
@@ -898,7 +930,7 @@ int psp_xgmi_set_topology_info(struct psp_context *psp,
        if (!topology || topology->num_nodes > TA_XGMI__MAX_CONNECTED_NODES)
                return -EINVAL;
 
-       xgmi_cmd = (struct ta_xgmi_shared_memory*)psp->xgmi_context.xgmi_shared_buf;
+       xgmi_cmd = (struct ta_xgmi_shared_memory *)psp->xgmi_context.xgmi_shared_buf;
        memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory));
 
        topology_info_input = &xgmi_cmd->xgmi_in_message.get_topology_info;
@@ -962,7 +994,7 @@ static int psp_ras_load(struct psp_context *psp)
        ret = psp_cmd_submit_buf(psp, NULL, cmd,
                        psp->fence_buf_mc_addr);
 
-       ras_cmd = (struct ta_ras_shared_memory*)psp->ras.ras_shared_buf;
+       ras_cmd = (struct ta_ras_shared_memory *)psp->ras.ras_shared_buf;
 
        if (!ret) {
                psp->ras.session_id = cmd->resp.session_id;
@@ -1884,7 +1916,7 @@ static int psp_execute_np_fw_load(struct psp_context *psp,
 static int psp_load_smu_fw(struct psp_context *psp)
 {
        int ret;
-       struct amdgpu_deviceadev = psp->adev;
+       struct amdgpu_device *adev = psp->adev;
        struct amdgpu_firmware_info *ucode =
                        &adev->firmware.ucode[AMDGPU_UCODE_ID_SMC];
        struct amdgpu_ras *ras = psp->ras.ras;
@@ -1893,7 +1925,8 @@ static int psp_load_smu_fw(struct psp_context *psp)
                return 0;
 
 
-       if (amdgpu_in_reset(adev) && ras && ras->supported) {
+       if (amdgpu_in_reset(adev) && ras && ras->supported &&
+               adev->asic_type == CHIP_ARCTURUS) {
                ret = amdgpu_dpm_set_mp1_state(adev, PP_MP1_STATE_UNLOAD);
                if (ret) {
                        DRM_WARN("Failed to set MP1 state prepare for reload\n");
@@ -1950,7 +1983,7 @@ static int psp_np_fw_load(struct psp_context *psp)
 {
        int i, ret;
        struct amdgpu_firmware_info *ucode;
-       struct amdgpu_deviceadev = psp->adev;
+       struct amdgpu_device *adev = psp->adev;
 
        if (psp->autoload_supported &&
            !psp->pmfw_centralized_cstate_management) {
@@ -1974,8 +2007,8 @@ static int psp_np_fw_load(struct psp_context *psp)
                        continue;
 
                if (psp->autoload_supported &&
-                   (adev->asic_type == CHIP_SIENNA_CICHLID ||
-                    adev->asic_type == CHIP_NAVY_FLOUNDER) &&
+                   (adev->asic_type >= CHIP_SIENNA_CICHLID &&
+                    adev->asic_type <= CHIP_DIMGREY_CAVEFISH) &&
                    (ucode->ucode_id == AMDGPU_UCODE_ID_SDMA1 ||
                     ucode->ucode_id == AMDGPU_UCODE_ID_SDMA2 ||
                     ucode->ucode_id == AMDGPU_UCODE_ID_SDMA3))
@@ -2390,7 +2423,7 @@ int psp_init_asd_microcode(struct psp_context *psp,
                           const char *chip_name)
 {
        struct amdgpu_device *adev = psp->adev;
-       char fw_name[30];
+       char fw_name[PSP_FW_NAME_LEN];
        const struct psp_firmware_header_v1_0 *asd_hdr;
        int err = 0;
 
@@ -2422,11 +2455,47 @@ out:
        return err;
 }
 
-int psp_init_sos_microcode(struct psp_context *psp,
+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)
+{
+       struct amdgpu_device *adev = psp->adev;
+       char fw_name[PSP_FW_NAME_LEN];
        const struct psp_firmware_header_v1_0 *sos_hdr;
        const struct psp_firmware_header_v1_1 *sos_hdr_v1_1;
        const struct psp_firmware_header_v1_2 *sos_hdr_v1_2;
@@ -2505,9 +2574,9 @@ out:
        return err;
 }
 
-int parse_ta_bin_descriptor(struct psp_context *psp,
-                           const struct ta_fw_bin_desc *desc,
-                           const struct ta_firmware_header_v2_0 *ta_hdr)
+static int parse_ta_bin_descriptor(struct psp_context *psp,
+                                  const struct ta_fw_bin_desc *desc,
+                                  const struct ta_firmware_header_v2_0 *ta_hdr)
 {
        uint8_t *ucode_start_addr  = NULL;
 
@@ -2520,9 +2589,9 @@ int parse_ta_bin_descriptor(struct psp_context *psp,
 
        switch (desc->fw_type) {
        case TA_FW_TYPE_PSP_ASD:
-               psp->asd_fw_version        = le32_to_cpu(desc->fw_version);
+               psp->asd_fw_version        = le32_to_cpu(desc->fw_version);
                psp->asd_feature_version   = le32_to_cpu(desc->fw_version);
-               psp->asd_ucode_size        = le32_to_cpu(desc->size_bytes);
+               psp->asd_ucode_size        = le32_to_cpu(desc->size_bytes);
                psp->asd_start_addr        = ucode_start_addr;
                psp->asd_fw                = psp->ta_fw;
                break;
@@ -2563,7 +2632,7 @@ int psp_init_ta_microcode(struct psp_context *psp,
                          const char *chip_name)
 {
        struct amdgpu_device *adev = psp->adev;
-       char fw_name[30];
+       char fw_name[PSP_FW_NAME_LEN];
        const struct ta_firmware_header_v2_0 *ta_hdr;
        int err = 0;
        int ta_index = 0;
This page took 0.046881 seconds and 4 git commands to generate.