Home | History | Annotate | Download | only in uniphier
      1 /*
      2  * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
      3  *
      4  * SPDX-License-Identifier: BSD-3-Clause
      5  */
      6 
      7 #include <asm_macros.S>
      8 
      9 #define UNIPHIER_UART_BASE	0x54006800
     10 #define UNIPHIER_UART_END	0x54006c00
     11 #define UNIPHIER_UART_OFFSET	0x100
     12 
     13 #define UNIPHIER_UART_RX	0x00	/* In:  Receive buffer */
     14 #define UNIPHIER_UART_TX	0x00	/* Out: Transmit buffer */
     15 
     16 #define UNIPHIER_UART_FCR	0x0c	/* Char/FIFO Control Register */
     17 #define   UNIPHIER_UART_FCR_ENABLE_FIFO	0x01	/* Enable the FIFO */
     18 
     19 #define UNIPHIER_UART_LCR_MCR	0x10	/* Line/Modem Control Register */
     20 #define   UNIPHIER_UART_LCR_WLEN8	0x03	/* Wordlength: 8 bits */
     21 #define UNIPHIER_UART_LSR	0x14	/* Line Status Register */
     22 #define   UNIPHIER_UART_LSR_TEMT_BIT	6	/* Transmitter empty */
     23 #define   UNIPHIER_UART_LSR_THRE_BIT	5	/* Transmit-hold-register empty */
     24 #define   UNIPHIER_UART_LSR_DR_BIT	0	/* Receiver data ready */
     25 #define UNIPHIER_UART_DLR	0x24	/* Divisor Latch Register */
     26 
     27 /*
     28  * Uncomment for debug
     29  */
     30 /* #define UNIPHIER_UART_INIT_DIVISOR */
     31 #define UNIPHIER_UART_DEFAULT_BASE	(UNIPHIER_UART_BASE)
     32 #define UNIPHIER_UART_CLK_RATE		58820000
     33 #define UNIPHIER_UART_DEFAULT_BAUDRATE	115200
     34 
     35 /*
     36  * In: x0 - console base address
     37  *     w1 - uart clock in Hz
     38  *     w2 - baud rate
     39  * Out: return 1 on success, or 0 on error
     40  */
     41 	.globl	console_core_init
     42 func console_core_init
     43 	cbz	x0, 1f
     44 #ifdef UNIPHIER_UART_INIT_DIVISOR
     45 	cbz	w1, 1f
     46 	cbz	w2, 1f
     47 	/* divisor = uart_clock / (16 * baud_rate) */
     48 	udiv	w2, w1, w2
     49 	lsr	w2, w2, #4
     50 #endif
     51 	/* Make sure the transmitter is empty before the divisor set/change */
     52 0:	ldr	w1, [x0, #UNIPHIER_UART_LSR]
     53 	tbz	w1, #UNIPHIER_UART_LSR_TEMT_BIT, 0b
     54 #ifdef UNIPHIER_UART_INIT_DIVISOR
     55 	str	w2, [x0, #UNIPHIER_UART_DLR]
     56 #endif
     57 	mov	w2, #UNIPHIER_UART_FCR_ENABLE_FIFO
     58 	str	w2, [x0, #UNIPHIER_UART_FCR]
     59 
     60 	mov	w2, #(UNIPHIER_UART_LCR_WLEN8 << 8)
     61 	str	w2, [x0, #UNIPHIER_UART_LCR_MCR]
     62 
     63 	mov	w0, #1
     64 	ret
     65 1:	mov	w0, #0
     66 	ret
     67 endfunc console_core_init
     68 
     69 /*
     70  * In: w0 - character to be printed
     71  *     x1 - console base address
     72  * Out: return the character written, or -1 on error
     73  * Clobber: x2
     74  */
     75 	.globl	console_core_putc
     76 func console_core_putc
     77 	/* Error out if the console is not initialized */
     78 	cbz	x1, 2f
     79 
     80 	/* Wait until the transmitter FIFO gets empty */
     81 0:	ldr	w2, [x1, #UNIPHIER_UART_LSR]
     82 	tbz	w2, #UNIPHIER_UART_LSR_THRE_BIT, 0b
     83 
     84 	mov	w2, w0
     85 
     86 1:	str	w2, [x1, #UNIPHIER_UART_TX]
     87 
     88 	cmp	w2, #'\n'
     89 	b.ne	3f
     90 	mov	w2, #'\r'	/* Append '\r' to '\n' */
     91 	b	1b
     92 2:	mov	w0, #-1
     93 3:	ret
     94 endfunc console_core_putc
     95 
     96 /*
     97  * In: x0 - console base address
     98  * Out: return the character read
     99  * Clobber: x1
    100  */
    101 	.globl	console_core_getc
    102 func console_core_getc
    103 	/* Error out if the console is not initialized */
    104 	cbz	x0, 1f
    105 
    106 	/* Wait while the receiver FIFO is empty */
    107 0:	ldr	w1, [x0, #UNIPHIER_UART_LSR]
    108 	tbz	w1, #UNIPHIER_UART_LSR_DR_BIT, 0b
    109 
    110 	ldr	w0, [x0, #UNIPHIER_UART_RX]
    111 
    112 	ret
    113 1:	mov	w0, #-1
    114 	ret
    115 endfunc console_core_getc
    116 
    117 /*
    118  * In:  x0 - console base address
    119  * Out: return 0, or -1 on error
    120  * Clobber: x1
    121  */
    122 	.global console_core_flush
    123 func console_core_flush
    124 	/* Error out if the console is not initialized */
    125 	cbz	x0, 1f
    126 
    127 	/* wait until the transmitter gets empty */
    128 0:	ldr	w1, [x0, #UNIPHIER_UART_LSR]
    129 	tbz	w1, #UNIPHIER_UART_LSR_TEMT_BIT, 0b
    130 
    131 	mov	w0, #0
    132 	ret
    133 1:	mov	w0, #-1
    134 	ret
    135 endfunc console_core_flush
    136 
    137 /* find initialized UART port */
    138 .macro uniphier_console_get_base base, tmpx, tmpw
    139 	ldr	\base, =UNIPHIER_UART_BASE
    140 0000:	ldr	\tmpw, [\base, #UNIPHIER_UART_DLR]
    141 	mvn	\tmpw, \tmpw
    142 	uxth	\tmpw, \tmpw
    143 	cbnz	\tmpw, 0001f
    144 	add	\base, \base, #UNIPHIER_UART_OFFSET
    145 	ldr	\tmpx, =UNIPHIER_UART_END
    146 	cmp	\base, \tmpx
    147 	b.lo	0000b
    148 	mov	\base, #0
    149 0001:
    150 .endm
    151 
    152 /*
    153  * int plat_crash_console_init(void)
    154  * Clobber: x0-x2
    155  */
    156 	.globl	plat_crash_console_init
    157 func plat_crash_console_init
    158 #ifdef UNIPHIER_UART_INIT_DIVISOR
    159 	ldr	x0, =UNIPHIER_UART_DEFAULT_BASE
    160 	ldr	x1, =UNIPHIER_UART_CLK_RATE
    161 	ldr	x2, =UNIPHIER_UART_DEFAULT_BAUDRATE
    162 	b	console_core_init
    163 #else
    164 	ret
    165 #endif
    166 endfunc plat_crash_console_init
    167 
    168 /*
    169  * int plat_crash_console_putc(int c)
    170  * Clobber: x1, x2
    171  */
    172 	.globl	plat_crash_console_putc
    173 func plat_crash_console_putc
    174 #ifdef UNIPHIER_UART_INIT_DIVISOR
    175 	ldr	x1, =UNIPHIER_UART_DEFAULT_BASE
    176 #else
    177 	uniphier_console_get_base x1, x2, w2
    178 #endif
    179 	b	console_core_putc
    180 endfunc plat_crash_console_putc
    181 
    182 /*
    183  * int plat_crash_console_flush(void)
    184  * Clobber: x0, x1
    185  */
    186 	.global plat_crash_console_flush
    187 func plat_crash_console_flush
    188 #ifdef UNIPHIER_UART_INIT_DIVISOR
    189 	ldr	x0, =UNIPHIER_UART_DEFAULT_BASE
    190 #else
    191 	uniphier_console_get_base x0, x1, w1
    192 #endif
    193 	b	console_core_flush
    194 endfunc plat_crash_console_flush
    195 
    196 /*
    197  * void uniphier_console_setup(void)
    198  * Clobber: x0-x2
    199  */
    200 	.globl	uniphier_console_setup
    201 func uniphier_console_setup
    202 #ifdef UNIPHIER_UART_INIT_DIVISOR
    203 	ldr	x0, =UNIPHIER_UART_DEFAULT_BASE
    204 	ldr	w1, =UNIPHIER_UART_CLK_RATE
    205 	ldr	w2, =UNIPHIER_UART_DEFAULT_BAUDRATE
    206 #else
    207 	uniphier_console_get_base x0, x1, w1
    208 	mov	w1, #0
    209 	mov	w2, #0
    210 #endif
    211 	b	console_init
    212 endfunc uniphier_console_setup
    213