/* * Copyright 2016 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * Authors: Christian König
*/
/** * DOC: mem_info_vram_total * * The amdgpu driver provides a sysfs API for reporting current total VRAM * available on the device * The file mem_info_vram_total is used for this and returns the total * amount of VRAM in bytes
*/ static ssize_t amdgpu_mem_info_vram_total_show(struct device *dev, struct device_attribute *attr, char *buf)
{ struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = drm_to_adev(ddev);
/** * DOC: mem_info_vis_vram_total * * The amdgpu driver provides a sysfs API for reporting current total * visible VRAM available on the device * The file mem_info_vis_vram_total is used for this and returns the total * amount of visible VRAM in bytes
*/ static ssize_t amdgpu_mem_info_vis_vram_total_show(struct device *dev, struct device_attribute *attr, char *buf)
{ struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = drm_to_adev(ddev);
/** * DOC: mem_info_vram_used * * The amdgpu driver provides a sysfs API for reporting current total VRAM * available on the device * The file mem_info_vram_used is used for this and returns the total * amount of currently used VRAM in bytes
*/ static ssize_t amdgpu_mem_info_vram_used_show(struct device *dev, struct device_attribute *attr, char *buf)
{ struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = drm_to_adev(ddev); struct ttm_resource_manager *man = &adev->mman.vram_mgr.manager;
/** * DOC: mem_info_vis_vram_used * * The amdgpu driver provides a sysfs API for reporting current total of * used visible VRAM * The file mem_info_vis_vram_used is used for this and returns the total * amount of currently used visible VRAM in bytes
*/ static ssize_t amdgpu_mem_info_vis_vram_used_show(struct device *dev, struct device_attribute *attr, char *buf)
{ struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = drm_to_adev(ddev);
/** * DOC: mem_info_vram_vendor * * The amdgpu driver provides a sysfs API for reporting the vendor of the * installed VRAM * The file mem_info_vram_vendor is used for this and returns the name of the * vendor.
*/ static ssize_t amdgpu_mem_info_vram_vendor(struct device *dev, struct device_attribute *attr, char *buf)
{ struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = drm_to_adev(ddev);
switch (adev->gmc.vram_vendor) { case SAMSUNG: return sysfs_emit(buf, "samsung\n"); case INFINEON: return sysfs_emit(buf, "infineon\n"); case ELPIDA: return sysfs_emit(buf, "elpida\n"); case ETRON: return sysfs_emit(buf, "etron\n"); case NANYA: return sysfs_emit(buf, "nanya\n"); case HYNIX: return sysfs_emit(buf, "hynix\n"); case MOSEL: return sysfs_emit(buf, "mosel\n"); case WINBOND: return sysfs_emit(buf, "winbond\n"); case ESMT: return sysfs_emit(buf, "esmt\n"); case MICRON: return sysfs_emit(buf, "micron\n"); default: return sysfs_emit(buf, "unknown\n");
}
}
/** * amdgpu_vram_mgr_reserve_range - Reserve a range from VRAM * * @mgr: amdgpu_vram_mgr pointer * @start: start address of the range in VRAM * @size: size of the range * * Reserve memory from start address with the specified size in VRAM
*/ int amdgpu_vram_mgr_reserve_range(struct amdgpu_vram_mgr *mgr,
uint64_t start, uint64_t size)
{ struct amdgpu_vram_reservation *rsv;
rsv = kzalloc(sizeof(*rsv), GFP_KERNEL); if (!rsv) return -ENOMEM;
/** * amdgpu_vram_mgr_query_page_status - query the reservation status * * @mgr: amdgpu_vram_mgr pointer * @start: start address of a page in VRAM * * Returns: * -EBUSY: the page is still hold and in pending list * 0: the page has been reserved * -ENOENT: the input page is not a reservation
*/ int amdgpu_vram_mgr_query_page_status(struct amdgpu_vram_mgr *mgr,
uint64_t start)
{ struct amdgpu_vram_reservation *rsv; int ret;
vres = kzalloc(sizeof(*vres), GFP_KERNEL); if (!vres) return -ENOMEM;
ttm_resource_init(tbo, place, &vres->base);
/* bail out quickly if there's likely not enough VRAM for this BO */ if (ttm_resource_manager_usage(man) > max_bytes) {
r = -ENOSPC; goto error_fini;
}
INIT_LIST_HEAD(&vres->blocks);
if (place->flags & TTM_PL_FLAG_TOPDOWN)
vres->flags |= DRM_BUDDY_TOPDOWN_ALLOCATION;
if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS)
vres->flags |= DRM_BUDDY_CONTIGUOUS_ALLOCATION;
if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CLEARED)
vres->flags |= DRM_BUDDY_CLEAR_ALLOCATION;
if (fpfn || lpfn != mgr->mm.size) /* Allocate blocks in desired range */
vres->flags |= DRM_BUDDY_RANGE_ALLOCATION;
if (bo->flags & AMDGPU_GEM_CREATE_GFX12_DCC &&
adev->gmc.gmc_funcs->get_dcc_alignment)
adjust_dcc_size = amdgpu_gmc_get_dcc_alignment(adev);
/** * amdgpu_vram_mgr_alloc_sgt - allocate and fill a sg table * * @adev: amdgpu device pointer * @res: TTM memory object * @offset: byte offset from the base of VRAM BO * @length: number of bytes to export in sg_table * @dev: the other device * @dir: dma direction * @sgt: resulting sg table * * Allocate and fill a sg table from a VRAM allocation.
*/ int amdgpu_vram_mgr_alloc_sgt(struct amdgpu_device *adev, struct ttm_resource *res,
u64 offset, u64 length, struct device *dev, enum dma_data_direction dir, struct sg_table **sgt)
{ struct amdgpu_res_cursor cursor; struct scatterlist *sg; int num_entries = 0; int i, r;
*sgt = kmalloc(sizeof(**sgt), GFP_KERNEL); if (!*sgt) return -ENOMEM;
/* Determine the number of DRM_BUDDY blocks to export */
amdgpu_res_first(res, offset, length, &cursor); while (cursor.remaining) {
num_entries++;
amdgpu_res_next(&cursor, min(cursor.size, AMDGPU_MAX_SG_SEGMENT_SIZE));
}
r = sg_alloc_table(*sgt, num_entries, GFP_KERNEL); if (r) goto error_free;
/* * Walk down DRM_BUDDY blocks to populate scatterlist nodes * @note: Use iterator api to get first the DRM_BUDDY block * and the number of bytes from it. Access the following * DRM_BUDDY block(s) if more buffer needs to exported
*/
amdgpu_res_first(res, offset, length, &cursor);
for_each_sgtable_sg((*sgt), sg, i) {
phys_addr_t phys = cursor.start + adev->gmc.aper_base; unsignedlong size = min(cursor.size, AMDGPU_MAX_SG_SEGMENT_SIZE);
dma_addr_t addr;
addr = dma_map_resource(dev, phys, size, dir,
DMA_ATTR_SKIP_CPU_SYNC);
r = dma_mapping_error(dev, addr); if (r) goto error_unmap;
/** * amdgpu_vram_mgr_vis_usage - how many bytes are used in the visible part * * @mgr: amdgpu_vram_mgr pointer * * Returns how many bytes are used in the visible part of VRAM
*/
uint64_t amdgpu_vram_mgr_vis_usage(struct amdgpu_vram_mgr *mgr)
{ return atomic64_read(&mgr->vis_usage);
}
/** * amdgpu_vram_mgr_intersects - test each drm buddy block for intersection * * @man: TTM memory type manager * @res: The resource to test * @place: The place to test against * @size: Size of the new allocation * * Test each drm buddy block for intersection for eviction decision.
*/ staticbool amdgpu_vram_mgr_intersects(struct ttm_resource_manager *man, struct ttm_resource *res, conststruct ttm_place *place,
size_t size)
{ struct amdgpu_vram_mgr_resource *mgr = to_amdgpu_vram_mgr_resource(res); struct drm_buddy_block *block;
/** * amdgpu_vram_mgr_compatible - test each drm buddy block for compatibility * * @man: TTM memory type manager * @res: The resource to test * @place: The place to test against * @size: Size of the new allocation * * Test each drm buddy block for placement compatibility.
*/ staticbool amdgpu_vram_mgr_compatible(struct ttm_resource_manager *man, struct ttm_resource *res, conststruct ttm_place *place,
size_t size)
{ struct amdgpu_vram_mgr_resource *mgr = to_amdgpu_vram_mgr_resource(res); struct drm_buddy_block *block;
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.28Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.