feat(plat/st): add STM32MP_UART_PROGRAMMER target
Handle boot from UART with STM32CubeProgammer based on mmap io
for STM32MP15.
Depends-On: Iba84e8dfd67b9f30416efb0f6778e48ba1f75dad
Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
Change-Id: Ibd719dd46a11da78633728675ef6639635b6cf67
diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c
index b0314d2..6069e5f 100644
--- a/plat/st/common/bl2_io_storage.c
+++ b/plat/st/common/bl2_io_storage.c
@@ -99,7 +99,7 @@
static const io_dev_connector_t *spi_dev_con;
#endif
-#if STM32MP_USB_PROGRAMMER
+#if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER
static const io_dev_connector_t *memmap_dev_con;
#endif
@@ -136,6 +136,9 @@
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI:
INFO("Using SPI NAND\n");
break;
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART:
+ INFO("Using UART\n");
+ break;
case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB:
INFO("Using USB\n");
break;
@@ -257,7 +260,7 @@
}
#endif /* STM32MP_SPI_NAND */
-#if STM32MP_USB_PROGRAMMER
+#if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER
static void mmap_io_setup(void)
{
int io_result __unused;
@@ -270,6 +273,21 @@
assert(io_result == 0);
}
+#if STM32MP_UART_PROGRAMMER
+static void stm32cubeprogrammer_uart(void)
+{
+ int ret __unused;
+ boot_api_context_t *boot_context =
+ (boot_api_context_t *)stm32mp_get_boot_ctx_address();
+ uintptr_t uart_base;
+
+ uart_base = get_uart_address(boot_context->boot_interface_instance);
+ ret = stm32cubeprog_uart_load(uart_base, DWL_BUFFER_BASE, DWL_BUFFER_SIZE);
+ assert(ret == 0);
+}
+#endif
+
+#if STM32MP_USB_PROGRAMMER
static void stm32cubeprogrammer_usb(void)
{
int ret __unused;
@@ -282,6 +300,8 @@
assert(ret == 0);
}
#endif
+#endif /* STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER */
+
void stm32mp_io_setup(void)
{
@@ -334,8 +354,13 @@
boot_spi_nand(boot_context);
break;
#endif
+#if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER
+#if STM32MP_UART_PROGRAMMER
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART:
+#endif
#if STM32MP_USB_PROGRAMMER
case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB:
+#endif
dmbsy();
mmap_io_setup();
break;
@@ -400,6 +425,16 @@
break;
#endif
+#if STM32MP_UART_PROGRAMMER
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART:
+ if (image_id == FW_CONFIG_ID) {
+ stm32cubeprogrammer_uart();
+ /* FIP loaded at DWL address */
+ image_block_spec.offset = DWL_BUFFER_BASE;
+ image_block_spec.length = DWL_BUFFER_SIZE;
+ }
+ break;
+#endif
#if STM32MP_USB_PROGRAMMER
case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB:
if (image_id == FW_CONFIG_ID) {
diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h
index 8a5fe48..6183964 100644
--- a/plat/st/common/include/stm32mp_common.h
+++ b/plat/st/common/include/stm32mp_common.h
@@ -48,6 +48,11 @@
uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags);
#endif
+#if STM32MP_UART_PROGRAMMER
+/* Get the UART address from its instance number */
+uintptr_t get_uart_address(uint32_t instance_nb);
+#endif
+
/*
* Platform util functions for the GPIO driver
* @bank: Target GPIO bank ID as per DT bindings