-
Notifications
You must be signed in to change notification settings - Fork 4
SPI
SPI and SPI-flash access are implemented in the Flash Interface Unit (FIU).
Although NPCM750's SPI controller is also called FIU, it uses an incompatible register layout.
physical address | description |
---|---|
0x40000000 |
SPI flash access window |
0xc0000000 |
SPI flash access window (alias) |
0xc8000000 |
SPI controller registers |
An unrelated secondary SPI controller also exists, but isn't described here.
FIU has the following registers at 0xc8000000
:
offset | type | name | description |
---|---|---|---|
0x00 | u8 | FIU_CFG |
FIU configuration |
0x01 | u8 | BURST_CFG |
Burst configuration |
0x02 | u8 | RESP_CFG |
FIU response configuration |
0x03 | u8 | CFBB_PROT |
Core firmware boot block protection |
0x04 | u16 | FWIN1_LOW |
Flash Access Window 1, low limit |
0x06 | u16 | FWIN1_HIGH |
Flash Access Window 1, high limit |
0x08 | u16 | FWIN2_LOW |
Flash Access Window 2, low limit |
0x0a | u16 | FWIN2_HIGH |
Flash Access Window 2, high limit |
0x0c | u16 | FWIN3_LOW |
Flash Access Window 3, low limit |
0x0e | u16 | FWIN3_HIGH |
Flash Access Window 3, high limit |
0x10 | u8 | PROT_LOCK |
Protection lock |
0x11 | u8 | PROT_CLEAR |
Protection and lock clear |
0x14 | u8 | SPI_FL_CFG |
SPI flash configuration |
0x16 | u8 | UMA_CODE |
UMA code byte |
0x17 | u8 | UMA_AB0 |
UMA Address Byte 0, LSB, transmitted last |
0x18 | u8 | UMA_AB1 |
UMA Address Byte 1, transmitted second |
0x19 | u8 | UMA_AB2 |
UMA Address Byte 2, MSB, transmitted first |
0x1a | u8 | UMA_DB0 |
UMA Data Byte 0 |
0x1b | u8 | UMA_DB1 |
UMA Data Byte 1 |
0x1c | u8 | UMA_DB2 |
UMA Data Byte 2 |
0x1d | u8 | UMA_DB3 |
UMA Data Byte 3 |
0x1e | u8 | UMA_CTS |
UMA control and status |
0x1f | u8 | UMA_ECTS |
UMA extended control and status |
This 8-bit field contains the size of the flash (in units of 512KiB).
Beyond the configured size, reads to the MMIO windows at 0x40000000 or
0xc0000000 will return 0xff
.
bits | description | values |
---|---|---|
5:4 | write burst | |
3:2 | read burst | 0 = 1 byte, 3 = 16 bytes |
When the read burst size is set to 1, SPI reads read only one byte at a time. When it is set to 16, then longer transactions are possible, but 1/2/4 byte fetches will still only read that many bytes from the SPI flash.
bits | description |
---|---|
1 | INT_EN |
0 | IAD_EN |
The flash access windows are configured through FWINx_LOW
and FWINx_HIGH
,
in units of 4096 bytes, but their purpose is unknown: Read accesss through
0x40000000
is still available after setting all windows to 0:0.
NOTE: Writes to the window registers must be 16-bit or 32-bit writes. 8-bit writes are apparently discarded.
bits | mask | description |
---|---|---|
7 | 0x80 | write 1: trigger command execution; read 1: busy |
6:5 | 0x60 | chip select number (0-3) |
4 | 0x10 | SPI direction: read (0) or write (1); exact function to be confirmed. |
3 | 0x08 | use address field |
2:0 | 0x07 | number of data bytes (0-4) |
bits | description |
---|---|
3 | chip select 3 (0=assert, 1=deassert) |
2 | chip select 2 (0=assert, 1=deassert) |
1 | chip select 1 (0=assert, 1=deassert) |
0 | chip select 0 (0=assert, 1=deassert) |
This register is used to assert the chip select lines manually.
In UMA transfers, the controller automatically inserts a dummy byte into the SPI transfer, if all of the following conditions are met:
-
UMA_CODE
is set to0x0b
(fast read) -
UMA_CTS.RD_WR
is set to0
(read) -
UMA_CTS.A_SIZE
is set to1
(use 3 address bytes) -
UMA_CTS.D_SIZE
is set to1
-4
(use 1-4 data bytes)
code | R/W | A | D | dummy byte inserted? |
---|---|---|---|---|
0x0b | R | 3 | 1-4 | yes |
0x0b | W | * | * | no |
0x0b | * | 0 | * | no |
0x0b | * | * | 0 | no |
other | * | * | * | no |
The FIU was not designed with 4-byte addressing in mind, but we can work around
this fact, by chaining multiple transfers together (see UMA_ECTS
).
Flash view: [ C A A A A D D D D]
bytes: 13 aa bb cc dd -> 5a a5 f0 0f
FIU's view: [ C A A A][ C D D D D]
FIU mode: [ read/write][ read ]
Even if the last address byte is 0x0b, a dummy byte will not be inserted because the second transfer (from FIU's point of view) doesn't have address bytes.
Flash view: [ C A A A A Du D D D D]
bytes: 0c aa bb cc dd 00 -> 5a a5 f0 0f
FIU's view: [ C A A A D][ C D D D D]
FIU mode: [ write ][ read ]
Due to the structure of a command as represented in FIU, only up to four bytes can be read at most. This presents a challenge in a few cases.
Although most flash memories can be identified by the first 3 bytes returned by the RDID command (0x9f), Linux reads 6 bytes.
FIU does not allow gapless reading of more than four bytes at once. However, because the device ID is constant, we can read it twice and stitch the bytes together.
Flash view: [ C I I I ]
bytes: 9f -> aa bb cc ]
FIU's view: [ C D D D ]
FIU mode: [ read ]
Flash view: [ C I I I I I I ]
bytes: 9f -> xx xx xx dd ee ff ]
FIU's view: [ C A A A D D D ]
FIU mode: [ read ]
Overview:
Basics:
Peripherals:
- Memory controller
- UART, SPI/SSPI, I2C, SD
- GPIOs and pinmux
- Ethernet
- USB, LPC, PECI, XBUS
- PWM and Tachometer, ADC
- Graphics
Board specifics: