PDAC: NV1 DAC and external devices control¶
Contents
Introduction¶
On NV1 cards, many display and IO tasks are handled by a separate SGS DAC chip. This chip’s registers are accessed through card’s main MMIO range. Its tasks are:
- generating video, memory, and audio clocks
- converting pixel data in memory to analog VGA signals
- handling the joystick port
- handling the saturn ports
The MMIO registers¶
-
8-bit space
nv1-pdac
[0x1000]
¶ -
nv1-mmio
0x609000: PDAC
This range contains DAC registers mapped directly to the MMIO space. Note that DAC is connected to NV1 by an 8-bit bus, so all these registers are in fact effectively 8-bit (with high 24 bits ignored on write, returned as 0 on reads).
This range is always active.
Address Name Description 0x0 PAL_WRITE Palette write index 0x4 PAL_DATA Palette data 0x8 PAL_MASK Palette index mask 0xc PAL_READ Palette read index 0x10 INDEX_LOW indirect DAC register index, low part 0x14 INDEX_HIGH indirect DAC register index, high part 0x18 DATA indirect DAC register data 0x1c GAME_PORT ISA-like game port
The DAC registers¶
The DAC has a lot of registers, and only a handful are available directly in the MMIO space. Most of its registers are so-called “inner DAC registers”, are selected by a 16-bit index, and can be accessed by indexed data port in MMIO space:
-
reg32
nv1-pdac-index-low
¶ -
nv1-pdac
0x10: INDEX_LOW
Stores low 8 bits of the register index to be accessed.
-
reg32
nv1-pdac-index-high
¶ -
nv1-pdac
0x14: INDEX_HIGH
Stores high 8 bits of the register index to be accessed.
-
reg32
nv1-pdac-data
¶ -
nv1-pdac
0x18: DATA
All accesses to this register are forwarded to
nv1-dac
register selected by the above two index registers. After every access, the index stored in the index registers is incremented by 1 (with proper carry between high and low part).
The inner DAC registers are:
-
8-bit space
nv1-dac
[0x10000]
¶ Todo
regs 0x1c-0xff
Todo
regs 0x1xx and 0x5xx
Todo
regs 0xf0xx
Address Name Description 0x0 VENDOR_ID Vendor ID 0x1 DEVICE_ID Device ID 0x2 REVISION_ID Revision ID 0x4 CONFIG_0 Configuration 0 0x5 CONFIG_1 Configuration 1 0x6 DDCIN DDC1 input 0x8 PAL_INDEX Current palette index 0x9 PAL_STATE Palette state 0xa PAL_RED Palette inflight red value 0xb PAL_GREEN Palette inflight green value 0xc POWERDOWN_0 Subunit powerdown 0 0xd POWERDOWN_1 Subunit powerdown 1 0xe POWERDOWN_2 Subunit powerdown 2 0x10+i*0x4 (i<nv1-dac-clock) PLL_M[i] PLL M parameter 0x11+i*0x4 (i<nv1-dac-clock) PLL_N[i] PLL N parameter 0x12+i*0x4 (i<nv1-dac-clock) PLL_O[i] PLL O parameter 0x13+i*0x4 (i<nv1-dac-clock) PLL_P[i] PLL P parameter 0x300+i*0x2 (i<2) SATURN_PORT_DATA[i] Saturn port data 0x301+i*0x2 (i<2) SATURN_PORT_MODE[i] Saturn port mode
DAC identification¶
The DAC can be identified by reading the 3 ID registers:
Powerdown registers¶
Parts of DAC functionality can be powered down when not used via powerdown registers:
-
reg8
nv1-dac-powerdown-0
¶ -
nv1-dac
0xc: POWERDOWN_0
- bits 0-2: ???
- bit 3: ??? powered down by default by BIOS
- bits 4-6: ???
- bit 7: ??? powered down by default by BIOS
Todo
RE me
Clocks¶
The DAC contains 3 PLLs, corresponding to the three clocks that NV1 uses:
- 0: MEMORY, used to control memory and PGRAPH operations
- 1: AUDIO, used to control PAUDIO operations
- 2: VIDEO, used to control scanout
Each PLL is controlled by 4 DAC registers:
Todo
write me
Palette¶
The DAC contains two palettes. Each palette consists of 256 entries. Each palette entry consists of three 8-bit values, one for each color.
Two palettes are present for VGA emulation: If a 16-color mode is in use, BIOS can bind palette 0 to the access registers, and palette 1 to display: user will be able to modify palette 0, and BIOS will periodically translate it into palette 1 taking into account the ATC palette remap registers.
The palette is accessed through 3 registers, which behave like VGA palette access registers.
The palette access circuitry has the following state:
- 8-bit current read/write index
- current mode: read or write
- current red and green value, 8-bit each
- current color: red, green, or blue
The state is stored in the following internal DAC registers:
-
reg8
nv1-dac-pal-state
¶ -
nv1-dac
0x9: PAL_STATE
- bits 0-2: CURRENT_COLOR, read only, one of:
- 1: RED
- 2: GREEN
- 4: BLUE
- bit 3: SELECT, selects which palette is accessed by the access register
- bits 4-5: CURRENT_MODE, read only, one of:
- 0: WRITE
- 3: READ
- bit 6: DISPLAY_SELECT, selects which palette is accessed by display pipeline
- bit 7: WIDTH, selects whether palette values are passed as-is, or
converted from/to 6-bit format, one of:
- 0: FULL, values are passed as-is
- 1: VGA, all values written to palette cells will be shifted left by 2 bits, and all values read from palette cells will be shifted right by 2 bits, to simulate 6-bit palette cells as used on VGA
- bits 0-2: CURRENT_COLOR, read only, one of:
The palette access registers are:
-
reg32
nv1-pdac-pal-write
¶ -
nv1-pdac
0x0: PAL_WRITE
When written, sets the current mode to write, sets the current index to the written value, and sets the current color to red.
When read, returns the current index.
-
reg32
nv1-pdac-pal-read
¶ -
nv1-pdac
0xc: PAL_READ
When written, sets the current mode to read, sets the current index to the written value + 1, and sets the current color to red. When read, returns the current index.
The behavior on reads depends on value of
nv1-dac-config-0
bit 4. If it’s to INDEX, the current index is returned. Otherwise, returns the current mode in low 2 bits (same values as in CURRENT_MODE), junk in high 6 bits.
-
reg32
nv1-pdac-pal-data
¶ -
nv1-pdac
0x4: PAL_DATA
When written: If the current color is red or green, store the value as the current value for the corresponding color. Otherwise, write the palette entry selected by the current index with the current red and green values, and the written value as the blue value.
When read: read entry (CURRENT_INDEX-1) of palette and return the color selected by current color.
After both read and write, the current color is cycled to the next one (red -> green -> blue -> red). If blue -> red transition happens, current index is increased by one.
Like on VGA, whenever the display pipeline needs a color index looked up, it is first ANDed together with the value of the palette index mask register:
DAC config¶
Todo
write me
-
reg8
nv1-dac-config-0
¶ -
nv1-dac
0x4: CONFIG_0
- bits 0-3: ???
- bit 4: PAL_READ_READ, selects
nv1-pdac-pal-read
value returned on reads- 0: INDEX, current index will be returned
- 1: MODE, current mode will be returned (like on VGA)
- bits 5-6: ???
Todo
write me
DDC input¶
The DAC supports DDC1 input. DDC1 protocol, as opposed to modern I2C-based DDC2 protocol, is fully unidirectional. The monitor continuously sends the entire EDID block in an endless cycle on the ID1 pin, clocked by the VSYNC signal from card. On NV1, the ID1 line is connected to DDCIN pin on the DAC. The raw state of this line is exposed directly as a DAC register:
To quickly read the EDID block, software can do bit-banging on the VSYNC line
via nv1-pfb-power-sync
register.
Saturn ports¶
The saturn ports are controlled by simple GPIO:
-
reg8
nv1-dac-saturn-port-data
¶ -
nv1-dac
0x300+i*0x2: SATURN_PORT_DATA[i] (i<2)
- bits 0-6: state of relevant saturn port pin. Read only if configured as input, read-write if configured as output.
-
reg8
nv1-dac-saturn-port-mode
¶ -
nv1-dac
0x301+i*0x2: SATURN_PORT_MODE[i] (i<2)
- bits 0-6: mode of relevant saturn port pin:
- 0: OUTPUT
- 1: INPUT
- bits 0-6: mode of relevant saturn port pin:
The bit assignments are:
- 0: DATA[0]
- 1: DATA[1]
- 2: DATA[2]
- 3: DATA[3]
- 4: SENSE
- 5: SELECT[1]
- 6: SELECT[0]
Todo
some newer DACs have more functionality?