NV1:NV4 PFIFO engine

Introduction

PFIFO is the functional unit in charge of collecting engine commands from user applications and delivering them to PGRAPH. See fifo/intro.txt for an overview of its construction.

PFIFO is controlled by PMC.ENABLE bit 8 and is connected to PMC interrupt 8. Setting PMC.ENABLE bit 8 to 0 forces the following registers to 0 [but doesn’t otherwise affect PFIFO]:

The MMIO registers

8-bit space nv1-pfifo [0x2000]
nv1-mmio 0x2000: PFIFO
nv3-mmio 0x2000: PFIFO [NV3:NV4]
Address Variants Name Description
0x40 all WAIT_RETRY ???
0x80 all CACHE_ERROR puller error status
0x100 all INTR interrupt status / acknowledge
0x140 all INTR_ENABLE interrupt enable
0x200 all CONFIG pusher configuration
0x210 NV3: RAMHT RAMHT pointer and configuration
0x214 NV3: RAMFC RAMFC pointer
0x218 NV3: RAMRO RAMRO pointer and configuration
0x400 all RUNOUT_STATUS RAMRO status
0x410 all RUNOUT_PUT RAMRO write pointer
0x420 all RUNOUT_GET RAMRO read pointer
0x500 all CHSW_ENABLE CACHE channel switch control
0x800 all DEVICE PGRAPH engine status?
0x1000 all CACHE0 aux cache
0x1200 all CACHE1 main cache
8-bit space nv1-pfifo-cache0 [0x200]
nv1-pfifo 0x1000: CACHE0
Address Variants Name Description
0x0 all PUSH_ACCESS pusher enable
0x10 NV1:NV3 CHID channel ID
0x20 NV1:NV3 STATUS status
0x30 NV1:NV3 PUT pusher write pointer
0x4 NV3:NV4 CHID channel ID
0x10 NV3:NV4 PUT pusher write pointer
0x14 NV3:NV4 STATUS status
0x40 all PULL_CTRL puller control
0x50 NV1:NV3 PULL_STATE puller state
0x70 all PUT puller read pointer
0x80 all CTX puller context
0x100 all ADDR cache entry - method & subchannel
0x104 all DATA cache entry - data
8-bit space nv1-pfifo-cache1 [0xe00]
nv1-pfifo 0x1200: CACHE1
Address Variants Name Description
0x0 all PUSH_ACCESS pusher enable
0x10 NV1:NV3 CHID channel ID
0x20 NV1:NV3 STATUS status
0x30 NV1:NV3 PUT pusher write pointer
0x4 NV3:NV4 CHID channel ID
0x10 NV3:NV4 PUT pusher write pointer
0x14 NV3:NV4 STATUS status
0x18 NV3:NV4 DMA_STATE DMA pusher state
0x20 NV3:NV4 DMA_CTRL DMA pusher control and status
0x24 NV3:NV4 DMA_COUNT DMA push buffer counter
0x28 NV3:NV4 DMA_GET DMA push buffer pointer
0x2c NV3:NV4 DMA_TARGET DMA push buffer target
0x30 NV3:NV4 DMA_TLB_TAG DMA push buffer TLB tag
0x34 NV3:NV4 DMA_TLB_PTE DMA push buffer TLB entry
0x38 NV3:NV4 DMA_PT DMA push buffer page table
0x40 all PULL_CTRL puller control
0x50 all PULL_STATE puller state
0x70 all PUT puller read pointer
0x80 all CTX[8/0x10] puller context
0x100 NV1:NV3T ADDR[0x20/8] cache entry - method & subchannel
0x104 NV1:NV3T DATA[0x20/8] cache entry - data
0x200 NV3T:NV4 ADDR[0x40/8] cache entry - method & subchannel
0x204 NV3T:NV4 DATA[0x40/8] cache entry - data

Interrupt reporting

The following registers deal with reporting PFIFO interrupts:

reg32 nv1-pfifo-intr
nv1-pfifo 0x100: INTR

Status of interrupts generated by PFIFO. On read, returns 1 for bits corresponding to pending interrupts. On write, if 1 is written to a bit, its interrupt gets cleared, if 0 is written nothing happens.

reg32 nv1-pfifo-intr-enable
nv1-pfifo 0x140: INTR_ENABLE

Interrupt enable bitmask. Set to enable, clear to disable. Interrupts that are masked will still show up in INTR when they’re triggered, but won’t cause the PFIFO interrupt line to go active.

The bitfields common to these registers are:
Bit Name Description
0 PULLER_ERROR puller had a problem while processing a command
4 RUNOUT pusher rejected a PIO FIFO access and wrote an entry to RAMRO
8 RUNOUT_OVERFLOW like above, but RAMRO was full and the entry was discarded
12 DMA_PUSHER the DMA pusher read a malformed command stream [NV3+]
16 DMA_PTE the DMA pusher got a page fault when reading the command stream [NV3+]
reg32 pfifo-cache-error
nv1-pfifo 0x80: CACHE_ERROR

Todo

write me

The memory structures

The NV1/NV3 PFIFO uses three memory structures that reside in RAMIN:

  • RAMHT, the puller hash table - can be 0x1000, 0x2000, 0x4000, or 0x8000 bytes long, depending on configuration
  • RAMFC, the puller context save area - 0x20 bytes per channel, on NV1 it’s always half the size of RAMHT, thus using 0x1000-byte RAMHT makes half the channels useless, and using >0x2000-byte RAMHT wastes RAMIN space. On NV3, it’s always 0x1000 bytes [128 channels] long.
  • RAMRO, the pusher runout area - made of 8-byte entries, always half the size of RAMHT on NV1, either 0x200 or 0x2000 bytes long on NV3.

In addition to these, NV3 also uses the page table part of standard DMA object structure to access the DMA command buffer.

On NV1, these three structures reside at fixed addresses in RAMIN, selected based on the PRAM size configuration [see nv1-pram-config]. There are special MMIO areas provided for easy access to them. On NV3, the structures can be located anywhere in the first 64kB of RAMIN, settable via the configuration registers:

reg32 nv1-pfifo-ramht
nv1-pfifo 0x210: RAMHT [NV3:]
  • bits 12-15 bits 12-15 of RAMHT start address inside RAMIN

  • bits 16-17 RAMHT size

    0 0x1000 bytes
    1 0x2000 bytes
    2 0x4000 bytes
    3 0x8000 bytes

The RAMHT address always has to be 0x1000-byte aligned.

reg32 nv1-pfifo-ramfc
nv1-pfifo 0x214: RAMFC [NV3:]
  • bits 9-15: bits 9-15 of RAMFC start address inside RAMIN

The RAMFC address always has to be 0x200-byte aligned.

reg32 nv1-pfifo-ramro
nv1-pfifo 0x218: RAMRO [NV3:]
  • bits 9-15: bits 9-15 of RAMRO start address inside RAMIN

  • bit 16: RAMRO size

    0 0x200 bytes [64 entries]
    1 0x2000 bytes [1024 entries]

The RAMRO address always has to be 0x200-byte aligned.

The cache

The cache is a “waiting area” for the commands submitted through PFIFO. There are two caches: the 32-entry [NV1, NV3] or 64-entry [NV3T] CACHE1, which is used for normal submission and the 1-entry CACHE0, available for manually injecting PGRAPH commands as part of software method execution, if needed.

A single cache entry holds one command and consists of:

  • 3-bit subchannel id
  • 11-bit method
  • 32-bit data

The channel id is not stored in the cache entries - it’s stored in a pusher register instead. This means that all commands in the cache have to belong to the same channel - pusher will refuse attempts to submit commands on a channel different from its current channel if it’s unable to switch to it [ie. there’s something in the cache already or channel switching is manually disabled].

The CACHE1 entries are indexed in Gray code instead of normal binary code.

Todo

document gray code

reg32 nv1-pfifo-cache-push-access
nv1-pfifo-cache0 0x0: PUSH_ACCESS
nv1-pfifo-cache1 0x0: PUSH_ACCESS

Todo

write me

reg32 nv1-pfifo-cache-pull-ctrl
nv1-pfifo-cache0 0x40: PULL_CTRL
nv1-pfifo-cache1 0x40: PULL_CTRL

Todo

write me

reg32 nv1-pfifo-cache-chid
nv1-pfifo-cache0 0x10: CHID [NV1:NV3]
nv1-pfifo-cache0 0x4: CHID [NV3:NV4]
nv1-pfifo-cache1 0x10: CHID [NV1:NV3]
nv1-pfifo-cache1 0x4: CHID [NV3:NV4]

Todo

write me

reg32 nv1-pfifo-cache-get
nv1-pfifo-cache0 0x70: PUT
nv1-pfifo-cache1 0x70: PUT

Todo

write me

reg32 nv1-pfifo-cache-put
nv1-pfifo-cache0 0x30: PUT [NV1:NV3]
nv1-pfifo-cache0 0x10: PUT [NV3:NV4]
nv1-pfifo-cache1 0x30: PUT [NV1:NV3]
nv1-pfifo-cache1 0x10: PUT [NV3:NV4]

Todo

write me

reg32 nv1-pfifo-cache-pull-state
nv1-pfifo-cache0 0x50: PULL_STATE [NV1:NV3]
nv1-pfifo-cache1 0x50: PULL_STATE

Todo

write me

reg32 nv1-pfifo-cache-status
nv1-pfifo-cache0 0x20: STATUS [NV1:NV3]
nv1-pfifo-cache0 0x14: STATUS [NV3:NV4]
nv1-pfifo-cache1 0x20: STATUS [NV1:NV3]
nv1-pfifo-cache1 0x14: STATUS [NV3:NV4]

Todo

write me

reg32 nv1-pfifo-cache-addr
nv1-pfifo-cache0 0x100: ADDR
nv1-pfifo-cache1 0x100: ADDR[0x20/8] [NV1:NV3T]
nv1-pfifo-cache1 0x200: ADDR[0x40/8] [NV3T:NV4]

Todo

write me

reg32 nv1-pfifo-cache-data
nv1-pfifo-cache0 0x104: DATA
nv1-pfifo-cache1 0x104: DATA[0x20/8] [NV1:NV3T]
nv1-pfifo-cache1 0x204: DATA[0x40/8] [NV3T:NV4]

Todo

write me

The pusher

Todo

write me

reg32 nv1-pfifo-config
nv1-pfifo 0x200: CONFIG

Todo

write me

reg32 nv1-pfifo-chsw-enable
nv1-pfifo 0x500: CHSW_ENABLE

Todo

write me

FIFO submission area

Todo

write me

8-bit space nv1-user [0x2000]
nv1-mmio 0x800000+chid*0x10000+subc*0x2000: USER[chid][subc] (chid<128, subc<8)
nv3-mmio 0x800000+chid*0x10000+subc*0x2000: USER[chid][subc] (chid<128, subc<8) [NV3:NV4]

Todo

document me

RAMRO

Todo

write me

reg32 pfifo-runout-status
nv1-pfifo 0x400: RUNOUT_STATUS

Todo

write me

reg32 pfifo-runout-put
nv1-pfifo 0x410: RUNOUT_PUT

Todo

write me

reg32 pfifo-runout-get
nv1-pfifo 0x420: RUNOUT_GET

Todo

write me

DMA submission

Todo

write me

reg32 nv1-pfifo-dma-state
nv1-pfifo-cache1 0x18: DMA_STATE [NV3:NV4]

Todo

write me

reg32 nv1-pfifo-dma-ctrl
nv1-pfifo-cache1 0x20: DMA_CTRL [NV3:NV4]

Todo

write me

reg32 nv1-pfifo-dma-count
nv1-pfifo-cache1 0x24: DMA_COUNT [NV3:NV4]

Todo

write me

reg32 nv1-pfifo-dma-get
nv1-pfifo-cache1 0x28: DMA_GET [NV3:NV4]

Todo

write me

reg32 nv1-pfifo-dma-target
nv1-pfifo-cache1 0x2c: DMA_TARGET [NV3:NV4]

Todo

write me

reg32 nv1-pfifo-dma-tlb-tag
nv1-pfifo-cache1 0x30: DMA_TLB_TAG [NV3:NV4]

Todo

write me

reg32 nv1-pfifo-dma-tlb-pte
nv1-pfifo-cache1 0x34: DMA_TLB_PTE [NV3:NV4]

Todo

write me

reg32 nv1-pfifo-dma-pt
nv1-pfifo-cache1 0x38: DMA_PT [NV3:NV4]

Todo

write me

The puller

Todo

write me

reg32 nv1-pfifo-cache-ctx
nv1-pfifo-cache0 0x80: CTX
nv1-pfifo-cache1 0x80: CTX[8/0x10]

Todo

write me

RAMFC

Todo

write me

RAMHT

Todo

write me

Unknown registers

reg32 pfifo-wait-retry
nv1-pfifo 0x40: WAIT_RETRY

Todo

write me

reg32 nv1-pfifo-device
nv1-pfifo 0x800: DEVICE

Todo

write me