drm/amdgpu: reclaim psp fw reservation memory region

PSP v14 fw update introduced changes on memory reservation region, according
to the change driver reclaim some non-reserved region.

1. introduce 2 new psp commands to query fw reservation regions
2. add a new reservation region for psp
3. reclaim psp non-used region

Signed-off-by: Frank Min <Frank.Min@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Frank Min 2025-05-21 16:46:27 +08:00 committed by Alex Deucher
parent e2d1e96c53
commit a3b7f9c306
5 changed files with 114 additions and 2 deletions

View File

@ -655,6 +655,10 @@ static const char *psp_gfx_cmd_name(enum psp_gfx_cmd_id cmd_id)
return "BOOT_CFG";
case GFX_CMD_ID_CONFIG_SQ_PERFMON:
return "CONFIG_SQ_PERFMON";
case GFX_CMD_ID_FB_FW_RESERV_ADDR:
return "FB_FW_RESERV_ADDR";
case GFX_CMD_ID_FB_FW_RESERV_EXT_ADDR:
return "FB_FW_RESERV_EXT_ADDR";
default:
return "UNKNOWN CMD";
}
@ -987,6 +991,93 @@ int psp_get_fw_attestation_records_addr(struct psp_context *psp,
return ret;
}
static int psp_get_fw_reservation_info(struct psp_context *psp,
uint32_t cmd_id,
uint64_t *addr,
uint32_t *size)
{
int ret;
uint32_t status;
struct psp_gfx_cmd_resp *cmd;
cmd = acquire_psp_cmd_buf(psp);
cmd->cmd_id = cmd_id;
ret = psp_cmd_submit_buf(psp, NULL, cmd,
psp->fence_buf_mc_addr);
if (ret) {
release_psp_cmd_buf(psp);
return ret;
}
status = cmd->resp.status;
if (status == PSP_ERR_UNKNOWN_COMMAND) {
release_psp_cmd_buf(psp);
*addr = 0;
*size = 0;
return 0;
}
*addr = (uint64_t)cmd->resp.uresp.fw_reserve_info.reserve_base_address_hi << 32 |
cmd->resp.uresp.fw_reserve_info.reserve_base_address_lo;
*size = cmd->resp.uresp.fw_reserve_info.reserve_size;
release_psp_cmd_buf(psp);
return 0;
}
int psp_update_fw_reservation(struct psp_context *psp)
{
int ret;
uint64_t reserv_addr, reserv_addr_ext;
uint32_t reserv_size, reserv_size_ext;
struct amdgpu_device *adev = psp->adev;
if (amdgpu_sriov_vf(psp->adev))
return 0;
if ((amdgpu_ip_version(adev, MP0_HWIP, 0) != IP_VERSION(14, 0, 2)) &&
(amdgpu_ip_version(adev, MP0_HWIP, 0) != IP_VERSION(14, 0, 3)))
return 0;
ret = psp_get_fw_reservation_info(psp, GFX_CMD_ID_FB_FW_RESERV_ADDR, &reserv_addr, &reserv_size);
if (ret)
return ret;
ret = psp_get_fw_reservation_info(psp, GFX_CMD_ID_FB_FW_RESERV_EXT_ADDR, &reserv_addr_ext, &reserv_size_ext);
if (ret)
return ret;
if (reserv_addr != adev->gmc.real_vram_size - reserv_size) {
dev_warn(adev->dev, "reserve fw region is not valid!\n");
return 0;
}
amdgpu_bo_free_kernel(&adev->mman.fw_reserved_memory, NULL, NULL);
reserv_size = roundup(reserv_size, SZ_1M);
ret = amdgpu_bo_create_kernel_at(adev, reserv_addr, reserv_size, &adev->mman.fw_reserved_memory, NULL);
if (ret) {
dev_err(adev->dev, "reserve fw region failed(%d)!\n", ret);
amdgpu_bo_free_kernel(&adev->mman.fw_reserved_memory, NULL, NULL);
return ret;
}
reserv_size_ext = roundup(reserv_size_ext, SZ_1M);
ret = amdgpu_bo_create_kernel_at(adev, reserv_addr_ext, reserv_size_ext,
&adev->mman.fw_reserved_memory_extend, NULL);
if (ret) {
dev_err(adev->dev, "reserve extend fw region failed(%d)!\n", ret);
amdgpu_bo_free_kernel(&adev->mman.fw_reserved_memory_extend, NULL, NULL);
return ret;
}
return 0;
}
static int psp_boot_config_get(struct amdgpu_device *adev, uint32_t *boot_cfg)
{
struct psp_context *psp = &adev->psp;
@ -2464,6 +2555,14 @@ static int psp_hw_start(struct psp_context *psp)
return ret;
}
if (!amdgpu_in_reset(adev) && !adev->in_suspend) {
ret = psp_update_fw_reservation(psp);
if (ret) {
dev_err(adev->dev, "update fw reservation failed!\n");
return ret;
}
}
if (amdgpu_sriov_vf(adev) && amdgpu_in_reset(adev))
goto skip_pin_bo;

View File

@ -588,7 +588,7 @@ int psp_init_cap_microcode(struct psp_context *psp,
const char *chip_name);
int psp_get_fw_attestation_records_addr(struct psp_context *psp,
uint64_t *output_ptr);
int psp_update_fw_reservation(struct psp_context *psp);
int psp_load_fw_list(struct psp_context *psp,
struct amdgpu_firmware_info **ucode_list, int ucode_count);
void psp_copy_fw(struct psp_context *psp, uint8_t *start_addr, uint32_t bin_size);

View File

@ -2060,6 +2060,8 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev)
/* return the FW reserved memory back to VRAM */
amdgpu_bo_free_kernel(&adev->mman.fw_reserved_memory, NULL,
NULL);
amdgpu_bo_free_kernel(&adev->mman.fw_reserved_memory_extend, NULL,
NULL);
if (adev->mman.stolen_reserved_size)
amdgpu_bo_free_kernel(&adev->mman.stolen_reserved_memory,
NULL, NULL);

View File

@ -86,6 +86,7 @@ struct amdgpu_mman {
uint32_t discovery_tmr_size;
/* fw reserved memory */
struct amdgpu_bo *fw_reserved_memory;
struct amdgpu_bo *fw_reserved_memory_extend;
/* firmware VRAM reservation */
u64 fw_vram_usage_start_offset;

View File

@ -106,7 +106,9 @@ enum psp_gfx_cmd_id
/*IDs of performance monitoring/profiling*/
GFX_CMD_ID_CONFIG_SQ_PERFMON = 0x00000046, /* Config CGTT_SQ_CLK_CTRL */
/* Dynamic memory partitioninig (NPS mode change)*/
GFX_CMD_ID_FB_NPS_MODE = 0x00000048, /* Configure memory partitioning mode */
GFX_CMD_ID_FB_NPS_MODE = 0x00000048, /* Configure memory partitioning mode */
GFX_CMD_ID_FB_FW_RESERV_ADDR = 0x00000050, /* Query FW reservation addr */
GFX_CMD_ID_FB_FW_RESERV_EXT_ADDR = 0x00000051, /* Query FW reservation extended addr */
};
/* PSP boot config sub-commands */
@ -404,11 +406,19 @@ struct psp_gfx_uresp_bootcfg {
uint32_t boot_cfg; /* boot config data */
};
/* Command-specific response for fw reserve info */
struct psp_gfx_uresp_fw_reserve_info {
uint32_t reserve_base_address_hi;
uint32_t reserve_base_address_lo;
uint32_t reserve_size;
};
/* Union of command-specific responses for GPCOM ring. */
union psp_gfx_uresp {
struct psp_gfx_uresp_reserved reserved;
struct psp_gfx_uresp_bootcfg boot_cfg;
struct psp_gfx_uresp_fwar_db_info fwar_db_info;
struct psp_gfx_uresp_fw_reserve_info fw_reserve_info;
};
/* Structure of GFX Response buffer.