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