Skip to content

Send release power-down (0xAB) instruction, to revive flash, that might be in power-down state #2130

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 21 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion src/rp2040/boot_stage2/boot2_at25sf128a.S
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
#define CMD_READ_STATUS2 0x35
#define CMD_WRITE_STATUS 0x01
#define CMD_WRITE_STATUS2 0x31
#define CMD_RELEASE_POWERDOWN 0xAB
#define SREG_DATA 0x02 // Enable quad-SPI mode

// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -147,10 +148,20 @@ program_sregs:
ldr r1, =(CTRL0_SPI_TXRX)
str r1, [r3, #SSI_CTRLR0_OFFSET]

// Enable SSI and select slave 0
// Enable SSI and select slave 0
movs r1, #1
str r1, [r3, #SSI_SSIENR_OFFSET]

#if PICO_BOOT_STAGE2_FLASH_RELEASE_POWERDOWN
// Send release power-down command, discard RX
movs r1, #CMD_RELEASE_POWERDOWN
str r1, [r3, #SSI_DR0_OFFSET]

// Poll for completion and discard RX
bl wait_ssi_ready
ldr r1, [r3, #SSI_DR0_OFFSET]
#endif

// Check whether SR needs updating
movs r0, #CMD_READ_STATUS2
bl read_flash_sreg
Expand Down
16 changes: 16 additions & 0 deletions src/rp2040/boot_stage2/boot2_generic_03h.S
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pico_default_asm_setup
#endif

#define CMD_READ 0x03
#define CMD_RELEASE_POWERDOWN 0xAB

// Value is number of address bits divided by 4
#define ADDR_L 6
Expand Down Expand Up @@ -92,13 +93,28 @@ regular_func _stage2_boot
movs r1, #1
str r1, [r3, #SSI_SSIENR_OFFSET]

#if PICO_BOOT_STAGE2_FLASH_RELEASE_POWERDOWN
// Send release power-down command, discard RX
movs r1, #CMD_RELEASE_POWERDOWN
str r1, [r3, #SSI_DR0_OFFSET]

// Poll for completion and discard RX
bl wait_ssi_ready
ldr r1, [r3, #SSI_DR0_OFFSET]
#endif

// We are now in XIP mode. Any bus accesses to the XIP address window will be
// translated by the SSI into 03h read commands to the external flash (if cache is missed),
// and the data will be returned to the bus.

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

#if PICO_BOOT_STAGE2_FLASH_RELEASE_POWERDOWN
// Common functions
#include "boot2_helpers/wait_ssi_ready.S"
#endif

.global literals
literals:
.ltorg
Expand Down
13 changes: 12 additions & 1 deletion src/rp2040/boot_stage2/boot2_is25lp080.S
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
#define CMD_WRITE_ENABLE 0x06
#define CMD_READ_STATUS 0x05
#define CMD_WRITE_STATUS 0x01
#define CMD_RELEASE_POWERDOWN 0xAB
#define SREG_DATA 0x40 // Enable quad-SPI mode

// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -114,10 +115,20 @@ program_sregs:
ldr r1, =(CTRL0_SPI_TXRX)
str r1, [r3, #SSI_CTRLR0_OFFSET]

// Enable SSI and select slave 0
// Enable SSI and select slave 0
movs r1, #1
str r1, [r3, #SSI_SSIENR_OFFSET]

#if PICO_BOOT_STAGE2_FLASH_RELEASE_POWERDOWN
// Send release power-down command, discard RX
movs r1, #CMD_RELEASE_POWERDOWN
str r1, [r3, #SSI_DR0_OFFSET]

// Poll for completion and discard RX
bl wait_ssi_ready
ldr r1, [r3, #SSI_DR0_OFFSET]
#endif

// Check whether SR needs updating
ldr r0, =CMD_READ_STATUS
bl read_flash_sreg
Expand Down
13 changes: 12 additions & 1 deletion src/rp2040/boot_stage2/boot2_w25q080.S
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
#define CMD_READ_STATUS 0x05
#define CMD_READ_STATUS2 0x35
#define CMD_WRITE_STATUS 0x01
#define CMD_RELEASE_POWERDOWN 0xAB
#define SREG_DATA 0x02 // Enable quad-SPI mode

// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -147,10 +148,20 @@ program_sregs:
ldr r1, =(CTRL0_SPI_TXRX)
str r1, [r3, #SSI_CTRLR0_OFFSET]

// Enable SSI and select slave 0
// Enable SSI and select slave 0
movs r1, #1
str r1, [r3, #SSI_SSIENR_OFFSET]

#if PICO_BOOT_STAGE2_FLASH_RELEASE_POWERDOWN
// Send release power-down command, discard RX
movs r1, #CMD_RELEASE_POWERDOWN
str r1, [r3, #SSI_DR0_OFFSET]

// Poll for completion and discard RX
bl wait_ssi_ready
ldr r1, [r3, #SSI_DR0_OFFSET]
#endif

// Check whether SR needs updating
movs r0, #CMD_READ_STATUS2
bl read_flash_sreg
Expand Down
5 changes: 5 additions & 0 deletions src/rp2040/boot_stage2/include/boot_stage2/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@

#include "pico.h"

// PICO_CONFIG: PICO_BOOT_STAGE2_FLASH_RELEASE_POWERDOWN, Release the flash device from power-down state during boot stage 2, type=bool, default=0, group=boot_stage2
#ifndef PICO_BOOT_STAGE2_FLASH_RELEASE_POWERDOWN
#define PICO_BOOT_STAGE2_FLASH_RELEASE_POWERDOWN 0
#endif

// PICO_CONFIG: PICO_BUILD_BOOT_STAGE2_NAME, Name of the boot stage 2 if selected in the build system, group=boot_stage2
#ifdef PICO_BUILD_BOOT_STAGE2_NAME
#define _BOOT_STAGE2_SELECTED
Expand Down
57 changes: 57 additions & 0 deletions src/rp2350/boot_stage2/boot2_generic_03h.S
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#endif

#define CMD_READ 0x03
#define CMD_RELEASE_POWERDOWN 0xAB

// ----------------------------------------------------------------------------
// Register initialisation values -- same in Arm/RISC-V code.
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,27 @@ regular_func _stage2_boot
sw a0, QMI_M0_RCMD_OFFSET(a3)
li a0, INIT_M0_RFMT
sw a0, QMI_M0_RFMT_OFFSET(a3)

#if PICO_BOOT_STAGE2_FLASH_RELEASE_POWERDOWN
// 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)
#endif
#else
push {lr}
ldr r3, =XIP_QMI_BASE
Expand All @@ -109,11 +140,37 @@ regular_func _stage2_boot
str r0, [r3, #QMI_M0_RCMD_OFFSET]
ldr r0, =INIT_M0_RFMT
str r0, [r3, #QMI_M0_RFMT_OFFSET]

#if PICO_BOOT_STAGE2_FLASH_RELEASE_POWERDOWN
// 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
#endif

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

#if PICO_BOOT_STAGE2_FLASH_RELEASE_POWERDOWN
// Common functions
#include "boot2_helpers/wait_qmi_ready.S"
#endif

#ifndef __riscv
.global literals
literals:
Expand Down
17 changes: 17 additions & 0 deletions src/rp2350/boot_stage2/boot2_w25q080.S
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
#define CMD_READ_STATUS 0x05
#define CMD_READ_STATUS2 0x35
#define CMD_WRITE_STATUS 0x01
#define CMD_RELEASE_POWERDOWN 0xAB
#define SREG_DATA 0x02 // Enable quad-SPI mode

// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -176,6 +177,14 @@ program_sregs:
lw a1, QMI_DIRECT_CSR_OFFSET(a3)
andi a1, a1, QMI_DIRECT_CSR_BUSY_BITS
bnez a1, 1b

#if PICO_BOOT_STAGE2_FLASH_RELEASE_POWERDOWN
// 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)
#endif

// Check whether SR needs updating
li a0, CMD_READ_STATUS2
Expand Down Expand Up @@ -268,6 +277,14 @@ program_sregs:
ldr r0, [r3, #QMI_DIRECT_CSR_OFFSET]
tst r0, #QMI_DIRECT_CSR_BUSY_BITS
bne 1b

#if PICO_BOOT_STAGE2_FLASH_RELEASE_POWERDOWN
// 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]
#endif

// Check whether SR needs updating
movs r0, #CMD_READ_STATUS2
Expand Down
5 changes: 5 additions & 0 deletions src/rp2350/boot_stage2/include/boot_stage2/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@

#include "pico/config.h"

// PICO_CONFIG: PICO_BOOT_STAGE2_FLASH_RELEASE_POWERDOWN, Release the flash device from power-down state during boot stage 2, type=bool, default=0, group=boot_stage2
#ifndef PICO_BOOT_STAGE2_FLASH_RELEASE_POWERDOWN
#define PICO_BOOT_STAGE2_FLASH_RELEASE_POWERDOWN 0
#endif

// PICO_CONFIG: PICO_BUILD_BOOT_STAGE2_NAME, Name of the boot stage 2 if selected in the build system, group=boot_stage2
#ifdef PICO_BUILD_BOOT_STAGE2_NAME
#define _BOOT_STAGE2_SELECTED
Expand Down