Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Tong Liu01 and committed by
Alex Deucher
4864f2ee 3e931368

+191 -32
+81 -23
drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
··· 101 101 } 102 102 } 103 103 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 + 104 168 int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev) 105 169 { 106 170 struct atom_context *ctx = adev->mode_info.atom_context; 107 171 int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, 108 172 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; 111 175 uint16_t data_offset; 176 + uint8_t frev, crev; 112 177 int usage_bytes = 0; 113 178 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); 135 192 } 136 193 } 194 + 137 195 ctx->scratch_size_bytes = 0; 138 196 if (usage_bytes == 0) 139 197 usage_bytes = 20 * 1024;
+51
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
··· 1561 1561 NULL, &adev->mman.fw_vram_usage_va); 1562 1562 } 1563 1563 1564 + /* 1565 + * Driver Reservation functions 1566 + */ 1567 + /** 1568 + * amdgpu_ttm_drv_reserve_vram_fini - free drv reserved vram 1569 + * 1570 + * @adev: amdgpu_device pointer 1571 + * 1572 + * free drv reserved vram if it has been reserved. 1573 + */ 1574 + static void amdgpu_ttm_drv_reserve_vram_fini(struct amdgpu_device *adev) 1575 + { 1576 + amdgpu_bo_free_kernel(&adev->mman.drv_vram_usage_reserved_bo, 1577 + NULL, 1578 + NULL); 1579 + } 1580 + 1564 1581 /** 1565 1582 * amdgpu_ttm_fw_reserve_vram_init - create bo vram reservation from fw 1566 1583 * ··· 1602 1585 AMDGPU_GEM_DOMAIN_VRAM, 1603 1586 &adev->mman.fw_vram_usage_reserved_bo, 1604 1587 &adev->mman.fw_vram_usage_va); 1588 + } 1589 + 1590 + /** 1591 + * amdgpu_ttm_drv_reserve_vram_init - create bo vram reservation from driver 1592 + * 1593 + * @adev: amdgpu_device pointer 1594 + * 1595 + * create bo vram reservation from drv. 1596 + */ 1597 + static int amdgpu_ttm_drv_reserve_vram_init(struct amdgpu_device *adev) 1598 + { 1599 + uint64_t vram_size = adev->gmc.visible_vram_size; 1600 + 1601 + adev->mman.drv_vram_usage_reserved_bo = NULL; 1602 + 1603 + if (adev->mman.drv_vram_usage_size == 0 || 1604 + adev->mman.drv_vram_usage_size > vram_size) 1605 + return 0; 1606 + 1607 + return amdgpu_bo_create_kernel_at(adev, 1608 + adev->mman.drv_vram_usage_start_offset, 1609 + adev->mman.drv_vram_usage_size, 1610 + AMDGPU_GEM_DOMAIN_VRAM, 1611 + &adev->mman.drv_vram_usage_reserved_bo, 1612 + NULL); 1605 1613 } 1606 1614 1607 1615 /* ··· 1797 1755 } 1798 1756 1799 1757 /* 1758 + *The reserved vram for driver must be pinned to the specified 1759 + *place on the VRAM, so reserve it early. 1760 + */ 1761 + r = amdgpu_ttm_drv_reserve_vram_init(adev); 1762 + if (r) 1763 + return r; 1764 + 1765 + /* 1800 1766 * only NAVI10 and onwards ASIC support for IP discovery. 1801 1767 * If IP discovery enabled, a block of memory should be 1802 1768 * reserved for IP discovey. ··· 1929 1879 amdgpu_bo_free_kernel(&adev->mman.sdma_access_bo, NULL, 1930 1880 &adev->mman.sdma_access_ptr); 1931 1881 amdgpu_ttm_fw_reserve_vram_fini(adev); 1882 + amdgpu_ttm_drv_reserve_vram_fini(adev); 1932 1883 1933 1884 if (drm_dev_enter(adev_to_drm(adev), &idx)) { 1934 1885
+5
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
··· 84 84 struct amdgpu_bo *fw_vram_usage_reserved_bo; 85 85 void *fw_vram_usage_va; 86 86 87 + /* driver VRAM reservation */ 88 + u64 drv_vram_usage_start_offset; 89 + u64 drv_vram_usage_size; 90 + struct amdgpu_bo *drv_vram_usage_reserved_bo; 91 + 87 92 /* PAGE_SIZE'd BO for process memory r/w over SDMA. */ 88 93 struct amdgpu_bo *sdma_access_bo; 89 94 void *sdma_access_ptr;
+54 -9
drivers/gpu/drm/amd/include/atomfirmware.h
··· 705 705 }; 706 706 707 707 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 + */ 713 749 714 750 struct vram_usagebyfirmware_v2_1 715 751 { 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; 720 756 }; 721 757 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 + }; 722 767 723 768 /* 724 769 ***************************************************************************