This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM623: AM62x OSPI (Cadence IP) — Mode byte for indirect write & disabling page boundary re-addressing for custom FPGA protocol

Part Number: AM623

Hello TI E2E Community,

We are using the OSPI controller on the AM623 (Verdin AM62 SoM) to communicate with a custom FPGA over a Quad-SPI interface (non-NOR flash use case). We have implemented a bare-metal Linux kernel driver that directly programs the Cadence QSPI registers, bypassing the spi-cadence-quadspi framework.

We have two questions regarding the controller behavior.


System Setup

  • Platform: AM623, Linux 6.12, Verdin AM62 SoM
  • SPI Mode: Quad (4-4-4), SDR, Mode 0 (CPOL=0, CPHA=0)
  • Clock: ref_clk = 167 MHz, baud_div = 3 → ~21 MHz on wire ( SPI clock: ref_clk / (2*(div+1)) )
  • PHY: Disabled (required for SDR)
  • DAC: Disabled
  • Transfer Modes:
    • STIG (≤ 8 bytes)
    • Indirect (PIO, polling-based)

FPGA SPI Protocol

The FPGA expects the following frame format:

  • WRITE:
    CMD (1B) + ADDR (3B) + COUNT (1B) + DATA (N bytes) + DUMMY (1B)
  • READ:
    CMD (1B) + ADDR (3B) + COUNT (1B) + DUMMY (10 clocks) + DATA (N bytes)

Additional details:

  • The CMD byte encodes opcode (read = 0x00, write = 0x80) and word width (1/2/4) in the lower bits
  • ADDR is 3 bytes (slave ID + register address)
  • COUNT is 1 byte representing the number of words (data_bytes / word_width)
  • All phases are transferred in quad mode (4-bit)

Since the Cadence OSPI controller does not natively support a count field, we currently pack the count byte into the 4th address byte using 4-byte address mode. This approach works: the FPGA correctly interprets the last address byte as the count. STIG mode uses its own address configuration (CMDCTRL register), so both modes coexist.


Question 1: Mode Byte Support for Writes

We would prefer to send the count byte via the mode byte phase instead of embedding it in the address field.

The Cadence IP provides:

  • MODE_BIT_CONFIG_REG (0x28)MODE_FLD [7:0] (mode byte value)
  • DEV_INSTR_RD_CONFIG_REG (0x04) → bit 20 (MODE_BIT_ENABLE) for read operations

However, we could not find an equivalent MODE_BIT_ENABLE bit in:

  • DEV_INSTR_WR_CONFIG_REG (0x08)

Questions:

  • Is it possible to enable mode byte transmission for indirect write operations?
  • Or is the mode byte feature strictly limited to reads?
  • If so, is there any alternative mechanism to insert an extra byte between the address and data phases during indirect writes?

Question 2: Disabling Page Boundary Re-Addressing

Because the count is encoded into the lowest address byte, the controller interprets large address values.

We configured:

  • BYTES_PER_DEVICE_PAGE (in DEV_SIZE_CONFIG_REG (0x14)) = 0x800 (2048 bytes, maximum valid power-of-2)

Problem:
The controller enforces page boundary logic and splits transfers when a boundary is crossed. This causes:

  1. CS deassertion and command re-issue
  2. Protocol corruption, since:
    • The new address no longer contains a valid count field
    • The FPGA interprets the new command as a separate transaction

Example:

fpga_addr = 0x150007
count = 0xFF
addr_encode = 0x150007FF

page_offset = 0x150007FF % 0x800 = 0x7FF (2047)
bytes_to_boundary = 2048 - 2047 = 1 byte
→ Page break after 1 byte
 

Questions:

  • Is there a way to completely disable page boundary handling in the OSPI controller?
  • Are any of the following approaches valid?
    • Setting BYTES_PER_DEVICE_PAGE to 0 or 0xFFF (did not work)
    • A configuration bit to disable automatic CS toggling on page boundaries
    • Alternative usage of DEV_SIZE_CONFIG for non-flash devices

We observed:

  • 0xFFF (non-power-of-2) leads to transfer corruption
  • 0 also causes issues

Any guidance on either topic would be greatly appreciated.

Thank you,
Fide