xref: /rk3399_ARM-atf/drivers/arm/pl011/aarch64/pl011_console.S (revision 82cb2c1ad9897473743f08437d0a3995bed561b9)
19c94d3b3SSoby Mathew/*
273e05284SAntonio Nino Diaz * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
39c94d3b3SSoby Mathew *
4*82cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause
59c94d3b3SSoby Mathew */
69c94d3b3SSoby Mathew#include <arch.h>
79c94d3b3SSoby Mathew#include <asm_macros.S>
89c94d3b3SSoby Mathew#include <pl011.h>
99c94d3b3SSoby Mathew
109c94d3b3SSoby Mathew/*
119c94d3b3SSoby Mathew * Pull in generic functions to provide backwards compatibility for
129c94d3b3SSoby Mathew * platform makefiles
139c94d3b3SSoby Mathew */
149c94d3b3SSoby Mathew#include "../../../console/aarch64/console.S"
159c94d3b3SSoby Mathew
169c94d3b3SSoby Mathew
179c94d3b3SSoby Mathew	.globl	console_core_init
189c94d3b3SSoby Mathew	.globl	console_core_putc
199c94d3b3SSoby Mathew	.globl	console_core_getc
2073e05284SAntonio Nino Diaz	.globl	console_core_flush
219c94d3b3SSoby Mathew
229c94d3b3SSoby Mathew
239c94d3b3SSoby Mathew	/* -----------------------------------------------
249c94d3b3SSoby Mathew	 * int console_core_init(uintptr_t base_addr,
259c94d3b3SSoby Mathew	 * unsigned int uart_clk, unsigned int baud_rate)
269c94d3b3SSoby Mathew	 * Function to initialize the console without a
279c94d3b3SSoby Mathew	 * C Runtime to print debug information. This
289c94d3b3SSoby Mathew	 * function will be accessed by console_init and
299c94d3b3SSoby Mathew	 * crash reporting.
309c94d3b3SSoby Mathew	 * In: x0 - console base address
319c94d3b3SSoby Mathew	 *     w1 - Uart clock in Hz
329c94d3b3SSoby Mathew	 *     w2 - Baud rate
339c94d3b3SSoby Mathew	 * Out: return 1 on success else 0 on error
349c94d3b3SSoby Mathew	 * Clobber list : x1, x2, x3, x4
359c94d3b3SSoby Mathew	 * -----------------------------------------------
369c94d3b3SSoby Mathew	 */
379c94d3b3SSoby Mathewfunc console_core_init
389c94d3b3SSoby Mathew	/* Check the input base address */
399c94d3b3SSoby Mathew	cbz	x0, core_init_fail
409c94d3b3SSoby Mathew#if !PL011_GENERIC_UART
419c94d3b3SSoby Mathew	/* Check baud rate and uart clock for sanity */
429c94d3b3SSoby Mathew	cbz	w1, core_init_fail
439c94d3b3SSoby Mathew	cbz	w2, core_init_fail
449c94d3b3SSoby Mathew	/* Disable uart before programming */
459c94d3b3SSoby Mathew	ldr	w3, [x0, #UARTCR]
469c94d3b3SSoby Mathew	mov	w4, #PL011_UARTCR_UARTEN
479c94d3b3SSoby Mathew	bic	w3, w3, w4
489c94d3b3SSoby Mathew	str	w3, [x0, #UARTCR]
499c94d3b3SSoby Mathew	/* Program the baudrate */
509c94d3b3SSoby Mathew	/* Divisor =  (Uart clock * 4) / baudrate */
519c94d3b3SSoby Mathew	lsl	w1, w1, #2
529c94d3b3SSoby Mathew	udiv	w2, w1, w2
539c94d3b3SSoby Mathew	/* IBRD = Divisor >> 6 */
549c94d3b3SSoby Mathew	lsr	w1, w2, #6
559c94d3b3SSoby Mathew	/* Write the IBRD */
569c94d3b3SSoby Mathew	str	w1, [x0, #UARTIBRD]
579c94d3b3SSoby Mathew	/* FBRD = Divisor & 0x3F */
589c94d3b3SSoby Mathew	and	w1, w2, #0x3f
599c94d3b3SSoby Mathew	/* Write the FBRD */
609c94d3b3SSoby Mathew	str	w1, [x0, #UARTFBRD]
619c94d3b3SSoby Mathew	mov	w1, #PL011_LINE_CONTROL
629c94d3b3SSoby Mathew	str	w1, [x0, #UARTLCR_H]
639c94d3b3SSoby Mathew	/* Clear any pending errors */
649c94d3b3SSoby Mathew	str	wzr, [x0, #UARTECR]
659c94d3b3SSoby Mathew	/* Enable tx, rx, and uart overall */
669c94d3b3SSoby Mathew	mov	w1, #(PL011_UARTCR_RXE | PL011_UARTCR_TXE | PL011_UARTCR_UARTEN)
679c94d3b3SSoby Mathew	str	w1, [x0, #UARTCR]
689c94d3b3SSoby Mathew#endif
699c94d3b3SSoby Mathew	mov	w0, #1
709c94d3b3SSoby Mathew	ret
719c94d3b3SSoby Mathewcore_init_fail:
729c94d3b3SSoby Mathew	mov	w0, wzr
739c94d3b3SSoby Mathew	ret
749c94d3b3SSoby Mathewendfunc console_core_init
759c94d3b3SSoby Mathew
769c94d3b3SSoby Mathew	/* --------------------------------------------------------
779c94d3b3SSoby Mathew	 * int console_core_putc(int c, uintptr_t base_addr)
789c94d3b3SSoby Mathew	 * Function to output a character over the console. It
799c94d3b3SSoby Mathew	 * returns the character printed on success or -1 on error.
809c94d3b3SSoby Mathew	 * In : w0 - character to be printed
819c94d3b3SSoby Mathew	 *      x1 - console base address
829c94d3b3SSoby Mathew	 * Out : return -1 on error else return character.
839c94d3b3SSoby Mathew	 * Clobber list : x2
849c94d3b3SSoby Mathew	 * --------------------------------------------------------
859c94d3b3SSoby Mathew	 */
869c94d3b3SSoby Mathewfunc console_core_putc
879c94d3b3SSoby Mathew	/* Check the input parameter */
889c94d3b3SSoby Mathew	cbz	x1, putc_error
899c94d3b3SSoby Mathew	/* Prepend '\r' to '\n' */
909c94d3b3SSoby Mathew	cmp	w0, #0xA
919c94d3b3SSoby Mathew	b.ne	2f
929c94d3b3SSoby Mathew1:
939c94d3b3SSoby Mathew	/* Check if the transmit FIFO is full */
949c94d3b3SSoby Mathew	ldr	w2, [x1, #UARTFR]
959c94d3b3SSoby Mathew	tbnz	w2, #PL011_UARTFR_TXFF_BIT, 1b
969c94d3b3SSoby Mathew	mov	w2, #0xD
979c94d3b3SSoby Mathew	str	w2, [x1, #UARTDR]
989c94d3b3SSoby Mathew2:
999c94d3b3SSoby Mathew	/* Check if the transmit FIFO is full */
1009c94d3b3SSoby Mathew	ldr	w2, [x1, #UARTFR]
1019c94d3b3SSoby Mathew	tbnz	w2, #PL011_UARTFR_TXFF_BIT, 2b
1029c94d3b3SSoby Mathew	str	w0, [x1, #UARTDR]
1039c94d3b3SSoby Mathew	ret
1049c94d3b3SSoby Mathewputc_error:
1059c94d3b3SSoby Mathew	mov	w0, #-1
1069c94d3b3SSoby Mathew	ret
1079c94d3b3SSoby Mathewendfunc console_core_putc
1089c94d3b3SSoby Mathew
1099c94d3b3SSoby Mathew	/* ---------------------------------------------
1109c94d3b3SSoby Mathew	 * int console_core_getc(uintptr_t base_addr)
1119c94d3b3SSoby Mathew	 * Function to get a character from the console.
1129c94d3b3SSoby Mathew	 * It returns the character grabbed on success
1139c94d3b3SSoby Mathew	 * or -1 on error.
1149c94d3b3SSoby Mathew	 * In : x0 - console base address
1159c94d3b3SSoby Mathew	 * Clobber list : x0, x1
1169c94d3b3SSoby Mathew	 * ---------------------------------------------
1179c94d3b3SSoby Mathew	 */
1189c94d3b3SSoby Mathewfunc console_core_getc
1199c94d3b3SSoby Mathew	cbz	x0, getc_error
1209c94d3b3SSoby Mathew1:
1219c94d3b3SSoby Mathew	/* Check if the receive FIFO is empty */
1229c94d3b3SSoby Mathew	ldr	w1, [x0, #UARTFR]
1239c94d3b3SSoby Mathew	tbnz	w1, #PL011_UARTFR_RXFE_BIT, 1b
1249c94d3b3SSoby Mathew	ldr	w1, [x0, #UARTDR]
1259c94d3b3SSoby Mathew	mov	w0, w1
1269c94d3b3SSoby Mathew	ret
1279c94d3b3SSoby Mathewgetc_error:
1289c94d3b3SSoby Mathew	mov	w0, #-1
1299c94d3b3SSoby Mathew	ret
1309c94d3b3SSoby Mathewendfunc console_core_getc
13173e05284SAntonio Nino Diaz
13273e05284SAntonio Nino Diaz	/* ---------------------------------------------
13373e05284SAntonio Nino Diaz	 * int console_core_flush(uintptr_t base_addr)
13473e05284SAntonio Nino Diaz	 * Function to force a write of all buffered
13573e05284SAntonio Nino Diaz	 * data that hasn't been output.
13673e05284SAntonio Nino Diaz	 * In : x0 - console base address
13773e05284SAntonio Nino Diaz	 * Out : return -1 on error else return 0.
13873e05284SAntonio Nino Diaz	 * Clobber list : x0, x1
13973e05284SAntonio Nino Diaz	 * ---------------------------------------------
14073e05284SAntonio Nino Diaz	 */
14173e05284SAntonio Nino Diazfunc console_core_flush
14273e05284SAntonio Nino Diaz	cbz	x0, flush_error
14373e05284SAntonio Nino Diaz
14473e05284SAntonio Nino Diaz1:
14573e05284SAntonio Nino Diaz	/* Loop until the transmit FIFO is empty */
14673e05284SAntonio Nino Diaz	ldr	w1, [x0, #UARTFR]
14773e05284SAntonio Nino Diaz	tbnz	w1, #PL011_UARTFR_BUSY_BIT, 1b
14873e05284SAntonio Nino Diaz
14973e05284SAntonio Nino Diaz	mov	w0, #0
15073e05284SAntonio Nino Diaz	ret
15173e05284SAntonio Nino Diazflush_error:
15273e05284SAntonio Nino Diaz	mov	w0, #-1
15373e05284SAntonio Nino Diaz	ret
15473e05284SAntonio Nino Diazendfunc console_core_flush
155