cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 TF-A FSBL customization workflow

koan
Associate III

I need to customize the TF-A

en.SOURCES-tf-a-stm32mp1-openstlinux-4.19-thud-mp1-19-10-09.tar.xz

Our custom board have a different pin selection for UART4 debug as you can see below, the UART4_TX pin is not on the STM32_PINMUX('G', 11, AF6), but is on the STM32_PINMUX('A', 0, AF8).

Our expectations were to have the system booting simply changing the line below in the file fdts/stm32mp157-pinctrl.dtsi

 uart4_pins_a: uart4@0 { 
   pins1 { 
-       pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX STM32MP157C-DK2 */ 
+       pinmux = <STM32_PINMUX('A', 0, AF8)>; /* UART4_TX CUSTOM*/ 
       bias-disable; 
       drive-push-pull; 
       slew-rate = <0>; 
   };

However I see that in plat/st/stm32mp1/stm32mp1_helper.S there is a func plat_crash_console_init who wants to use

#define GPIO_TX_SHIFT   (DEBUG_UART_TX_GPIO_PORT << 1)
#define GPIO_TX_ALT_SHIFT   ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)

Those macros come from plat/st/stm32mp1/stm32mp1_def.h where I have

/* For UART crash console */
#define STM32MP_DEBUG_USART_BASE	UART4_BASE
/* UART4 on HSI@64MHz, TX on GPIOG11 Alternate 6 */
#define DEBUG_UART_TX_GPIO_BANK_ADDRESS	GPIOG_BASE
#define DEBUG_UART_TX_GPIO_PORT 11
#define DEBUG_UART_TX_GPIO_ALTERNATE 6

however if I change it as I need...

/* Custom UART4 with TX on GPIOA0 Alternate 8 */
#define DEBUG_UART_TX_GPIO_BANK_ADDRESS	GPIOA_BASE
#define DEBUG_UART_TX_GPIO_PORT 0	
#define DEBUG_UART_TX_GPIO_ALTERNATE	8

...the compilation have an error (of course) because DEBUG_UART_TX_GPIO_PORT can't be zero.

Warning: shift count out of range (-32 is not between 0 and 63)

So my question is how is supposed to be customized the UAT4_TX in TF-A ?

Do I have to rely on the DTS/DTSI only or there is something more to verify?

Any help would be very appreciated.

Thanks,

8 REPLIES 8
PatrickF
ST Employee

Hello,

please have a look to https://wiki.st.com/stm32mpu/wiki/How_to_create_your_board_device_tree

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
koan
Associate III

Hello,

if I use STM32CubeMX seems impossible to use UART4_TX on PA0,8

0690X00000D9BqXQAV.png

The key question is: Is it possible to change the hard coded UART4 settings with TX on GPIO G11 for the crash console, in plat/st/stm32mp1/stm32mp1_def.h ?

PatrickF
ST Employee

You should un-select 'Boot ROM' for the UART4 to unrestrict the selection.

if you want to support UART Boot, you are constrained in the choice of UART pins muxing.

You could use another U(S)ART instance (even while keeping UART4 for Linux console) if you want to allow UART boot (USB boot is privileged and sufficient in most cases).

see https://wiki.st.com/stm32mpu/wiki/STM32MP15_ROM_code_overview#UART_Boot and also AN5031

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
koan
Associate III

Hello,

I need to use the debug port on UART4_TX pin PA0,8 and I understand that is not possible in BootROM, and that can be fine.

But I need it starting from FSBL (TF-A or SPL) and from the SSBL (u-boot).

Reading the document "Boot chains overview" https://wiki.st.com/stm32mpu/wiki/Boot_chains_overview

looks like that RomBOOT is not the FSBL, so I still wonder if is possible to use UART4 settings with TX on GPIO A0,8.

Could you please confirm if is it possible?

0690X00000D9CAcQAN.png

PatrickF
ST Employee

Yes, that will work.

All the features linked to UART4 will work on TF-A, uBoot and Linux.

The Boot chain you put above is linked to Boot from Flash and BootROM does not use UART at all during a successful FSBL load (BootROM fall back to UART/USB in case of failure).

By using 'non-default-BootROM-UART' pins you only loose the ability to load the FSBL into SYSRAM thru UART (e.g. Flashload, or low level debug during board bring-up).

Flashing using UART is usually never used due to the amount time it take to load 10's of MBytes.

USB is used during product bring-up as it usually work without much issue from BootROM usage (OTG_HS_DP/DM pin wiring + a 24MHz clock on OSC_IN are sufficient to load).

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
koan
Associate III

But do I need to modify the crash console, in plat/st/stm32mp1/stm32mp1_def.h ?

Is not possible to set GPIO 0

#define DEBUG_UART_TX_GPIO_PORT 0

There is likely a bug in TF-A around the way the GPIOs AF mux are set, as those belong to two different registers: GPIOx_AFRL for GPIO Px0 to Px7 and GPIOx_AFRH for GPIO Px8 to Px15.

I have escalated this to development team.

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
Bernard PUEL
ST Employee

Here is the patch to correct the issue (based on V1.2.0):

diff --git a/plat/st/stm32mp1/stm32mp1_helper.S b/plat/st/stm32mp1/stm32mp1_helper.S

index afaa1f4..28abaf9 100644

--- a/plat/st/stm32mp1/stm32mp1_helper.S

+++ b/plat/st/stm32mp1/stm32mp1_helper.S

@@ -1,5 +1,5 @@

 /*

- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.

+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.

 *

 * SPDX-License-Identifier: BSD-3-Clause

 */

@@ -13,7 +13,6 @@

 #include <stm32mp1_rcc.h>

 

 #define GPIO_TX_SHIFT     (DEBUG_UART_TX_GPIO_PORT << 1)

-#define GPIO_TX_ALT_SHIFT ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)

 

     .globl     platform_mem_init

     .globl     plat_report_exception

@@ -265,10 +264,16 @@

     bic  r2, r2, #(GPIO_PULL_MASK << GPIO_TX_SHIFT)

     str  r2, [r1, #GPIO_PUPD_OFFSET]

     /* Set alternate */

-    ldr  r2, [r1, #GPIO_AFRH_OFFSET]

-    bic  r2, r2, #(GPIO_ALTERNATE_MASK << GPIO_TX_ALT_SHIFT)

-    orr  r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << GPIO_TX_ALT_SHIFT)

-    str  r2, [r1, #GPIO_AFRH_OFFSET]

+    ldr  r2, =DEBUG_UART_TX_GPIO_PORT

+    cmp  r2, #GPIO_ALT_LOWER_LIMIT

+    ldrge r2, [r1, #GPIO_AFRH_OFFSET]

+    bicge r2, r2, #(GPIO_ALTERNATE_MASK << ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2))

+    orrge r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2))

+    strge r2, [r1, #GPIO_AFRH_OFFSET]

+    ldrlt r2, [r1, #GPIO_AFRL_OFFSET]

+    biclt r2, r2, #(GPIO_ALTERNATE_MASK << (DEBUG_UART_TX_GPIO_PORT << 2))

+    orrlt r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << (DEBUG_UART_TX_GPIO_PORT << 2))

+    strlt r2, [r1, #GPIO_AFRL_OFFSET]

     /* Enable UART clock, with its source */

     ldr  r1, =(RCC_BASE + DEBUG_UART_TX_CLKSRC_REG)

     mov  r2, #DEBUG_UART_TX_CLKSRC