.. _pmc: ======================== 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 ================== .. space:: 8 pmc 0x1000 card master control 0x000 ID pmc-id-nv1 NV1:NV4 0x000 ID pmc-id-nv4 NV4:NV10 0x000 ID pmc-id-nv10 NV10: 0x004 ENDIAN pmc-endian NV1A: 0x008 BOOT_2 pmc-boot-2 G92: 0x100 INTR_HOST pmc-intr-host 0x104 INTR_NRHOST pmc-intr-nrhost GT215: 0x108 INTR_DAEMON pmc-intr-daemon GT215: 0x140 INTR_ENABLE_HOST pmc-intr-enable-host 0x144 INTR_ENABLE_NRHOST pmc-intr-enable-nrhost GT215: 0x148 INTR_ENABLE_DAEMON pmc-intr-enable-daemon GT215: 0x160 INTR_LINE_HOST pmc-intr-line-host 0x164 INTR_LINE_NRHOST pmc-intr-line-nrhost GT215: 0x168 INTR_LINE_DAEMON pmc-intr-line-daemon GT215: 0x17c INTR_PMFB pmc-intr-pmfb GF100: 0x180 INTR_PBFB pmc-intr-pbfb GF100: 0x200 ENABLE pmc-enable 0x204 SPOON_ENABLE pmc-spoon-enable GF100: 0x208 ENABLE_UNK08 pmc-enable-unk08 GF100: 0x20c ENABLE_UNK0C pmc-enable-unk0c GF104: 0x260[6] FIFO_ENG_UNK260 pmc-fifo-eng-unk260 GF100: 0x300 VRAM_HIDE_LOW pmc-vram-hide-low NV17:GK110 0x304 VRAM_HIDE_HIGH pmc-vram-hide-high NV17:GK110 0x640 INTR_MASK_HOST pmc-intr-mask-host GT215: 0x644 INTR_MASK_NRHOST pmc-intr-mask-nrhost GT215: 0x648 INTR_MASK_DAEMON pmc-intr-mask-daemon GT215: 0xa00 NEW_ID pmc-new-id G94: The PMC register range is always active. .. _pmc-id: 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: .. reg:: 32 pmc-id-nv1 card identification - 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 .. reg:: 32 pmc-id-nv4 card identification - 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 .. reg:: 32 pmc-id-nv10 card identification - 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 :ref:`pstraps` and :ref:`gpu` for more details. - bits 20-27: GPU id. This is THE GPU id that comes after "NV". See :ref:`gpu` for the list. - bits 28-31: ??? .. todo:: unk bitfields G92[?] introduced another identification register in PMC, with unknown purpose: .. reg:: 32 pmc-boot-2 ??? ??? .. todo:: what is this? when was it introduced? seen non-0 on at least G92 G94 introduced a new identification register with rearranged bitfields: .. reg:: 32 pmc-new-id card identification - 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 :ref:`bars` for more details. It is controlled by the ENDIAN register: .. reg:: 32 pmc-endian endian switch 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 :ref:`G80+ PFIFO` for details. The MMIO areas containing aliases of 8-bit VGA registers are unaffected by this switch, despite being in BAR0. .. _pmc-enable: Engine enables ============== PMC contains the main engine enable register, which is used to turn whole engines on and off: .. reg:: 32 pmc-enable engine master 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: - 0: :ref:`PAUDIO ` - 4: :ref:`PDMA ` and :ref:`PTIMER ` - 8: :ref:`PFIFO ` - 12: :ref:`PGRAPH ` - 16: :ref:`PRM ` - 24: :ref:`PFB ` On NV3:NV4, the bits are: - 0: ??? [XXX] - 4: :ref:`PMEDIA ` - 8: :ref:`PFIFO ` - 12: :ref:`PGRAPH ` and :ref:`PDMA ` - 16: :ref:`PTIMER ` - 20: :ref:`PFB ` - 24: :ref:`PCRTC ` - 28: :ref:`PRAMDAC.VIDEO ` On NV4:G80, the bits are: - 0: ??? - alleged to be related to I2C [NV10-] [XXX] - 1: :ref:`PVPE ` [NV17-] - 4: :ref:`PMEDIA ` - 8: :ref:`PFIFO ` - 12: :ref:`PGRAPH ` [NV4:NV10] - 12: :ref:`PGRAPH ` [NV10:NV20] - 12: :ref:`PGRAPH ` [NV20:NV40] - 12: :ref:`PGRAPH ` [NV40:G80] - 13: PGRAPH CS??? apparently exists on some late NV4x... [NV4?-] - 16: :ref:`PTIMER ` - 20: PFB [:ref:`NV3 `, :ref:`NV10 `, :ref:`NV40 `, :ref:`NV44 `] - 24: :ref:`PCRTC ` - 25: :ref:`PCRTC2 ` [NV11-] - 26: :ref:`PTV ` [NV17:NV20, NV25:G80] - 28: :ref:`PRAMDAC.VIDEO ` [NV4:NV10] or :ref:`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: :ref:`PVPE ` [G80:G98 G200:MCP77] - 1: :ref:`PPPP ` [G98:G200 MCP77-] - 4: :ref:`PMEDIA ` - 8: :ref:`PFIFO ` - 12: :ref:`PGRAPH ` - 13: :ref:`PCOPY ` [GT215-] - 14: :ref:`PCIPHER ` [G84:G98 G200:MCP77] - 14: :ref:`PSEC ` [G98:G200 MCP77:GT215] - 14: :ref:`PVCOMP ` [MCP89] - 15: :ref:`PBSP ` [G84:G98 G200:MCP77] - 15: :ref:`PVLD ` [G98:G200 MCP77-] - 16: :ref:`PTIMER ` - 17: :ref:`PVP2 ` [G84:G98 G200:MCP77] - 17: :ref:`PPDEC ` [G98:G200 MCP77-] - 20: :ref:`PFB ` - 21: :ref:`PGRAPH CHSW ` [G84-] - 22: :ref:`PMPEG CHSW ` [G84-] - 23: :ref:`PCOPY CHSW ` [GT215-] - 24: :ref:`PVP2 CHSW ` [G84:G98 G200:MCP77] - 24: :ref:`PPDEC CHSW ` [G98:G200 MCP77-] - 25: :ref:`PCIPHER CHSW ` [G84:G98 G200:MCP77] - 25: :ref:`PSEC CHSW ` [G98:G200 MCP77:GT215] - 25: :ref:`PVCOMP CHSW ` [MCP89] - 26: :ref:`PBSP CHSW ` [G84:G98 G200:MCP77] - 26: :ref:`PVLD CHSW ` [G98:G200 MCP77-] - 27: ??? [G84-] - 28: ??? [G84-] - 30: :ref:`PDISPLAY ` - 31: ??? .. todo:: unknowns On GF100+, the bits are: - 0: ??? - alleged to be related to I2C - 1: :ref:`PPPP ` [GF100:GM107] - 2: :ref:`PXBAR ` - 3: :ref:`PMFB ` - 4: :ref:`PMEDIA ` [GF100:GM107] - 5: :ref:`PRING ` - 6: :ref:`PCOPY[0] ` - 7: :ref:`PCOPY[1] ` [GF100:GM107] - 8: :ref:`PFIFO ` - 12: :ref:`PGRAPH ` - 13: :ref:`PDAEMON ` - 14: :ref:`PSEC ` [GM107:] - 15: :ref:`PVLD ` [GF100:GM107] - 15: :ref:`PVDEC ` [GM107:] - 16: :ref:`PTIMER ` - 17: :ref:`PPDEC ` [GF100:GM107] - 18: :ref:`PVENC ` [GK104-] - 20: :ref:`PBFB ` - 21: :ref:`PCOPY[2] ` [GK104-] - 26: ??? allegedly zpw [GK104-] - 27: ??? allegedly blg - 28: :ref:`PCOUNTER ` - 29: :ref:`PFFB ` - 30: :ref:`PDISPLAY ` - 31: ??? allegedly isohub GF100 also introduced SUBFIFO_ENABLE register: .. reg:: 32 pmc-spoon-enable PSPOON enables Enables PFIFO's PSPOONs. Bit i corresponds to PSPOON[i]. See :ref:`GF100+ PFIFO ` for details. There are also two other registers looking like ENABLE, but with seemingly no effect and currently unknown purpose: .. reg:: 32 pmc-enable-unk08 ??? related to enable Has the same bits as ENABLE, comes up as all-1 on boot, except for PDISPLAY bit which comes up as 0. .. reg:: 32 pmc-enable-unk0c ??? related to enable 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. .. reg:: 32 pmc-fifo-eng-unk260 ??? related to PFIFO engines Single-bit registers, 6 of them. .. todo:: RE these three .. _pmc-intr: .. _pdaemon-intr-pmc-daemon: 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 :ref:`pdaemon-iredir`] - 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 .. reg:: 32 pmc-intr-host interrupt status - 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. .. reg:: 32 pmc-intr-nrhost interrupt status - non-redirectable host Like :obj:`pmc-intr-host`, but for NRHOST. .. reg:: 32 pmc-intr-daemon interrupt status - PDAEMON Like :obj:`pmc-intr-host`, but for DAEMON. .. reg:: 32 pmc-intr-enable-host interrupt 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. .. reg:: 32 pmc-intr-enable-nrhost interrupt enable - non-redirectable host Like :obj:`pmc-intr-enable-nrhost`, but for NRHOST. .. reg:: 32 pmc-intr-enable-daemon interrupt enable - PDAEMON Like :obj:`pmc-intr-enable-host`, but for DAEMON. .. reg:: 32 pmc-intr-line-host interrupt line status - 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. .. reg:: 32 pmc-intr-line-nrhost interrupt line status - non-redirectable host Like :obj:`pmc-intr-line-host`, but for NRHOST. .. reg:: 32 pmc-intr-line-daemon interrupt line status - PDAEMON Like :obj:`pmc-intr-line-host`, but for DAEMON. .. reg:: 32 pmc-intr-mask-host interrupt mask - host 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. .. reg:: 32 pmc-intr-mask-nrhost interrupt mask - non-redirectable host Like :obj:`pmc-intr-mask-host`, but for NRHOST. .. reg:: 32 pmc-intr-mask-daemon interrupt mask - PDAEMON Like :obj:`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: - 0: :ref:`PAUDIO ` - 4: :ref:`PDMA ` - 8: :ref:`PFIFO ` - 12: :ref:`PGRAPH ` - 16: :ref:`PRM ` - 20: :ref:`PTIMER ` - 24: :ref:`PGRAPH's vblank interrupt ` - 28: software .. todo:: check For NV3: - 4: :ref:`PMEDIA ` - 8: :ref:`PFIFO ` - 12: :ref:`PGRAPH ` - 13: :ref:`PDMA ` - 16: :ref:`PRAMDAC.VIDEO ` - 20: :ref:`PTIMER ` - 24: :ref:`PGRAPH's vblank interrupt ` - 28: :ref:`PBUS ` - 31: software For NV4:G80: - 0: :ref:`PVPE ` [NV17:NV20 and NV25:G80] - 4: :ref:`PMEDIA ` - 8: :ref:`PFIFO ` - 12: :ref:`PGRAPH ` - 16: :ref:`PRAMDAC.VIDEO ` [NV4:NV10] or :ref:`PVIDEO ` [NV10:G80] - 20: :ref:`PTIMER ` - 24: :ref:`PCRTC ` - 25: :ref:`PCRTC2 ` [NV17:NV20 and NV25:G80] - 28: :ref:`PBUS ` - 31: software For G80:GF100: - 0: :ref:`PVPE ` [G80:G98 G200:MCP77] - 0: :ref:`PPPP ` [G98:G200 MCP77-] - 4: :ref:`PMEDIA ` - 8: :ref:`PFIFO ` - has separate NRHOST line on GT215+ - 9: ??? [GT215?-] - 11: ??? [GT215?-] - 12: :ref:`PGRAPH ` - 13: ??? [GT215?-] - 14: :ref:`PCIPHER ` [G84:G98 G200:MCP77] - 14: :ref:`PSEC ` [G98:G200 MCP77:GT215] - 14: :ref:`PVCOMP ` [MCP89-] - 15: :ref:`PBSP ` [G84:G98 G200:MCP77] - 15: :ref:`PVLD ` [G98:G200 MCP77-] - 16: ??? [GT215?-] - 17: :ref:`PVP2 ` [G84:G98 G200:MCP77] - 17: :ref:`PPDEC ` [G98:G200 MCP77-] - 18: :ref:`PDAEMON [GT215-] ` - 19: :ref:`PTHERM [GT215-] ` - 20: :ref:`PTIMER ` - 21: :ref:`PNVIO's GPIO interrupts ` - 22: :ref:`PCOPY ` - 26: :ref:`PDISPLAY ` - 27: ??? [GT215?-] - 28: :ref:`PBUS ` - 29: :ref:`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: :ref:`PPPP ` - has separate NRHOST line [GF100:GM107] - 4: :ref:`PMEDIA ` [GF100:GM107] - 5: PCOPY[0] [:ref:`GF100 `, :ref:`GK104 `] - has separate NRHOST line - 6: PCOPY[1] [:ref:`GF100 `, :ref:`GK104 `] - has separate NRHOST line - 7: :ref:`PCOPY[2] ` [GK104-] - has separate NRHOST line - 8: :ref:`PFIFO ` - 9: ??? allegedly remapper - 12: :ref:`PGRAPH ` - has separate NRHOST line - 13: :ref:`PBFB ` - 15: :ref:`PSEC ` - has separate NRHOST line [GM107:] - 15: :ref:`PVLD ` - has separate NRHOST line [GF100:GM107] - 16: :ref:`PVENC ` [GK104-] - has separate NRHOST line - 17: :ref:`PPDEC ` - has separate NRHOST line [GF100:GM107] - 17: :ref:`PVDEC ` - has separate NRHOST line [GM107:] - 18: :ref:`PTHERM ` - 19: ??? allegedly HDA codec [GF119-] - 20: :ref:`PTIMER ` - 21: :ref:`PNVIO's GPIO interrupts ` - 23: ??? allegedly dfd - 24: :ref:`PDAEMON ` - 25: :ref:`PMFB ` - 26: :ref:`PDISPLAY ` - 27: :ref:`PFFB ` - 28: :ref:`PBUS ` - has separate NRHOST line - 29: :ref:`PPCI ` - 30: :ref:`PRING ` - 31: software .. todo:: unknowns .. todo:: document these two .. reg:: 32 pmc-intr-pmfb PMFB interrupt status Bit x == interrupt for PMFB part x pending. .. reg:: 32 pmc-intr-pbfb PBFB interrupt status Bit x == interrupt for PBFB part x pending. .. todo:: verify variants for these? .. _pmc-vram-hide: VRAM hidden area ================ NV17/NV20 added a feature to disable host reads through selected range of VRAM. The registers are: .. reg:: 32 pmc-vram-hide-low VRAM hidden area low address - bits 0-28: address of start of the hidden area. bits 0-1 are ignored, the area is always 4-byte aligned. - bit 31: hidden area enabled .. reg:: 32 pmc-vram-hide-high VRAM hidden area high address - bits 0-28: address of end of the hidden area. bits 0-1 are ignored, the area is always 4-byte aligned. The start and end addresses are both inclusive. All BAR1, BAR2/BAR3, PEEPHOLE and PMEM/PRAMIN reads whose offsets fall into this window will be silently mangled to read 0 instead. Writes are unaffected. Note that offset from start of the BAR/PEEPHOLE/PRAMIN/PMEM is used for the comparison, not the actual VRAM address - thus the selected window will cover a different thing in each affected space. The VRAM hidden area functionality got silently nuked on GF100+ GPUs. The registers are still present, but they don't do anything.