drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv04.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv04.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv04.c- Extension
.c- Size
- 13297 bytes
- Lines
- 466
- 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
nv04.hfbmem.hsubdev/bios.hsubdev/bios/init.hsubdev/bios/pll.hsubdev/clk/pll.hsubdev/vga.h
Detected Declarations
function Copyrightfunction powerctrl_1_shiftfunction setPLL_singlefunction new_ramdac580function setPLL_double_highregsfunction setPLL_double_lowregsfunction nv04_devinit_pll_setfunction nv04_devinit_postfunction nv04_devinit_preinitfunction nv04_devinit_dtorfunction nv04_devinit_new_function nv04_devinit_new
Annotated Snippet
switch (reg1) {
case 0x680504:
shift_c040 += 2; fallthrough;
case 0x680500:
shift_c040 += 2; fallthrough;
case 0x680520:
shift_c040 += 2; fallthrough;
case 0x680508:
shift_c040 += 2;
}
savedc040 = nvkm_rd32(device, 0xc040);
if (shift_c040 != 14)
nvkm_wr32(device, 0xc040, savedc040 & ~(3 << shift_c040));
}
if (oldramdac580 != ramdac580)
nvkm_wr32(device, 0x680580, ramdac580);
if (!nv3035)
nvkm_wr32(device, reg2, pll2);
nvkm_wr32(device, reg1, pll1);
if (shift_powerctrl_1 >= 0)
nvkm_wr32(device, 0x001584, saved_powerctrl_1);
if (chip_version >= 0x40)
nvkm_wr32(device, 0xc040, savedc040);
}
void
setPLL_double_lowregs(struct nvkm_devinit *init, u32 NMNMreg,
struct nvkm_pll_vals *pv)
{
/* When setting PLLs, there is a merry game of disabling and enabling
* various bits of hardware during the process. This function is a
* synthesis of six nv4x traces, nearly each card doing a subtly
* different thing. With luck all the necessary bits for each card are
* combined herein. Without luck it deviates from each card's formula
* so as to not work on any :)
*/
struct nvkm_device *device = init->subdev.device;
uint32_t Preg = NMNMreg - 4;
bool mpll = Preg == 0x4020;
uint32_t oldPval = nvkm_rd32(device, Preg);
uint32_t NMNM = pv->NM2 << 16 | pv->NM1;
uint32_t Pval = (oldPval & (mpll ? ~(0x77 << 16) : ~(7 << 16))) |
0xc << 28 | pv->log2P << 16;
uint32_t saved4600 = 0;
/* some cards have different maskc040s */
uint32_t maskc040 = ~(3 << 14), savedc040;
bool single_stage = !pv->NM2 || pv->N2 == pv->M2;
if (nvkm_rd32(device, NMNMreg) == NMNM && (oldPval & 0xc0070000) == Pval)
return;
if (Preg == 0x4000)
maskc040 = ~0x333;
if (Preg == 0x4058)
maskc040 = ~(0xc << 24);
if (mpll) {
struct nvbios_pll info;
uint8_t Pval2;
if (nvbios_pll_parse(device->bios, Preg, &info))
return;
Pval2 = pv->log2P + info.bias_p;
if (Pval2 > info.max_p)
Pval2 = info.max_p;
Pval |= 1 << 28 | Pval2 << 20;
saved4600 = nvkm_rd32(device, 0x4600);
nvkm_wr32(device, 0x4600, saved4600 | 8 << 28);
}
if (single_stage)
Pval |= mpll ? 1 << 12 : 1 << 8;
nvkm_wr32(device, Preg, oldPval | 1 << 28);
nvkm_wr32(device, Preg, Pval & ~(4 << 28));
if (mpll) {
Pval |= 8 << 20;
nvkm_wr32(device, 0x4020, Pval & ~(0xc << 28));
nvkm_wr32(device, 0x4038, Pval & ~(0xc << 28));
}
savedc040 = nvkm_rd32(device, 0xc040);
nvkm_wr32(device, 0xc040, savedc040 & maskc040);
nvkm_wr32(device, NMNMreg, NMNM);
Annotation
- Immediate include surface: `nv04.h`, `fbmem.h`, `subdev/bios.h`, `subdev/bios/init.h`, `subdev/bios/pll.h`, `subdev/clk/pll.h`, `subdev/vga.h`.
- Detected declarations: `function Copyright`, `function powerctrl_1_shift`, `function setPLL_single`, `function new_ramdac580`, `function setPLL_double_highregs`, `function setPLL_double_lowregs`, `function nv04_devinit_pll_set`, `function nv04_devinit_post`, `function nv04_devinit_preinit`, `function nv04_devinit_dtor`.
- 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.