console: 16550: Prepare for skipping initialisation

On some platforms the UART might have already been initialised, for
instance by firmware running before TF-A or by a separate management
processor. In this case it would not be need to initialise it again
(doing so could create spurious characters). But more importantly this
saves us from knowing the right baudrate and the right base clock rate
for the UART. This can lead to more robust and versatile firmware builds.

Allow to skip the 16550 UART initialisation and baud rate divisor
programming, by interpreting an input clock rate of "0" to signify this
case. This will just skip the call to console_16550_core_init, but still
will register the console properly.

Users should just pass 0 as the second parameter, the baudrate (third
parameter) will then be ignored as well.

Fix copy & paste typos in comments for the console_16550_register()
function on the way.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Change-Id: I9f8fca5b358f878fac0f31dc411358fd160786ee
This commit is contained in:
Andre Przywara 2019-12-12 12:00:15 +00:00 committed by Manish Pandey
parent 2b4c5e4b6f
commit cd50ffd2fc
3 changed files with 26 additions and 6 deletions

View File

@ -89,16 +89,19 @@ endfunc console_16550_core_init
.globl console_16550_register
/* -------------------------------------------------------
* int console_stm32_register(uintptr_t baseaddr,
* int console_16550_register(uintptr_t baseaddr,
* uint32_t clock, uint32_t baud,
* struct console_stm32 *console);
* Function to initialize and register a new STM32
* console_16550_t *console);
* Function to initialize and register a new 16550
* console. Storage passed in for the console struct
* *must* be persistent (i.e. not from the stack).
* If r1 (UART clock) is 0, initialisation will be
* skipped, relying on previous code to have done
* this already. r2 is ignored then as well.
* In: r0 - UART register base address
* r1 - UART clock in Hz
* r2 - Baud rate
* r3 - pointer to empty console_stm32 struct
* r2 - Baud rate (ignored if r1 is 0)
* r3 - pointer to empty console_16550_t struct
* Out: return 1 on success, 0 on error
* Clobber list : r0, r1, r2
* -------------------------------------------------------
@ -110,10 +113,15 @@ func console_16550_register
beq register_fail
str r0, [r4, #CONSOLE_T_16550_BASE]
/* A clock rate of zero means to skip the initialisation. */
cmp r1, #0
beq register_16550
bl console_16550_core_init
cmp r0, #0
beq register_fail
register_16550:
mov r0, r4
pop {r4, lr}
finish_console_register 16550 putc=1, getc=1, flush=1

View File

@ -92,9 +92,12 @@ endfunc console_16550_core_init
* Function to initialize and register a new 16550
* console. Storage passed in for the console struct
* *must* be persistent (i.e. not from the stack).
* If w1 (UART clock) is 0, initialisation will be
* skipped, relying on previous code to have done
* this already. w2 is ignored then as well.
* In: x0 - UART register base address
* w1 - UART clock in Hz
* w2 - Baud rate
* w2 - Baud rate (ignored if w1 is 0)
* x3 - pointer to empty console_16550_t struct
* Out: return 1 on success, 0 on error
* Clobber list : x0, x1, x2, x6, x7, x14
@ -106,9 +109,13 @@ func console_16550_register
cbz x6, register_fail
str x0, [x6, #CONSOLE_T_16550_BASE]
/* A clock rate of zero means to skip the initialisation. */
cbz w1, register_16550
bl console_16550_core_init
cbz x0, register_fail
register_16550:
mov x0, x6
mov x30, x7
finish_console_register 16550 putc=1, getc=1, flush=1

View File

@ -87,6 +87,11 @@ typedef struct {
* framework. The |console| pointer must point to storage that will be valid
* for the lifetime of the console, such as a global or static local variable.
* Its contents will be reinitialized from scratch.
* When |clock| has a value of 0, the UART will *not* be initialised. This
* means the UART should already be enabled and the baudrate and clock setup
* should have been done already, either by platform specific code or by
* previous firmware stages. The |baud| parameter will be ignored in this
* case as well.
*/
int console_16550_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
console_16550_t *console);