xref: /rk3399_ARM-atf/drivers/arm/pl011/aarch32/pl011_console.S (revision 66be868e9acc7b34852f755934664b191e9fae13)
1*66be868eSSoby Mathew/*
2*66be868eSSoby Mathew * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
3*66be868eSSoby Mathew *
4*66be868eSSoby Mathew * Redistribution and use in source and binary forms, with or without
5*66be868eSSoby Mathew * modification, are permitted provided that the following conditions are met:
6*66be868eSSoby Mathew *
7*66be868eSSoby Mathew * Redistributions of source code must retain the above copyright notice, this
8*66be868eSSoby Mathew * list of conditions and the following disclaimer.
9*66be868eSSoby Mathew *
10*66be868eSSoby Mathew * Redistributions in binary form must reproduce the above copyright notice,
11*66be868eSSoby Mathew * this list of conditions and the following disclaimer in the documentation
12*66be868eSSoby Mathew * and/or other materials provided with the distribution.
13*66be868eSSoby Mathew *
14*66be868eSSoby Mathew * Neither the name of ARM nor the names of its contributors may be used
15*66be868eSSoby Mathew * to endorse or promote products derived from this software without specific
16*66be868eSSoby Mathew * prior written permission.
17*66be868eSSoby Mathew *
18*66be868eSSoby Mathew * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19*66be868eSSoby Mathew * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20*66be868eSSoby Mathew * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21*66be868eSSoby Mathew * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22*66be868eSSoby Mathew * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23*66be868eSSoby Mathew * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24*66be868eSSoby Mathew * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25*66be868eSSoby Mathew * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26*66be868eSSoby Mathew * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27*66be868eSSoby Mathew * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28*66be868eSSoby Mathew * POSSIBILITY OF SUCH DAMAGE.
29*66be868eSSoby Mathew */
30*66be868eSSoby Mathew#include <arch.h>
31*66be868eSSoby Mathew#include <asm_macros.S>
32*66be868eSSoby Mathew#include <pl011.h>
33*66be868eSSoby Mathew
34*66be868eSSoby Mathew/*
35*66be868eSSoby Mathew * Pull in generic functions to provide backwards compatibility for
36*66be868eSSoby Mathew * platform makefiles
37*66be868eSSoby Mathew */
38*66be868eSSoby Mathew#include "../../../console/aarch32/console.S"
39*66be868eSSoby Mathew
40*66be868eSSoby Mathew	.globl	console_core_init
41*66be868eSSoby Mathew	.globl	console_core_putc
42*66be868eSSoby Mathew	.globl	console_core_getc
43*66be868eSSoby Mathew
44*66be868eSSoby Mathew
45*66be868eSSoby Mathew	/* -----------------------------------------------
46*66be868eSSoby Mathew	 * int console_core_init(uintptr_t base_addr,
47*66be868eSSoby Mathew	 * unsigned int uart_clk, unsigned int baud_rate)
48*66be868eSSoby Mathew	 * Function to initialize the console without a
49*66be868eSSoby Mathew	 * C Runtime to print debug information. This
50*66be868eSSoby Mathew	 * function will be accessed by console_init and
51*66be868eSSoby Mathew	 * crash reporting.
52*66be868eSSoby Mathew	 * In: r0 - console base address
53*66be868eSSoby Mathew	 *     r1 - Uart clock in Hz
54*66be868eSSoby Mathew	 *     r2 - Baud rate
55*66be868eSSoby Mathew	 * Out: return 1 on success else 0 on error
56*66be868eSSoby Mathew	 * Clobber list : r1, r2, r3
57*66be868eSSoby Mathew	 * -----------------------------------------------
58*66be868eSSoby Mathew	 */
59*66be868eSSoby Mathewfunc console_core_init
60*66be868eSSoby Mathew	/* Check the input base address */
61*66be868eSSoby Mathew	cmp	r0, #0
62*66be868eSSoby Mathew	beq	core_init_fail
63*66be868eSSoby Mathew#if !PL011_GENERIC_UART
64*66be868eSSoby Mathew	/* Check baud rate and uart clock for sanity */
65*66be868eSSoby Mathew	cmp	r1, #0
66*66be868eSSoby Mathew	beq	core_init_fail
67*66be868eSSoby Mathew	cmp	r2, #0
68*66be868eSSoby Mathew	beq	core_init_fail
69*66be868eSSoby Mathew	/* Disable the UART before initialization */
70*66be868eSSoby Mathew	ldr	r3, [r0, #UARTCR]
71*66be868eSSoby Mathew	bic	r3, r3, #PL011_UARTCR_UARTEN
72*66be868eSSoby Mathew	str	r3, [r0, #UARTCR]
73*66be868eSSoby Mathew	/* Program the baudrate */
74*66be868eSSoby Mathew	/* Divisor =  (Uart clock * 4) / baudrate */
75*66be868eSSoby Mathew	lsl	r1, r1, #2
76*66be868eSSoby Mathew	udiv	r2, r1, r2
77*66be868eSSoby Mathew	/* IBRD = Divisor >> 6 */
78*66be868eSSoby Mathew	lsr	r1, r2, #6
79*66be868eSSoby Mathew	/* Write the IBRD */
80*66be868eSSoby Mathew	str	r1, [r0, #UARTIBRD]
81*66be868eSSoby Mathew	/* FBRD = Divisor & 0x3F */
82*66be868eSSoby Mathew	and	r1, r2, #0x3f
83*66be868eSSoby Mathew	/* Write the FBRD */
84*66be868eSSoby Mathew	str	r1, [r0, #UARTFBRD]
85*66be868eSSoby Mathew	mov	r1, #PL011_LINE_CONTROL
86*66be868eSSoby Mathew	str	r1, [r0, #UARTLCR_H]
87*66be868eSSoby Mathew	/* Clear any pending errors */
88*66be868eSSoby Mathew	mov	r1, #0
89*66be868eSSoby Mathew	str	r1, [r0, #UARTECR]
90*66be868eSSoby Mathew	/* Enable tx, rx, and uart overall */
91*66be868eSSoby Mathew	ldr	r1, =(PL011_UARTCR_RXE | PL011_UARTCR_TXE | PL011_UARTCR_UARTEN)
92*66be868eSSoby Mathew	str	r1, [r0, #UARTCR]
93*66be868eSSoby Mathew#endif
94*66be868eSSoby Mathew	mov	r0, #1
95*66be868eSSoby Mathew	bx	lr
96*66be868eSSoby Mathewcore_init_fail:
97*66be868eSSoby Mathew	mov	r0, #0
98*66be868eSSoby Mathew	bx	lr
99*66be868eSSoby Mathewendfunc console_core_init
100*66be868eSSoby Mathew
101*66be868eSSoby Mathew	/* --------------------------------------------------------
102*66be868eSSoby Mathew	 * int console_core_putc(int c, uintptr_t base_addr)
103*66be868eSSoby Mathew	 * Function to output a character over the console. It
104*66be868eSSoby Mathew	 * returns the character printed on success or -1 on error.
105*66be868eSSoby Mathew	 * In : r0 - character to be printed
106*66be868eSSoby Mathew	 *      r1 - console base address
107*66be868eSSoby Mathew	 * Out : return -1 on error else return character.
108*66be868eSSoby Mathew	 * Clobber list : r2
109*66be868eSSoby Mathew	 * --------------------------------------------------------
110*66be868eSSoby Mathew	 */
111*66be868eSSoby Mathewfunc console_core_putc
112*66be868eSSoby Mathew	/* Check the input parameter */
113*66be868eSSoby Mathew	cmp	r1, #0
114*66be868eSSoby Mathew	beq	putc_error
115*66be868eSSoby Mathew	/* Prepend '\r' to '\n' */
116*66be868eSSoby Mathew	cmp	r0, #0xA
117*66be868eSSoby Mathew	bne	2f
118*66be868eSSoby Mathew1:
119*66be868eSSoby Mathew	/* Check if the transmit FIFO is full */
120*66be868eSSoby Mathew	ldr	r2, [r1, #UARTFR]
121*66be868eSSoby Mathew	tst	r2, #PL011_UARTFR_TXFF_BIT
122*66be868eSSoby Mathew	beq	1b
123*66be868eSSoby Mathew	mov	r2, #0xD
124*66be868eSSoby Mathew	str	r2, [r1, #UARTDR]
125*66be868eSSoby Mathew2:
126*66be868eSSoby Mathew	/* Check if the transmit FIFO is full */
127*66be868eSSoby Mathew	ldr	r2, [r1, #UARTFR]
128*66be868eSSoby Mathew	tst	r2, #PL011_UARTFR_TXFF_BIT
129*66be868eSSoby Mathew	beq	2b
130*66be868eSSoby Mathew	str	r0, [r1, #UARTDR]
131*66be868eSSoby Mathew	bx	lr
132*66be868eSSoby Mathewputc_error:
133*66be868eSSoby Mathew	mov	r0, #-1
134*66be868eSSoby Mathew	bx	lr
135*66be868eSSoby Mathewendfunc console_core_putc
136*66be868eSSoby Mathew
137*66be868eSSoby Mathew	/* ---------------------------------------------
138*66be868eSSoby Mathew	 * int console_core_getc(uintptr_t base_addr)
139*66be868eSSoby Mathew	 * Function to get a character from the console.
140*66be868eSSoby Mathew	 * It returns the character grabbed on success
141*66be868eSSoby Mathew	 * or -1 on error.
142*66be868eSSoby Mathew	 * In : r0 - console base address
143*66be868eSSoby Mathew	 * Clobber list : r0, r1
144*66be868eSSoby Mathew	 * ---------------------------------------------
145*66be868eSSoby Mathew	 */
146*66be868eSSoby Mathewfunc console_core_getc
147*66be868eSSoby Mathew	cmp	r0, #0
148*66be868eSSoby Mathew	beq	getc_error
149*66be868eSSoby Mathew1:
150*66be868eSSoby Mathew	/* Check if the receive FIFO is empty */
151*66be868eSSoby Mathew	ldr	r1, [r0, #UARTFR]
152*66be868eSSoby Mathew	tst	r1, #PL011_UARTFR_RXFE_BIT
153*66be868eSSoby Mathew	beq	1b
154*66be868eSSoby Mathew	ldr	r1, [r0, #UARTDR]
155*66be868eSSoby Mathew	mov	r0, r1
156*66be868eSSoby Mathew	bx	lr
157*66be868eSSoby Mathewgetc_error:
158*66be868eSSoby Mathew	mov	r0, #-1
159*66be868eSSoby Mathew	bx	lr
160*66be868eSSoby Mathewendfunc console_core_getc
161