drivers/gpu/drm/etnaviv/etnaviv_iommu.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/etnaviv/etnaviv_iommu.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/etnaviv/etnaviv_iommu.c- Extension
.c- Size
- 4728 bytes
- Lines
- 177
- 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/bitops.hlinux/dma-mapping.hlinux/platform_device.hlinux/sizes.hlinux/slab.hetnaviv_gpu.hetnaviv_mmu.hstate_hi.xml.h
Detected Declarations
struct etnaviv_iommuv1_contextfunction to_v1_contextfunction etnaviv_iommuv1_freefunction etnaviv_iommuv1_mapfunction etnaviv_iommuv1_unmapfunction etnaviv_iommuv1_dump_sizefunction etnaviv_iommuv1_dumpfunction etnaviv_iommuv1_restorefunction etnaviv_iommuv1_context_alloc
Annotated Snippet
struct etnaviv_iommuv1_context {
struct etnaviv_iommu_context base;
u32 *pgtable_cpu;
dma_addr_t pgtable_dma;
};
static struct etnaviv_iommuv1_context *
to_v1_context(struct etnaviv_iommu_context *context)
{
return container_of(context, struct etnaviv_iommuv1_context, base);
}
static void etnaviv_iommuv1_free(struct etnaviv_iommu_context *context)
{
struct etnaviv_iommuv1_context *v1_context = to_v1_context(context);
drm_mm_takedown(&context->mm);
dma_free_wc(context->global->dev, PT_SIZE, v1_context->pgtable_cpu,
v1_context->pgtable_dma);
context->global->v1.shared_context = NULL;
kfree(v1_context);
}
static int etnaviv_iommuv1_map(struct etnaviv_iommu_context *context,
unsigned long iova, phys_addr_t paddr,
size_t size, int prot)
{
struct etnaviv_iommuv1_context *v1_context = to_v1_context(context);
unsigned int index = (iova - GPU_MEM_START) / SZ_4K;
if (size != SZ_4K)
return -EINVAL;
v1_context->pgtable_cpu[index] = paddr;
return 0;
}
static size_t etnaviv_iommuv1_unmap(struct etnaviv_iommu_context *context,
unsigned long iova, size_t size)
{
struct etnaviv_iommuv1_context *v1_context = to_v1_context(context);
unsigned int index = (iova - GPU_MEM_START) / SZ_4K;
if (size != SZ_4K)
return -EINVAL;
v1_context->pgtable_cpu[index] = context->global->bad_page_dma;
return SZ_4K;
}
static size_t etnaviv_iommuv1_dump_size(struct etnaviv_iommu_context *context)
{
return PT_SIZE;
}
static void etnaviv_iommuv1_dump(struct etnaviv_iommu_context *context,
void *buf)
{
struct etnaviv_iommuv1_context *v1_context = to_v1_context(context);
memcpy(buf, v1_context->pgtable_cpu, PT_SIZE);
}
static void etnaviv_iommuv1_restore(struct etnaviv_gpu *gpu,
struct etnaviv_iommu_context *context)
{
struct etnaviv_iommuv1_context *v1_context = to_v1_context(context);
u32 pgtable;
if (gpu->mmu_context)
etnaviv_iommu_context_put(gpu->mmu_context);
gpu->mmu_context = etnaviv_iommu_context_get(context);
/* set base addresses */
gpu_write(gpu, VIVS_MC_MEMORY_BASE_ADDR_RA, context->global->memory_base);
gpu_write(gpu, VIVS_MC_MEMORY_BASE_ADDR_FE, context->global->memory_base);
gpu_write(gpu, VIVS_MC_MEMORY_BASE_ADDR_TX, context->global->memory_base);
gpu_write(gpu, VIVS_MC_MEMORY_BASE_ADDR_PEZ, context->global->memory_base);
gpu_write(gpu, VIVS_MC_MEMORY_BASE_ADDR_PE, context->global->memory_base);
/* set page table address in MC */
pgtable = (u32)v1_context->pgtable_dma;
gpu_write(gpu, VIVS_MC_MMU_FE_PAGE_TABLE, pgtable);
gpu_write(gpu, VIVS_MC_MMU_TX_PAGE_TABLE, pgtable);
Annotation
- Immediate include surface: `linux/bitops.h`, `linux/dma-mapping.h`, `linux/platform_device.h`, `linux/sizes.h`, `linux/slab.h`, `etnaviv_gpu.h`, `etnaviv_mmu.h`, `state_hi.xml.h`.
- Detected declarations: `struct etnaviv_iommuv1_context`, `function to_v1_context`, `function etnaviv_iommuv1_free`, `function etnaviv_iommuv1_map`, `function etnaviv_iommuv1_unmap`, `function etnaviv_iommuv1_dump_size`, `function etnaviv_iommuv1_dump`, `function etnaviv_iommuv1_restore`, `function etnaviv_iommuv1_context_alloc`.
- 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.