blob: 5b0ae6df3324c4d3dd37df502398fb44ac0cb728 [file] [log] [blame]
developer65014b82015-04-13 14:47:57 +08001/*
2 * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * Neither the name of ARM nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific
16 * prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30#include <asm_macros.S>
31#include <uart8250.h>
32
33 .globl console_core_init
34 .globl console_core_putc
35 .globl console_core_getc
36
37 /* -----------------------------------------------
38 * int console_core_init(unsigned long base_addr,
39 * unsigned int uart_clk, unsigned int baud_rate)
40 * Function to initialize the console without a
41 * C Runtime to print debug information. This
42 * function will be accessed by console_init and
43 * crash reporting.
44 * In: x0 - console base address
45 * w1 - Uart clock in Hz
46 * w2 - Baud rate
47 * Out: return 1 on success else 0 on error
48 * Clobber list : x1, x2, x3
49 * -----------------------------------------------
50 */
51func console_core_init
52 /* Check the input base address */
53 cbz x0, core_init_fail
54 /* Check baud rate and uart clock for sanity */
55 cbz w1, core_init_fail
56 cbz w2, core_init_fail
57
58 /* Disable interrupt */
59 str wzr, [x0, #UART_IER]
60
61 /* Force DTR and RTS to high */
62 mov w3, #(UART_MCR_DTR | UART_MCR_RTS)
63 str w3, [x0, #UART_MCR]
64
65 /* Check high speed */
66 movz w3, #:abs_g1:115200
67 movk w3, #:abs_g0_nc:115200
68 cmp w2, w3
69 b.hi 1f
70
71 /* Non high speed */
72 lsl w2, w2, #4
73 mov w3, wzr
74 b 2f
75
76 /* High speed */
771: lsl w2, w2, #2
78 mov w3, #2
79
80 /* Set high speed UART register */
812: str w3, [x0, #UART_HIGHSPEED]
82
83 /* Calculate divisor */
84 udiv w3, w1, w2 /* divisor = uartclk / (quot * baudrate) */
85 msub w1, w3, w2, w1 /* remainder = uartclk % (quot * baudrate) */
86 lsr w2, w2, #1
87 cmp w1, w2
88 cinc w3, w3, hs
89
90 /* Set line configuration, access divisor latches */
91 mov w1, #(UART_LCR_DLAB | UART_LCR_WLS_8)
92 str w1, [x0, #UART_LCR]
93
94 /* Set the divisor */
95 and w1, w3, #0xff
96 str w1, [x0, #UART_DLL]
97 lsr w1, w3, #8
98 and w1, w1, #0xff
99 str w1, [x0, #UART_DLH]
100
101 /* Hide the divisor latches */
102 mov w1, #UART_LCR_WLS_8
103 str w1, [x0, #UART_LCR]
104
105 /* Enable FIFOs, and clear receive and transmit */
106 mov w1, #(UART_FCR_FIFO_EN | UART_FCR_CLEAR_RCVR | \
107 UART_FCR_CLEAR_XMIT)
108 str w1, [x0, #UART_FCR]
109
110 mov w0, #1
111 ret
112core_init_fail:
113 mov w0, wzr
114 ret
115endfunc console_core_init
116
117 /* --------------------------------------------------------
118 * int console_core_putc(int c, unsigned long base_addr)
119 * Function to output a character over the console. It
120 * returns the character printed on success or -1 on error.
121 * In : w0 - character to be printed
122 * x1 - console base address
123 * Out : return -1 on error else return character.
124 * Clobber list : x2
125 * --------------------------------------------------------
126 */
127func console_core_putc
128 /* Check the input parameter */
129 cbz x1, putc_error
130 /* Prepend '\r' to '\n' */
131 cmp w0, #0xA
132 b.ne 2f
133
134 /* Check if the transmit FIFO is full */
1351: ldr w2, [x1, #UART_LSR]
136 and w2, w2, #UART_LSR_THRE
137 cbz w2, 1b
138 mov w2, #0xD
139 str w2, [x1, #UART_THR]
140
141 /* Check if the transmit FIFO is full */
1422: ldr w2, [x1, #UART_LSR]
143 and w2, w2, #UART_LSR_THRE
144 cbz w2, 2b
145 str w0, [x1, #UART_THR]
146 ret
147putc_error:
148 mov w0, #-1
149 ret
150endfunc console_core_putc
151
152 /* ---------------------------------------------
153 * int console_core_getc(unsigned long base_addr)
154 * Function to get a character from the console.
155 * It returns the character grabbed on success
156 * or -1 on error.
157 * In : x0 - console base address
158 * Clobber list : x0, x1
159 * ---------------------------------------------
160 */
161func console_core_getc
162 cbz x0, getc_error
163
164 /* Check if the receive FIFO is empty */
1651: ldr w1, [x0, #UART_LSR]
166 tbz w1, #UART_LSR_DR, 1b
167 ldr w0, [x0, #UART_RBR]
168 ret
169getc_error:
170 mov w0, #-1
171 ret
172endfunc console_core_getc