[U-Boot] AM335x configurations - console output at early stages lost

Hi Tom,
I’m working on rebasing an old U-Boot branch for our company’s AM335x based board upon the current U-Boot release (v2015.04). Our branch was initially based on the v2013.10 release (the ti/am335x/ board was taken as reference).
After making all the code compile, I discovered there was a change in the U-Boot initialization sequence, introduced by commit a6b541b09022acb6f7c2754100ae26bd44eed1d9, that prevents our code from working:
Prior to the above mentioned commit, the console serial port was initialized at a very early stage in the armv7/am335x/board.c:s_init() function (calling preloader_console_init()). Roughly saying, it was the first thing done by the SPL code. This made quite much sense, as it enabled all the code afterwards to output status/debugging info to the console. Moving the preloader_console_init() call to spl_board_init() caused it to be run at a very "late" stage (as part of the board_init_r() function). AFAIU, now all the code that runs till then has no ability for any console output. For example, in our particular case, the DDR configuration code (in sdram_init()) reads the DDR type from an I2C EEPROM. Obviously, if something goes wrong in this process, we would like to report it to the console.
I understand there was a good reason for the mentioned commit (the GD), however, as you see, we have also lost some important functionality with it. I would appreciate your advice on how to solve it.
Best regards, Vasili Galka

Hi Vasili,
On 29 April 2015 at 10:57, Vasili Galka vvv444@gmail.com wrote:
Hi Tom,
I’m working on rebasing an old U-Boot branch for our company’s AM335x based board upon the current U-Boot release (v2015.04). Our branch was initially based on the v2013.10 release (the ti/am335x/ board was taken as reference).
After making all the code compile, I discovered there was a change in the U-Boot initialization sequence, introduced by commit a6b541b09022acb6f7c2754100ae26bd44eed1d9, that prevents our code from working:
Prior to the above mentioned commit, the console serial port was initialized at a very early stage in the armv7/am335x/board.c:s_init() function (calling preloader_console_init()). Roughly saying, it was the first thing done by the SPL code. This made quite much sense, as it enabled all the code afterwards to output status/debugging info to the console. Moving the preloader_console_init() call to spl_board_init() caused it to be run at a very "late" stage (as part of the board_init_r() function). AFAIU, now all the code that runs till then has no ability for any console output. For example, in our particular case, the DDR configuration code (in sdram_init()) reads the DDR type from an I2C EEPROM. Obviously, if something goes wrong in this process, we would like to report it to the console.
I understand there was a good reason for the mentioned commit (the GD), however, as you see, we have also lost some important functionality with it. I would appreciate your advice on how to solve it.
It would certainly be very useful and it would be great if we could printf() from as soon as we have a stack (and perhaps printch() even earlier). I think it can be done, but I have not put in the time to figure it out.
You could take a look at CONFIG_DEBUG_UART which at least allows primitive UART access before gd is set up. I wonder if we could do something like change printf() /purchatr() to use this when gd is NULL?
Regards, Simon

Hi Simon,
On Thu, Apr 30, 2015 at 3:38 AM, Simon Glass sjg@chromium.org wrote:
Hi Vasili,
On 29 April 2015 at 10:57, Vasili Galka vvv444@gmail.com wrote:
Hi Tom,
I’m working on rebasing an old U-Boot branch for our company’s AM335x based board upon the current U-Boot release (v2015.04). Our branch was initially based on the v2013.10 release (the ti/am335x/ board was taken as reference).
After making all the code compile, I discovered there was a change in the U-Boot initialization sequence, introduced by commit a6b541b09022acb6f7c2754100ae26bd44eed1d9, that prevents our code from working:
Prior to the above mentioned commit, the console serial port was initialized at a very early stage in the armv7/am335x/board.c:s_init() function (calling preloader_console_init()). Roughly saying, it was the first thing done by the SPL code. This made quite much sense, as it enabled all the code afterwards to output status/debugging info to the console. Moving the preloader_console_init() call to spl_board_init() caused it to be run at a very "late" stage (as part of the board_init_r() function). AFAIU, now all the code that runs till then has no ability for any console output. For example, in our particular case, the DDR configuration code (in sdram_init()) reads the DDR type from an I2C EEPROM. Obviously, if something goes wrong in this process, we would like to report it to the console.
I understand there was a good reason for the mentioned commit (the GD), however, as you see, we have also lost some important functionality with it. I would appreciate your advice on how to solve it.
It would certainly be very useful and it would be great if we could printf() from as soon as we have a stack (and perhaps printch() even earlier). I think it can be done, but I have not put in the time to figure it out.
You could take a look at CONFIG_DEBUG_UART which at least allows primitive UART access before gd is set up. I wonder if we could do something like change printf() /purchatr() to use this when gd is NULL?
Regards, Simon
Thanks for the suggestion! I'm attempting to make it work. Was the "Debug UART" code (added in 21d004368fc8a4da07147c58dfe9a4e16d4ab761) ever tested on AM335x? It does not seem to work for me, I'm currently debugging in attempt to understand the cause.
Regards, Vasili

Hi Vasili,
On 4 May 2015 at 10:21, Vasili Galka vvv444@gmail.com wrote:
Hi Simon,
On Thu, Apr 30, 2015 at 3:38 AM, Simon Glass sjg@chromium.org wrote:
Hi Vasili,
On 29 April 2015 at 10:57, Vasili Galka vvv444@gmail.com wrote:
Hi Tom,
I’m working on rebasing an old U-Boot branch for our company’s AM335x based board upon the current U-Boot release (v2015.04). Our branch was initially based on the v2013.10 release (the ti/am335x/ board was taken as reference).
After making all the code compile, I discovered there was a change in the U-Boot initialization sequence, introduced by commit a6b541b09022acb6f7c2754100ae26bd44eed1d9, that prevents our code from working:
Prior to the above mentioned commit, the console serial port was initialized at a very early stage in the armv7/am335x/board.c:s_init() function (calling preloader_console_init()). Roughly saying, it was the first thing done by the SPL code. This made quite much sense, as it enabled all the code afterwards to output status/debugging info to the console. Moving the preloader_console_init() call to spl_board_init() caused it to be run at a very "late" stage (as part of the board_init_r() function). AFAIU, now all the code that runs till then has no ability for any console output. For example, in our particular case, the DDR configuration code (in sdram_init()) reads the DDR type from an I2C EEPROM. Obviously, if something goes wrong in this process, we would like to report it to the console.
I understand there was a good reason for the mentioned commit (the GD), however, as you see, we have also lost some important functionality with it. I would appreciate your advice on how to solve it.
It would certainly be very useful and it would be great if we could printf() from as soon as we have a stack (and perhaps printch() even earlier). I think it can be done, but I have not put in the time to figure it out.
You could take a look at CONFIG_DEBUG_UART which at least allows primitive UART access before gd is set up. I wonder if we could do something like change printf() /purchatr() to use this when gd is NULL?
Regards, Simon
Thanks for the suggestion! I'm attempting to make it work. Was the "Debug UART" code (added in 21d004368fc8a4da07147c58dfe9a4e16d4ab761) ever tested on AM335x? It does not seem to work for me, I'm currently debugging in attempt to understand the cause.
From memory I think I did test it locally but did not send patches to enable it.
You will need to enable DEBUG_UART_NS16550, and supply suitable values for DEBUG_UART_BASE and DEBUG_UART_CLOCK.
But the debug UART code (in ns16550.c) is really simple so it should not be possible to debug it.
I think it would be good to have the DEBUG_UART_... options in the board's defconfig file, even though CONFIG_DEBUG_UART itself is disabled. Then people can enable it easily when they want to use the debug UART.
Regards, Simon

Hi Simon,
On Mon, May 4, 2015 at 7:45 PM, Simon Glass sjg@chromium.org wrote:
Hi Vasili,
On 4 May 2015 at 10:21, Vasili Galka vvv444@gmail.com wrote:
Hi Simon,
On Thu, Apr 30, 2015 at 3:38 AM, Simon Glass sjg@chromium.org wrote:
Hi Vasili,
On 29 April 2015 at 10:57, Vasili Galka vvv444@gmail.com wrote:
Hi Tom,
I’m working on rebasing an old U-Boot branch for our company’s AM335x based board upon the current U-Boot release (v2015.04). Our branch was initially based on the v2013.10 release (the ti/am335x/ board was taken as reference).
After making all the code compile, I discovered there was a change in the U-Boot initialization sequence, introduced by commit a6b541b09022acb6f7c2754100ae26bd44eed1d9, that prevents our code from working:
Prior to the above mentioned commit, the console serial port was initialized at a very early stage in the armv7/am335x/board.c:s_init() function (calling preloader_console_init()). Roughly saying, it was the first thing done by the SPL code. This made quite much sense, as it enabled all the code afterwards to output status/debugging info to the console. Moving the preloader_console_init() call to spl_board_init() caused it to be run at a very "late" stage (as part of the board_init_r() function). AFAIU, now all the code that runs till then has no ability for any console output. For example, in our particular case, the DDR configuration code (in sdram_init()) reads the DDR type from an I2C EEPROM. Obviously, if something goes wrong in this process, we would like to report it to the console.
I understand there was a good reason for the mentioned commit (the GD), however, as you see, we have also lost some important functionality with it. I would appreciate your advice on how to solve it.
It would certainly be very useful and it would be great if we could printf() from as soon as we have a stack (and perhaps printch() even earlier). I think it can be done, but I have not put in the time to figure it out.
You could take a look at CONFIG_DEBUG_UART which at least allows primitive UART access before gd is set up. I wonder if we could do something like change printf() /purchatr() to use this when gd is NULL?
Regards, Simon
Thanks for the suggestion! I'm attempting to make it work. Was the "Debug UART" code (added in
21d004368fc8a4da07147c58dfe9a4e16d4ab761) ever tested on AM335x? It does not seem to work for me, I'm currently debugging in attempt to understand the cause.
From memory I think I did test it locally but did not send patches to enable it.
You will need to enable DEBUG_UART_NS16550, and supply suitable values for DEBUG_UART_BASE and DEBUG_UART_CLOCK.
But the debug UART code (in ns16550.c) is really simple so it should not be possible to debug it.
I think it would be good to have the DEBUG_UART_... options in the board's defconfig file, even though CONFIG_DEBUG_UART itself is disabled. Then people can enable it easily when they want to use the debug UART.
Regards, Simon
Yes, of course, please see below the changes I applied. I expected to see a character written on to the UART, but I see nothing. So I attempt to compare the new serial code to the old one (from 2013) that definitely works.
Best, Vasili
--- diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c index 67bef23..79026d4 100644 --- a/arch/arm/cpu/armv7/am33xx/board.c +++ b/arch/arm/cpu/armv7/am33xx/board.c @@ -35,6 +35,7 @@ #include <linux/usb/musb.h> #include <asm/omap_musb.h> #include <asm/davinci_rtc.h> +#include <debug_uart.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -297,6 +298,11 @@ void s_init(void) set_uart_mux_conf(); setup_clocks_for_console(); uart_soft_reset(); +#ifdef CONFIG_DEBUG_UART + debug_uart_init(); + printch('A'); + for(;;); +#endif #if defined(CONFIG_NOR_BOOT) || defined(CONFIG_QSPI_BOOT) /* TODO: This does not work, gd is not available yet */ gd->baudrate = CONFIG_BAUDRATE; diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index 03beab5..7674433 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -54,7 +54,7 @@ DECLARE_GLOBAL_DATA_PTR; #define CONFIG_SYS_NS16550_IER 0x00 #endif /* CONFIG_SYS_NS16550_IER */
-#ifdef CONFIG_DM_SERIAL +#if defined(CONFIG_DM_SERIAL) || defined(CONFIG_DEBUG_UART_NS16550)
static inline void serial_out_shift(unsigned char *addr, int shift, int value) { @@ -85,6 +85,9 @@ static inline int serial_in_shift(unsigned char *addr, int shift) return readb(addr); #endif } +#endif + +#if defined(CONFIG_DM_SERIAL)
static void ns16550_writeb(NS16550_t port, int offset, int value) { diff --git a/include/configs/vm_am335x.h b/include/configs/vm_am335x.h index 9725c3f..3a1abc9 100644 --- a/include/configs/vm_am335x.h +++ b/include/configs/vm_am335x.h @@ -69,6 +69,11 @@ #define CONFIG_SYS_NS16550_COM1 0x44e09000 /* Baseboard has UART0 */ #define CONFIG_BAUDRATE 115200
+/* Enable "debug UART" to be the same (this is used at very beginning before gd is set-up) */ +#define CONFIG_DEBUG_UART +#define CONFIG_DEBUG_UART_NS16550 +#define CONFIG_DEBUG_UART_BASE CONFIG_SYS_NS16550_COM1 +#define CONFIG_DEBUG_UART_CLOCK CONFIG_SYS_NS16550_CLK
/* * Default to using SPI for environment, etc.

Hi Simon,
On Mon, May 4, 2015 at 7:52 PM, Vasili Galka vvv444@gmail.com wrote:
Hi Simon,
On Mon, May 4, 2015 at 7:45 PM, Simon Glass sjg@chromium.org wrote:
Hi Vasili,
On 4 May 2015 at 10:21, Vasili Galka vvv444@gmail.com wrote:
Hi Simon,
On Thu, Apr 30, 2015 at 3:38 AM, Simon Glass sjg@chromium.org wrote:
Hi Vasili,
On 29 April 2015 at 10:57, Vasili Galka vvv444@gmail.com wrote:
Hi Tom,
I’m working on rebasing an old U-Boot branch for our company’s AM335x based board upon the current U-Boot release (v2015.04). Our branch
was
initially based on the v2013.10 release (the ti/am335x/ board was taken as reference).
After making all the code compile, I discovered there was a change in the U-Boot initialization sequence, introduced by commit a6b541b09022acb6f7c2754100ae26bd44eed1d9, that prevents our code from working:
Prior to the above mentioned commit, the console serial port was initialized at a very early stage in the
armv7/am335x/board.c:s_init()
function (calling preloader_console_init()). Roughly saying, it was the first thing done by the SPL code. This made quite much sense, as it enabled all the code afterwards to output status/debugging info to the console. Moving the preloader_console_init() call to spl_board_init() caused
it
to be run at a very "late" stage (as part of the board_init_r() function). AFAIU, now all the code that runs till then has no ability for any console output. For example, in our particular case, the DDR configuration code (in sdram_init()) reads the DDR type from an I2C EEPROM. Obviously, if something goes wrong in this process, we would like to report it to the console.
I understand there was a good reason for the mentioned commit (the GD), however, as you see, we have also lost some important functionality with it. I would appreciate your advice on how to solve it.
It would certainly be very useful and it would be great if we could printf() from as soon as we have a stack (and perhaps printch() even earlier). I think it can be done, but I have not put in the time to figure it out.
You could take a look at CONFIG_DEBUG_UART which at least allows primitive UART access before gd is set up. I wonder if we could do something like change printf() /purchatr() to use this when gd is NULL?
Regards, Simon
Thanks for the suggestion! I'm attempting to make it work. Was the "Debug UART" code (added in
21d004368fc8a4da07147c58dfe9a4e16d4ab761) ever tested on AM335x? It does not seem to work for me, I'm currently debugging in attempt to understand the cause.
From memory I think I did test it locally but did not send patches to enable it.
You will need to enable DEBUG_UART_NS16550, and supply suitable values for DEBUG_UART_BASE and DEBUG_UART_CLOCK.
But the debug UART code (in ns16550.c) is really simple so it should not be possible to debug it.
I think it would be good to have the DEBUG_UART_... options in the board's defconfig file, even though CONFIG_DEBUG_UART itself is disabled. Then people can enable it easily when they want to use the debug UART.
Regards, Simon
Yes, of course, please see below the changes I applied. I expected to see a character written on to the UART, but I see nothing. So I attempt to compare the new serial code to the old one (from 2013) that definitely works.
Best, Vasili
...
I've altered the debug_uart_init() to mimic the behaviour of NS16550_init() more closely and it fixed the problem. I'll send a clean patch shortly.
Many thanks!
Best regards, Vasili

On 4 May 2015 at 11:17, Vasili Galka vvv444@gmail.com wrote:
Hi Simon,
On Mon, May 4, 2015 at 7:52 PM, Vasili Galka vvv444@gmail.com wrote:
Hi Simon,
On Mon, May 4, 2015 at 7:45 PM, Simon Glass sjg@chromium.org wrote:
Hi Vasili,
On 4 May 2015 at 10:21, Vasili Galka vvv444@gmail.com wrote:
Hi Simon,
On Thu, Apr 30, 2015 at 3:38 AM, Simon Glass sjg@chromium.org wrote:
Hi Vasili,
On 29 April 2015 at 10:57, Vasili Galka vvv444@gmail.com wrote:
Hi Tom,
I’m working on rebasing an old U-Boot branch for our company’s AM335x based board upon the current U-Boot release (v2015.04). Our branch was initially based on the v2013.10 release (the ti/am335x/ board was taken as reference).
After making all the code compile, I discovered there was a change in the U-Boot initialization sequence, introduced by commit a6b541b09022acb6f7c2754100ae26bd44eed1d9, that prevents our code from working:
Prior to the above mentioned commit, the console serial port was initialized at a very early stage in the armv7/am335x/board.c:s_init() function (calling preloader_console_init()). Roughly saying, it was the first thing done by the SPL code. This made quite much sense, as it enabled all the code afterwards to output status/debugging info to the console. Moving the preloader_console_init() call to spl_board_init() caused it to be run at a very "late" stage (as part of the board_init_r() function). AFAIU, now all the code that runs till then has no ability for any console output. For example, in our particular case, the DDR configuration code (in sdram_init()) reads the DDR type from an I2C EEPROM. Obviously, if something goes wrong in this process, we would like to report it to the console.
I understand there was a good reason for the mentioned commit (the GD), however, as you see, we have also lost some important functionality with it. I would appreciate your advice on how to solve it.
It would certainly be very useful and it would be great if we could printf() from as soon as we have a stack (and perhaps printch() even earlier). I think it can be done, but I have not put in the time to figure it out.
You could take a look at CONFIG_DEBUG_UART which at least allows primitive UART access before gd is set up. I wonder if we could do something like change printf() /purchatr() to use this when gd is NULL?
Regards, Simon
Thanks for the suggestion! I'm attempting to make it work. Was the "Debug UART" code (added in 21d004368fc8a4da07147c58dfe9a4e16d4ab761) ever tested on AM335x? It does not seem to work for me, I'm currently debugging in attempt to understand the cause.
From memory I think I did test it locally but did not send patches to enable it.
You will need to enable DEBUG_UART_NS16550, and supply suitable values for DEBUG_UART_BASE and DEBUG_UART_CLOCK.
But the debug UART code (in ns16550.c) is really simple so it should not be possible to debug it.
I think it would be good to have the DEBUG_UART_... options in the board's defconfig file, even though CONFIG_DEBUG_UART itself is disabled. Then people can enable it easily when they want to use the debug UART.
Regards, Simon
Yes, of course, please see below the changes I applied. I expected to see a character written on to the UART, but I see nothing. So I attempt to compare the new serial code to the old one (from 2013) that definitely works.
Best, Vasili
...
I've altered the debug_uart_init() to mimic the behaviour of NS16550_init() more closely and it fixed the problem. I'll send a clean patch shortly.
Great! The code is a bit of a mess, hoping we can simplify it once everything moves to driver model.
- Simon
participants (2)
-
Simon Glass
-
Vasili Galka