drivers/gpu/drm/panfrost/panfrost_mmu.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/panfrost/panfrost_mmu.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/panfrost/panfrost_mmu.c- Extension
.c- Size
- 25410 bytes
- Lines
- 988
- 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
drm/panfrost_drm.hdrm/drm_print.hlinux/atomic.hlinux/bitfield.hlinux/delay.hlinux/dma-mapping.hlinux/interrupt.hlinux/io.hlinux/iopoll.hlinux/io-pgtable.hlinux/iommu.hlinux/platform_device.hlinux/pm_runtime.hlinux/shmem_fs.hlinux/sizes.hpanfrost_device.hpanfrost_mmu.hpanfrost_gem.hpanfrost_features.hpanfrost_regs.h
Detected Declarations
function mair_to_memattrfunction wait_readyfunction write_cmdfunction lock_regionfunction mmu_hw_do_operation_lockedfunction mmu_hw_do_operationfunction panfrost_mmu_enablefunction panfrost_mmu_disablefunction mmu_cfg_init_mali_lpaefunction mmu_cfg_init_aarch64_4kfunction panfrost_mmu_cfg_initfunction panfrost_mmu_as_getfunction list_for_each_entry_reversefunction panfrost_mmu_as_putfunction panfrost_mmu_resetfunction list_for_each_entry_safefunction get_pgsizefunction panfrost_mmu_flush_rangefunction mmu_unmap_rangefunction mmu_map_sgfunction for_each_sgtable_dma_sgfunction panfrost_mmu_mapfunction panfrost_mmu_unmapfunction mmu_tlb_inv_context_s1function mmu_tlb_flush_walkfunction addr_to_mappingfunction drm_mm_for_each_nodefunction panfrost_mmu_map_fault_addrfunction panfrost_mmu_release_ctxfunction panfrost_mmu_ctx_putfunction panfrost_drm_mm_color_adjustfunction panfrost_mmu_irq_handlerfunction panfrost_mmu_irq_handler_threadfunction panfrost_mmu_initfunction panfrost_mmu_finifunction panfrost_mmu_suspend_irq
Annotated Snippet
if (!(outer & 3) || !(outer & 4) || !(inner & 4)) {
out_attr = AS_MEMATTR_AARCH64_INNER_OUTER_NC |
AS_MEMATTR_AARCH64_SH_MIDGARD_INNER |
AS_MEMATTR_AARCH64_INNER_ALLOC_EXPL(false, false);
} else {
out_attr = AS_MEMATTR_AARCH64_INNER_OUTER_WB |
AS_MEMATTR_AARCH64_INNER_ALLOC_EXPL(inner & 1, inner & 2);
/* Use SH_MIDGARD_INNER mode when device isn't coherent,
* so SH_IS, which is used when IOMMU_CACHE is set, maps
* to Mali's internal-shareable mode. As per the Mali
* Spec, inner and outer-shareable modes aren't allowed
* for WB memory when coherency is disabled.
* Use SH_CPU_INNER mode when coherency is enabled, so
* that SH_IS actually maps to the standard definition of
* inner-shareable.
*/
if (!coherent)
out_attr |= AS_MEMATTR_AARCH64_SH_MIDGARD_INNER;
else
out_attr |= AS_MEMATTR_AARCH64_SH_CPU_INNER;
}
memattr |= (u64)out_attr << (8 * i);
}
return memattr;
}
static int wait_ready(struct panfrost_device *pfdev, u32 as_nr)
{
int ret;
u32 val;
/* Wait for the MMU status to indicate there is no active command, in
* case one is pending. */
ret = readl_relaxed_poll_timeout_atomic(pfdev->iomem + AS_STATUS(as_nr),
val, !(val & AS_STATUS_AS_ACTIVE), 10, 100000);
if (ret) {
/* The GPU hung, let's trigger a reset */
panfrost_device_schedule_reset(pfdev);
dev_err(pfdev->base.dev, "AS_ACTIVE bit stuck\n");
}
return ret;
}
static int write_cmd(struct panfrost_device *pfdev, u32 as_nr, u32 cmd)
{
int status;
/* write AS_COMMAND when MMU is ready to accept another command */
status = wait_ready(pfdev, as_nr);
if (!status)
mmu_write(pfdev, AS_COMMAND(as_nr), cmd);
return status;
}
static void lock_region(struct panfrost_device *pfdev, u32 as_nr,
u64 region_start, u64 size)
{
u8 region_width;
u64 region;
u64 region_end = region_start + size;
if (!size)
return;
/*
* The locked region is a naturally aligned power of 2 block encoded as
* log2 minus(1).
* Calculate the desired start/end and look for the highest bit which
* differs. The smallest naturally aligned block must include this bit
* change, the desired region starts with this bit (and subsequent bits)
* zeroed and ends with the bit (and subsequent bits) set to one.
*/
region_width = max(fls64(region_start ^ (region_end - 1)),
const_ilog2(AS_LOCK_REGION_MIN_SIZE)) - 1;
/*
* Mask off the low bits of region_start (which would be ignored by
* the hardware anyway)
*/
region_start &= GENMASK_ULL(63, region_width);
region = region_width | region_start;
/* Lock the region that needs to be updated */
mmu_write(pfdev, AS_LOCKADDR_LO(as_nr), lower_32_bits(region));
Annotation
- Immediate include surface: `drm/panfrost_drm.h`, `drm/drm_print.h`, `linux/atomic.h`, `linux/bitfield.h`, `linux/delay.h`, `linux/dma-mapping.h`, `linux/interrupt.h`, `linux/io.h`.
- Detected declarations: `function mair_to_memattr`, `function wait_ready`, `function write_cmd`, `function lock_region`, `function mmu_hw_do_operation_locked`, `function mmu_hw_do_operation`, `function panfrost_mmu_enable`, `function panfrost_mmu_disable`, `function mmu_cfg_init_mali_lpae`, `function mmu_cfg_init_aarch64_4k`.
- 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.