This support was introduced for pre-navi3x dGPUS. The interface that this was wired up to isn't usable by fwupd, and no devices had a need to release firmware into the wild. Navi3x dGPUs introduce an interface that can flash the entire IFWI image that is acceptable by userspace software like fwupd. Signed-off-by: Mario Limonciello <mario.limonciello@xxxxxxx> --- Documentation/gpu/amdgpu/flashing.rst | 12 ---- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 91 ------------------------- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | 10 --- drivers/gpu/drm/amd/amdgpu/psp_v11_0.c | 60 ---------------- drivers/gpu/drm/amd/amdgpu/psp_v13_0.c | 60 ---------------- 5 files changed, 233 deletions(-) diff --git a/Documentation/gpu/amdgpu/flashing.rst b/Documentation/gpu/amdgpu/flashing.rst index bd745c42a538f..4556d58866e8e 100644 --- a/Documentation/gpu/amdgpu/flashing.rst +++ b/Documentation/gpu/amdgpu/flashing.rst @@ -16,18 +16,6 @@ The IFWI flash process is: 3. "Read" from the `psp_vbflash` sysfs file to initiate the flash process. 4. Poll the `psp_vbflash_status` sysfs file to determine when the flash process completes. -USB-C PD F/W ------------- -On GPUs that support flashing an updated USB-C PD firmware image, the process -is done using the `usbc_pd_fw` sysfs file. - -* Reading the file will provide the current firmware version. -* Writing the name of a firmware payload stored in `/lib/firmware/amdgpu` to the sysfs file will initiate the flash process. - -The firmware payload stored in `/lib/firmware/amdgpu` can be named any name -as long as it doesn't conflict with other existing binaries that are used by -`amdgpu`. - sysfs files ----------- .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 8fdca54bb8a11..15450b9aabdae 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -3471,88 +3471,6 @@ static int psp_set_powergating_state(void *handle, return 0; } -static ssize_t psp_usbc_pd_fw_sysfs_read(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct drm_device *ddev = dev_get_drvdata(dev); - struct amdgpu_device *adev = drm_to_adev(ddev); - uint32_t fw_ver; - int ret; - - if (!adev->ip_blocks[AMD_IP_BLOCK_TYPE_PSP].status.late_initialized) { - DRM_INFO("PSP block is not ready yet."); - return -EBUSY; - } - - mutex_lock(&adev->psp.mutex); - ret = psp_read_usbc_pd_fw(&adev->psp, &fw_ver); - mutex_unlock(&adev->psp.mutex); - - if (ret) { - DRM_ERROR("Failed to read USBC PD FW, err = %d", ret); - return ret; - } - - return sysfs_emit(buf, "%x\n", fw_ver); -} - -static ssize_t psp_usbc_pd_fw_sysfs_write(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) -{ - struct drm_device *ddev = dev_get_drvdata(dev); - struct amdgpu_device *adev = drm_to_adev(ddev); - int ret, idx; - char fw_name[100]; - const struct firmware *usbc_pd_fw; - struct amdgpu_bo *fw_buf_bo = NULL; - uint64_t fw_pri_mc_addr; - void *fw_pri_cpu_addr; - - if (!adev->ip_blocks[AMD_IP_BLOCK_TYPE_PSP].status.late_initialized) { - DRM_INFO("PSP block is not ready yet."); - return -EBUSY; - } - - if (!drm_dev_enter(ddev, &idx)) - return -ENODEV; - - snprintf(fw_name, sizeof(fw_name), "amdgpu/%s", buf); - ret = request_firmware(&usbc_pd_fw, fw_name, adev->dev); - if (ret) - goto fail; - - /* LFB address which is aligned to 1MB boundary per PSP request */ - ret = amdgpu_bo_create_kernel(adev, usbc_pd_fw->size, 0x100000, - AMDGPU_GEM_DOMAIN_VRAM | - AMDGPU_GEM_DOMAIN_GTT, - &fw_buf_bo, &fw_pri_mc_addr, - &fw_pri_cpu_addr); - if (ret) - goto rel_buf; - - memcpy_toio(fw_pri_cpu_addr, usbc_pd_fw->data, usbc_pd_fw->size); - - mutex_lock(&adev->psp.mutex); - ret = psp_load_usbc_pd_fw(&adev->psp, fw_pri_mc_addr); - mutex_unlock(&adev->psp.mutex); - - amdgpu_bo_free_kernel(&fw_buf_bo, &fw_pri_mc_addr, &fw_pri_cpu_addr); - -rel_buf: - release_firmware(usbc_pd_fw); -fail: - if (ret) { - DRM_ERROR("Failed to load USBC PD FW, err = %d", ret); - count = ret; - } - - drm_dev_exit(idx); - return count; -} - void psp_copy_fw(struct psp_context *psp, uint8_t *start_addr, uint32_t bin_size) { int idx; @@ -3566,15 +3484,6 @@ void psp_copy_fw(struct psp_context *psp, uint8_t *start_addr, uint32_t bin_size drm_dev_exit(idx); } -/** - * DOC: usbc_pd_fw - * Reading from this file will retrieve the USB-C PD firmware version. Writing to - * this file will trigger the update process. - */ -static DEVICE_ATTR(usbc_pd_fw, 0644, - psp_usbc_pd_fw_sysfs_read, - psp_usbc_pd_fw_sysfs_write); - int is_psp_fw_valid(struct psp_bin_desc bin) { return bin.size_bytes; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h index 3c7d9051b8c6b..4f62013ffed3a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h @@ -128,8 +128,6 @@ struct psp_funcs { int (*mem_training)(struct psp_context *psp, uint32_t ops); uint32_t (*ring_get_wptr)(struct psp_context *psp); void (*ring_set_wptr)(struct psp_context *psp, uint32_t value); - int (*load_usbc_pd_fw)(struct psp_context *psp, uint64_t fw_pri_mc_addr); - int (*read_usbc_pd_fw)(struct psp_context *psp, uint32_t *fw_ver); int (*update_spirom)(struct psp_context *psp, uint64_t fw_pri_mc_addr); int (*vbflash_stat)(struct psp_context *psp); }; @@ -429,14 +427,6 @@ struct amdgpu_psp_funcs { #define psp_ring_get_wptr(psp) (psp)->funcs->ring_get_wptr((psp)) #define psp_ring_set_wptr(psp, value) (psp)->funcs->ring_set_wptr((psp), (value)) -#define psp_load_usbc_pd_fw(psp, fw_pri_mc_addr) \ - ((psp)->funcs->load_usbc_pd_fw ? \ - (psp)->funcs->load_usbc_pd_fw((psp), (fw_pri_mc_addr)) : -EINVAL) - -#define psp_read_usbc_pd_fw(psp, fw_ver) \ - ((psp)->funcs->read_usbc_pd_fw ? \ - (psp)->funcs->read_usbc_pd_fw((psp), fw_ver) : -EINVAL) - #define psp_update_spirom(psp, fw_pri_mc_addr) \ ((psp)->funcs->update_spirom ? \ (psp)->funcs->update_spirom((psp), fw_pri_mc_addr) : -EINVAL) diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c index 8f84fe40abbbb..8aaecc725ec19 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c @@ -586,64 +586,6 @@ static void psp_v11_0_ring_set_wptr(struct psp_context *psp, uint32_t value) WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67, value); } -static int psp_v11_0_load_usbc_pd_fw(struct psp_context *psp, uint64_t fw_pri_mc_addr) -{ - struct amdgpu_device *adev = psp->adev; - uint32_t reg_status; - int ret, i = 0; - - /* - * LFB address which is aligned to 1MB address and has to be - * right-shifted by 20 so that LFB address can be passed on a 32-bit C2P - * register - */ - WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, (fw_pri_mc_addr >> 20)); - - ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_35), - 0x80000000, 0x80000000, false); - if (ret) - return ret; - - /* Fireup interrupt so PSP can pick up the address */ - WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_35, (GFX_CMD_USB_PD_USE_LFB << 16)); - - /* FW load takes very long time */ - do { - msleep(1000); - reg_status = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_35); - - if (reg_status & 0x80000000) - goto done; - - } while (++i < USBC_PD_POLLING_LIMIT_S); - - return -ETIME; -done: - - if ((reg_status & 0xFFFF) != 0) { - DRM_ERROR("Address load failed - MP0_SMN_C2PMSG_35.Bits [15:0] = 0x%04x\n", - reg_status & 0xFFFF); - return -EIO; - } - - return 0; -} - -static int psp_v11_0_read_usbc_pd_fw(struct psp_context *psp, uint32_t *fw_ver) -{ - struct amdgpu_device *adev = psp->adev; - int ret; - - WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_35, C2PMSG_CMD_GFX_USB_PD_FW_VER); - - ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_35), - 0x80000000, 0x80000000, false); - if (!ret) - *fw_ver = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36); - - return ret; -} - static const struct psp_funcs psp_v11_0_funcs = { .init_microcode = psp_v11_0_init_microcode, .bootloader_load_kdb = psp_v11_0_bootloader_load_kdb, @@ -657,8 +599,6 @@ static const struct psp_funcs psp_v11_0_funcs = { .mem_training = psp_v11_0_memory_training, .ring_get_wptr = psp_v11_0_ring_get_wptr, .ring_set_wptr = psp_v11_0_ring_set_wptr, - .load_usbc_pd_fw = psp_v11_0_load_usbc_pd_fw, - .read_usbc_pd_fw = psp_v11_0_read_usbc_pd_fw }; void psp_v11_0_set_psp_funcs(struct psp_context *psp) diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c index 58db1ee631b39..46af460e60ed8 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c @@ -557,64 +557,6 @@ static int psp_v13_0_memory_training(struct psp_context *psp, uint32_t ops) return 0; } -static int psp_v13_0_load_usbc_pd_fw(struct psp_context *psp, uint64_t fw_pri_mc_addr) -{ - struct amdgpu_device *adev = psp->adev; - uint32_t reg_status; - int ret, i = 0; - - /* - * LFB address which is aligned to 1MB address and has to be - * right-shifted by 20 so that LFB address can be passed on a 32-bit C2P - * register - */ - WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_36, (fw_pri_mc_addr >> 20)); - - ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_35), - 0x80000000, 0x80000000, false); - if (ret) - return ret; - - /* Fireup interrupt so PSP can pick up the address */ - WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_35, (GFX_CMD_USB_PD_USE_LFB << 16)); - - /* FW load takes very long time */ - do { - msleep(1000); - reg_status = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_35); - - if (reg_status & 0x80000000) - goto done; - - } while (++i < USBC_PD_POLLING_LIMIT_S); - - return -ETIME; -done: - - if ((reg_status & 0xFFFF) != 0) { - DRM_ERROR("Address load failed - MP0_SMN_C2PMSG_35.Bits [15:0] = %04x\n", - reg_status & 0xFFFF); - return -EIO; - } - - return 0; -} - -static int psp_v13_0_read_usbc_pd_fw(struct psp_context *psp, uint32_t *fw_ver) -{ - struct amdgpu_device *adev = psp->adev; - int ret; - - WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_35, C2PMSG_CMD_GFX_USB_PD_FW_VER); - - ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_35), - 0x80000000, 0x80000000, false); - if (!ret) - *fw_ver = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_36); - - return ret; -} - static int psp_v13_0_exec_spi_cmd(struct psp_context *psp, int cmd) { uint32_t reg_status = 0, reg_val = 0; @@ -707,8 +649,6 @@ static const struct psp_funcs psp_v13_0_funcs = { .ring_get_wptr = psp_v13_0_ring_get_wptr, .ring_set_wptr = psp_v13_0_ring_set_wptr, .mem_training = psp_v13_0_memory_training, - .load_usbc_pd_fw = psp_v13_0_load_usbc_pd_fw, - .read_usbc_pd_fw = psp_v13_0_read_usbc_pd_fw, .update_spirom = psp_v13_0_update_spirom, .vbflash_stat = psp_v13_0_vbflash_status }; -- 2.34.1