> -----Original Message----- > From: amd-gfx [mailto:amd-gfx-bounces at lists.freedesktop.org] On Behalf > Of Horace Chen > Sent: Wednesday, September 27, 2017 5:24 AM > To: amd-gfx at lists.freedesktop.org > Cc: Deucher, Alexander; Chen, Horace > Subject: [PATCH 3/3] drm/amdgpu: Reserve shared memory on VRAM for > SR-IOV > > SR-IOV need to reserve a piece of shared VRAM 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. > > Signed-off-by: Horace Chen <horace.chen at amd.com> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu.h | 17 ++++++++ > drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c | 18 +++++++- > drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 62 > ++++++++++++++++++++++++++++ > drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 9 ++++ > 4 files changed, 105 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > index a5b0b67..ac53dba 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > @@ -1380,6 +1380,21 @@ struct amdgpu_atcs { > }; > > /* > + * Firmware VRAM reservation > + */ > +#define KB_TO_BYTE(x) ((x) << 10) > +#define BYTE_TO_KB(x) ((x) >> 10) > + > +struct amdgpu_fw_vram_usage { > + uint32_t start_address_in_kb; > + uint16_t size_in_kb; Just store these in bytes. Do the conversion when you read them out of the vbios table. That's more consistent with how we start addresses elsewhere in the driver. Alex > + struct amdgpu_bo *reserved_bo; > + volatile uint32_t *va; > +}; > + > +int amdgpu_fw_reserve_vram_init(struct amdgpu_device *adev); > + > +/* > * CGS > */ > struct cgs_device *amdgpu_cgs_create_device(struct amdgpu_device > *adev); > @@ -1588,6 +1603,8 @@ struct amdgpu_device { > struct delayed_work late_init_work; > > struct amdgpu_virt virt; > + /* firmware VRAM reservation */ > + struct amdgpu_fw_vram_usage fw_vram_usage; > > /* link all shadow bo */ > 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 ce44358..56bfddf 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) > uint16_t data_offset; > int usage_bytes = 0; > struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage; > + uint32_t start_addr; > + uint16_t size; > > if (amdgpu_atom_parse_data_header(ctx, index, NULL, NULL, NULL, > &data_offset)) { > 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) > le32_to_cpu(firmware_usage- > >asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware), > le16_to_cpu(firmware_usage- > >asFirmwareVramReserveInfo[0].usFirmwareUseInKb)); > > - usage_bytes = le16_to_cpu(firmware_usage- > >asFirmwareVramReserveInfo[0].usFirmwareUseInKb) * 1024; > + start_addr = firmware_usage- > >asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware; > + size = firmware_usage- > >asFirmwareVramReserveInfo[0].usFirmwareUseInKb; > + > + if ((uint32_t)(start_addr & > ATOM_VRAM_OPERATION_FLAGS_MASK) == > + > (uint32_t)(ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATIO > N << > + ATOM_VRAM_OPERATION_FLAGS_SHIFT)) { > + /* Firmware request VRAM reservation for SR-IOV */ > + adev->fw_vram_usage.start_address_in_kb = > + start_addr & > (~ATOM_VRAM_OPERATION_FLAGS_MASK); > + adev->fw_vram_usage.size_in_kb = size; > + /* Use the default scratch size */ > + usage_bytes = 0; > + } else { > + usage_bytes = le16_to_cpu(firmware_usage- > >asFirmwareVramReserveInfo[0].usFirmwareUseInKb) * 1024; > + } > } > ctx->scratch_size_bytes = 0; > 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 a86d856..3da87cc 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > @@ -658,6 +658,66 @@ void amdgpu_gart_location(struct amdgpu_device > *adev, struct amdgpu_mc *mc) > } > > /* > + * Firmware Reservation function > + */ > +/** > + * amdgpu_fw_reserve_vram_fini - free fw reserved vram > + * > + * @adev: amdgpu_device pointer > + * > + * free fw reserved vram if it is reserved. > + */ > +void amdgpu_fw_reserve_vram_fini(struct amdgpu_device *adev) > +{ > + > + if (adev->fw_vram_usage.reserved_bo == NULL) > + return; > + > + amdgpu_bo_free_vram_specified(&adev- > >fw_vram_usage.reserved_bo, NULL, > + (void **)&adev->fw_vram_usage.va); > + adev->fw_vram_usage.reserved_bo = NULL; > +} > + > +/** > + * amdgpu_fw_reserve_vram_fini - create bo vram reservation from fw > + * > + * @adev: amdgpu_device pointer > + * > + * create bo vram reservation from fw. > + */ > +int amdgpu_fw_reserve_vram_init(struct amdgpu_device *adev) > +{ > + int r = 0; > + u64 gpu_addr; > + u64 vram_size = adev->mc.visible_vram_size; > + u64 start_addr; > + u32 size; > + > + adev->fw_vram_usage.va = NULL; > + adev->fw_vram_usage.reserved_bo = NULL; > + > + if (adev->fw_vram_usage.size_in_kb > 0 && > + KB_TO_BYTE((u64)adev->fw_vram_usage.size_in_kb) <= > vram_size) { > + > + start_addr = > + KB_TO_BYTE((u64)adev- > >fw_vram_usage.start_address_in_kb); > + size = KB_TO_BYTE((u64)adev->fw_vram_usage.size_in_kb); > + > + r = amdgpu_bo_create_vram_specified(adev, > + start_addr, size, PAGE_SIZE, > + AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED > | > + AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, > + &adev->fw_vram_usage.reserved_bo, > + &gpu_addr, (void **)&adev->fw_vram_usage.va); > + if (r) > + dev_info(adev->dev, "Reserve VRAM for firmware > failed"); > + } > + > + return r; > +} > + > + > +/* > * GPU helpers function. > */ > /** > @@ -2055,6 +2115,7 @@ int amdgpu_device_init(struct amdgpu_device > *adev, > adev->vm_manager.vm_pte_num_rings = 0; > adev->gart.gart_funcs = NULL; > adev->fence_context = > dma_fence_context_alloc(AMDGPU_MAX_RINGS); > + adev->fw_vram_usage.size_in_kb = 0; No need to set this explicitly. The device structure is already initialized to 0 at allocation time. > > adev->smc_rreg = &amdgpu_invalid_rreg; > adev->smc_wreg = &amdgpu_invalid_wreg; > @@ -2331,6 +2392,7 @@ void amdgpu_device_fini(struct amdgpu_device > *adev) > /* evict vram memory */ > amdgpu_bo_evict_vram(adev); > amdgpu_ib_pool_fini(adev); > + amdgpu_fw_reserve_vram_fini(adev); > amdgpu_fence_driver_fini(adev); > amdgpu_fbdev_fini(adev); > 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 1086f03..a5253cf 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > @@ -1256,6 +1256,15 @@ int amdgpu_ttm_init(struct amdgpu_device > *adev) > /* Change the size here instead of the init above so only lpfn is > affected */ > amdgpu_ttm_set_active_vram_size(adev, adev- > >mc.visible_vram_size); > > + /* > + *The reserved vram for firmware must be pinned to the specified > + *place on the VRAM, so reserve it early. > + */ > + r = amdgpu_fw_reserve_vram_init(adev); > + if (r) { > + return r; > + } > + > r = amdgpu_bo_create_kernel(adev, adev->mc.stolen_size, > PAGE_SIZE, > AMDGPU_GEM_DOMAIN_VRAM, > &adev->stolen_vga_memory, > -- > 2.7.4 > > _______________________________________________ > amd-gfx mailing list > amd-gfx at lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx