drivers/gpu/drm/etnaviv/etnaviv_mmu.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/etnaviv/etnaviv_mmu.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/etnaviv/etnaviv_mmu.c- Extension
.c- Size
- 13797 bytes
- Lines
- 561
- Domain
- Driver Families
- Bucket
- drivers/gpu
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/dma-mapping.hlinux/scatterlist.hdrm/drm_print.hcommon.xml.hetnaviv_cmdbuf.hetnaviv_drv.hetnaviv_gem.hetnaviv_gpu.hetnaviv_mmu.h
Detected Declarations
function Copyrightfunction etnaviv_context_mapfunction etnaviv_iommu_mapfunction for_each_sgtable_dma_sgfunction etnaviv_iommu_unmapfunction etnaviv_iommu_remove_mappingfunction etnaviv_iommu_reap_mappingfunction etnaviv_iommu_find_iovafunction list_for_each_entryfunction list_for_each_entry_safefunction etnaviv_iommu_insert_exactfunction yetfunction list_for_each_entry_safefunction etnaviv_iommu_map_gemfunction etnaviv_iommu_unmap_gemfunction etnaviv_iommu_context_freefunction etnaviv_iommu_context_putfunction etnaviv_iommu_context_initfunction etnaviv_iommu_restorefunction etnaviv_iommu_get_suballoc_vafunction etnaviv_iommu_put_suballoc_vafunction etnaviv_iommu_dump_sizefunction etnaviv_iommu_dumpfunction etnaviv_iommu_global_initfunction etnaviv_iommu_global_fini
Annotated Snippet
if (!IS_ALIGNED(iova | pa | bytes, SZ_4K)) {
dev_err(context->global->dev,
"unaligned: iova 0x%x pa %pa size 0x%x\n",
iova, &pa, bytes);
ret = -EINVAL;
goto fail;
}
ret = etnaviv_context_map(context, da, pa, bytes, prot);
if (ret)
goto fail;
va_len -= bytes;
da += bytes;
}
context->flush_seq++;
return 0;
fail:
etnaviv_context_unmap(context, iova, da - iova);
return ret;
}
static void etnaviv_iommu_unmap(struct etnaviv_iommu_context *context, u32 iova,
struct sg_table *sgt, unsigned len)
{
etnaviv_context_unmap(context, iova, len);
context->flush_seq++;
}
static void etnaviv_iommu_remove_mapping(struct etnaviv_iommu_context *context,
struct etnaviv_vram_mapping *mapping)
{
struct etnaviv_gem_object *etnaviv_obj = mapping->object;
lockdep_assert_held(&context->lock);
etnaviv_iommu_unmap(context, mapping->vram_node.start,
etnaviv_obj->sgt, etnaviv_obj->size);
drm_mm_remove_node(&mapping->vram_node);
}
void etnaviv_iommu_reap_mapping(struct etnaviv_vram_mapping *mapping)
{
struct etnaviv_iommu_context *context = mapping->context;
lockdep_assert_held(&context->lock);
WARN_ON(mapping->use);
etnaviv_iommu_remove_mapping(context, mapping);
etnaviv_iommu_context_put(mapping->context);
mapping->context = NULL;
list_del_init(&mapping->mmu_node);
}
static int etnaviv_iommu_find_iova(struct etnaviv_iommu_context *context,
struct drm_mm_node *node, size_t size)
{
struct etnaviv_vram_mapping *free = NULL;
enum drm_mm_insert_mode mode = DRM_MM_INSERT_LOW;
int ret;
lockdep_assert_held(&context->lock);
while (1) {
struct etnaviv_vram_mapping *m, *n;
struct drm_mm_scan scan;
struct list_head list;
bool found;
ret = drm_mm_insert_node_in_range(&context->mm, node,
size, 0, 0, 0, U64_MAX, mode);
if (ret != -ENOSPC)
break;
/* Try to retire some entries */
drm_mm_scan_init(&scan, &context->mm, size, 0, 0, mode);
found = 0;
INIT_LIST_HEAD(&list);
list_for_each_entry(free, &context->mappings, mmu_node) {
/* If this vram node has not been used, skip this. */
if (!free->vram_node.mm)
continue;
/*
* If the iova is pinned, then it's in-use,
Annotation
- Immediate include surface: `linux/dma-mapping.h`, `linux/scatterlist.h`, `drm/drm_print.h`, `common.xml.h`, `etnaviv_cmdbuf.h`, `etnaviv_drv.h`, `etnaviv_gem.h`, `etnaviv_gpu.h`.
- Detected declarations: `function Copyright`, `function etnaviv_context_map`, `function etnaviv_iommu_map`, `function for_each_sgtable_dma_sg`, `function etnaviv_iommu_unmap`, `function etnaviv_iommu_remove_mapping`, `function etnaviv_iommu_reap_mapping`, `function etnaviv_iommu_find_iova`, `function list_for_each_entry`, `function list_for_each_entry_safe`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.