drm/amdgpu: add vram reservation based on vram_usagebyfirmware_v2_2
Move TMR region from top of FB to 2MB for FFBM, so we need to reserve TMR region firstly to make sure TMR can be allocated at 2MB Signed-off-by: Tong Liu01 <Tong.Liu01@amd.com> Acked-by: Christian König <christian.koenig@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
3e93136809
commit
4864f2ee9e
@ -101,39 +101,97 @@ void amdgpu_atomfirmware_scratch_regs_init(struct amdgpu_device *adev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev)
|
static int amdgpu_atomfirmware_allocate_fb_v2_1(struct amdgpu_device *adev,
|
||||||
|
struct vram_usagebyfirmware_v2_1 *fw_usage, int *usage_bytes)
|
||||||
{
|
{
|
||||||
struct atom_context *ctx = adev->mode_info.atom_context;
|
uint32_t start_addr, fw_size, drv_size;
|
||||||
int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
|
|
||||||
vram_usagebyfirmware);
|
|
||||||
struct vram_usagebyfirmware_v2_1 *firmware_usage;
|
|
||||||
uint32_t start_addr, size;
|
|
||||||
uint16_t data_offset;
|
|
||||||
int usage_bytes = 0;
|
|
||||||
|
|
||||||
if (amdgpu_atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) {
|
start_addr = le32_to_cpu(fw_usage->start_address_in_kb);
|
||||||
firmware_usage = (struct vram_usagebyfirmware_v2_1 *)(ctx->bios + data_offset);
|
fw_size = le16_to_cpu(fw_usage->used_by_firmware_in_kb);
|
||||||
DRM_DEBUG("atom firmware requested %08x %dkb fw %dkb drv\n",
|
drv_size = le16_to_cpu(fw_usage->used_by_driver_in_kb);
|
||||||
le32_to_cpu(firmware_usage->start_address_in_kb),
|
|
||||||
le16_to_cpu(firmware_usage->used_by_firmware_in_kb),
|
|
||||||
le16_to_cpu(firmware_usage->used_by_driver_in_kb));
|
|
||||||
|
|
||||||
start_addr = le32_to_cpu(firmware_usage->start_address_in_kb);
|
DRM_DEBUG("atom firmware v2_1 requested %08x %dkb fw %dkb drv\n",
|
||||||
size = le16_to_cpu(firmware_usage->used_by_firmware_in_kb);
|
start_addr,
|
||||||
|
fw_size,
|
||||||
|
drv_size);
|
||||||
|
|
||||||
if ((uint32_t)(start_addr & ATOM_VRAM_OPERATION_FLAGS_MASK) ==
|
if ((start_addr & ATOM_VRAM_OPERATION_FLAGS_MASK) ==
|
||||||
(uint32_t)(ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATION <<
|
(uint32_t)(ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATION <<
|
||||||
ATOM_VRAM_OPERATION_FLAGS_SHIFT)) {
|
ATOM_VRAM_OPERATION_FLAGS_SHIFT)) {
|
||||||
/* Firmware request VRAM reservation for SR-IOV */
|
/* Firmware request VRAM reservation for SR-IOV */
|
||||||
adev->mman.fw_vram_usage_start_offset = (start_addr &
|
adev->mman.fw_vram_usage_start_offset = (start_addr &
|
||||||
(~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10;
|
(~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10;
|
||||||
adev->mman.fw_vram_usage_size = size << 10;
|
adev->mman.fw_vram_usage_size = fw_size << 10;
|
||||||
/* Use the default scratch size */
|
/* Use the default scratch size */
|
||||||
usage_bytes = 0;
|
*usage_bytes = 0;
|
||||||
} else {
|
} else {
|
||||||
usage_bytes = le16_to_cpu(firmware_usage->used_by_driver_in_kb) << 10;
|
*usage_bytes = drv_size << 10;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int amdgpu_atomfirmware_allocate_fb_v2_2(struct amdgpu_device *adev,
|
||||||
|
struct vram_usagebyfirmware_v2_2 *fw_usage, int *usage_bytes)
|
||||||
|
{
|
||||||
|
uint32_t fw_start_addr, fw_size, drv_start_addr, drv_size;
|
||||||
|
|
||||||
|
fw_start_addr = le32_to_cpu(fw_usage->fw_region_start_address_in_kb);
|
||||||
|
fw_size = le16_to_cpu(fw_usage->used_by_firmware_in_kb);
|
||||||
|
|
||||||
|
drv_start_addr = le32_to_cpu(fw_usage->driver_region0_start_address_in_kb);
|
||||||
|
drv_size = le32_to_cpu(fw_usage->used_by_driver_region0_in_kb);
|
||||||
|
|
||||||
|
DRM_DEBUG("atom requested fw start at %08x %dkb and drv start at %08x %dkb\n",
|
||||||
|
fw_start_addr,
|
||||||
|
fw_size,
|
||||||
|
drv_start_addr,
|
||||||
|
drv_size);
|
||||||
|
|
||||||
|
if ((fw_start_addr & (ATOM_VRAM_BLOCK_NEEDS_NO_RESERVATION << 30)) == 0) {
|
||||||
|
/* Firmware request VRAM reservation for SR-IOV */
|
||||||
|
adev->mman.fw_vram_usage_start_offset = (fw_start_addr &
|
||||||
|
(~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10;
|
||||||
|
adev->mman.fw_vram_usage_size = fw_size << 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((drv_start_addr & (ATOM_VRAM_BLOCK_NEEDS_NO_RESERVATION << 30)) == 0) {
|
||||||
|
/* driver request VRAM reservation for SR-IOV */
|
||||||
|
adev->mman.drv_vram_usage_start_offset = (drv_start_addr &
|
||||||
|
(~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10;
|
||||||
|
adev->mman.drv_vram_usage_size = drv_size << 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
*usage_bytes = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev)
|
||||||
|
{
|
||||||
|
struct atom_context *ctx = adev->mode_info.atom_context;
|
||||||
|
int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
|
||||||
|
vram_usagebyfirmware);
|
||||||
|
struct vram_usagebyfirmware_v2_1 *fw_usage_v2_1;
|
||||||
|
struct vram_usagebyfirmware_v2_2 *fw_usage_v2_2;
|
||||||
|
uint16_t data_offset;
|
||||||
|
uint8_t frev, crev;
|
||||||
|
int usage_bytes = 0;
|
||||||
|
|
||||||
|
if (amdgpu_atom_parse_data_header(ctx, index, NULL, &frev, &crev, &data_offset)) {
|
||||||
|
if (frev == 2 && crev == 1) {
|
||||||
|
fw_usage_v2_1 =
|
||||||
|
(struct vram_usagebyfirmware_v2_1 *)(ctx->bios + data_offset);
|
||||||
|
amdgpu_atomfirmware_allocate_fb_v2_1(adev,
|
||||||
|
fw_usage_v2_1,
|
||||||
|
&usage_bytes);
|
||||||
|
} else if (frev >= 2 && crev >= 2) {
|
||||||
|
fw_usage_v2_2 =
|
||||||
|
(struct vram_usagebyfirmware_v2_2 *)(ctx->bios + data_offset);
|
||||||
|
amdgpu_atomfirmware_allocate_fb_v2_2(adev,
|
||||||
|
fw_usage_v2_2,
|
||||||
|
&usage_bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->scratch_size_bytes = 0;
|
ctx->scratch_size_bytes = 0;
|
||||||
if (usage_bytes == 0)
|
if (usage_bytes == 0)
|
||||||
usage_bytes = 20 * 1024;
|
usage_bytes = 20 * 1024;
|
||||||
|
@ -1561,6 +1561,23 @@ static void amdgpu_ttm_fw_reserve_vram_fini(struct amdgpu_device *adev)
|
|||||||
NULL, &adev->mman.fw_vram_usage_va);
|
NULL, &adev->mman.fw_vram_usage_va);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Driver Reservation functions
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* amdgpu_ttm_drv_reserve_vram_fini - free drv reserved vram
|
||||||
|
*
|
||||||
|
* @adev: amdgpu_device pointer
|
||||||
|
*
|
||||||
|
* free drv reserved vram if it has been reserved.
|
||||||
|
*/
|
||||||
|
static void amdgpu_ttm_drv_reserve_vram_fini(struct amdgpu_device *adev)
|
||||||
|
{
|
||||||
|
amdgpu_bo_free_kernel(&adev->mman.drv_vram_usage_reserved_bo,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* amdgpu_ttm_fw_reserve_vram_init - create bo vram reservation from fw
|
* amdgpu_ttm_fw_reserve_vram_init - create bo vram reservation from fw
|
||||||
*
|
*
|
||||||
@ -1587,6 +1604,31 @@ static int amdgpu_ttm_fw_reserve_vram_init(struct amdgpu_device *adev)
|
|||||||
&adev->mman.fw_vram_usage_va);
|
&adev->mman.fw_vram_usage_va);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* amdgpu_ttm_drv_reserve_vram_init - create bo vram reservation from driver
|
||||||
|
*
|
||||||
|
* @adev: amdgpu_device pointer
|
||||||
|
*
|
||||||
|
* create bo vram reservation from drv.
|
||||||
|
*/
|
||||||
|
static int amdgpu_ttm_drv_reserve_vram_init(struct amdgpu_device *adev)
|
||||||
|
{
|
||||||
|
uint64_t vram_size = adev->gmc.visible_vram_size;
|
||||||
|
|
||||||
|
adev->mman.drv_vram_usage_reserved_bo = NULL;
|
||||||
|
|
||||||
|
if (adev->mman.drv_vram_usage_size == 0 ||
|
||||||
|
adev->mman.drv_vram_usage_size > vram_size)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return amdgpu_bo_create_kernel_at(adev,
|
||||||
|
adev->mman.drv_vram_usage_start_offset,
|
||||||
|
adev->mman.drv_vram_usage_size,
|
||||||
|
AMDGPU_GEM_DOMAIN_VRAM,
|
||||||
|
&adev->mman.drv_vram_usage_reserved_bo,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Memoy training reservation functions
|
* Memoy training reservation functions
|
||||||
*/
|
*/
|
||||||
@ -1754,6 +1796,14 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*The reserved vram for driver must be pinned to the specified
|
||||||
|
*place on the VRAM, so reserve it early.
|
||||||
|
*/
|
||||||
|
r = amdgpu_ttm_drv_reserve_vram_init(adev);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* only NAVI10 and onwards ASIC support for IP discovery.
|
* only NAVI10 and onwards ASIC support for IP discovery.
|
||||||
* If IP discovery enabled, a block of memory should be
|
* If IP discovery enabled, a block of memory should be
|
||||||
@ -1879,6 +1929,7 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev)
|
|||||||
amdgpu_bo_free_kernel(&adev->mman.sdma_access_bo, NULL,
|
amdgpu_bo_free_kernel(&adev->mman.sdma_access_bo, NULL,
|
||||||
&adev->mman.sdma_access_ptr);
|
&adev->mman.sdma_access_ptr);
|
||||||
amdgpu_ttm_fw_reserve_vram_fini(adev);
|
amdgpu_ttm_fw_reserve_vram_fini(adev);
|
||||||
|
amdgpu_ttm_drv_reserve_vram_fini(adev);
|
||||||
|
|
||||||
if (drm_dev_enter(adev_to_drm(adev), &idx)) {
|
if (drm_dev_enter(adev_to_drm(adev), &idx)) {
|
||||||
|
|
||||||
|
@ -84,6 +84,11 @@ struct amdgpu_mman {
|
|||||||
struct amdgpu_bo *fw_vram_usage_reserved_bo;
|
struct amdgpu_bo *fw_vram_usage_reserved_bo;
|
||||||
void *fw_vram_usage_va;
|
void *fw_vram_usage_va;
|
||||||
|
|
||||||
|
/* driver VRAM reservation */
|
||||||
|
u64 drv_vram_usage_start_offset;
|
||||||
|
u64 drv_vram_usage_size;
|
||||||
|
struct amdgpu_bo *drv_vram_usage_reserved_bo;
|
||||||
|
|
||||||
/* PAGE_SIZE'd BO for process memory r/w over SDMA. */
|
/* PAGE_SIZE'd BO for process memory r/w over SDMA. */
|
||||||
struct amdgpu_bo *sdma_access_bo;
|
struct amdgpu_bo *sdma_access_bo;
|
||||||
void *sdma_access_ptr;
|
void *sdma_access_ptr;
|
||||||
|
@ -706,9 +706,45 @@ struct atom_gpio_pin_lut_v2_1
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
***************************************************************************
|
* VBIOS/PRE-OS always reserve a FB region at the top of frame buffer. driver should not write
|
||||||
Data Table vram_usagebyfirmware structure
|
* access that region. driver can allocate their own reservation region as long as it does not
|
||||||
***************************************************************************
|
* overlap firwmare's reservation region.
|
||||||
|
* if (pre-NV1X) atom data table firmwareInfoTable version < 3.3:
|
||||||
|
* in this case, atom data table vram_usagebyfirmwareTable version always <= 2.1
|
||||||
|
* if VBIOS/UEFI GOP is posted:
|
||||||
|
* VBIOS/UEFIGOP update used_by_firmware_in_kb = total reserved size by VBIOS
|
||||||
|
* update start_address_in_kb = total_mem_size_in_kb - used_by_firmware_in_kb;
|
||||||
|
* ( total_mem_size_in_kb = reg(CONFIG_MEMSIZE)<<10)
|
||||||
|
* driver can allocate driver reservation region under firmware reservation,
|
||||||
|
* used_by_driver_in_kb = driver reservation size
|
||||||
|
* driver reservation start address = (start_address_in_kb - used_by_driver_in_kb)
|
||||||
|
* Comment1[hchan]: There is only one reservation at the beginning of the FB reserved by
|
||||||
|
* host driver. Host driver would overwrite the table with the following
|
||||||
|
* used_by_firmware_in_kb = total reserved size for pf-vf info exchange and
|
||||||
|
* set SRIOV_MSG_SHARE_RESERVATION mask start_address_in_kb = 0
|
||||||
|
* else there is no VBIOS reservation region:
|
||||||
|
* driver must allocate driver reservation region at top of FB.
|
||||||
|
* driver set used_by_driver_in_kb = driver reservation size
|
||||||
|
* driver reservation start address = (total_mem_size_in_kb - used_by_driver_in_kb)
|
||||||
|
* same as Comment1
|
||||||
|
* else (NV1X and after):
|
||||||
|
* if VBIOS/UEFI GOP is posted:
|
||||||
|
* VBIOS/UEFIGOP update:
|
||||||
|
* used_by_firmware_in_kb = atom_firmware_Info_v3_3.fw_reserved_size_in_kb;
|
||||||
|
* start_address_in_kb = total_mem_size_in_kb - used_by_firmware_in_kb;
|
||||||
|
* (total_mem_size_in_kb = reg(CONFIG_MEMSIZE)<<10)
|
||||||
|
* if vram_usagebyfirmwareTable version <= 2.1:
|
||||||
|
* driver can allocate driver reservation region under firmware reservation,
|
||||||
|
* driver set used_by_driver_in_kb = driver reservation size
|
||||||
|
* driver reservation start address = start_address_in_kb - used_by_driver_in_kb
|
||||||
|
* same as Comment1
|
||||||
|
* else driver can:
|
||||||
|
* allocate it reservation any place as long as it does overlap pre-OS FW reservation area
|
||||||
|
* set used_by_driver_region0_in_kb = driver reservation size
|
||||||
|
* set driver_region0_start_address_in_kb = driver reservation region start address
|
||||||
|
* Comment2[hchan]: Host driver can set used_by_firmware_in_kb and start_address_in_kb to
|
||||||
|
* zero as the reservation for VF as it doesn’t exist. And Host driver should also
|
||||||
|
* update atom_firmware_Info table to remove the same VBIOS reservation as well.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct vram_usagebyfirmware_v2_1
|
struct vram_usagebyfirmware_v2_1
|
||||||
@ -719,6 +755,15 @@ struct vram_usagebyfirmware_v2_1
|
|||||||
uint16_t used_by_driver_in_kb;
|
uint16_t used_by_driver_in_kb;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct vram_usagebyfirmware_v2_2 {
|
||||||
|
struct atom_common_table_header table_header;
|
||||||
|
uint32_t fw_region_start_address_in_kb;
|
||||||
|
uint16_t used_by_firmware_in_kb;
|
||||||
|
uint16_t reserved;
|
||||||
|
uint32_t driver_region0_start_address_in_kb;
|
||||||
|
uint32_t used_by_driver_region0_in_kb;
|
||||||
|
uint32_t reserved32[7];
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
|
Loading…
x
Reference in New Issue
Block a user