drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c- Extension
.c- Size
- 12400 bytes
- Lines
- 451
- 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.
- 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
priv.hcore/memory.hsubdev/bar.hsubdev/fb.hsubdev/gsp.hsubdev/mmu.h
Detected Declarations
struct nv50_instmemstruct nv50_instobjfunction nv50_instobj_wr32_slowfunction nv50_instobj_rd32_slowfunction nv50_instobj_wr32function nv50_instobj_rd32function nv50_instobj_kmapfunction nv50_instobj_mapfunction nv50_instobj_releasefunction nv50_instobj_acquirefunction nv50_instobj_bootfunction nv50_instobj_sizefunction nv50_instobj_addrfunction nv50_instobj_bar2function nv50_instobj_targetfunction nv50_instobj_dtorfunction nv50_instobj_wrapfunction nv50_instobj_newfunction nv50_instmem_set_bar0_window_addrfunction nv50_instmem_finifunction nv50_instmem_dtorfunction nv50_instmem_new_function nv50_instmem_new
Annotated Snippet
struct nv50_instmem {
struct nvkm_instmem base;
u64 addr;
/* Mappings that can be evicted when BAR2 space has been exhausted. */
struct list_head lru;
};
/******************************************************************************
* instmem object implementation
*****************************************************************************/
#define nv50_instobj(p) container_of((p), struct nv50_instobj, base.memory)
struct nv50_instobj {
struct nvkm_instobj base;
struct nv50_instmem *imem;
struct nvkm_memory *ram;
struct nvkm_vma *bar;
refcount_t maps;
void *map;
struct list_head lru;
};
static void
nv50_instobj_wr32_slow(struct nvkm_memory *memory, u64 offset, u32 data)
{
struct nv50_instobj *iobj = nv50_instobj(memory);
struct nv50_instmem *imem = iobj->imem;
struct nvkm_device *device = imem->base.subdev.device;
u64 base = (nvkm_memory_addr(iobj->ram) + offset) & 0xffffff00000ULL;
u64 addr = (nvkm_memory_addr(iobj->ram) + offset) & 0x000000fffffULL;
unsigned long flags;
spin_lock_irqsave(&imem->base.lock, flags);
if (unlikely(imem->addr != base)) {
imem->base.func->set_bar0_window_addr(device, base);
imem->addr = base;
}
nvkm_wr32(device, 0x700000 + addr, data);
spin_unlock_irqrestore(&imem->base.lock, flags);
}
static u32
nv50_instobj_rd32_slow(struct nvkm_memory *memory, u64 offset)
{
struct nv50_instobj *iobj = nv50_instobj(memory);
struct nv50_instmem *imem = iobj->imem;
struct nvkm_device *device = imem->base.subdev.device;
u64 base = (nvkm_memory_addr(iobj->ram) + offset) & 0xffffff00000ULL;
u64 addr = (nvkm_memory_addr(iobj->ram) + offset) & 0x000000fffffULL;
u32 data;
unsigned long flags;
spin_lock_irqsave(&imem->base.lock, flags);
if (unlikely(imem->addr != base)) {
imem->base.func->set_bar0_window_addr(device, base);
imem->addr = base;
}
data = nvkm_rd32(device, 0x700000 + addr);
spin_unlock_irqrestore(&imem->base.lock, flags);
return data;
}
static const struct nvkm_memory_ptrs
nv50_instobj_slow = {
.rd32 = nv50_instobj_rd32_slow,
.wr32 = nv50_instobj_wr32_slow,
};
static void
nv50_instobj_wr32(struct nvkm_memory *memory, u64 offset, u32 data)
{
iowrite32_native(data, nv50_instobj(memory)->map + offset);
}
static u32
nv50_instobj_rd32(struct nvkm_memory *memory, u64 offset)
{
return ioread32_native(nv50_instobj(memory)->map + offset);
}
static const struct nvkm_memory_ptrs
nv50_instobj_fast = {
.rd32 = nv50_instobj_rd32,
.wr32 = nv50_instobj_wr32,
};
static void
nv50_instobj_kmap(struct nv50_instobj *iobj, struct nvkm_vmm *vmm)
{
Annotation
- Immediate include surface: `priv.h`, `core/memory.h`, `subdev/bar.h`, `subdev/fb.h`, `subdev/gsp.h`, `subdev/mmu.h`.
- Detected declarations: `struct nv50_instmem`, `struct nv50_instobj`, `function nv50_instobj_wr32_slow`, `function nv50_instobj_rd32_slow`, `function nv50_instobj_wr32`, `function nv50_instobj_rd32`, `function nv50_instobj_kmap`, `function nv50_instobj_map`, `function nv50_instobj_release`, `function nv50_instobj_acquire`.
- 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.
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.