Skip to content
Jonathan Neuschäfer edited this page Apr 21, 2022 · 10 revisions

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.

Registers

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

FIU_CFG - FIU configuration

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.

BURST_CFG - Burst configuration

bits description values
5:4 write burst
3:2 read burst 0 = 1 byte, 3 = 16 bytes

Read burst

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.

RESP_CFG - FIU response configuration

bits description
1 INT_EN
0 IAD_EN

FWIN* - Flash Access Window configuration

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.

UMA_CTS - UMA control and status

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)

UMA_ECTS - UMA extended control and status

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.

Automatic dummy byte insertion (for fast reads)

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 to 0x0b (fast read)
  • UMA_CTS.RD_WR is set to 0 (read)
  • UMA_CTS.A_SIZE is set to 1 (use 3 address bytes)
  • UMA_CTS.D_SIZE is set to 1-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

Limitations

Four byte addressing

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).

READ 4B:

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.

FAST READ 4B:

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       ]

Long reads

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.

RDID (read identification)

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          ]

References

Clone this wiki locally