mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	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:
		
							parent
							
								
									e2d1e96c53
								
							
						
					
					
						commit
						a3b7f9c306
					
				
					 5 changed files with 114 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -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;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue