PMC: Master control unit¶
Contents
Introduction¶
PMC is the “master control” engine of the card. Its purpose is to provide card identication, manage enable/disable bits of other engines, and handle top-level interrupt routing.
MMIO register list¶
-
8-bit space
pmc
[0x1000]
¶ -
nv1-mmio
0x0: PMC
-
nv3-mmio
0x0: PMC
-
g80-mmio
0x0: PMC
-
gf100-mmio
0x0: PMC
The PMC register range is always active.
Address Variants Name Description 0x0 NV1:NV4 ID card identification 0x0 NV4:NV10 ID card identification 0x0 NV10: ID card identification 0x4 NV1A: ENDIAN endian switch 0x8 G92: BOOT_2 ??? 0x100 all INTR_HOST interrupt status - host 0x104 GT215: INTR_NRHOST interrupt status - non-redirectable host 0x108 GT215: INTR_DAEMON interrupt status - PDAEMON 0x140 all INTR_ENABLE_HOST interrupt enable - host 0x144 GT215: INTR_ENABLE_NRHOST interrupt enable - non-redirectable host 0x148 GT215: INTR_ENABLE_DAEMON interrupt enable - PDAEMON 0x160 all INTR_LINE_HOST interrupt line status - host 0x164 GT215: INTR_LINE_NRHOST interrupt line status - non-redirectable host 0x168 GT215: INTR_LINE_DAEMON interrupt line status - PDAEMON 0x17c GF100: INTR_PMFB PMFB interrupt status 0x180 GF100: INTR_PBFB PBFB interrupt status 0x200 all ENABLE engine master enable 0x204 GF100: SPOON_ENABLE PSPOON enables 0x208 GF100: ENABLE_UNK08 ??? related to enable 0x20c GF104: ENABLE_UNK0C ??? related to enable 0x260+i*0x4 (i<6) GF100: FIFO_ENG_UNK260[i] ??? related to PFIFO engines 0x300 NV17:GK110 VRAM_HIDE_LOW VRAM hidden area low address 0x304 NV17:GK110 VRAM_HIDE_HIGH VRAM hidden area high address 0x640 GT215: INTR_MASK_HOST interrupt mask - host 0x644 GT215: INTR_MASK_NRHOST interrupt mask - non-redirectable host 0x648 GT215: INTR_MASK_DAEMON interrupt mask - PDAEMON 0xa00 G94: NEW_ID card identification
Card identification¶
The main register used to identify the card is the ID register. However, the ID register has different formats depending on the GPU family:
-
reg32
pmc-id-nv1
¶ -
pmc
0x0: ID
[NV1:NV4] - bits 0-3: minor revision.
- bits 4-7: major revision. These two bitfields together are also visible as PCI revision. For NV3, revisions equal or higher than 0x20 mean NV3T.
- bits 8-11: implementation - always 1 except on NV2
- bits 12-15: always 0
- bits 16-19: GPU - 1 is NV1, 2 is NV2, 3 is NV3 or NV3T
- bits 20-27: always 0
- bits 28-31: foundry - 0 is SGS, 1 is Helios, 2 is TMSC
-
reg32
pmc-id-nv4
¶ -
pmc
0x0: ID
[NV4:NV10] - bits 0-3: ???
- bits 4-11: always 0
- bits 12-15: architecture - always 4
- bits 16-19: minor revision
- bits 20-23: major revision - 0 is NV4, 1 and 2 are NV5. These two bitfields together are also visible as PCI revision.
- bits 24-27: always 0
- bits 28-31: foundry - 0 is SGS, 1 is Helios, 2 is TMSC
-
reg32
pmc-id-nv10
¶ -
pmc
0x0: ID
[NV10:] - bits 0-7: stepping
- bits 16-19: device id [NV10:G92]
- bits 15-19: device id [G92:GF119]
- bits 12-19: device id [GF119-] The value of this bitfield is equal to low 4, 5, or 6 bits of the PCI device id. The bitfield size and position changed between cards due to varying amount of changeable bits. See PSTRAPS: straps readout and override and GPU chips for more details.
- bits 20-27: GPU id. This is THE GPU id that comes after “NV”. See GPU chips for the list.
- bits 28-31: ???
Todo
unk bitfields
G92[?] introduced another identification register in PMC, with unknown purpose:
Todo
what is this? when was it introduced? seen non-0 on at least G92
G94 introduced a new identification register with rearranged bitfields:
-
reg32
pmc-new-id
¶ -
pmc
0xa00: NEW_ID
[G94:] - bits 0-7: device id
- bits 8-11: same value as BOOT_2 register
- bits 12-19: stepping
- bits 20-27: GPU id
Todo
there are cards where the steppings don’t match between registers - does this mean something or is it just a random screwup?
Endian switch¶
PMC also contains the endian switch register. The endian switch can be set to either little or big endian, and affects all accesses to BAR0 and, if present, BAR2/BAR3 - see PCI BARs and other means of accessing the GPU for more details. It is controlled by the ENDIAN register:
-
reg32
pmc-endian
¶ -
pmc
0x4: ENDIAN
[NV1A:] When read, returns 0x01000001 if in big-endian mode, 0 if in little-endian mode. When written, if bit 24 of the written value is 1, flips the endian switch to the opposite value, otherwise does nothing.
The register operates in such idiosyncratic way because it is itself affected by the endian switch - thus the read value was chosen to be unaffected by wrong endian setting, while write behavior was chosen so that writing “1” in either endianness will switch the card to that endianness.
This register and the endian switch don’t exist on pre-NV1A cards - they’re always little-endian.
Note that this switch is also used by G80+ PFIFO as its default endianness - see G80+ PFIFO for details.
The MMIO areas containing aliases of 8-bit VGA registers are unaffected by this switch, despite being in BAR0.
Engine enables¶
PMC contains the main engine enable register, which is used to turn whole engines on and off:
-
reg32
pmc-enable
¶ -
pmc
0x200: ENABLE
When given bit is set to 0, the corresponding engine is disabled, when set to 1, it is enabled. Most engines disappear from MMIO space and reset to default state when disabled.
On NV1, the bits are:
On NV3:NV4, the bits are:
On NV4:G80, the bits are:
- 0: ??? - alleged to be related to I2C [NV10-] [XXX]
- 1: PVPE [NV17-]
- 4: PMEDIA
- 8: PFIFO
- 12: PGRAPH [NV4:NV10]
- 12: PGRAPH [NV10:NV20]
- 12: PGRAPH [NV20:NV40]
- 12: PGRAPH [NV40:G80]
- 13: PGRAPH CS??? apparently exists on some late NV4x… [NV4?-]
- 16: PTIMER
- 20: PFB [NV3, NV10, NV40, NV44]
- 24: PCRTC
- 25: PCRTC2 [NV11-]
- 26: PTV [NV17:NV20, NV25:G80]
- 28: PRAMDAC.VIDEO [NV4:NV10] or PVIDEO [NV10:G80]
Todo
figure out the CS thing, figure out the variants. Known not to exist on NV40, NV43, NV44, C51, G71; known to exist on MCP73
On G80:GF100, the bits are:
- 0: ??? - alleged to be related to I2C
- 1: PVPE [G80:G98 G200:MCP77]
- 1: PPPP [G98:G200 MCP77-]
- 4: PMEDIA
- 8: PFIFO
- 12: PGRAPH
- 13: PCOPY [GT215-]
- 14: PCIPHER [G84:G98 G200:MCP77]
- 14: PSEC [G98:G200 MCP77:GT215]
- 14: PVCOMP [MCP89]
- 15: PBSP [G84:G98 G200:MCP77]
- 15: PVLD [G98:G200 MCP77-]
- 16: PTIMER
- 17: PVP2 [G84:G98 G200:MCP77]
- 17: PPDEC [G98:G200 MCP77-]
- 20: PFB
- 21: PGRAPH CHSW [G84-]
- 22: PMPEG CHSW [G84-]
- 23: PCOPY CHSW [GT215-]
- 24: PVP2 CHSW [G84:G98 G200:MCP77]
- 24: PPDEC CHSW [G98:G200 MCP77-]
- 25: PCIPHER CHSW [G84:G98 G200:MCP77]
- 25: PSEC CHSW [G98:G200 MCP77:GT215]
- 25: PVCOMP CHSW [MCP89]
- 26: PBSP CHSW [G84:G98 G200:MCP77]
- 26: PVLD CHSW [G98:G200 MCP77-]
- 27: ??? [G84-]
- 28: ??? [G84-]
- 30: PDISPLAY
- 31: ???
Todo
unknowns
On GF100+, the bits are:
- 0: ??? - alleged to be related to I2C
- 1: PPPP [GF100:GM107]
- 2: PXBAR
- 3: PMFB
- 4: PMEDIA [GF100:GM107]
- 5: PRING
- 6: PCOPY[0]
- 7: PCOPY[1] [GF100:GM107]
- 8: PFIFO
- 12: PGRAPH
- 13: PDAEMON
- 14: PSEC [GM107:]
- 15: PVLD [GF100:GM107]
- 15: PVDEC [GM107:]
- 16: PTIMER
- 17: PPDEC [GF100:GM107]
- 18: PVENC [GK104-]
- 20: PBFB
- 21: PCOPY[2] [GK104-]
- 26: ??? allegedly zpw [GK104-]
- 27: ??? allegedly blg
- 28: PCOUNTER
- 29: PFFB
- 30: PDISPLAY
- 31: ??? allegedly isohub
GF100 also introduced SUBFIFO_ENABLE register:
-
reg32
pmc-spoon-enable
¶ -
pmc
0x204: SPOON_ENABLE
[GF100:] Enables PFIFO’s PSPOONs. Bit i corresponds to PSPOON[i]. See GF100+ PFIFO for details.
There are also two other registers looking like ENABLE, but with seemingly no effect and currently unknown purpose:
-
reg32
pmc-enable-unk08
¶ -
pmc
0x208: ENABLE_UNK08
[GF100:] Has the same bits as ENABLE, comes up as all-1 on boot, except for PDISPLAY bit which comes up as 0.
-
reg32
pmc-enable-unk0c
¶ -
pmc
0x20c: ENABLE_UNK0C
[GF104:] Has bits which correspond to PFIFO engines in ENABLE, ie.
- 1: PPPP
- 6: PCOPY[0]
- 7: PCOPY[1]
- 12: PGRAPH
- 15: PVLD
- 17: PPDEC
Comes up as all-1.
-
reg32
pmc-fifo-eng-unk260
¶ -
pmc
0x260+i*0x4: FIFO_ENG_UNK260[i] (i<6)
[GF100:] Single-bit registers, 6 of them.
Todo
RE these three
Interrupts¶
Another thing that PMC handles is the top-level interrupt routing. On cards earlier than GT215, PMC gets interrupt lines from all interested engines on the card, aggregates them together, adds in an option to trigger a “software” interrupt manually, and routes them to the PCI INTA pin. There is an enable register, but it only allows one to enable/disable all hardware or all software interrupts.
GT215 introduced fine-grained interrupt masking, as well as an option to route interrupts to PDAEMON. The HOST interrupts have a new redirection stage in PDAEMON [see PMC interrupt redirection] - while normally routed to the PCI interrupt line, they may be switched over to PDAEMON delivery when it so decides. As a side effect of that, powering off PDAEMON will disable host interrupt delivery. A subset of interrupt types can also be routed to NRHOST destination, which is identical to HOST, but doesn’t go through the PDAEMON redirection circuitry.
Todo
change all this duplication to indexing
-
reg32
pmc-intr-host
¶ -
pmc
0x100: INTR_HOST
Interrupt status. Bits 0-30 are hardware interrupts, bit 31 is software interrupt. 1 if the relevant input interrupt line is active and, for GT215+ GPUs, enabled in INTR_MASK_*. Bits 0-30 are read-only, bit 31 can be written to set/clear the software interrupt. Bit 31 can only be set to 1 if software interrupts are enabled in INTR_MASK_*, except for NRHOST on GF100+, where it works even if masked.
-
reg32
pmc-intr-nrhost
¶ -
pmc
0x104: INTR_NRHOST
[GT215:] Like
pmc-intr-host
, but for NRHOST.
-
reg32
pmc-intr-daemon
¶ -
pmc
0x108: INTR_DAEMON
[GT215:] Like
pmc-intr-host
, but for DAEMON.
-
reg32
pmc-intr-enable-host
¶ -
pmc
0x140: INTR_ENABLE_HOST
- bit 0: hardware interrupt enable - if 1, and any of bits 0-30 of INTR_* are active, the corresponding output interrupt line will be asserted.
- bit 1: software interrupt enable - if 1, bit 31 of INTR_* is active, the corresponding output interrupt line will be asserted.
-
reg32
pmc-intr-enable-nrhost
¶ -
pmc
0x144: INTR_ENABLE_NRHOST
[GT215:] Like
pmc-intr-enable-nrhost
, but for NRHOST.
-
reg32
pmc-intr-enable-daemon
¶ -
pmc
0x148: INTR_ENABLE_DAEMON
[GT215:] Like
pmc-intr-enable-host
, but for DAEMON.
-
reg32
pmc-intr-line-host
¶ -
pmc
0x160: INTR_LINE_HOST
Provides a way to peek at the status of corresponding output interrupt line. On NV1:GF100, 0 if the output line is active, 1 if inactive. On GF100+, 1 if active, 0 if inactive.
-
reg32
pmc-intr-line-nrhost
¶ -
pmc
0x164: INTR_LINE_NRHOST
[GT215:] Like
pmc-intr-line-host
, but for NRHOST.
-
reg32
pmc-intr-line-daemon
¶ -
pmc
0x168: INTR_LINE_DAEMON
[GT215:] Like
pmc-intr-line-host
, but for DAEMON.
-
reg32
pmc-intr-mask-host
¶ -
pmc
0x640: INTR_MASK_HOST
[GT215:] Interrupt mask. If a bit is set to 0 here, it’ll be masked off to always-0 in the INTR_* register, otherwise it’ll be connected to the corresponding input interrupt line. For HOST and DAEMON, all interrupts can be enabled. For NRHOST on pre-GF100 cards, only input line #8 [PFIFO] can be enabled, for NRHOST on GF100+ cards all interrupts but the software interrupt can be enabled - however in this case software interrupt works even without being enabled.
-
reg32
pmc-intr-mask-nrhost
¶ -
pmc
0x644: INTR_MASK_NRHOST
[GT215:] Like
pmc-intr-mask-host
, but for NRHOST.
-
reg32
pmc-intr-mask-daemon
¶ -
pmc
0x648: INTR_MASK_DAEMON
[GT215:] Like
pmc-intr-mask-host
, but for DAEMON.
The HOST and NRHOST output interrupt lines are connected to the PCI INTA pin on the card. HOST goes through PDAEMON’s HOST interrupt redirection circuitry [IREDIR], while NRHOST doesn’t. DAEMON goes to PDAEMON’s falcon interrupt line #10 [PMC_DAEMON].
On pre-GT215, each PMC interrupt input is a single 0/1 line. On GT215+, some inputs have a single line for all three outputs, while some others have 2 lines: one for HOST and DAEMON outputs, and one for NRHOST outuput.
The input interrupts are, for NV1:
Todo
check
For NV3:
- 4: PMEDIA
- 8: PFIFO
- 12: PGRAPH
- 13: PDMA
- 16: PRAMDAC.VIDEO
- 20: PTIMER
- 24: PGRAPH’s vblank interrupt
- 28: PBUS
- 31: software
For NV4:G80:
- 0: PVPE [NV17:NV20 and NV25:G80]
- 4: PMEDIA
- 8: PFIFO
- 12: PGRAPH
- 16: PRAMDAC.VIDEO [NV4:NV10] or PVIDEO [NV10:G80]
- 20: PTIMER
- 24: PCRTC
- 25: PCRTC2 [NV17:NV20 and NV25:G80]
- 28: PBUS
- 31: software
For G80:GF100:
- 0: PVPE [G80:G98 G200:MCP77]
- 0: PPPP [G98:G200 MCP77-]
- 4: PMEDIA
- 8: PFIFO - has separate NRHOST line on GT215+
- 9: ??? [GT215?-]
- 11: ??? [GT215?-]
- 12: PGRAPH
- 13: ??? [GT215?-]
- 14: PCIPHER [G84:G98 G200:MCP77]
- 14: PSEC [G98:G200 MCP77:GT215]
- 14: PVCOMP [MCP89-]
- 15: PBSP [G84:G98 G200:MCP77]
- 15: PVLD [G98:G200 MCP77-]
- 16: ??? [GT215?-]
- 17: PVP2 [G84:G98 G200:MCP77]
- 17: PPDEC [G98:G200 MCP77-]
- 18: PDAEMON [GT215-]
- 19: PTHERM [GT215-]
- 20: PTIMER
- 21: PNVIO’s GPIO interrupts
- 22: PCOPY
- 26: PDISPLAY
- 27: ??? [GT215?-]
- 28: PBUS
- 29: PPCI [G84-]
- 31: software
Todo
figure out unknown interrupts. They could’ve been introduced much earlier, but we only know them from bitscanning the INTR_MASK regs. on GT215+.
For GF100+:
- 0: PPPP - has separate NRHOST line [GF100:GM107]
- 4: PMEDIA [GF100:GM107]
- 5: PCOPY[0] [GF100, GK104] - has separate NRHOST line
- 6: PCOPY[1] [GF100, GK104] - has separate NRHOST line
- 7: PCOPY[2] [GK104-] - has separate NRHOST line
- 8: PFIFO
- 9: ??? allegedly remapper
- 12: PGRAPH - has separate NRHOST line
- 13: PBFB
- 15: PSEC - has separate NRHOST line [GM107:]
- 15: PVLD - has separate NRHOST line [GF100:GM107]
- 16: PVENC [GK104-] - has separate NRHOST line
- 17: PPDEC - has separate NRHOST line [GF100:GM107]
- 17: PVDEC - has separate NRHOST line [GM107:]
- 18: PTHERM
- 19: ??? allegedly HDA codec [GF119-]
- 20: PTIMER
- 21: PNVIO’s GPIO interrupts
- 23: ??? allegedly dfd
- 24: PDAEMON
- 25: PMFB
- 26: PDISPLAY
- 27: PFFB
- 28: PBUS - has separate NRHOST line
- 29: PPCI
- 30: PRING
- 31: software
Todo
unknowns
Todo
document these two
Todo
verify variants for these?