aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHorace Chen <horace.chen@amd.com>2017-09-29 02:41:57 -0400
committerAlex Deucher <alexander.deucher@amd.com>2017-10-09 16:30:16 -0400
commita05502e5cfa9abe17a16592be82c2f5692c91f35 (patch)
tree4469aaafa3b34b2f81768ee775c08ee9e218ee45 /drivers
parent6d16dac85c081825af58111023428c43d1da7e1a (diff)
drm/amdgpu: Reserve shared memory on VRAM for SR-IOV
SR-IOV need to reserve a piece of shared VRAM at the exact place to exchange data betweem PF and VF. The start address and size of the shared mem are passed to guest through VBIOS structure VRAM_UsageByFirmware. VRAM_UsageByFirmware is a general feature in VBIOS, it indicates that VBIOS need to reserve a piece of memory on the VRAM. Because the mem address is specified. Reserve it early in amdgpu_ttm_init to make sure that it can monoplize the space. Signed-off-by: Horace Chen <horace.chen@amd.com> Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h14
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c18
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c76
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c9
4 files changed, 116 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index a23b8af95319..5c4bed7778d9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1379,6 +1379,18 @@ struct amdgpu_atcs {
1379}; 1379};
1380 1380
1381/* 1381/*
1382 * Firmware VRAM reservation
1383 */
1384struct amdgpu_fw_vram_usage {
1385 u64 start_offset;
1386 u64 size;
1387 struct amdgpu_bo *reserved_bo;
1388 void *va;
1389};
1390
1391int amdgpu_fw_reserve_vram_init(struct amdgpu_device *adev);
1392
1393/*
1382 * CGS 1394 * CGS
1383 */ 1395 */
1384struct cgs_device *amdgpu_cgs_create_device(struct amdgpu_device *adev); 1396struct cgs_device *amdgpu_cgs_create_device(struct amdgpu_device *adev);
@@ -1582,6 +1594,8 @@ struct amdgpu_device {
1582 struct delayed_work late_init_work; 1594 struct delayed_work late_init_work;
1583 1595
1584 struct amdgpu_virt virt; 1596 struct amdgpu_virt virt;
1597 /* firmware VRAM reservation */
1598 struct amdgpu_fw_vram_usage fw_vram_usage;
1585 1599
1586 /* link all shadow bo */ 1600 /* link all shadow bo */
1587 struct list_head shadow_list; 1601 struct list_head shadow_list;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
index ce443586a0c7..f66d33e4baca 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
@@ -1807,6 +1807,8 @@ int amdgpu_atombios_allocate_fb_scratch(struct amdgpu_device *adev)
1807 uint16_t data_offset; 1807 uint16_t data_offset;
1808 int usage_bytes = 0; 1808 int usage_bytes = 0;
1809 struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage; 1809 struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage;
1810 u64 start_addr;
1811 u64 size;
1810 1812
1811 if (amdgpu_atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) { 1813 if (amdgpu_atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) {
1812 firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset); 1814 firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset);
@@ -1815,7 +1817,21 @@ int amdgpu_atombios_allocate_fb_scratch(struct amdgpu_device *adev)
1815 le32_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware), 1817 le32_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware),
1816 le16_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb)); 1818 le16_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb));
1817 1819
1818 usage_bytes = le16_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb) * 1024; 1820 start_addr = firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware;
1821 size = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb;
1822
1823 if ((uint32_t)(start_addr & ATOM_VRAM_OPERATION_FLAGS_MASK) ==
1824 (uint32_t)(ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATION <<
1825 ATOM_VRAM_OPERATION_FLAGS_SHIFT)) {
1826 /* Firmware request VRAM reservation for SR-IOV */
1827 adev->fw_vram_usage.start_offset = (start_addr &
1828 (~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10;
1829 adev->fw_vram_usage.size = size << 10;
1830 /* Use the default scratch size */
1831 usage_bytes = 0;
1832 } else {
1833 usage_bytes = le16_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb) * 1024;
1834 }
1819 } 1835 }
1820 ctx->scratch_size_bytes = 0; 1836 ctx->scratch_size_bytes = 0;
1821 if (usage_bytes == 0) 1837 if (usage_bytes == 0)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 1949d8aedf49..7b3e3b5461c3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -658,6 +658,81 @@ void amdgpu_gart_location(struct amdgpu_device *adev, struct amdgpu_mc *mc)
658} 658}
659 659
660/* 660/*
661 * Firmware Reservation functions
662 */
663/**
664 * amdgpu_fw_reserve_vram_fini - free fw reserved vram
665 *
666 * @adev: amdgpu_device pointer
667 *
668 * free fw reserved vram if it has been reserved.
669 */
670void amdgpu_fw_reserve_vram_fini(struct amdgpu_device *adev)
671{
672 amdgpu_bo_free_kernel(&adev->fw_vram_usage.reserved_bo,
673 NULL, &adev->fw_vram_usage.va);
674}
675
676/**
677 * amdgpu_fw_reserve_vram_init - create bo vram reservation from fw
678 *
679 * @adev: amdgpu_device pointer
680 *
681 * create bo vram reservation from fw.
682 */
683int amdgpu_fw_reserve_vram_init(struct amdgpu_device *adev)
684{
685 int r = 0;
686 u64 gpu_addr;
687 u64 vram_size = adev->mc.visible_vram_size;
688
689 adev->fw_vram_usage.va = NULL;
690 adev->fw_vram_usage.reserved_bo = NULL;
691
692 if (adev->fw_vram_usage.size > 0 &&
693 adev->fw_vram_usage.size <= vram_size) {
694
695 r = amdgpu_bo_create(adev, adev->fw_vram_usage.size,
696 PAGE_SIZE, true, 0,
697 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
698 AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, NULL, NULL, 0,
699 &adev->fw_vram_usage.reserved_bo);
700 if (r)
701 goto error_create;
702
703 r = amdgpu_bo_reserve(adev->fw_vram_usage.reserved_bo, false);
704 if (r)
705 goto error_reserve;
706 r = amdgpu_bo_pin_restricted(adev->fw_vram_usage.reserved_bo,
707 AMDGPU_GEM_DOMAIN_VRAM,
708 adev->fw_vram_usage.start_offset,
709 (adev->fw_vram_usage.start_offset +
710 adev->fw_vram_usage.size), &gpu_addr);
711 if (r)
712 goto error_pin;
713 r = amdgpu_bo_kmap(adev->fw_vram_usage.reserved_bo,
714 &adev->fw_vram_usage.va);
715 if (r)
716 goto error_kmap;
717
718 amdgpu_bo_unreserve(adev->fw_vram_usage.reserved_bo);
719 }
720 return r;
721
722error_kmap:
723 amdgpu_bo_unpin(adev->fw_vram_usage.reserved_bo);
724error_pin:
725 amdgpu_bo_unreserve(adev->fw_vram_usage.reserved_bo);
726error_reserve:
727 amdgpu_bo_unref(&adev->fw_vram_usage.reserved_bo);
728error_create:
729 adev->fw_vram_usage.va = NULL;
730 adev->fw_vram_usage.reserved_bo = NULL;
731 return r;
732}
733
734
735/*
661 * GPU helpers function. 736 * GPU helpers function.
662 */ 737 */
663/** 738/**
@@ -2300,6 +2375,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
2300 /* evict vram memory */ 2375 /* evict vram memory */
2301 amdgpu_bo_evict_vram(adev); 2376 amdgpu_bo_evict_vram(adev);
2302 amdgpu_ib_pool_fini(adev); 2377 amdgpu_ib_pool_fini(adev);
2378 amdgpu_fw_reserve_vram_fini(adev);
2303 amdgpu_fence_driver_fini(adev); 2379 amdgpu_fence_driver_fini(adev);
2304 amdgpu_fbdev_fini(adev); 2380 amdgpu_fbdev_fini(adev);
2305 r = amdgpu_fini(adev); 2381 r = amdgpu_fini(adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 15a28578d458..1f68a146e26c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -1255,6 +1255,15 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
1255 /* Change the size here instead of the init above so only lpfn is affected */ 1255 /* Change the size here instead of the init above so only lpfn is affected */
1256 amdgpu_ttm_set_active_vram_size(adev, adev->mc.visible_vram_size); 1256 amdgpu_ttm_set_active_vram_size(adev, adev->mc.visible_vram_size);
1257 1257
1258 /*
1259 *The reserved vram for firmware must be pinned to the specified
1260 *place on the VRAM, so reserve it early.
1261 */
1262 r = amdgpu_fw_reserve_vram_init(adev);
1263 if (r) {
1264 return r;
1265 }
1266
1258 r = amdgpu_bo_create_kernel(adev, adev->mc.stolen_size, PAGE_SIZE, 1267 r = amdgpu_bo_create_kernel(adev, adev->mc.stolen_size, PAGE_SIZE,
1259 AMDGPU_GEM_DOMAIN_VRAM, 1268 AMDGPU_GEM_DOMAIN_VRAM,
1260 &adev->stolen_vga_memory, 1269 &adev->stolen_vga_memory,