rp: Run clang-format
This commit is contained in:
parent
14882c61ab
commit
bf0302b076
262
src/target/rp.c
262
src/target/rp.c
|
@ -56,19 +56,19 @@
|
||||||
#define RP_SRAM_BASE 0x20000000U
|
#define RP_SRAM_BASE 0x20000000U
|
||||||
#define RP_SRAM_SIZE 0x42000U
|
#define RP_SRAM_SIZE 0x42000U
|
||||||
|
|
||||||
#define RP_GPIO_QSPI_BASE_ADDR 0x40018000U
|
#define RP_GPIO_QSPI_BASE_ADDR 0x40018000U
|
||||||
#define RP_GPIO_QSPI_SCLK_CTRL (RP_GPIO_QSPI_BASE_ADDR + 0x04U)
|
#define RP_GPIO_QSPI_SCLK_CTRL (RP_GPIO_QSPI_BASE_ADDR + 0x04U)
|
||||||
#define RP_GPIO_QSPI_CS_CTRL (RP_GPIO_QSPI_BASE_ADDR + 0x0cU)
|
#define RP_GPIO_QSPI_CS_CTRL (RP_GPIO_QSPI_BASE_ADDR + 0x0cU)
|
||||||
#define RP_GPIO_QSPI_SD0_CTRL (RP_GPIO_QSPI_BASE_ADDR + 0x14U)
|
#define RP_GPIO_QSPI_SD0_CTRL (RP_GPIO_QSPI_BASE_ADDR + 0x14U)
|
||||||
#define RP_GPIO_QSPI_SD1_CTRL (RP_GPIO_QSPI_BASE_ADDR + 0x1cU)
|
#define RP_GPIO_QSPI_SD1_CTRL (RP_GPIO_QSPI_BASE_ADDR + 0x1cU)
|
||||||
#define RP_GPIO_QSPI_SD2_CTRL (RP_GPIO_QSPI_BASE_ADDR + 0x24U)
|
#define RP_GPIO_QSPI_SD2_CTRL (RP_GPIO_QSPI_BASE_ADDR + 0x24U)
|
||||||
#define RP_GPIO_QSPI_SD3_CTRL (RP_GPIO_QSPI_BASE_ADDR + 0x2cU)
|
#define RP_GPIO_QSPI_SD3_CTRL (RP_GPIO_QSPI_BASE_ADDR + 0x2cU)
|
||||||
#define RP_GPIO_QSPI_CS_DRIVE_NORMAL (0U << 8U)
|
#define RP_GPIO_QSPI_CS_DRIVE_NORMAL (0U << 8U)
|
||||||
#define RP_GPIO_QSPI_CS_DRIVE_INVERT (1U << 8U)
|
#define RP_GPIO_QSPI_CS_DRIVE_INVERT (1U << 8U)
|
||||||
#define RP_GPIO_QSPI_CS_DRIVE_LOW (2U << 8U)
|
#define RP_GPIO_QSPI_CS_DRIVE_LOW (2U << 8U)
|
||||||
#define RP_GPIO_QSPI_CS_DRIVE_HIGH (3U << 8U)
|
#define RP_GPIO_QSPI_CS_DRIVE_HIGH (3U << 8U)
|
||||||
#define RP_GPIO_QSPI_CS_DRIVE_MASK 0x00000300U
|
#define RP_GPIO_QSPI_CS_DRIVE_MASK 0x00000300U
|
||||||
#define RP_GPIO_QSPI_SD1_CTRL_INOVER_BITS 0x00030000U
|
#define RP_GPIO_QSPI_SD1_CTRL_INOVER_BITS 0x00030000U
|
||||||
|
|
||||||
#define RP_SSI_BASE_ADDR 0x18000000U
|
#define RP_SSI_BASE_ADDR 0x18000000U
|
||||||
#define RP_SSI_CTRL0 (RP_SSI_BASE_ADDR + 0x00U)
|
#define RP_SSI_CTRL0 (RP_SSI_BASE_ADDR + 0x00U)
|
||||||
|
@ -93,40 +93,40 @@
|
||||||
#define RP_SSI_CTRL0_TMOD_EEPROM (3U << 8U)
|
#define RP_SSI_CTRL0_TMOD_EEPROM (3U << 8U)
|
||||||
#define RP_SSI_CTRL0_DATA_BIT_MASK 0x001f0000U
|
#define RP_SSI_CTRL0_DATA_BIT_MASK 0x001f0000U
|
||||||
#define RP_SSI_CTRL0_DATA_BIT_SHIFT 16U
|
#define RP_SSI_CTRL0_DATA_BIT_SHIFT 16U
|
||||||
#define RP_SSI_CTRL0_DATA_BITS(x) (((x) - 1U) << RP_SSI_CTRL0_DATA_BIT_SHIFT)
|
#define RP_SSI_CTRL0_DATA_BITS(x) (((x)-1U) << RP_SSI_CTRL0_DATA_BIT_SHIFT)
|
||||||
#define RP_SSI_CTRL0_MASK (RP_SSI_CTRL0_FRF_MASK | RP_SSI_CTRL0_TMOD_MASK | RP_SSI_CTRL0_DATA_BIT_MASK)
|
#define RP_SSI_CTRL0_MASK (RP_SSI_CTRL0_FRF_MASK | RP_SSI_CTRL0_TMOD_MASK | RP_SSI_CTRL0_DATA_BIT_MASK)
|
||||||
#define RP_SSI_ENABLE_SSI (1U << 0U)
|
#define RP_SSI_ENABLE_SSI (1U << 0U)
|
||||||
#define RP_SSI_XIP_SPI_CTRL0_FORMAT_STD_SPI (0U << 0U)
|
#define RP_SSI_XIP_SPI_CTRL0_FORMAT_STD_SPI (0U << 0U)
|
||||||
#define RP_SSI_XIP_SPI_CTRL0_FORMAT_SPLIT (1U << 0U)
|
#define RP_SSI_XIP_SPI_CTRL0_FORMAT_SPLIT (1U << 0U)
|
||||||
#define RP_SSI_XIP_SPI_CTRL0_FORMAT_FRF (2U << 0U)
|
#define RP_SSI_XIP_SPI_CTRL0_FORMAT_FRF (2U << 0U)
|
||||||
#define RP_SSI_XIP_SPI_CTRL0_ADDRESS_LENGTH(x) (((x) * 2U) << 2U)
|
#define RP_SSI_XIP_SPI_CTRL0_ADDRESS_LENGTH(x) (((x)*2U) << 2U)
|
||||||
#define RP_SSI_XIP_SPI_CTRL0_INSTR_LENGTH_8b (2U << 8U)
|
#define RP_SSI_XIP_SPI_CTRL0_INSTR_LENGTH_8b (2U << 8U)
|
||||||
#define RP_SSI_XIP_SPI_CTRL0_WAIT_CYCLES(x) (((x) * 8U) << 11U)
|
#define RP_SSI_XIP_SPI_CTRL0_WAIT_CYCLES(x) (((x)*8U) << 11U)
|
||||||
#define RP_SSI_XIP_SPI_CTRL0_XIP_CMD_SHIFT 24U
|
#define RP_SSI_XIP_SPI_CTRL0_XIP_CMD_SHIFT 24U
|
||||||
#define RP_SSI_XIP_SPI_CTRL0_XIP_CMD(x) ((x) << RP_SSI_XIP_SPI_CTRL0_XIP_CMD_SHIFT)
|
#define RP_SSI_XIP_SPI_CTRL0_XIP_CMD(x) ((x) << RP_SSI_XIP_SPI_CTRL0_XIP_CMD_SHIFT)
|
||||||
#define RP_SSI_XIP_SPI_CTRL0_TRANS_1C1A (0U << 0U)
|
#define RP_SSI_XIP_SPI_CTRL0_TRANS_1C1A (0U << 0U)
|
||||||
#define RP_SSI_XIP_SPI_CTRL0_TRANS_1C2A (1U << 0U)
|
#define RP_SSI_XIP_SPI_CTRL0_TRANS_1C2A (1U << 0U)
|
||||||
#define RP_SSI_XIP_SPI_CTRL0_TRANS_2C2A (2U << 0U)
|
#define RP_SSI_XIP_SPI_CTRL0_TRANS_2C2A (2U << 0U)
|
||||||
|
|
||||||
#define RP_PADS_QSPI_BASE_ADDR 0x40020000U
|
#define RP_PADS_QSPI_BASE_ADDR 0x40020000U
|
||||||
#define RP_PADS_QSPI_GPIO_SD0 (RP_PADS_QSPI_BASE_ADDR + 0x08U)
|
#define RP_PADS_QSPI_GPIO_SD0 (RP_PADS_QSPI_BASE_ADDR + 0x08U)
|
||||||
#define RP_PADS_QSPI_GPIO_SD1 (RP_PADS_QSPI_BASE_ADDR + 0x0cU)
|
#define RP_PADS_QSPI_GPIO_SD1 (RP_PADS_QSPI_BASE_ADDR + 0x0cU)
|
||||||
#define RP_PADS_QSPI_GPIO_SD2 (RP_PADS_QSPI_BASE_ADDR + 0x10U)
|
#define RP_PADS_QSPI_GPIO_SD2 (RP_PADS_QSPI_BASE_ADDR + 0x10U)
|
||||||
#define RP_PADS_QSPI_GPIO_SD3 (RP_PADS_QSPI_BASE_ADDR + 0x14U)
|
#define RP_PADS_QSPI_GPIO_SD3 (RP_PADS_QSPI_BASE_ADDR + 0x14U)
|
||||||
#define RP_PADS_QSPI_GPIO_SD0_OD_BITS 0x00000080U
|
#define RP_PADS_QSPI_GPIO_SD0_OD_BITS 0x00000080U
|
||||||
#define RP_PADS_QSPI_GPIO_SD0_PUE_BITS 0x00000008U
|
#define RP_PADS_QSPI_GPIO_SD0_PUE_BITS 0x00000008U
|
||||||
#define RP_PADS_QSPI_GPIO_SD0_PDE_BITS 0x00000004U
|
#define RP_PADS_QSPI_GPIO_SD0_PDE_BITS 0x00000004U
|
||||||
|
|
||||||
#define RP_XIP_BASE_ADDR 0x14000000U
|
#define RP_XIP_BASE_ADDR 0x14000000U
|
||||||
#define RP_XIP_CTRL (RP_XIP_BASE_ADDR + 0x00U)
|
#define RP_XIP_CTRL (RP_XIP_BASE_ADDR + 0x00U)
|
||||||
#define RP_XIP_FLUSH (RP_XIP_BASE_ADDR + 0x04U)
|
#define RP_XIP_FLUSH (RP_XIP_BASE_ADDR + 0x04U)
|
||||||
#define RP_XIP_CTRL_ENABLE 0x00000001U
|
#define RP_XIP_CTRL_ENABLE 0x00000001U
|
||||||
|
|
||||||
#define RP_RESETS_BASE_ADDR 0x4000c000U
|
#define RP_RESETS_BASE_ADDR 0x4000c000U
|
||||||
#define RP_RESETS_RESET (RP_RESETS_BASE_ADDR + 0x00U)
|
#define RP_RESETS_RESET (RP_RESETS_BASE_ADDR + 0x00U)
|
||||||
#define RP_RESETS_RESET_DONE (RP_RESETS_BASE_ADDR + 0x08U)
|
#define RP_RESETS_RESET_DONE (RP_RESETS_BASE_ADDR + 0x08U)
|
||||||
#define RP_RESETS_RESET_IO_QSPI_BITS 0x00000040U
|
#define RP_RESETS_RESET_IO_QSPI_BITS 0x00000040U
|
||||||
#define RP_RESETS_RESET_PADS_QSPI_BITS 0x00000200U
|
#define RP_RESETS_RESET_PADS_QSPI_BITS 0x00000200U
|
||||||
|
|
||||||
#define BOOTROM_FUNC_TABLE_ADDR 0x00000014U
|
#define BOOTROM_FUNC_TABLE_ADDR 0x00000014U
|
||||||
#define BOOTROM_FUNC_TABLE_TAG(x, y) ((uint8_t)(x) | ((uint8_t)(y) << 8U))
|
#define BOOTROM_FUNC_TABLE_TAG(x, y) ((uint8_t)(x) | ((uint8_t)(y) << 8U))
|
||||||
|
@ -142,7 +142,7 @@
|
||||||
#define RP_SPI_OPCODE(x) (x)
|
#define RP_SPI_OPCODE(x) (x)
|
||||||
#define RP_SPI_OPCODE_MASK 0x00ffU
|
#define RP_SPI_OPCODE_MASK 0x00ffU
|
||||||
#define RP_SPI_INTER_SHIFT 8U
|
#define RP_SPI_INTER_SHIFT 8U
|
||||||
#define RP_SPI_INTER_LENGTH(x) (((x) & 7U) << RP_SPI_INTER_SHIFT)
|
#define RP_SPI_INTER_LENGTH(x) (((x)&7U) << RP_SPI_INTER_SHIFT)
|
||||||
#define RP_SPI_INTER_MASK 0x0700U
|
#define RP_SPI_INTER_MASK 0x0700U
|
||||||
#define RP_SPI_FRAME_OPCODE_ONLY (1 << 11U)
|
#define RP_SPI_FRAME_OPCODE_ONLY (1 << 11U)
|
||||||
#define RP_SPI_FRAME_OPCODE_3B_ADDR (2 << 11U)
|
#define RP_SPI_FRAME_OPCODE_3B_ADDR (2 << 11U)
|
||||||
|
@ -157,9 +157,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SPI_FLASH_CMD_SECTOR_ERASE 0x20
|
#define SPI_FLASH_CMD_SECTOR_ERASE 0x20
|
||||||
#define FLASHCMD_BLOCK32K_ERASE 0x52
|
#define FLASHCMD_BLOCK32K_ERASE 0x52
|
||||||
#define FLASHCMD_BLOCK64K_ERASE 0xd8
|
#define FLASHCMD_BLOCK64K_ERASE 0xd8
|
||||||
#define FLASHCMD_CHIP_ERASE 0x60
|
#define FLASHCMD_CHIP_ERASE 0x60
|
||||||
#define SPI_FLASH_CMD_READ_JEDEC_ID (RP_SPI_OPCODE(0x9fU) | RP_SPI_INTER_LENGTH(0) | RP_SPI_FRAME_OPCODE_ONLY)
|
#define SPI_FLASH_CMD_READ_JEDEC_ID (RP_SPI_OPCODE(0x9fU) | RP_SPI_INTER_LENGTH(0) | RP_SPI_FRAME_OPCODE_ONLY)
|
||||||
#define SPI_FLASH_CMD_READ_SFDP (RP_SPI_OPCODE(0x5aU) | RP_SPI_INTER_LENGTH(1) | RP_SPI_FRAME_OPCODE_3B_ADDR)
|
#define SPI_FLASH_CMD_READ_SFDP (RP_SPI_OPCODE(0x5aU) | RP_SPI_INTER_LENGTH(1) | RP_SPI_FRAME_OPCODE_3B_ADDR)
|
||||||
|
|
||||||
|
@ -205,9 +205,9 @@ static uint32_t rp_get_flash_length(target *t);
|
||||||
static bool rp_mass_erase(target *t);
|
static bool rp_mass_erase(target *t);
|
||||||
|
|
||||||
// Our own implementation of bootloader functions for handling flash chip
|
// Our own implementation of bootloader functions for handling flash chip
|
||||||
static void __attribute__((unused))rp_flash_connect_internal(target *t);
|
static void __attribute__((unused)) rp_flash_connect_internal(target *t);
|
||||||
static void rp_flash_exit_xip(target *t);
|
static void rp_flash_exit_xip(target *t);
|
||||||
static void __attribute__((unused))rp_flash_flush_cache(target *t);
|
static void __attribute__((unused)) rp_flash_flush_cache(target *t);
|
||||||
static void rp_flash_enter_xip(target *t);
|
static void rp_flash_enter_xip(target *t);
|
||||||
|
|
||||||
static void rp_spi_read_sfdp(target *const t, const uint32_t address, void *const buffer, const size_t length)
|
static void rp_spi_read_sfdp(target *const t, const uint32_t address, void *const buffer, const size_t length)
|
||||||
|
@ -622,14 +622,15 @@ static void rp_spi_read(
|
||||||
// Connect the XIP controller to the flash pads
|
// Connect the XIP controller to the flash pads
|
||||||
static void rp_flash_connect_internal(target *t)
|
static void rp_flash_connect_internal(target *t)
|
||||||
{
|
{
|
||||||
// Use hard reset to force IO and pad controls to known state (don't touch
|
// Use hard reset to force IO and pad controls to known state (don't touch
|
||||||
// IO_BANK0 as that does not affect XIP signals)
|
// IO_BANK0 as that does not affect XIP signals)
|
||||||
uint32_t reset = target_mem_read32(t, RP_RESETS_RESET);
|
uint32_t reset = target_mem_read32(t, RP_RESETS_RESET);
|
||||||
target_mem_write32(t, RP_RESETS_RESET, reset | RP_RESETS_RESET_IO_QSPI_BITS | RP_RESETS_RESET_PADS_QSPI_BITS);
|
target_mem_write32(t, RP_RESETS_RESET, reset | RP_RESETS_RESET_IO_QSPI_BITS | RP_RESETS_RESET_PADS_QSPI_BITS);
|
||||||
target_mem_write32(t, RP_RESETS_RESET, reset);
|
target_mem_write32(t, RP_RESETS_RESET, reset);
|
||||||
while (~target_mem_read32(t, RP_RESETS_RESET_DONE) & (RP_RESETS_RESET_IO_QSPI_BITS | RP_RESETS_RESET_PADS_QSPI_BITS));
|
while (
|
||||||
|
~target_mem_read32(t, RP_RESETS_RESET_DONE) & (RP_RESETS_RESET_IO_QSPI_BITS | RP_RESETS_RESET_PADS_QSPI_BITS));
|
||||||
|
|
||||||
// Then mux XIP block onto internal QSPI flash pads
|
// Then mux XIP block onto internal QSPI flash pads
|
||||||
target_mem_write32(t, RP_GPIO_QSPI_SCLK_CTRL, 0);
|
target_mem_write32(t, RP_GPIO_QSPI_SCLK_CTRL, 0);
|
||||||
target_mem_write32(t, RP_GPIO_QSPI_CS_CTRL, 0);
|
target_mem_write32(t, RP_GPIO_QSPI_CS_CTRL, 0);
|
||||||
target_mem_write32(t, RP_GPIO_QSPI_SD0_CTRL, 0);
|
target_mem_write32(t, RP_GPIO_QSPI_SD0_CTRL, 0);
|
||||||
|
@ -652,9 +653,9 @@ static void rp_flash_init_spi(target *t)
|
||||||
// Hopefully-conservative baud rate for boot and programming
|
// Hopefully-conservative baud rate for boot and programming
|
||||||
target_mem_write32(t, RP_SSI_BAUD, 6);
|
target_mem_write32(t, RP_SSI_BAUD, 6);
|
||||||
target_mem_write32(t, RP_SSI_CTRL0,
|
target_mem_write32(t, RP_SSI_CTRL0,
|
||||||
RP_SSI_CTRL0_FRF_SERIAL | // Standard 1-bit SPI serial frames
|
RP_SSI_CTRL0_FRF_SERIAL | // Standard 1-bit SPI serial frames
|
||||||
RP_SSI_CTRL0_DATA_BITS(8) | // 8 clocks per data frame
|
RP_SSI_CTRL0_DATA_BITS(8) | // 8 clocks per data frame
|
||||||
RP_SSI_CTRL0_TMOD_BIDI // TX and RX FIFOs are both used for every byte
|
RP_SSI_CTRL0_TMOD_BIDI // TX and RX FIFOs are both used for every byte
|
||||||
);
|
);
|
||||||
// Slave selected when transfers in progress
|
// Slave selected when transfers in progress
|
||||||
target_mem_write32(t, RP_SSI_SER, 1);
|
target_mem_write32(t, RP_SSI_SER, 1);
|
||||||
|
@ -664,8 +665,9 @@ static void rp_flash_init_spi(target *t)
|
||||||
|
|
||||||
// Also allow any unbounded loops to check whether the above abort condition
|
// Also allow any unbounded loops to check whether the above abort condition
|
||||||
// was asserted, and terminate early
|
// was asserted, and terminate early
|
||||||
static int rp_flash_was_aborted(target *t) {
|
static int rp_flash_was_aborted(target *t)
|
||||||
return target_mem_read32(t, RP_GPIO_QSPI_SD1_CTRL) & RP_GPIO_QSPI_SD1_CTRL_INOVER_BITS;
|
{
|
||||||
|
return target_mem_read32(t, RP_GPIO_QSPI_SD1_CTRL) & RP_GPIO_QSPI_SD1_CTRL_INOVER_BITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put bytes from one buffer, and get bytes into another buffer.
|
// Put bytes from one buffer, and get bytes into another buffer.
|
||||||
|
@ -676,39 +678,40 @@ static int rp_flash_was_aborted(target *t) {
|
||||||
// If rx_skip is nonzero, this many bytes will first be consumed from the FIFO,
|
// If rx_skip is nonzero, this many bytes will first be consumed from the FIFO,
|
||||||
// before reading a further count bytes into *rx.
|
// before reading a further count bytes into *rx.
|
||||||
// E.g. if you have written a command+address just before calling this function.
|
// E.g. if you have written a command+address just before calling this function.
|
||||||
static void rp_flash_put_get(target *t, const uint8_t *tx, uint8_t *rx, size_t count, size_t rx_skip) {
|
static void rp_flash_put_get(target *t, const uint8_t *tx, uint8_t *rx, size_t count, size_t rx_skip)
|
||||||
// Make sure there is never more data in flight than the depth of the RX
|
{
|
||||||
// FIFO. Otherwise, when we are interrupted for long periods, hardware
|
// Make sure there is never more data in flight than the depth of the RX
|
||||||
// will overflow the RX FIFO.
|
// FIFO. Otherwise, when we are interrupted for long periods, hardware
|
||||||
const uint max_in_flight = 16 - 2; // account for data internal to SSI
|
// will overflow the RX FIFO.
|
||||||
size_t tx_count = count;
|
const uint max_in_flight = 16 - 2; // account for data internal to SSI
|
||||||
size_t rx_count = count;
|
size_t tx_count = count;
|
||||||
while (tx_count || rx_skip || rx_count) {
|
size_t rx_count = count;
|
||||||
// NB order of reads, for pessimism rather than optimism
|
while (tx_count || rx_skip || rx_count) {
|
||||||
uint32_t tx_level = target_mem_read32(t, RP_SSI_TXFLR);
|
// NB order of reads, for pessimism rather than optimism
|
||||||
uint32_t rx_level = target_mem_read32(t, RP_SSI_RXFLR);
|
uint32_t tx_level = target_mem_read32(t, RP_SSI_TXFLR);
|
||||||
bool did_something = false; // Expect this to be folded into control flow, not register
|
uint32_t rx_level = target_mem_read32(t, RP_SSI_RXFLR);
|
||||||
if (tx_count && tx_level + rx_level < max_in_flight) {
|
bool did_something = false; // Expect this to be folded into control flow, not register
|
||||||
target_mem_write32(t, RP_SSI_DR0, (uint32_t) (tx ? *tx++ : 0));
|
if (tx_count && tx_level + rx_level < max_in_flight) {
|
||||||
--tx_count;
|
target_mem_write32(t, RP_SSI_DR0, (uint32_t)(tx ? *tx++ : 0));
|
||||||
did_something = true;
|
--tx_count;
|
||||||
}
|
did_something = true;
|
||||||
if (rx_level) {
|
}
|
||||||
uint8_t rxbyte = target_mem_read32(t, RP_SSI_DR0);
|
if (rx_level) {
|
||||||
did_something = true;
|
uint8_t rxbyte = target_mem_read32(t, RP_SSI_DR0);
|
||||||
if (rx_skip) {
|
did_something = true;
|
||||||
--rx_skip;
|
if (rx_skip) {
|
||||||
} else {
|
--rx_skip;
|
||||||
if (rx)
|
} else {
|
||||||
*rx++ = rxbyte;
|
if (rx)
|
||||||
--rx_count;
|
*rx++ = rxbyte;
|
||||||
}
|
--rx_count;
|
||||||
}
|
}
|
||||||
// APB load costs 4 cycles, so only do it on idle loops (our budget is 48 cyc/byte)
|
}
|
||||||
if (!did_something && rp_flash_was_aborted(t))
|
// APB load costs 4 cycles, so only do it on idle loops (our budget is 48 cyc/byte)
|
||||||
break;
|
if (!did_something && rp_flash_was_aborted(t))
|
||||||
}
|
break;
|
||||||
rp_spi_chip_select(t, RP_GPIO_QSPI_CS_DRIVE_HIGH);
|
}
|
||||||
|
rp_spi_chip_select(t, RP_GPIO_QSPI_CS_DRIVE_HIGH);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sequence:
|
// Sequence:
|
||||||
|
@ -721,55 +724,50 @@ static void rp_flash_put_get(target *t, const uint8_t *tx, uint8_t *rx, size_t c
|
||||||
// Parts 1 and 2 are to improve compatibility with Micron parts
|
// Parts 1 and 2 are to improve compatibility with Micron parts
|
||||||
static void rp_flash_exit_xip(target *t)
|
static void rp_flash_exit_xip(target *t)
|
||||||
{
|
{
|
||||||
uint8_t buf[2];
|
uint8_t buf[2];
|
||||||
buf[0] = 0xff;
|
buf[0] = 0xff;
|
||||||
buf[1] = 0xff;
|
buf[1] = 0xff;
|
||||||
|
|
||||||
rp_flash_init_spi(t);
|
rp_flash_init_spi(t);
|
||||||
|
|
||||||
uint32_t padctrl_save = target_mem_read32(t, RP_PADS_QSPI_GPIO_SD0);
|
uint32_t padctrl_save = target_mem_read32(t, RP_PADS_QSPI_GPIO_SD0);
|
||||||
uint32_t padctrl_tmp = (padctrl_save
|
uint32_t padctrl_tmp = (padctrl_save & ~(RP_PADS_QSPI_GPIO_SD0_OD_BITS | RP_PADS_QSPI_GPIO_SD0_PUE_BITS |
|
||||||
& ~(RP_PADS_QSPI_GPIO_SD0_OD_BITS | RP_PADS_QSPI_GPIO_SD0_PUE_BITS |
|
RP_PADS_QSPI_GPIO_SD0_PDE_BITS)) |
|
||||||
RP_PADS_QSPI_GPIO_SD0_PDE_BITS)
|
RP_PADS_QSPI_GPIO_SD0_OD_BITS | RP_PADS_QSPI_GPIO_SD0_PDE_BITS;
|
||||||
) | RP_PADS_QSPI_GPIO_SD0_OD_BITS | RP_PADS_QSPI_GPIO_SD0_PDE_BITS;
|
|
||||||
|
|
||||||
// First two 32-clock sequences
|
// First two 32-clock sequences
|
||||||
// CSn is held high for the first 32 clocks, then asserted low for next 32
|
// CSn is held high for the first 32 clocks, then asserted low for next 32
|
||||||
rp_spi_chip_select(t, RP_GPIO_QSPI_CS_DRIVE_HIGH);
|
rp_spi_chip_select(t, RP_GPIO_QSPI_CS_DRIVE_HIGH);
|
||||||
for (int i = 0; i < 2; ++i) {
|
for (int i = 0; i < 2; ++i) {
|
||||||
// This gives 4 16-bit offset store instructions. Anything else seems to
|
// This gives 4 16-bit offset store instructions. Anything else seems to
|
||||||
// produce a large island of constants
|
// produce a large island of constants
|
||||||
target_mem_write32(t, RP_PADS_QSPI_GPIO_SD0, padctrl_tmp);
|
target_mem_write32(t, RP_PADS_QSPI_GPIO_SD0, padctrl_tmp);
|
||||||
target_mem_write32(t, RP_PADS_QSPI_GPIO_SD1, padctrl_tmp);
|
target_mem_write32(t, RP_PADS_QSPI_GPIO_SD1, padctrl_tmp);
|
||||||
target_mem_write32(t, RP_PADS_QSPI_GPIO_SD2, padctrl_tmp);
|
target_mem_write32(t, RP_PADS_QSPI_GPIO_SD2, padctrl_tmp);
|
||||||
target_mem_write32(t, RP_PADS_QSPI_GPIO_SD3, padctrl_tmp);
|
target_mem_write32(t, RP_PADS_QSPI_GPIO_SD3, padctrl_tmp);
|
||||||
|
|
||||||
// Brief delay (~6000 cyc) for pulls to take effect
|
// Brief delay (~6000 cyc) for pulls to take effect
|
||||||
platform_delay(10);
|
platform_delay(10);
|
||||||
|
|
||||||
rp_flash_put_get(t, NULL, NULL, 4, 0);
|
rp_flash_put_get(t, NULL, NULL, 4, 0);
|
||||||
|
|
||||||
padctrl_tmp = (padctrl_tmp
|
padctrl_tmp = (padctrl_tmp & ~RP_PADS_QSPI_GPIO_SD0_PDE_BITS) | RP_PADS_QSPI_GPIO_SD0_PUE_BITS;
|
||||||
& ~RP_PADS_QSPI_GPIO_SD0_PDE_BITS)
|
|
||||||
| RP_PADS_QSPI_GPIO_SD0_PUE_BITS;
|
|
||||||
|
|
||||||
rp_spi_chip_select(t, RP_GPIO_QSPI_CS_DRIVE_LOW);
|
rp_spi_chip_select(t, RP_GPIO_QSPI_CS_DRIVE_LOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore IO/pad controls, and send 0xff, 0xff. Put pullup on IO2/IO3 as
|
// Restore IO/pad controls, and send 0xff, 0xff. Put pullup on IO2/IO3 as
|
||||||
// these may be used as WPn/HOLDn at this point, and we are now starting
|
// these may be used as WPn/HOLDn at this point, and we are now starting
|
||||||
// to issue serial commands.
|
// to issue serial commands.
|
||||||
|
|
||||||
target_mem_write32(t, RP_PADS_QSPI_GPIO_SD0, padctrl_save);
|
target_mem_write32(t, RP_PADS_QSPI_GPIO_SD0, padctrl_save);
|
||||||
target_mem_write32(t, RP_PADS_QSPI_GPIO_SD1, padctrl_save);
|
target_mem_write32(t, RP_PADS_QSPI_GPIO_SD1, padctrl_save);
|
||||||
padctrl_save = (padctrl_save
|
padctrl_save = (padctrl_save & ~RP_PADS_QSPI_GPIO_SD0_PDE_BITS) | RP_PADS_QSPI_GPIO_SD0_PUE_BITS;
|
||||||
& ~RP_PADS_QSPI_GPIO_SD0_PDE_BITS
|
target_mem_write32(t, RP_PADS_QSPI_GPIO_SD2, padctrl_save);
|
||||||
) | RP_PADS_QSPI_GPIO_SD0_PUE_BITS;
|
target_mem_write32(t, RP_PADS_QSPI_GPIO_SD3, padctrl_save);
|
||||||
target_mem_write32(t, RP_PADS_QSPI_GPIO_SD2, padctrl_save);
|
|
||||||
target_mem_write32(t, RP_PADS_QSPI_GPIO_SD3, padctrl_save);
|
|
||||||
|
|
||||||
rp_spi_chip_select(t, RP_GPIO_QSPI_CS_DRIVE_LOW);
|
rp_spi_chip_select(t, RP_GPIO_QSPI_CS_DRIVE_LOW);
|
||||||
rp_flash_put_get(t, buf, NULL, 2, 0);
|
rp_flash_put_get(t, buf, NULL, 2, 0);
|
||||||
|
|
||||||
target_mem_write32(t, RP_GPIO_QSPI_CS_CTRL, 0);
|
target_mem_write32(t, RP_GPIO_QSPI_CS_CTRL, 0);
|
||||||
}
|
}
|
||||||
|
@ -780,13 +778,13 @@ static void rp_flash_exit_xip(target *t)
|
||||||
// programming.
|
// programming.
|
||||||
static void rp_flash_flush_cache(target *t)
|
static void rp_flash_flush_cache(target *t)
|
||||||
{
|
{
|
||||||
target_mem_write32(t, RP_XIP_FLUSH, 1);
|
target_mem_write32(t, RP_XIP_FLUSH, 1);
|
||||||
// Read blocks until flush completion
|
// Read blocks until flush completion
|
||||||
target_mem_read32(t, RP_XIP_FLUSH);
|
target_mem_read32(t, RP_XIP_FLUSH);
|
||||||
// Enable the cache
|
// Enable the cache
|
||||||
const uint32_t ctrl = target_mem_read32(t, RP_XIP_CTRL);
|
const uint32_t ctrl = target_mem_read32(t, RP_XIP_CTRL);
|
||||||
target_mem_write32(t, RP_XIP_CTRL, ctrl | RP_XIP_CTRL_ENABLE);
|
target_mem_write32(t, RP_XIP_CTRL, ctrl | RP_XIP_CTRL_ENABLE);
|
||||||
rp_spi_chip_select(t, RP_GPIO_QSPI_CS_DRIVE_NORMAL);
|
rp_spi_chip_select(t, RP_GPIO_QSPI_CS_DRIVE_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put the SSI into a mode where XIP accesses translate to standard
|
// Put the SSI into a mode where XIP accesses translate to standard
|
||||||
|
@ -796,15 +794,15 @@ static void rp_flash_enter_xip(target *t)
|
||||||
{
|
{
|
||||||
target_mem_write32(t, RP_SSI_ENABLE, 0);
|
target_mem_write32(t, RP_SSI_ENABLE, 0);
|
||||||
target_mem_write32(t, RP_SSI_CTRL0,
|
target_mem_write32(t, RP_SSI_CTRL0,
|
||||||
RP_SSI_CTRL0_FRF_SERIAL | // Standard 1-bit SPI serial frames
|
RP_SSI_CTRL0_FRF_SERIAL | // Standard 1-bit SPI serial frames
|
||||||
RP_SSI_CTRL0_DATA_BITS(32) | // 32 clocks per data frame
|
RP_SSI_CTRL0_DATA_BITS(32) | // 32 clocks per data frame
|
||||||
RP_SSI_CTRL0_TMOD_EEPROM // Send instr + addr, receive data
|
RP_SSI_CTRL0_TMOD_EEPROM // Send instr + addr, receive data
|
||||||
);
|
);
|
||||||
target_mem_write32(t, RP_SSI_XIP_SPI_CTRL0,
|
target_mem_write32(t, RP_SSI_XIP_SPI_CTRL0,
|
||||||
RP_SSI_XIP_SPI_CTRL0_XIP_CMD(0x03) | // Standard 03h read
|
RP_SSI_XIP_SPI_CTRL0_XIP_CMD(0x03) | // Standard 03h read
|
||||||
RP_SSI_XIP_SPI_CTRL0_INSTR_LENGTH_8b | // 8-bit instruction prefix
|
RP_SSI_XIP_SPI_CTRL0_INSTR_LENGTH_8b | // 8-bit instruction prefix
|
||||||
RP_SSI_XIP_SPI_CTRL0_ADDRESS_LENGTH(0x03) | // 24-bit addressing for 03h commands
|
RP_SSI_XIP_SPI_CTRL0_ADDRESS_LENGTH(0x03) | // 24-bit addressing for 03h commands
|
||||||
RP_SSI_XIP_SPI_CTRL0_TRANS_1C1A // Command and address both in serial format
|
RP_SSI_XIP_SPI_CTRL0_TRANS_1C1A // Command and address both in serial format
|
||||||
);
|
);
|
||||||
target_mem_write32(t, RP_SSI_ENABLE, RP_SSI_ENABLE_SSI);
|
target_mem_write32(t, RP_SSI_ENABLE, RP_SSI_ENABLE_SSI);
|
||||||
}
|
}
|
||||||
|
@ -818,7 +816,7 @@ static uint32_t rp_get_flash_length(target *t)
|
||||||
DEBUG_INFO("Flash device ID: %02x %02x %02x\n", flash_id.manufacturer, flash_id.type, flash_id.capacity);
|
DEBUG_INFO("Flash device ID: %02x %02x %02x\n", flash_id.manufacturer, flash_id.type, flash_id.capacity);
|
||||||
if (flash_id.capacity >= 8 && flash_id.capacity <= 34)
|
if (flash_id.capacity >= 8 && flash_id.capacity <= 34)
|
||||||
return 1 << flash_id.capacity;
|
return 1 << flash_id.capacity;
|
||||||
|
|
||||||
// Guess maximum flash size
|
// Guess maximum flash size
|
||||||
return MAX_FLASH;
|
return MAX_FLASH;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue