diff --git a/boards/raspberrypi/rpi_pico2/rpi_pico2.dtsi b/boards/raspberrypi/rpi_pico2/rpi_pico2.dtsi index 522413c94f1a..85defeb758c8 100644 --- a/boards/raspberrypi/rpi_pico2/rpi_pico2.dtsi +++ b/boards/raspberrypi/rpi_pico2/rpi_pico2.dtsi @@ -16,6 +16,7 @@ chosen { zephyr,sram = &sram0; zephyr,flash = &flash0; + zephyr,flash-controller = &qmi; zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,code-partition = &code_partition; diff --git a/drivers/flash/flash_rpi_pico.c b/drivers/flash/flash_rpi_pico.c index de86ea7cdd70..527fc5bf78f0 100644 --- a/drivers/flash/flash_rpi_pico.c +++ b/drivers/flash/flash_rpi_pico.c @@ -13,180 +13,25 @@ #include #include #include -#include #include -#include -#include -#include -#include -#include -#include LOG_MODULE_REGISTER(flash_rpi_pico, CONFIG_FLASH_LOG_LEVEL); #define DT_DRV_COMPAT raspberrypi_pico_flash_controller -#define PAGE_SIZE 256 +#define PAGE_SIZE 256 #define SECTOR_SIZE DT_PROP(DT_CHOSEN(zephyr_flash), erase_block_size) #define ERASE_VALUE 0xff -#define FLASH_SIZE KB(CONFIG_FLASH_SIZE) -#define FLASH_BASE CONFIG_FLASH_BASE_ADDRESS -#define SSI_BASE_ADDRESS DT_REG_ADDR(DT_CHOSEN(zephyr_flash_controller)) +#define FLASH_SIZE KB(CONFIG_FLASH_SIZE) static const struct flash_parameters flash_rpi_parameters = { .write_block_size = 1, .erase_value = ERASE_VALUE, }; -/** - * Low level flash functions are based on: - * github.com/raspberrypi/pico-bootrom/blob/master/bootrom/program_flash_generic.c - * and - * github.com/raspberrypi/pico-sdk/blob/master/src/rp2_common/hardware_flash/flash.c - */ - -#define FLASHCMD_PAGE_PROGRAM 0x02 -#define FLASHCMD_READ_STATUS 0x05 -#define FLASHCMD_WRITE_ENABLE 0x06 -#define BOOT2_SIZE_WORDS 64 - -enum outover { - OUTOVER_NORMAL = 0, - OUTOVER_INVERT, - OUTOVER_LOW, - OUTOVER_HIGH -}; - -static ssi_hw_t *const ssi = (ssi_hw_t *)SSI_BASE_ADDRESS; -static uint32_t boot2_copyout[BOOT2_SIZE_WORDS]; -static bool boot2_copyout_valid; static uint8_t flash_ram_buffer[PAGE_SIZE]; -static void __no_inline_not_in_flash_func(flash_init_boot2_copyout)(void) -{ - if (boot2_copyout_valid) { - return; - } - for (int i = 0; i < BOOT2_SIZE_WORDS; ++i) { - boot2_copyout[i] = ((uint32_t *)FLASH_BASE)[i]; - } - __compiler_memory_barrier(); - boot2_copyout_valid = true; -} - -static void __no_inline_not_in_flash_func(flash_enable_xip_via_boot2)(void) -{ - ((void (*)(void))((uint32_t)boot2_copyout+1))(); -} - -void __no_inline_not_in_flash_func(flash_cs_force)(enum outover over) -{ - io_rw_32 *reg = (io_rw_32 *) (IO_QSPI_BASE + IO_QSPI_GPIO_QSPI_SS_CTRL_OFFSET); - *reg = (*reg & ~IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_BITS) - | (over << IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_LSB); - (void) *reg; -} - -int __no_inline_not_in_flash_func(flash_was_aborted)() -{ - return *(io_rw_32 *) (IO_QSPI_BASE + IO_QSPI_GPIO_QSPI_SD1_CTRL_OFFSET) - & IO_QSPI_GPIO_QSPI_SD1_CTRL_INOVER_BITS; -} - -void __no_inline_not_in_flash_func(flash_put_get)(const uint8_t *tx, uint8_t *rx, size_t count, - size_t rx_skip) -{ - const uint max_in_flight = 16 - 2; - size_t tx_count = count; - size_t rx_count = count; - bool did_something; - uint32_t tx_level; - uint32_t rx_level; - uint8_t rxbyte; - - while (tx_count || rx_skip || rx_count) { - tx_level = ssi_hw->txflr; - rx_level = ssi_hw->rxflr; - did_something = false; - if (tx_count && tx_level + rx_level < max_in_flight) { - ssi->dr0 = (uint32_t) (tx ? *tx++ : 0); - --tx_count; - did_something = true; - } - if (rx_level) { - rxbyte = ssi->dr0; - did_something = true; - if (rx_skip) { - --rx_skip; - } else { - if (rx) { - *rx++ = rxbyte; - } - --rx_count; - } - } - - if (!did_something && __builtin_expect(flash_was_aborted(), 0)) { - break; - } - } - flash_cs_force(OUTOVER_HIGH); -} - -void __no_inline_not_in_flash_func(flash_put_get_wrapper)(uint8_t cmd, const uint8_t *tx, - uint8_t *rx, size_t count) -{ - flash_cs_force(OUTOVER_LOW); - ssi->dr0 = cmd; - flash_put_get(tx, rx, count, 1); -} - -static ALWAYS_INLINE void flash_put_cmd_addr(uint8_t cmd, uint32_t addr) -{ - flash_cs_force(OUTOVER_LOW); - addr |= cmd << 24; - for (int i = 0; i < 4; ++i) { - ssi->dr0 = addr >> 24; - addr <<= 8; - } -} - -void __no_inline_not_in_flash_func(flash_write_partial_internal)(uint32_t addr, const uint8_t *data, - size_t size) -{ - uint8_t status_reg; - - flash_put_get_wrapper(FLASHCMD_WRITE_ENABLE, NULL, NULL, 0); - flash_put_cmd_addr(FLASHCMD_PAGE_PROGRAM, addr); - flash_put_get(data, NULL, size, 4); - - do { - flash_put_get_wrapper(FLASHCMD_READ_STATUS, NULL, &status_reg, 1); - } while (status_reg & 0x1 && !flash_was_aborted()); -} - -void __no_inline_not_in_flash_func(flash_write_partial)(uint32_t flash_offs, const uint8_t *data, - size_t count) -{ - rom_connect_internal_flash_fn connect_internal_flash = (rom_connect_internal_flash_fn) - rom_func_lookup_inline(ROM_FUNC_CONNECT_INTERNAL_FLASH); - rom_flash_exit_xip_fn exit_xip = (rom_flash_exit_xip_fn) - rom_func_lookup_inline(ROM_FUNC_FLASH_EXIT_XIP); - rom_flash_flush_cache_fn flush_cache = (rom_flash_flush_cache_fn) - rom_func_lookup_inline(ROM_FUNC_FLASH_FLUSH_CACHE); - - flash_init_boot2_copyout(); - - __compiler_memory_barrier(); - - connect_internal_flash(); - exit_xip(); - flash_write_partial_internal(flash_offs, data, count); - flush_cache(); - flash_enable_xip_via_boot2(); -} - static bool is_valid_range(off_t offset, uint32_t size) { return (offset >= 0) && ((offset + size) <= FLASH_SIZE); @@ -194,6 +39,8 @@ static bool is_valid_range(off_t offset, uint32_t size) static int flash_rpi_read(const struct device *dev, off_t offset, void *data, size_t size) { + ARG_UNUSED(dev); + if (size == 0) { return 0; } @@ -214,13 +61,15 @@ static int flash_rpi_write(const struct device *dev, off_t offset, const void *d size_t bytes_to_write; uint8_t *data_pointer = (uint8_t *)data; + ARG_UNUSED(dev); + if (size == 0) { return 0; } if (!is_valid_range(offset, size)) { - LOG_ERR("Write range exceeds the flash boundaries. Offset=%#lx, Size=%u", - offset, size); + LOG_ERR("Write range exceeds the flash boundaries. Offset=%#lx, Size=%u", offset, + size); return -EINVAL; } @@ -263,14 +112,14 @@ static int flash_rpi_erase(const struct device *dev, off_t offset, size_t size) } if (!is_valid_range(offset, size)) { - LOG_ERR("Erase range exceeds the flash boundaries. Offset=%#lx, Size=%u", - offset, size); + LOG_ERR("Erase range exceeds the flash boundaries. Offset=%#lx, Size=%u", offset, + size); return -EINVAL; } if ((offset % SECTOR_SIZE) || (size % SECTOR_SIZE)) { LOG_ERR("Erase range is not a multiple of the sector size. Offset=%#lx, Size=%u", - offset, size); + offset, size); return -EINVAL; } @@ -298,7 +147,7 @@ static const struct flash_pages_layout flash_rpi_pages_layout = { }; void flash_rpi_page_layout(const struct device *dev, const struct flash_pages_layout **layout, - size_t *layout_size) + size_t *layout_size) { *layout = &flash_rpi_pages_layout; *layout_size = 1; @@ -316,5 +165,5 @@ static DEVICE_API(flash, flash_rpi_driver_api) = { #endif /* CONFIG_FLASH_PAGE_LAYOUT */ }; -DEVICE_DT_INST_DEFINE(0, NULL, NULL, NULL, NULL, POST_KERNEL, - CONFIG_FLASH_INIT_PRIORITY, &flash_rpi_driver_api); +DEVICE_DT_INST_DEFINE(0, NULL, NULL, NULL, NULL, POST_KERNEL, CONFIG_FLASH_INIT_PRIORITY, + &flash_rpi_driver_api); diff --git a/dts/arm/raspberrypi/rpi_pico/rp2350.dtsi b/dts/arm/raspberrypi/rpi_pico/rp2350.dtsi index 62da179b6679..65553e401b01 100644 --- a/dts/arm/raspberrypi/rpi_pico/rp2350.dtsi +++ b/dts/arm/raspberrypi/rpi_pico/rp2350.dtsi @@ -192,7 +192,7 @@ qmi: flash-controller@400d0000 { compatible = "raspberrypi,pico-flash-controller"; - reg = <0x400d0000 0xfc>; + reg = <0x400d0000 0x54>; #address-cells = <1>; #size-cells = <1>; @@ -202,7 +202,6 @@ write-block-size = <1>; erase-block-size = ; }; - status = "disabled"; }; reset: reset-controller@40020000 { diff --git a/west.yml b/west.yml index 3c57f452369a..ace97a69a748 100644 --- a/west.yml +++ b/west.yml @@ -231,7 +231,7 @@ manifest: - hal - name: hal_rpi_pico path: modules/hal/rpi_pico - revision: 7b57b24588797e6e7bf18b6bda168e6b96374264 + revision: 5a981c7c29e3846646549a1902183684f0147e1d groups: - hal - name: hal_silabs