Skip to content

Commit

Permalink
Update boot2_generic_03h.S
Browse files Browse the repository at this point in the history
Send release power-down (0xAB) instruction, to revive flash, that might be in power-down state
  • Loading branch information
matsobdev authored Dec 8, 2024
1 parent 7b4b8a9 commit 9233fef
Showing 1 changed file with 51 additions and 0 deletions.
51 changes: 51 additions & 0 deletions src/rp2350/boot_stage2/boot2_generic_03h.S
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#error "RX delay greater than maximum"
#endif

#define CMD_RELEASE_POWERDOWN 0xAB
#define CMD_READ 0x03

// ----------------------------------------------------------------------------
Expand All @@ -60,6 +61,15 @@
// CLKDIV and RXDELAY, and no constraints on CS max assertion, CS min
// deassertion, or page boundary burst breaks.

// Need to use direct serial mode to send SR commands. Choose a
// conservative direct-mode divisor (5 MHz at 150 MHz clk_sys)
// since the XIP-mode divisor may be unsafe without an RX delay.
#define INIT_DIRECT_CSR (\
30 << QMI_DIRECT_CSR_CLKDIV_LSB | \
QMI_DIRECT_CSR_EN_BITS | \
QMI_DIRECT_CSR_AUTO_CS0N_BITS | \
0)

#define INIT_M0_TIMING (\
1 << QMI_M0_TIMING_COOLDOWN_LSB |\
PICO_FLASH_SPI_RXDELAY << QMI_M0_TIMING_RXDELAY_LSB |\
Expand Down Expand Up @@ -100,6 +110,25 @@ regular_func _stage2_boot
sw a0, QMI_M0_RCMD_OFFSET(a3)
li a0, INIT_M0_RFMT
sw a0, QMI_M0_RFMT_OFFSET(a3)

// Need to use direct serial mode to send commands.
li a1, INIT_DIRECT_CSR
sw a1, QMI_DIRECT_CSR_OFFSET(a3)
// Wait for cooldown on last XIP transfer to expire, by polling BUSY
1:
lw a1, QMI_DIRECT_CSR_OFFSET(a3)
andi a1, a1, QMI_DIRECT_CSR_BUSY_BITS
bnez a1, 1b

// Send release power-down command, discard RX
li a0, CMD_RELEASE_POWERDOWN
sw a0, QMI_DIRECT_TX_OFFSET(a3)
jal wait_qmi_ready
lw a0, QMI_DIRECT_RX_OFFSET(a3)

// Disable direct mode
andi a1, a1, ~QMI_DIRECT_CSR_EN_BITS
sw a1, QMI_DIRECT_CSR_OFFSET(a3)
#else
push {lr}
ldr r3, =XIP_QMI_BASE
Expand All @@ -109,11 +138,33 @@ regular_func _stage2_boot
str r0, [r3, #QMI_M0_RCMD_OFFSET]
ldr r0, =INIT_M0_RFMT
str r0, [r3, #QMI_M0_RFMT_OFFSET]

// Need to use direct serial mode to send commands.
ldr r1, =INIT_DIRECT_CSR
str r1, [r3, #QMI_DIRECT_CSR_OFFSET]
// Wait for cooldown on last XIP transfer to expire, by polling BUSY
1:
ldr r0, [r3, #QMI_DIRECT_CSR_OFFSET]
tst r0, #QMI_DIRECT_CSR_BUSY_BITS
bne 1b

// Send release power-down command, discard RX
movs r0, #CMD_RELEASE_POWERDOWN
str r0, [r3, #QMI_DIRECT_TX_OFFSET]
bl wait_qmi_ready
ldr r0, [r3, #QMI_DIRECT_RX_OFFSET]

// Disable direct mode
bics r1, #QMI_DIRECT_CSR_EN_BITS
str r1, [r3, #QMI_DIRECT_CSR_OFFSET]
#endif

// Pull in standard exit routine
#include "boot2_helpers/exit_from_boot2.S"

// Common functions
#include "boot2_helpers/wait_qmi_ready.S"

#ifndef __riscv
.global literals
literals:
Expand Down

0 comments on commit 9233fef

Please sign in to comment.