Skip to content

Commit 5d36e85

Browse files
hanan619cfriedt
authored andcommitted
drivers: flash: rpi_pico: add support for rp2350 flash controller
The Raspberry Pi Pico 2 uses a QMI flash controller, which differs from the SSI controller used in the original Pico. Zephyr already has support for the SSI controller, but lacked support for QMI. This change adds the QMI flash controller implementation in the flash_rpi_pico.c driver file. Additionally, the RP2350 SoC devicetree file (rp2350.dtsi) has been updated to enable and describe the flash controller for Pico 2. Signed-off-by: Hanan Arshad <[email protected]>
1 parent c0e1268 commit 5d36e85

File tree

3 files changed

+2
-157
lines changed

3 files changed

+2
-157
lines changed

boards/raspberrypi/rpi_pico2/rpi_pico2.dtsi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
chosen {
1717
zephyr,sram = &sram0;
1818
zephyr,flash = &flash0;
19+
zephyr,flash-controller = &qmi;
1920
zephyr,console = &uart0;
2021
zephyr,shell-uart = &uart0;
2122
zephyr,code-partition = &code_partition;

drivers/flash/flash_rpi_pico.c

Lines changed: 0 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,8 @@
1313
#include <zephyr/drivers/flash.h>
1414
#include <zephyr/logging/log.h>
1515
#include <zephyr/irq.h>
16-
#include <zephyr/toolchain.h>
1716

1817
#include <hardware/flash.h>
19-
#include <hardware/regs/io_qspi.h>
20-
#include <hardware/regs/pads_qspi.h>
21-
#include <hardware/structs/ssi.h>
22-
#include <hardware/structs/xip_ctrl.h>
23-
#include <hardware/resets.h>
24-
#include <pico/bootrom.h>
2518

2619
LOG_MODULE_REGISTER(flash_rpi_pico, CONFIG_FLASH_LOG_LEVEL);
2720

@@ -31,162 +24,14 @@ LOG_MODULE_REGISTER(flash_rpi_pico, CONFIG_FLASH_LOG_LEVEL);
3124
#define SECTOR_SIZE DT_PROP(DT_CHOSEN(zephyr_flash), erase_block_size)
3225
#define ERASE_VALUE 0xff
3326
#define FLASH_SIZE KB(CONFIG_FLASH_SIZE)
34-
#define FLASH_BASE CONFIG_FLASH_BASE_ADDRESS
35-
#define SSI_BASE_ADDRESS DT_REG_ADDR(DT_CHOSEN(zephyr_flash_controller))
3627

3728
static const struct flash_parameters flash_rpi_parameters = {
3829
.write_block_size = 1,
3930
.erase_value = ERASE_VALUE,
4031
};
4132

42-
/**
43-
* Low level flash functions are based on:
44-
* github.com/raspberrypi/pico-bootrom/blob/master/bootrom/program_flash_generic.c
45-
* and
46-
* github.com/raspberrypi/pico-sdk/blob/master/src/rp2_common/hardware_flash/flash.c
47-
*/
48-
49-
#define FLASHCMD_PAGE_PROGRAM 0x02
50-
#define FLASHCMD_READ_STATUS 0x05
51-
#define FLASHCMD_WRITE_ENABLE 0x06
52-
#define BOOT2_SIZE_WORDS 64
53-
54-
enum outover {
55-
OUTOVER_NORMAL = 0,
56-
OUTOVER_INVERT,
57-
OUTOVER_LOW,
58-
OUTOVER_HIGH
59-
};
60-
61-
static ssi_hw_t *const ssi = (ssi_hw_t *)SSI_BASE_ADDRESS;
62-
static uint32_t boot2_copyout[BOOT2_SIZE_WORDS];
63-
static bool boot2_copyout_valid;
6433
static uint8_t flash_ram_buffer[PAGE_SIZE];
6534

66-
static void __no_inline_not_in_flash_func(flash_init_boot2_copyout)(void)
67-
{
68-
if (boot2_copyout_valid) {
69-
return;
70-
}
71-
for (int i = 0; i < BOOT2_SIZE_WORDS; ++i) {
72-
boot2_copyout[i] = ((uint32_t *)FLASH_BASE)[i];
73-
}
74-
__compiler_memory_barrier();
75-
boot2_copyout_valid = true;
76-
}
77-
78-
static void __no_inline_not_in_flash_func(flash_enable_xip_via_boot2)(void)
79-
{
80-
((void (*)(void))((uint32_t)boot2_copyout+1))();
81-
}
82-
83-
void __no_inline_not_in_flash_func(flash_cs_force)(enum outover over)
84-
{
85-
io_rw_32 *reg = (io_rw_32 *) (IO_QSPI_BASE + IO_QSPI_GPIO_QSPI_SS_CTRL_OFFSET);
86-
*reg = (*reg & ~IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_BITS)
87-
| (over << IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_LSB);
88-
(void) *reg;
89-
}
90-
91-
int __no_inline_not_in_flash_func(flash_was_aborted)()
92-
{
93-
return *(io_rw_32 *) (IO_QSPI_BASE + IO_QSPI_GPIO_QSPI_SD1_CTRL_OFFSET)
94-
& IO_QSPI_GPIO_QSPI_SD1_CTRL_INOVER_BITS;
95-
}
96-
97-
void __no_inline_not_in_flash_func(flash_put_get)(const uint8_t *tx, uint8_t *rx, size_t count,
98-
size_t rx_skip)
99-
{
100-
const uint max_in_flight = 16 - 2;
101-
size_t tx_count = count;
102-
size_t rx_count = count;
103-
bool did_something;
104-
uint32_t tx_level;
105-
uint32_t rx_level;
106-
uint8_t rxbyte;
107-
108-
while (tx_count || rx_skip || rx_count) {
109-
tx_level = ssi_hw->txflr;
110-
rx_level = ssi_hw->rxflr;
111-
did_something = false;
112-
if (tx_count && tx_level + rx_level < max_in_flight) {
113-
ssi->dr0 = (uint32_t) (tx ? *tx++ : 0);
114-
--tx_count;
115-
did_something = true;
116-
}
117-
if (rx_level) {
118-
rxbyte = ssi->dr0;
119-
did_something = true;
120-
if (rx_skip) {
121-
--rx_skip;
122-
} else {
123-
if (rx) {
124-
*rx++ = rxbyte;
125-
}
126-
--rx_count;
127-
}
128-
}
129-
130-
if (!did_something && __builtin_expect(flash_was_aborted(), 0)) {
131-
break;
132-
}
133-
}
134-
flash_cs_force(OUTOVER_HIGH);
135-
}
136-
137-
void __no_inline_not_in_flash_func(flash_put_get_wrapper)(uint8_t cmd, const uint8_t *tx,
138-
uint8_t *rx, size_t count)
139-
{
140-
flash_cs_force(OUTOVER_LOW);
141-
ssi->dr0 = cmd;
142-
flash_put_get(tx, rx, count, 1);
143-
}
144-
145-
static ALWAYS_INLINE void flash_put_cmd_addr(uint8_t cmd, uint32_t addr)
146-
{
147-
flash_cs_force(OUTOVER_LOW);
148-
addr |= cmd << 24;
149-
for (int i = 0; i < 4; ++i) {
150-
ssi->dr0 = addr >> 24;
151-
addr <<= 8;
152-
}
153-
}
154-
155-
void __no_inline_not_in_flash_func(flash_write_partial_internal)(uint32_t addr, const uint8_t *data,
156-
size_t size)
157-
{
158-
uint8_t status_reg;
159-
160-
flash_put_get_wrapper(FLASHCMD_WRITE_ENABLE, NULL, NULL, 0);
161-
flash_put_cmd_addr(FLASHCMD_PAGE_PROGRAM, addr);
162-
flash_put_get(data, NULL, size, 4);
163-
164-
do {
165-
flash_put_get_wrapper(FLASHCMD_READ_STATUS, NULL, &status_reg, 1);
166-
} while (status_reg & 0x1 && !flash_was_aborted());
167-
}
168-
169-
void __no_inline_not_in_flash_func(flash_write_partial)(uint32_t flash_offs, const uint8_t *data,
170-
size_t count)
171-
{
172-
rom_connect_internal_flash_fn connect_internal_flash = (rom_connect_internal_flash_fn)
173-
rom_func_lookup_inline(ROM_FUNC_CONNECT_INTERNAL_FLASH);
174-
rom_flash_exit_xip_fn exit_xip = (rom_flash_exit_xip_fn)
175-
rom_func_lookup_inline(ROM_FUNC_FLASH_EXIT_XIP);
176-
rom_flash_flush_cache_fn flush_cache = (rom_flash_flush_cache_fn)
177-
rom_func_lookup_inline(ROM_FUNC_FLASH_FLUSH_CACHE);
178-
179-
flash_init_boot2_copyout();
180-
181-
__compiler_memory_barrier();
182-
183-
connect_internal_flash();
184-
exit_xip();
185-
flash_write_partial_internal(flash_offs, data, count);
186-
flush_cache();
187-
flash_enable_xip_via_boot2();
188-
}
189-
19035
static bool is_valid_range(off_t offset, uint32_t size)
19136
{
19237
return (offset >= 0) && ((offset + size) <= FLASH_SIZE);

dts/arm/raspberrypi/rpi_pico/rp2350.dtsi

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@
192192

193193
qmi: flash-controller@400d0000 {
194194
compatible = "raspberrypi,pico-flash-controller";
195-
reg = <0x400d0000 0xfc>;
195+
reg = <0x400d0000 0x54>;
196196

197197
#address-cells = <1>;
198198
#size-cells = <1>;
@@ -202,7 +202,6 @@
202202
write-block-size = <1>;
203203
erase-block-size = <DT_SIZE_K(4)>;
204204
};
205-
status = "disabled";
206205
};
207206

208207
reset: reset-controller@40020000 {

0 commit comments

Comments
 (0)