Home | History | Annotate | Download | only in uart
      1 /*
      2  * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
      3  *
      4  * SPDX-License-Identifier: BSD-3-Clause
      5  */
      6 #include <asm_macros.S>
      7 #include <uart8250.h>
      8 
      9 	.globl	console_core_init
     10 	.globl	console_core_putc
     11 	.globl	console_core_getc
     12 	.globl	console_core_flush
     13 
     14 	/* -----------------------------------------------
     15 	 * int console_core_init(unsigned long base_addr,
     16 	 * unsigned int uart_clk, unsigned int baud_rate)
     17 	 * Function to initialize the console without a
     18 	 * C Runtime to print debug information. This
     19 	 * function will be accessed by console_init and
     20 	 * crash reporting.
     21 	 * In: x0 - console base address
     22 	 *     w1 - Uart clock in Hz
     23 	 *     w2 - Baud rate
     24 	 * Out: return 1 on success else 0 on error
     25 	 * Clobber list : x1, x2, x3
     26 	 * -----------------------------------------------
     27 	 */
     28 func console_core_init
     29 	/* Check the input base address */
     30 	cbz	x0, core_init_fail
     31 	/* Check baud rate and uart clock for sanity */
     32 	cbz	w1, core_init_fail
     33 	cbz	w2, core_init_fail
     34 
     35 	/* Disable interrupt */
     36 	str	wzr, [x0, #UART_IER]
     37 
     38 	/* Force DTR and RTS to high */
     39 	mov	w3, #(UART_MCR_DTR | UART_MCR_RTS)
     40 	str	w3, [x0, #UART_MCR]
     41 
     42 	/* Check high speed */
     43 	movz	w3, #:abs_g1:115200
     44 	movk	w3, #:abs_g0_nc:115200
     45 	cmp	w2, w3
     46 	b.hi	1f
     47 
     48 	/* Non high speed */
     49 	lsl	w2, w2, #4
     50 	mov	w3, wzr
     51 	b	2f
     52 
     53 	/* High speed */
     54 1:	lsl	w2, w2, #2
     55 	mov	w3, #2
     56 
     57 	/* Set high speed UART register */
     58 2:	str	w3, [x0, #UART_HIGHSPEED]
     59 
     60 	/* Calculate divisor */
     61 	udiv	w3, w1, w2	/* divisor = uartclk / (quot * baudrate) */
     62 	msub	w1, w3, w2, w1	/* remainder = uartclk % (quot * baudrate) */
     63 	lsr	w2, w2, #1
     64 	cmp	w1, w2
     65 	cinc	w3, w3, hs
     66 
     67 	/* Set line configuration, access divisor latches */
     68 	mov	w1, #(UART_LCR_DLAB | UART_LCR_WLS_8)
     69 	str	w1, [x0, #UART_LCR]
     70 
     71 	/* Set the divisor */
     72 	and	w1, w3, #0xff
     73 	str	w1, [x0, #UART_DLL]
     74 	lsr	w1, w3, #8
     75 	and	w1, w1, #0xff
     76 	str	w1, [x0, #UART_DLH]
     77 
     78 	/* Hide the divisor latches */
     79 	mov	w1, #UART_LCR_WLS_8
     80 	str	w1, [x0, #UART_LCR]
     81 
     82 	/* Enable FIFOs, and clear receive and transmit */
     83 	mov	w1, #(UART_FCR_FIFO_EN | UART_FCR_CLEAR_RCVR |	\
     84 			UART_FCR_CLEAR_XMIT)
     85 	str	w1, [x0, #UART_FCR]
     86 
     87 	mov	w0, #1
     88 	ret
     89 core_init_fail:
     90 	mov	w0, wzr
     91 	ret
     92 endfunc console_core_init
     93 
     94 	/* --------------------------------------------------------
     95 	 * int console_core_putc(int c, unsigned long base_addr)
     96 	 * Function to output a character over the console. It
     97 	 * returns the character printed on success or -1 on error.
     98 	 * In : w0 - character to be printed
     99 	 *      x1 - console base address
    100 	 * Out : return -1 on error else return character.
    101 	 * Clobber list : x2
    102 	 * --------------------------------------------------------
    103 	 */
    104 func console_core_putc
    105 	/* Check the input parameter */
    106 	cbz	x1, putc_error
    107 	/* Prepend '\r' to '\n' */
    108 	cmp	w0, #0xA
    109 	b.ne	2f
    110 
    111 	/* Check if the transmit FIFO is full */
    112 1:	ldr	w2, [x1, #UART_LSR]
    113 	and	w2, w2, #UART_LSR_THRE
    114 	cbz	w2, 1b
    115 	mov	w2, #0xD
    116 	str	w2, [x1, #UART_THR]
    117 
    118 	/* Check if the transmit FIFO is full */
    119 2:	ldr	w2, [x1, #UART_LSR]
    120 	and	w2, w2, #UART_LSR_THRE
    121 	cbz	w2, 2b
    122 	str	w0, [x1, #UART_THR]
    123 	ret
    124 putc_error:
    125 	mov	w0, #-1
    126 	ret
    127 endfunc console_core_putc
    128 
    129 	/* ---------------------------------------------
    130 	 * int console_core_getc(unsigned long base_addr)
    131 	 * Function to get a character from the console.
    132 	 * It returns the character grabbed on success
    133 	 * or -1 on error.
    134 	 * In : x0 - console base address
    135 	 * Clobber list : x0, x1
    136 	 * ---------------------------------------------
    137 	 */
    138 func console_core_getc
    139 	cbz	x0, getc_error
    140 
    141 	/* Check if the receive FIFO is empty */
    142 1:	ldr	w1, [x0, #UART_LSR]
    143 	tbz	w1, #UART_LSR_DR, 1b
    144 	ldr	w0, [x0, #UART_RBR]
    145 	ret
    146 getc_error:
    147 	mov	w0, #-1
    148 	ret
    149 endfunc console_core_getc
    150 
    151 	/* ---------------------------------------------
    152 	 * int console_core_flush(uintptr_t base_addr)
    153 	 * Function to force a write of all buffered
    154 	 * data that hasn't been output.
    155 	 * In : x0 - console base address
    156 	 * Out : return -1 on error else return 0.
    157 	 * Clobber list : x0, x1
    158 	 * ---------------------------------------------
    159 	 */
    160 func console_core_flush
    161 	/* Placeholder */
    162 	mov	w0, #0
    163 	ret
    164 endfunc console_core_flush
    165