xref: /rk3399_ARM-atf/drivers/marvell/uart/a3700_console.S (revision 19112b795e5040a9b0e101736864f5d404c215fe)
1*19112b79SKonstantin Porotchkin/*
2*19112b79SKonstantin Porotchkin * Copyright (C) 2016 Marvell International Ltd.
3*19112b79SKonstantin Porotchkin *
4*19112b79SKonstantin Porotchkin * SPDX-License-Identifier:	BSD-3-Clause
5*19112b79SKonstantin Porotchkin * https://spdx.org/licenses
6*19112b79SKonstantin Porotchkin */
7*19112b79SKonstantin Porotchkin
8*19112b79SKonstantin Porotchkin#include <asm_macros.S>
9*19112b79SKonstantin Porotchkin#include <a3700_console.h>
10*19112b79SKonstantin Porotchkin
11*19112b79SKonstantin Porotchkin	.globl	console_core_init
12*19112b79SKonstantin Porotchkin	.globl	console_core_putc
13*19112b79SKonstantin Porotchkin	.globl	console_core_getc
14*19112b79SKonstantin Porotchkin	.globl	console_core_flush
15*19112b79SKonstantin Porotchkin
16*19112b79SKonstantin Porotchkin	/* -----------------------------------------------
17*19112b79SKonstantin Porotchkin	 * int console_core_init(unsigned long base_addr,
18*19112b79SKonstantin Porotchkin	 * unsigned int uart_clk, unsigned int baud_rate)
19*19112b79SKonstantin Porotchkin	 * Function to initialize the console without a
20*19112b79SKonstantin Porotchkin	 * C Runtime to print debug information. This
21*19112b79SKonstantin Porotchkin	 * function will be accessed by console_init and
22*19112b79SKonstantin Porotchkin	 * crash reporting.
23*19112b79SKonstantin Porotchkin	 * In: x0 - console base address
24*19112b79SKonstantin Porotchkin	 *     w1 - Uart clock in Hz
25*19112b79SKonstantin Porotchkin	 *     w2 - Baud rate
26*19112b79SKonstantin Porotchkin	 * Out: return 1 on success
27*19112b79SKonstantin Porotchkin	 * Clobber list : x1, x2, x3
28*19112b79SKonstantin Porotchkin	 * -----------------------------------------------
29*19112b79SKonstantin Porotchkin	 */
30*19112b79SKonstantin Porotchkinfunc console_core_init
31*19112b79SKonstantin Porotchkin	/* Check the input base address */
32*19112b79SKonstantin Porotchkin	cbz	x0, init_fail
33*19112b79SKonstantin Porotchkin	/* Check baud rate and uart clock for sanity */
34*19112b79SKonstantin Porotchkin	cbz	w1, init_fail
35*19112b79SKonstantin Porotchkin	cbz	w2, init_fail
36*19112b79SKonstantin Porotchkin
37*19112b79SKonstantin Porotchkin	/* Program the baudrate */
38*19112b79SKonstantin Porotchkin	/* Divisor =  Uart clock / (16 * baudrate) */
39*19112b79SKonstantin Porotchkin	lsl	w2, w2, #4
40*19112b79SKonstantin Porotchkin	udiv	w2, w1, w2
41*19112b79SKonstantin Porotchkin	and	w2, w2, #0x3ff
42*19112b79SKonstantin Porotchkin
43*19112b79SKonstantin Porotchkin	ldr	w3, [x0, #UART_BAUD_REG]
44*19112b79SKonstantin Porotchkin	bic	w3, w3, 0x3ff
45*19112b79SKonstantin Porotchkin	orr	w3, w3, w2
46*19112b79SKonstantin Porotchkin	str	w3, [x0, #UART_BAUD_REG]/* set baud rate divisor */
47*19112b79SKonstantin Porotchkin
48*19112b79SKonstantin Porotchkin	/* Set UART to default 16X scheme */
49*19112b79SKonstantin Porotchkin	mov	w3, #0
50*19112b79SKonstantin Porotchkin	str	w3, [x0, #UART_POSSR_REG]
51*19112b79SKonstantin Porotchkin
52*19112b79SKonstantin Porotchkin	/*
53*19112b79SKonstantin Porotchkin	 * Wait for the TX FIFO to be empty. If wait for 20ms, the TX FIFO is
54*19112b79SKonstantin Porotchkin	 * still not empty, TX FIFO will reset by all means.
55*19112b79SKonstantin Porotchkin	 */
56*19112b79SKonstantin Porotchkin	mov	w1, #20				/* max time out 20ms */
57*19112b79SKonstantin Porotchkin2:
58*19112b79SKonstantin Porotchkin	/* Check whether TX FIFO is empty */
59*19112b79SKonstantin Porotchkin	ldr	w3, [x0, #UART_STATUS_REG]
60*19112b79SKonstantin Porotchkin	and	w3, w3, #UARTLSR_TXFIFOEMPTY
61*19112b79SKonstantin Porotchkin	cmp	w3, #0
62*19112b79SKonstantin Porotchkin	b.ne	4f
63*19112b79SKonstantin Porotchkin
64*19112b79SKonstantin Porotchkin	/* Delay */
65*19112b79SKonstantin Porotchkin	mov	w2, #30000
66*19112b79SKonstantin Porotchkin3:
67*19112b79SKonstantin Porotchkin	sub     w2, w2, #1
68*19112b79SKonstantin Porotchkin	cmp	w2, #0
69*19112b79SKonstantin Porotchkin	b.ne	3b
70*19112b79SKonstantin Porotchkin
71*19112b79SKonstantin Porotchkin	/* Check whether 10ms is waited */
72*19112b79SKonstantin Porotchkin	sub     w1, w1, #1
73*19112b79SKonstantin Porotchkin	cmp	w1, #0
74*19112b79SKonstantin Porotchkin	b.ne	2b
75*19112b79SKonstantin Porotchkin
76*19112b79SKonstantin Porotchkin4:
77*19112b79SKonstantin Porotchkin	/* Reset FIFO */
78*19112b79SKonstantin Porotchkin	mov	w3, #UART_CTRL_RXFIFO_RESET
79*19112b79SKonstantin Porotchkin	orr	w3, w3, #UART_CTRL_TXFIFO_RESET
80*19112b79SKonstantin Porotchkin	str	w3, [x0, #UART_CTRL_REG]
81*19112b79SKonstantin Porotchkin
82*19112b79SKonstantin Porotchkin	/* Delay */
83*19112b79SKonstantin Porotchkin	mov	w2, #2000
84*19112b79SKonstantin Porotchkin1:
85*19112b79SKonstantin Porotchkin	sub     w2, w2, #1
86*19112b79SKonstantin Porotchkin	cmp	w2, #0
87*19112b79SKonstantin Porotchkin	b.ne	1b
88*19112b79SKonstantin Porotchkin
89*19112b79SKonstantin Porotchkin	/* No Parity, 1 Stop */
90*19112b79SKonstantin Porotchkin	mov	w3, #0
91*19112b79SKonstantin Porotchkin	str	w3, [x0, #UART_CTRL_REG]
92*19112b79SKonstantin Porotchkin
93*19112b79SKonstantin Porotchkin	mov	w0, #1
94*19112b79SKonstantin Porotchkin	ret
95*19112b79SKonstantin Porotchkininit_fail:
96*19112b79SKonstantin Porotchkin	mov	w0, #0
97*19112b79SKonstantin Porotchkin	ret
98*19112b79SKonstantin Porotchkinendfunc console_core_init
99*19112b79SKonstantin Porotchkin
100*19112b79SKonstantin Porotchkin	/* --------------------------------------------------------
101*19112b79SKonstantin Porotchkin	 * int console_core_putc(int c, unsigned int base_addr)
102*19112b79SKonstantin Porotchkin	 * Function to output a character over the console. It
103*19112b79SKonstantin Porotchkin	 * returns the character printed on success or -1 on error.
104*19112b79SKonstantin Porotchkin	 * In : w0 - character to be printed
105*19112b79SKonstantin Porotchkin	 *      x1 - console base address
106*19112b79SKonstantin Porotchkin	 * Out : return -1 on error else return character.
107*19112b79SKonstantin Porotchkin	 * Clobber list : x2
108*19112b79SKonstantin Porotchkin	 * --------------------------------------------------------
109*19112b79SKonstantin Porotchkin	 */
110*19112b79SKonstantin Porotchkinfunc console_core_putc
111*19112b79SKonstantin Porotchkin	/* Check the input parameter */
112*19112b79SKonstantin Porotchkin	cbz	x1, putc_error
113*19112b79SKonstantin Porotchkin
114*19112b79SKonstantin Porotchkin	/* Prepend '\r' to '\n' */
115*19112b79SKonstantin Porotchkin	cmp	w0, #0xA
116*19112b79SKonstantin Porotchkin	b.ne	2f
117*19112b79SKonstantin Porotchkin	/* Check if the transmit FIFO is full */
118*19112b79SKonstantin Porotchkin1:	ldr	w2, [x1, #UART_STATUS_REG]
119*19112b79SKonstantin Porotchkin	and	w2, w2, #UARTLSR_TXFIFOFULL
120*19112b79SKonstantin Porotchkin	cmp	w2, #UARTLSR_TXFIFOFULL
121*19112b79SKonstantin Porotchkin	b.eq	1b
122*19112b79SKonstantin Porotchkin	mov	w2, #0xD		/* '\r' */
123*19112b79SKonstantin Porotchkin	str	w2, [x1, #UART_TX_REG]
124*19112b79SKonstantin Porotchkin
125*19112b79SKonstantin Porotchkin	/* Check if the transmit FIFO is full */
126*19112b79SKonstantin Porotchkin2:	ldr	w2, [x1, #UART_STATUS_REG]
127*19112b79SKonstantin Porotchkin	and	w2, w2, #UARTLSR_TXFIFOFULL
128*19112b79SKonstantin Porotchkin	cmp	w2, #UARTLSR_TXFIFOFULL
129*19112b79SKonstantin Porotchkin	b.eq	2b
130*19112b79SKonstantin Porotchkin	str	w0, [x1, #UART_TX_REG]
131*19112b79SKonstantin Porotchkin	ret
132*19112b79SKonstantin Porotchkinputc_error:
133*19112b79SKonstantin Porotchkin	mov	w0, #-1
134*19112b79SKonstantin Porotchkin	ret
135*19112b79SKonstantin Porotchkinendfunc console_core_putc
136*19112b79SKonstantin Porotchkin
137*19112b79SKonstantin Porotchkin	/* ---------------------------------------------
138*19112b79SKonstantin Porotchkin	 * int console_core_getc(void)
139*19112b79SKonstantin Porotchkin	 * Function to get a character from the console.
140*19112b79SKonstantin Porotchkin	 * It returns the character grabbed on success
141*19112b79SKonstantin Porotchkin	 * or -1 on error.
142*19112b79SKonstantin Porotchkin	 * In : w0 - console base address
143*19112b79SKonstantin Porotchkin	 * Out : return -1 on error else return character.
144*19112b79SKonstantin Porotchkin	 * Clobber list : x0, x1
145*19112b79SKonstantin Porotchkin	 * ---------------------------------------------
146*19112b79SKonstantin Porotchkin	 */
147*19112b79SKonstantin Porotchkinfunc console_core_getc
148*19112b79SKonstantin Porotchkin	/* Check if the receive FIFO is empty */
149*19112b79SKonstantin Porotchkin	ret
150*19112b79SKonstantin Porotchkingetc_error:
151*19112b79SKonstantin Porotchkin	mov	w0, #-1
152*19112b79SKonstantin Porotchkin	ret
153*19112b79SKonstantin Porotchkinendfunc console_core_getc
154*19112b79SKonstantin Porotchkin
155*19112b79SKonstantin Porotchkin	/* ---------------------------------------------
156*19112b79SKonstantin Porotchkin	 * int console_core_flush(uintptr_t base_addr)
157*19112b79SKonstantin Porotchkin	 * Function to force a write of all buffered
158*19112b79SKonstantin Porotchkin	 * data that hasn't been output.
159*19112b79SKonstantin Porotchkin	 * In : x0 - console base address
160*19112b79SKonstantin Porotchkin	 * Out : return -1 on error else return 0.
161*19112b79SKonstantin Porotchkin	 * Clobber list : x0, x1
162*19112b79SKonstantin Porotchkin	 * ---------------------------------------------
163*19112b79SKonstantin Porotchkin	 */
164*19112b79SKonstantin Porotchkinfunc console_core_flush
165*19112b79SKonstantin Porotchkin	/* Placeholder */
166*19112b79SKonstantin Porotchkin	mov	w0, #0
167*19112b79SKonstantin Porotchkin	ret
168*19112b79SKonstantin Porotchkinendfunc console_core_flush
169