Skip to content

Commit 526defe

Browse files
Tong Liu01gregkh
authored andcommitted
drm/amdgpu: add vram reservation based on vram_usagebyfirmware_v2_2
commit 4864f2e upstream 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> Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 99255a2 commit 526defe

File tree

4 files changed

+191
-32
lines changed

4 files changed

+191
-32
lines changed

drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c

Lines changed: 81 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -101,39 +101,97 @@ void amdgpu_atomfirmware_scratch_regs_init(struct amdgpu_device *adev)
101101
}
102102
}
103103

104+
static int amdgpu_atomfirmware_allocate_fb_v2_1(struct amdgpu_device *adev,
105+
struct vram_usagebyfirmware_v2_1 *fw_usage, int *usage_bytes)
106+
{
107+
uint32_t start_addr, fw_size, drv_size;
108+
109+
start_addr = le32_to_cpu(fw_usage->start_address_in_kb);
110+
fw_size = le16_to_cpu(fw_usage->used_by_firmware_in_kb);
111+
drv_size = le16_to_cpu(fw_usage->used_by_driver_in_kb);
112+
113+
DRM_DEBUG("atom firmware v2_1 requested %08x %dkb fw %dkb drv\n",
114+
start_addr,
115+
fw_size,
116+
drv_size);
117+
118+
if ((start_addr & ATOM_VRAM_OPERATION_FLAGS_MASK) ==
119+
(uint32_t)(ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATION <<
120+
ATOM_VRAM_OPERATION_FLAGS_SHIFT)) {
121+
/* Firmware request VRAM reservation for SR-IOV */
122+
adev->mman.fw_vram_usage_start_offset = (start_addr &
123+
(~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10;
124+
adev->mman.fw_vram_usage_size = fw_size << 10;
125+
/* Use the default scratch size */
126+
*usage_bytes = 0;
127+
} else {
128+
*usage_bytes = drv_size << 10;
129+
}
130+
return 0;
131+
}
132+
133+
static int amdgpu_atomfirmware_allocate_fb_v2_2(struct amdgpu_device *adev,
134+
struct vram_usagebyfirmware_v2_2 *fw_usage, int *usage_bytes)
135+
{
136+
uint32_t fw_start_addr, fw_size, drv_start_addr, drv_size;
137+
138+
fw_start_addr = le32_to_cpu(fw_usage->fw_region_start_address_in_kb);
139+
fw_size = le16_to_cpu(fw_usage->used_by_firmware_in_kb);
140+
141+
drv_start_addr = le32_to_cpu(fw_usage->driver_region0_start_address_in_kb);
142+
drv_size = le32_to_cpu(fw_usage->used_by_driver_region0_in_kb);
143+
144+
DRM_DEBUG("atom requested fw start at %08x %dkb and drv start at %08x %dkb\n",
145+
fw_start_addr,
146+
fw_size,
147+
drv_start_addr,
148+
drv_size);
149+
150+
if ((fw_start_addr & (ATOM_VRAM_BLOCK_NEEDS_NO_RESERVATION << 30)) == 0) {
151+
/* Firmware request VRAM reservation for SR-IOV */
152+
adev->mman.fw_vram_usage_start_offset = (fw_start_addr &
153+
(~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10;
154+
adev->mman.fw_vram_usage_size = fw_size << 10;
155+
}
156+
157+
if ((drv_start_addr & (ATOM_VRAM_BLOCK_NEEDS_NO_RESERVATION << 30)) == 0) {
158+
/* driver request VRAM reservation for SR-IOV */
159+
adev->mman.drv_vram_usage_start_offset = (drv_start_addr &
160+
(~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10;
161+
adev->mman.drv_vram_usage_size = drv_size << 10;
162+
}
163+
164+
*usage_bytes = 0;
165+
return 0;
166+
}
167+
104168
int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev)
105169
{
106170
struct atom_context *ctx = adev->mode_info.atom_context;
107171
int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
108172
vram_usagebyfirmware);
109-
struct vram_usagebyfirmware_v2_1 *firmware_usage;
110-
uint32_t start_addr, size;
173+
struct vram_usagebyfirmware_v2_1 *fw_usage_v2_1;
174+
struct vram_usagebyfirmware_v2_2 *fw_usage_v2_2;
111175
uint16_t data_offset;
176+
uint8_t frev, crev;
112177
int usage_bytes = 0;
113178

114-
if (amdgpu_atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) {
115-
firmware_usage = (struct vram_usagebyfirmware_v2_1 *)(ctx->bios + data_offset);
116-
DRM_DEBUG("atom firmware requested %08x %dkb fw %dkb drv\n",
117-
le32_to_cpu(firmware_usage->start_address_in_kb),
118-
le16_to_cpu(firmware_usage->used_by_firmware_in_kb),
119-
le16_to_cpu(firmware_usage->used_by_driver_in_kb));
120-
121-
start_addr = le32_to_cpu(firmware_usage->start_address_in_kb);
122-
size = le16_to_cpu(firmware_usage->used_by_firmware_in_kb);
123-
124-
if ((uint32_t)(start_addr & ATOM_VRAM_OPERATION_FLAGS_MASK) ==
125-
(uint32_t)(ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATION <<
126-
ATOM_VRAM_OPERATION_FLAGS_SHIFT)) {
127-
/* Firmware request VRAM reservation for SR-IOV */
128-
adev->mman.fw_vram_usage_start_offset = (start_addr &
129-
(~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10;
130-
adev->mman.fw_vram_usage_size = size << 10;
131-
/* Use the default scratch size */
132-
usage_bytes = 0;
133-
} else {
134-
usage_bytes = le16_to_cpu(firmware_usage->used_by_driver_in_kb) << 10;
179+
if (amdgpu_atom_parse_data_header(ctx, index, NULL, &frev, &crev, &data_offset)) {
180+
if (frev == 2 && crev == 1) {
181+
fw_usage_v2_1 =
182+
(struct vram_usagebyfirmware_v2_1 *)(ctx->bios + data_offset);
183+
amdgpu_atomfirmware_allocate_fb_v2_1(adev,
184+
fw_usage_v2_1,
185+
&usage_bytes);
186+
} else if (frev >= 2 && crev >= 2) {
187+
fw_usage_v2_2 =
188+
(struct vram_usagebyfirmware_v2_2 *)(ctx->bios + data_offset);
189+
amdgpu_atomfirmware_allocate_fb_v2_2(adev,
190+
fw_usage_v2_2,
191+
&usage_bytes);
135192
}
136193
}
194+
137195
ctx->scratch_size_bytes = 0;
138196
if (usage_bytes == 0)
139197
usage_bytes = 20 * 1024;

drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1537,6 +1537,23 @@ static void amdgpu_ttm_fw_reserve_vram_fini(struct amdgpu_device *adev)
15371537
NULL, &adev->mman.fw_vram_usage_va);
15381538
}
15391539

1540+
/*
1541+
* Driver Reservation functions
1542+
*/
1543+
/**
1544+
* amdgpu_ttm_drv_reserve_vram_fini - free drv reserved vram
1545+
*
1546+
* @adev: amdgpu_device pointer
1547+
*
1548+
* free drv reserved vram if it has been reserved.
1549+
*/
1550+
static void amdgpu_ttm_drv_reserve_vram_fini(struct amdgpu_device *adev)
1551+
{
1552+
amdgpu_bo_free_kernel(&adev->mman.drv_vram_usage_reserved_bo,
1553+
NULL,
1554+
NULL);
1555+
}
1556+
15401557
/**
15411558
* amdgpu_ttm_fw_reserve_vram_init - create bo vram reservation from fw
15421559
*
@@ -1563,6 +1580,31 @@ static int amdgpu_ttm_fw_reserve_vram_init(struct amdgpu_device *adev)
15631580
&adev->mman.fw_vram_usage_va);
15641581
}
15651582

1583+
/**
1584+
* amdgpu_ttm_drv_reserve_vram_init - create bo vram reservation from driver
1585+
*
1586+
* @adev: amdgpu_device pointer
1587+
*
1588+
* create bo vram reservation from drv.
1589+
*/
1590+
static int amdgpu_ttm_drv_reserve_vram_init(struct amdgpu_device *adev)
1591+
{
1592+
uint64_t vram_size = adev->gmc.visible_vram_size;
1593+
1594+
adev->mman.drv_vram_usage_reserved_bo = NULL;
1595+
1596+
if (adev->mman.drv_vram_usage_size == 0 ||
1597+
adev->mman.drv_vram_usage_size > vram_size)
1598+
return 0;
1599+
1600+
return amdgpu_bo_create_kernel_at(adev,
1601+
adev->mman.drv_vram_usage_start_offset,
1602+
adev->mman.drv_vram_usage_size,
1603+
AMDGPU_GEM_DOMAIN_VRAM,
1604+
&adev->mman.drv_vram_usage_reserved_bo,
1605+
NULL);
1606+
}
1607+
15661608
/*
15671609
* Memoy training reservation functions
15681610
*/
@@ -1730,6 +1772,14 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
17301772
return r;
17311773
}
17321774

1775+
/*
1776+
*The reserved vram for driver must be pinned to the specified
1777+
*place on the VRAM, so reserve it early.
1778+
*/
1779+
r = amdgpu_ttm_drv_reserve_vram_init(adev);
1780+
if (r)
1781+
return r;
1782+
17331783
/*
17341784
* only NAVI10 and onwards ASIC support for IP discovery.
17351785
* If IP discovery enabled, a block of memory should be
@@ -1855,6 +1905,7 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev)
18551905
amdgpu_bo_free_kernel(&adev->mman.sdma_access_bo, NULL,
18561906
&adev->mman.sdma_access_ptr);
18571907
amdgpu_ttm_fw_reserve_vram_fini(adev);
1908+
amdgpu_ttm_drv_reserve_vram_fini(adev);
18581909

18591910
if (drm_dev_enter(adev_to_drm(adev), &idx)) {
18601911

drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ struct amdgpu_mman {
8686
struct amdgpu_bo *fw_vram_usage_reserved_bo;
8787
void *fw_vram_usage_va;
8888

89+
/* driver VRAM reservation */
90+
u64 drv_vram_usage_start_offset;
91+
u64 drv_vram_usage_size;
92+
struct amdgpu_bo *drv_vram_usage_reserved_bo;
93+
8994
/* PAGE_SIZE'd BO for process memory r/w over SDMA. */
9095
struct amdgpu_bo *sdma_access_bo;
9196
void *sdma_access_ptr;

drivers/gpu/drm/amd/include/atomfirmware.h

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -705,20 +705,65 @@ struct atom_gpio_pin_lut_v2_1
705705
};
706706

707707

708-
/*
709-
***************************************************************************
710-
Data Table vram_usagebyfirmware structure
711-
***************************************************************************
712-
*/
708+
/*
709+
* VBIOS/PRE-OS always reserve a FB region at the top of frame buffer. driver should not write
710+
* access that region. driver can allocate their own reservation region as long as it does not
711+
* overlap firwmare's reservation region.
712+
* if (pre-NV1X) atom data table firmwareInfoTable version < 3.3:
713+
* in this case, atom data table vram_usagebyfirmwareTable version always <= 2.1
714+
* if VBIOS/UEFI GOP is posted:
715+
* VBIOS/UEFIGOP update used_by_firmware_in_kb = total reserved size by VBIOS
716+
* update start_address_in_kb = total_mem_size_in_kb - used_by_firmware_in_kb;
717+
* ( total_mem_size_in_kb = reg(CONFIG_MEMSIZE)<<10)
718+
* driver can allocate driver reservation region under firmware reservation,
719+
* used_by_driver_in_kb = driver reservation size
720+
* driver reservation start address = (start_address_in_kb - used_by_driver_in_kb)
721+
* Comment1[hchan]: There is only one reservation at the beginning of the FB reserved by
722+
* host driver. Host driver would overwrite the table with the following
723+
* used_by_firmware_in_kb = total reserved size for pf-vf info exchange and
724+
* set SRIOV_MSG_SHARE_RESERVATION mask start_address_in_kb = 0
725+
* else there is no VBIOS reservation region:
726+
* driver must allocate driver reservation region at top of FB.
727+
* driver set used_by_driver_in_kb = driver reservation size
728+
* driver reservation start address = (total_mem_size_in_kb - used_by_driver_in_kb)
729+
* same as Comment1
730+
* else (NV1X and after):
731+
* if VBIOS/UEFI GOP is posted:
732+
* VBIOS/UEFIGOP update:
733+
* used_by_firmware_in_kb = atom_firmware_Info_v3_3.fw_reserved_size_in_kb;
734+
* start_address_in_kb = total_mem_size_in_kb - used_by_firmware_in_kb;
735+
* (total_mem_size_in_kb = reg(CONFIG_MEMSIZE)<<10)
736+
* if vram_usagebyfirmwareTable version <= 2.1:
737+
* driver can allocate driver reservation region under firmware reservation,
738+
* driver set used_by_driver_in_kb = driver reservation size
739+
* driver reservation start address = start_address_in_kb - used_by_driver_in_kb
740+
* same as Comment1
741+
* else driver can:
742+
* allocate it reservation any place as long as it does overlap pre-OS FW reservation area
743+
* set used_by_driver_region0_in_kb = driver reservation size
744+
* set driver_region0_start_address_in_kb = driver reservation region start address
745+
* Comment2[hchan]: Host driver can set used_by_firmware_in_kb and start_address_in_kb to
746+
* zero as the reservation for VF as it doesn’t exist. And Host driver should also
747+
* update atom_firmware_Info table to remove the same VBIOS reservation as well.
748+
*/
713749

714750
struct vram_usagebyfirmware_v2_1
715751
{
716-
struct atom_common_table_header table_header;
717-
uint32_t start_address_in_kb;
718-
uint16_t used_by_firmware_in_kb;
719-
uint16_t used_by_driver_in_kb;
752+
struct atom_common_table_header table_header;
753+
uint32_t start_address_in_kb;
754+
uint16_t used_by_firmware_in_kb;
755+
uint16_t used_by_driver_in_kb;
720756
};
721757

758+
struct vram_usagebyfirmware_v2_2 {
759+
struct atom_common_table_header table_header;
760+
uint32_t fw_region_start_address_in_kb;
761+
uint16_t used_by_firmware_in_kb;
762+
uint16_t reserved;
763+
uint32_t driver_region0_start_address_in_kb;
764+
uint32_t used_by_driver_region0_in_kb;
765+
uint32_t reserved32[7];
766+
};
722767

723768
/*
724769
***************************************************************************

0 commit comments

Comments
 (0)