mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-17 10:04:26 +00:00

Initial commit for Socionext UniPhier SoC support. BL1, Bl2, and BL31 are supported. Refer to docs/plat/socionext-uniphier.md for more detais. Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
212 lines
4.9 KiB
ArmAsm
212 lines
4.9 KiB
ArmAsm
/*
|
|
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include <asm_macros.S>
|
|
|
|
#define UNIPHIER_UART_BASE 0x54006800
|
|
#define UNIPHIER_UART_END 0x54006c00
|
|
#define UNIPHIER_UART_OFFSET 0x100
|
|
|
|
#define UNIPHIER_UART_RX 0x00 /* In: Receive buffer */
|
|
#define UNIPHIER_UART_TX 0x00 /* Out: Transmit buffer */
|
|
|
|
#define UNIPHIER_UART_FCR 0x0c /* Char/FIFO Control Register */
|
|
#define UNIPHIER_UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */
|
|
|
|
#define UNIPHIER_UART_LCR_MCR 0x10 /* Line/Modem Control Register */
|
|
#define UNIPHIER_UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */
|
|
#define UNIPHIER_UART_LSR 0x14 /* Line Status Register */
|
|
#define UNIPHIER_UART_LSR_TEMT_BIT 6 /* Transmitter empty */
|
|
#define UNIPHIER_UART_LSR_THRE_BIT 5 /* Transmit-hold-register empty */
|
|
#define UNIPHIER_UART_LSR_DR_BIT 0 /* Receiver data ready */
|
|
#define UNIPHIER_UART_DLR 0x24 /* Divisor Latch Register */
|
|
|
|
/*
|
|
* Uncomment for debug
|
|
*/
|
|
/* #define UNIPHIER_UART_INIT_DIVISOR */
|
|
#define UNIPHIER_UART_DEFAULT_BASE (UNIPHIER_UART_BASE)
|
|
#define UNIPHIER_UART_CLK_RATE 58820000
|
|
#define UNIPHIER_UART_DEFAULT_BAUDRATE 115200
|
|
|
|
/*
|
|
* In: x0 - console base address
|
|
* w1 - uart clock in Hz
|
|
* w2 - baud rate
|
|
* Out: return 1 on success, or 0 on error
|
|
*/
|
|
.globl console_core_init
|
|
func console_core_init
|
|
cbz x0, 1f
|
|
#ifdef UNIPHIER_UART_INIT_DIVISOR
|
|
cbz w1, 1f
|
|
cbz w2, 1f
|
|
/* divisor = uart_clock / (16 * baud_rate) */
|
|
udiv w2, w1, w2
|
|
lsr w2, w2, #4
|
|
#endif
|
|
/* Make sure the transmitter is empty before the divisor set/change */
|
|
0: ldr w1, [x0, #UNIPHIER_UART_LSR]
|
|
tbz w1, #UNIPHIER_UART_LSR_TEMT_BIT, 0b
|
|
#ifdef UNIPHIER_UART_INIT_DIVISOR
|
|
str w2, [x0, #UNIPHIER_UART_DLR]
|
|
#endif
|
|
mov w2, #UNIPHIER_UART_FCR_ENABLE_FIFO
|
|
str w2, [x0, #UNIPHIER_UART_FCR]
|
|
|
|
mov w2, #(UNIPHIER_UART_LCR_WLEN8 << 8)
|
|
str w2, [x0, #UNIPHIER_UART_LCR_MCR]
|
|
|
|
mov w0, #1
|
|
ret
|
|
1: mov w0, #0
|
|
ret
|
|
endfunc console_core_init
|
|
|
|
/*
|
|
* In: w0 - character to be printed
|
|
* x1 - console base address
|
|
* Out: return the character written, or -1 on error
|
|
* Clobber: x2
|
|
*/
|
|
.globl console_core_putc
|
|
func console_core_putc
|
|
/* Error out if the console is not initialized */
|
|
cbz x1, 2f
|
|
|
|
/* Wait until the transmitter FIFO gets empty */
|
|
0: ldr w2, [x1, #UNIPHIER_UART_LSR]
|
|
tbz w2, #UNIPHIER_UART_LSR_THRE_BIT, 0b
|
|
|
|
mov w2, w0
|
|
|
|
1: str w2, [x1, #UNIPHIER_UART_TX]
|
|
|
|
cmp w2, #'\n'
|
|
b.ne 3f
|
|
mov w2, #'\r' /* Append '\r' to '\n' */
|
|
b 1b
|
|
2: mov w0, #-1
|
|
3: ret
|
|
endfunc console_core_putc
|
|
|
|
/*
|
|
* In: x0 - console base address
|
|
* Out: return the character read
|
|
* Clobber: x1
|
|
*/
|
|
.globl console_core_getc
|
|
func console_core_getc
|
|
/* Error out if the console is not initialized */
|
|
cbz x0, 1f
|
|
|
|
/* Wait while the receiver FIFO is empty */
|
|
0: ldr w1, [x0, #UNIPHIER_UART_LSR]
|
|
tbz w1, #UNIPHIER_UART_LSR_DR_BIT, 0b
|
|
|
|
ldr w0, [x0, #UNIPHIER_UART_RX]
|
|
|
|
ret
|
|
1: mov w0, #-1
|
|
ret
|
|
endfunc console_core_getc
|
|
|
|
/*
|
|
* In: x0 - console base address
|
|
* Out: return 0, or -1 on error
|
|
* Clobber: x1
|
|
*/
|
|
.global console_core_flush
|
|
func console_core_flush
|
|
/* Error out if the console is not initialized */
|
|
cbz x0, 1f
|
|
|
|
/* wait until the transmitter gets empty */
|
|
0: ldr w1, [x0, #UNIPHIER_UART_LSR]
|
|
tbz w1, #UNIPHIER_UART_LSR_TEMT_BIT, 0b
|
|
|
|
mov w0, #0
|
|
ret
|
|
1: mov w0, #-1
|
|
ret
|
|
endfunc console_core_flush
|
|
|
|
/* find initialized UART port */
|
|
.macro uniphier_console_get_base base, tmpx, tmpw
|
|
ldr \base, =UNIPHIER_UART_BASE
|
|
0000: ldr \tmpw, [\base, #UNIPHIER_UART_DLR]
|
|
mvn \tmpw, \tmpw
|
|
uxth \tmpw, \tmpw
|
|
cbnz \tmpw, 0001f
|
|
add \base, \base, #UNIPHIER_UART_OFFSET
|
|
ldr \tmpx, =UNIPHIER_UART_END
|
|
cmp \base, \tmpx
|
|
b.lo 0000b
|
|
mov \base, #0
|
|
0001:
|
|
.endm
|
|
|
|
/*
|
|
* int plat_crash_console_init(void)
|
|
* Clobber: x0-x2
|
|
*/
|
|
.globl plat_crash_console_init
|
|
func plat_crash_console_init
|
|
#ifdef UNIPHIER_UART_INIT_DIVISOR
|
|
ldr x0, =UNIPHIER_UART_DEFAULT_BASE
|
|
ldr x1, =UNIPHIER_UART_CLK_RATE
|
|
ldr x2, =UNIPHIER_UART_DEFAULT_BAUDRATE
|
|
b console_core_init
|
|
#else
|
|
ret
|
|
#endif
|
|
endfunc plat_crash_console_init
|
|
|
|
/*
|
|
* int plat_crash_console_putc(int c)
|
|
* Clobber: x1, x2
|
|
*/
|
|
.globl plat_crash_console_putc
|
|
func plat_crash_console_putc
|
|
#ifdef UNIPHIER_UART_INIT_DIVISOR
|
|
ldr x1, =UNIPHIER_UART_DEFAULT_BASE
|
|
#else
|
|
uniphier_console_get_base x1, x2, w2
|
|
#endif
|
|
b console_core_putc
|
|
endfunc plat_crash_console_putc
|
|
|
|
/*
|
|
* int plat_crash_console_flush(void)
|
|
* Clobber: x0, x1
|
|
*/
|
|
.global plat_crash_console_flush
|
|
func plat_crash_console_flush
|
|
#ifdef UNIPHIER_UART_INIT_DIVISOR
|
|
ldr x0, =UNIPHIER_UART_DEFAULT_BASE
|
|
#else
|
|
uniphier_console_get_base x0, x1, w1
|
|
#endif
|
|
b console_core_flush
|
|
endfunc plat_crash_console_flush
|
|
|
|
/*
|
|
* void uniphier_console_setup(void)
|
|
* Clobber: x0-x2
|
|
*/
|
|
.globl uniphier_console_setup
|
|
func uniphier_console_setup
|
|
#ifdef UNIPHIER_UART_INIT_DIVISOR
|
|
ldr x0, =UNIPHIER_UART_DEFAULT_BASE
|
|
ldr w1, =UNIPHIER_UART_CLK_RATE
|
|
ldr w2, =UNIPHIER_UART_DEFAULT_BAUDRATE
|
|
#else
|
|
uniphier_console_get_base x0, x1, w1
|
|
mov w1, #0
|
|
mov w2, #0
|
|
#endif
|
|
b console_init
|
|
endfunc uniphier_console_setup
|