xref: /rk3399_ARM-atf/drivers/arm/pl011/aarch32/pl011_console.S (revision 82cb2c1ad9897473743f08437d0a3995bed561b9)
166be868eSSoby Mathew/*
273e05284SAntonio Nino Diaz * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
366be868eSSoby Mathew *
4*82cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause
566be868eSSoby Mathew */
666be868eSSoby Mathew#include <arch.h>
766be868eSSoby Mathew#include <asm_macros.S>
866be868eSSoby Mathew#include <pl011.h>
966be868eSSoby Mathew
1066be868eSSoby Mathew/*
1166be868eSSoby Mathew * Pull in generic functions to provide backwards compatibility for
1266be868eSSoby Mathew * platform makefiles
1366be868eSSoby Mathew */
1466be868eSSoby Mathew#include "../../../console/aarch32/console.S"
1566be868eSSoby Mathew
1666be868eSSoby Mathew	.globl	console_core_init
1766be868eSSoby Mathew	.globl	console_core_putc
1866be868eSSoby Mathew	.globl	console_core_getc
1973e05284SAntonio Nino Diaz	.globl	console_core_flush
2066be868eSSoby Mathew
2166be868eSSoby Mathew
2266be868eSSoby Mathew	/* -----------------------------------------------
2366be868eSSoby Mathew	 * int console_core_init(uintptr_t base_addr,
2466be868eSSoby Mathew	 * unsigned int uart_clk, unsigned int baud_rate)
2566be868eSSoby Mathew	 * Function to initialize the console without a
2666be868eSSoby Mathew	 * C Runtime to print debug information. This
2766be868eSSoby Mathew	 * function will be accessed by console_init and
2866be868eSSoby Mathew	 * crash reporting.
2966be868eSSoby Mathew	 * In: r0 - console base address
3066be868eSSoby Mathew	 *     r1 - Uart clock in Hz
3166be868eSSoby Mathew	 *     r2 - Baud rate
3266be868eSSoby Mathew	 * Out: return 1 on success else 0 on error
3366be868eSSoby Mathew	 * Clobber list : r1, r2, r3
3466be868eSSoby Mathew	 * -----------------------------------------------
3566be868eSSoby Mathew	 */
3666be868eSSoby Mathewfunc console_core_init
3766be868eSSoby Mathew	/* Check the input base address */
3866be868eSSoby Mathew	cmp	r0, #0
3966be868eSSoby Mathew	beq	core_init_fail
4066be868eSSoby Mathew#if !PL011_GENERIC_UART
4166be868eSSoby Mathew	/* Check baud rate and uart clock for sanity */
4266be868eSSoby Mathew	cmp	r1, #0
4366be868eSSoby Mathew	beq	core_init_fail
4466be868eSSoby Mathew	cmp	r2, #0
4566be868eSSoby Mathew	beq	core_init_fail
4666be868eSSoby Mathew	/* Disable the UART before initialization */
4766be868eSSoby Mathew	ldr	r3, [r0, #UARTCR]
4866be868eSSoby Mathew	bic	r3, r3, #PL011_UARTCR_UARTEN
4966be868eSSoby Mathew	str	r3, [r0, #UARTCR]
5066be868eSSoby Mathew	/* Program the baudrate */
5166be868eSSoby Mathew	/* Divisor =  (Uart clock * 4) / baudrate */
5266be868eSSoby Mathew	lsl	r1, r1, #2
5366be868eSSoby Mathew	udiv	r2, r1, r2
5466be868eSSoby Mathew	/* IBRD = Divisor >> 6 */
5566be868eSSoby Mathew	lsr	r1, r2, #6
5666be868eSSoby Mathew	/* Write the IBRD */
5766be868eSSoby Mathew	str	r1, [r0, #UARTIBRD]
5866be868eSSoby Mathew	/* FBRD = Divisor & 0x3F */
5966be868eSSoby Mathew	and	r1, r2, #0x3f
6066be868eSSoby Mathew	/* Write the FBRD */
6166be868eSSoby Mathew	str	r1, [r0, #UARTFBRD]
6266be868eSSoby Mathew	mov	r1, #PL011_LINE_CONTROL
6366be868eSSoby Mathew	str	r1, [r0, #UARTLCR_H]
6466be868eSSoby Mathew	/* Clear any pending errors */
6566be868eSSoby Mathew	mov	r1, #0
6666be868eSSoby Mathew	str	r1, [r0, #UARTECR]
6766be868eSSoby Mathew	/* Enable tx, rx, and uart overall */
6866be868eSSoby Mathew	ldr	r1, =(PL011_UARTCR_RXE | PL011_UARTCR_TXE | PL011_UARTCR_UARTEN)
6966be868eSSoby Mathew	str	r1, [r0, #UARTCR]
7066be868eSSoby Mathew#endif
7166be868eSSoby Mathew	mov	r0, #1
7266be868eSSoby Mathew	bx	lr
7366be868eSSoby Mathewcore_init_fail:
7466be868eSSoby Mathew	mov	r0, #0
7566be868eSSoby Mathew	bx	lr
7666be868eSSoby Mathewendfunc console_core_init
7766be868eSSoby Mathew
7866be868eSSoby Mathew	/* --------------------------------------------------------
7966be868eSSoby Mathew	 * int console_core_putc(int c, uintptr_t base_addr)
8066be868eSSoby Mathew	 * Function to output a character over the console. It
8166be868eSSoby Mathew	 * returns the character printed on success or -1 on error.
8266be868eSSoby Mathew	 * In : r0 - character to be printed
8366be868eSSoby Mathew	 *      r1 - console base address
8466be868eSSoby Mathew	 * Out : return -1 on error else return character.
8566be868eSSoby Mathew	 * Clobber list : r2
8666be868eSSoby Mathew	 * --------------------------------------------------------
8766be868eSSoby Mathew	 */
8866be868eSSoby Mathewfunc console_core_putc
8966be868eSSoby Mathew	/* Check the input parameter */
9066be868eSSoby Mathew	cmp	r1, #0
9166be868eSSoby Mathew	beq	putc_error
9266be868eSSoby Mathew	/* Prepend '\r' to '\n' */
9366be868eSSoby Mathew	cmp	r0, #0xA
9466be868eSSoby Mathew	bne	2f
9566be868eSSoby Mathew1:
9666be868eSSoby Mathew	/* Check if the transmit FIFO is full */
9766be868eSSoby Mathew	ldr	r2, [r1, #UARTFR]
9869d59e0cSYatharth Kochar	tst	r2, #PL011_UARTFR_TXFF
9969d59e0cSYatharth Kochar	bne	1b
10066be868eSSoby Mathew	mov	r2, #0xD
10166be868eSSoby Mathew	str	r2, [r1, #UARTDR]
10266be868eSSoby Mathew2:
10366be868eSSoby Mathew	/* Check if the transmit FIFO is full */
10466be868eSSoby Mathew	ldr	r2, [r1, #UARTFR]
10569d59e0cSYatharth Kochar	tst	r2, #PL011_UARTFR_TXFF
10669d59e0cSYatharth Kochar	bne	2b
10766be868eSSoby Mathew	str	r0, [r1, #UARTDR]
10866be868eSSoby Mathew	bx	lr
10966be868eSSoby Mathewputc_error:
11066be868eSSoby Mathew	mov	r0, #-1
11166be868eSSoby Mathew	bx	lr
11266be868eSSoby Mathewendfunc console_core_putc
11366be868eSSoby Mathew
11466be868eSSoby Mathew	/* ---------------------------------------------
11566be868eSSoby Mathew	 * int console_core_getc(uintptr_t base_addr)
11666be868eSSoby Mathew	 * Function to get a character from the console.
11766be868eSSoby Mathew	 * It returns the character grabbed on success
11866be868eSSoby Mathew	 * or -1 on error.
11966be868eSSoby Mathew	 * In : r0 - console base address
12066be868eSSoby Mathew	 * Clobber list : r0, r1
12166be868eSSoby Mathew	 * ---------------------------------------------
12266be868eSSoby Mathew	 */
12366be868eSSoby Mathewfunc console_core_getc
12466be868eSSoby Mathew	cmp	r0, #0
12566be868eSSoby Mathew	beq	getc_error
12666be868eSSoby Mathew1:
12766be868eSSoby Mathew	/* Check if the receive FIFO is empty */
12866be868eSSoby Mathew	ldr	r1, [r0, #UARTFR]
12969d59e0cSYatharth Kochar	tst	r1, #PL011_UARTFR_RXFE
13069d59e0cSYatharth Kochar	bne	1b
13166be868eSSoby Mathew	ldr	r1, [r0, #UARTDR]
13266be868eSSoby Mathew	mov	r0, r1
13366be868eSSoby Mathew	bx	lr
13466be868eSSoby Mathewgetc_error:
13566be868eSSoby Mathew	mov	r0, #-1
13666be868eSSoby Mathew	bx	lr
13766be868eSSoby Mathewendfunc console_core_getc
13873e05284SAntonio Nino Diaz
13973e05284SAntonio Nino Diaz	/* ---------------------------------------------
14073e05284SAntonio Nino Diaz	 * int console_core_flush(uintptr_t base_addr)
14173e05284SAntonio Nino Diaz	 * Function to force a write of all buffered
14273e05284SAntonio Nino Diaz	 * data that hasn't been output.
14373e05284SAntonio Nino Diaz	 * In : r0 - console base address
14473e05284SAntonio Nino Diaz	 * Out : return -1 on error else return 0.
14573e05284SAntonio Nino Diaz	 * Clobber list : r0, r1
14673e05284SAntonio Nino Diaz	 * ---------------------------------------------
14773e05284SAntonio Nino Diaz	 */
14873e05284SAntonio Nino Diazfunc console_core_flush
14973e05284SAntonio Nino Diaz	cmp	r0, #0
15073e05284SAntonio Nino Diaz	beq	flush_error
15173e05284SAntonio Nino Diaz
15273e05284SAntonio Nino Diaz1:
15373e05284SAntonio Nino Diaz	/* Loop while the transmit FIFO is busy */
15473e05284SAntonio Nino Diaz	ldr	r1, [r0, #UARTFR]
15573e05284SAntonio Nino Diaz	tst	r1, #PL011_UARTFR_BUSY
15673e05284SAntonio Nino Diaz	bne	1b
15773e05284SAntonio Nino Diaz
15873e05284SAntonio Nino Diaz	mov	r0, #0
15973e05284SAntonio Nino Diaz	bx	lr
16073e05284SAntonio Nino Diazflush_error:
16173e05284SAntonio Nino Diaz	mov	r0, #-1
16273e05284SAntonio Nino Diaz	bx	lr
16373e05284SAntonio Nino Diazendfunc console_core_flush
164