drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.c- Extension
.c- Size
- 4562 bytes
- Lines
- 178
- 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.
- 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.h
Detected Declarations
struct nvkm_hwsqfunction hwsq_cmdfunction nvkm_hwsq_initfunction nvkm_hwsq_finifunction nvkm_hwsq_wr32function hwsq_cmdfunction hwsq_cmdfunction nvkm_hwsq_setffunction nvkm_hwsq_waitfunction nvkm_hwsq_wait_vblankfunction nvkm_hwsq_nsec
Annotated Snippet
struct nvkm_hwsq {
struct nvkm_subdev *subdev;
u32 addr;
u32 data;
struct {
u8 data[512];
u16 size;
} c;
};
static void
hwsq_cmd(struct nvkm_hwsq *hwsq, int size, u8 data[])
{
memcpy(&hwsq->c.data[hwsq->c.size], data, size * sizeof(data[0]));
hwsq->c.size += size;
}
int
nvkm_hwsq_init(struct nvkm_subdev *subdev, struct nvkm_hwsq **phwsq)
{
struct nvkm_hwsq *hwsq;
hwsq = *phwsq = kmalloc_obj(*hwsq);
if (hwsq) {
hwsq->subdev = subdev;
hwsq->addr = ~0;
hwsq->data = ~0;
memset(hwsq->c.data, 0x7f, sizeof(hwsq->c.data));
hwsq->c.size = 0;
}
return hwsq ? 0 : -ENOMEM;
}
int
nvkm_hwsq_fini(struct nvkm_hwsq **phwsq, bool exec)
{
struct nvkm_hwsq *hwsq = *phwsq;
int ret = 0, i;
if (hwsq) {
struct nvkm_subdev *subdev = hwsq->subdev;
struct nvkm_bus *bus = subdev->device->bus;
hwsq->c.size = (hwsq->c.size + 4) / 4;
if (hwsq->c.size <= bus->func->hwsq_size) {
if (exec)
ret = bus->func->hwsq_exec(bus,
(u32 *)hwsq->c.data,
hwsq->c.size);
if (ret)
nvkm_error(subdev, "hwsq exec failed: %d\n", ret);
} else {
nvkm_error(subdev, "hwsq ucode too large\n");
ret = -ENOSPC;
}
for (i = 0; ret && i < hwsq->c.size; i++)
nvkm_error(subdev, "\t%08x\n", ((u32 *)hwsq->c.data)[i]);
*phwsq = NULL;
kfree(hwsq);
}
return ret;
}
void
nvkm_hwsq_wr32(struct nvkm_hwsq *hwsq, u32 addr, u32 data)
{
nvkm_debug(hwsq->subdev, "R[%06x] = %08x\n", addr, data);
if (hwsq->data != data) {
if ((data & 0xffff0000) != (hwsq->data & 0xffff0000)) {
hwsq_cmd(hwsq, 5, (u8[]){ 0xe2, data, data >> 8,
data >> 16, data >> 24 });
} else {
hwsq_cmd(hwsq, 3, (u8[]){ 0x42, data, data >> 8 });
}
}
if ((addr & 0xffff0000) != (hwsq->addr & 0xffff0000)) {
hwsq_cmd(hwsq, 5, (u8[]){ 0xe0, addr, addr >> 8,
addr >> 16, addr >> 24 });
} else {
hwsq_cmd(hwsq, 3, (u8[]){ 0x40, addr, addr >> 8 });
}
hwsq->addr = addr;
hwsq->data = data;
}
void
Annotation
- Immediate include surface: `priv.h`.
- Detected declarations: `struct nvkm_hwsq`, `function hwsq_cmd`, `function nvkm_hwsq_init`, `function nvkm_hwsq_fini`, `function nvkm_hwsq_wr32`, `function hwsq_cmd`, `function hwsq_cmd`, `function nvkm_hwsq_setf`, `function nvkm_hwsq_wait`, `function nvkm_hwsq_wait_vblank`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: source implementation candidate.
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.