19c94d3b3SSoby Mathew/* 29c94d3b3SSoby Mathew * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. 39c94d3b3SSoby Mathew * 49c94d3b3SSoby Mathew * Redistribution and use in source and binary forms, with or without 59c94d3b3SSoby Mathew * modification, are permitted provided that the following conditions are met: 69c94d3b3SSoby Mathew * 79c94d3b3SSoby Mathew * Redistributions of source code must retain the above copyright notice, this 89c94d3b3SSoby Mathew * list of conditions and the following disclaimer. 99c94d3b3SSoby Mathew * 109c94d3b3SSoby Mathew * Redistributions in binary form must reproduce the above copyright notice, 119c94d3b3SSoby Mathew * this list of conditions and the following disclaimer in the documentation 129c94d3b3SSoby Mathew * and/or other materials provided with the distribution. 139c94d3b3SSoby Mathew * 149c94d3b3SSoby Mathew * Neither the name of ARM nor the names of its contributors may be used 159c94d3b3SSoby Mathew * to endorse or promote products derived from this software without specific 169c94d3b3SSoby Mathew * prior written permission. 179c94d3b3SSoby Mathew * 189c94d3b3SSoby Mathew * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 199c94d3b3SSoby Mathew * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 209c94d3b3SSoby Mathew * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 219c94d3b3SSoby Mathew * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 229c94d3b3SSoby Mathew * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 239c94d3b3SSoby Mathew * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 249c94d3b3SSoby Mathew * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 259c94d3b3SSoby Mathew * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 269c94d3b3SSoby Mathew * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 279c94d3b3SSoby Mathew * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 289c94d3b3SSoby Mathew * POSSIBILITY OF SUCH DAMAGE. 299c94d3b3SSoby Mathew */ 309c94d3b3SSoby Mathew 319c94d3b3SSoby Mathew#include <arch.h> 329c94d3b3SSoby Mathew#include <asm_macros.S> 339c94d3b3SSoby Mathew#include <uart_16550.h> 349c94d3b3SSoby Mathew 359c94d3b3SSoby Mathew .globl console_core_init 369c94d3b3SSoby Mathew .globl console_core_putc 379c94d3b3SSoby Mathew .globl console_core_getc 389c94d3b3SSoby Mathew 399c94d3b3SSoby Mathew /* ----------------------------------------------- 409c94d3b3SSoby Mathew * int console_core_init(unsigned long base_addr, 419c94d3b3SSoby Mathew * unsigned int uart_clk, unsigned int baud_rate) 429c94d3b3SSoby Mathew * Function to initialize the console without a 439c94d3b3SSoby Mathew * C Runtime to print debug information. This 449c94d3b3SSoby Mathew * function will be accessed by console_init and 459c94d3b3SSoby Mathew * crash reporting. 469c94d3b3SSoby Mathew * In: x0 - console base address 479c94d3b3SSoby Mathew * w1 - Uart clock in Hz 489c94d3b3SSoby Mathew * w2 - Baud rate 499c94d3b3SSoby Mathew * Out: return 1 on success 509c94d3b3SSoby Mathew * Clobber list : x1, x2, x3 519c94d3b3SSoby Mathew * ----------------------------------------------- 529c94d3b3SSoby Mathew */ 539c94d3b3SSoby Mathewfunc console_core_init 549c94d3b3SSoby Mathew /* Check the input base address */ 559c94d3b3SSoby Mathew cbz x0, init_fail 569c94d3b3SSoby Mathew /* Check baud rate and uart clock for sanity */ 579c94d3b3SSoby Mathew cbz w1, init_fail 589c94d3b3SSoby Mathew cbz w2, init_fail 599c94d3b3SSoby Mathew 609c94d3b3SSoby Mathew /* Program the baudrate */ 619c94d3b3SSoby Mathew /* Divisor = Uart clock / (16 * baudrate) */ 629c94d3b3SSoby Mathew lsl w2, w2, #4 639c94d3b3SSoby Mathew udiv w2, w1, w2 649c94d3b3SSoby Mathew and w1, w2, #0xff /* w1 = DLL */ 659c94d3b3SSoby Mathew lsr w2, w2, #8 669c94d3b3SSoby Mathew and w2, w2, #0xff /* w2 = DLLM */ 679c94d3b3SSoby Mathew ldr w3, [x0, #UARTLCR] 689c94d3b3SSoby Mathew orr w3, w3, #UARTLCR_DLAB 699c94d3b3SSoby Mathew str w3, [x0, #UARTLCR] /* enable DLL, DLLM programming */ 709c94d3b3SSoby Mathew str w1, [x0, #UARTDLL] /* program DLL */ 719c94d3b3SSoby Mathew str w2, [x0, #UARTDLLM] /* program DLLM */ 729c94d3b3SSoby Mathew mov w2, #~UARTLCR_DLAB 739c94d3b3SSoby Mathew and w3, w3, w2 749c94d3b3SSoby Mathew str w3, [x0, #UARTLCR] /* disable DLL, DLLM programming */ 759c94d3b3SSoby Mathew 769c94d3b3SSoby Mathew /* 8n1 */ 779c94d3b3SSoby Mathew mov w3, #3 789c94d3b3SSoby Mathew str w3, [x0, #UARTLCR] 799c94d3b3SSoby Mathew /* no interrupt */ 809c94d3b3SSoby Mathew mov w3, #0 819c94d3b3SSoby Mathew str w3, [x0, #UARTIER] 829c94d3b3SSoby Mathew /* enable fifo, DMA */ 839c94d3b3SSoby Mathew mov w3, #(UARTFCR_FIFOEN | UARTFCR_DMAEN) 849c94d3b3SSoby Mathew str w3, [x0, #UARTFCR] 859c94d3b3SSoby Mathew /* DTR + RTS */ 869c94d3b3SSoby Mathew mov w3, #3 879c94d3b3SSoby Mathew str w3, [x0, #UARTMCR] 889c94d3b3SSoby Mathew mov w0, #1 899c94d3b3SSoby Mathewinit_fail: 909c94d3b3SSoby Mathew ret 919c94d3b3SSoby Mathewendfunc console_core_init 929c94d3b3SSoby Mathew 939c94d3b3SSoby Mathew /* -------------------------------------------------------- 949c94d3b3SSoby Mathew * int console_core_putc(int c, unsigned int base_addr) 959c94d3b3SSoby Mathew * Function to output a character over the console. It 969c94d3b3SSoby Mathew * returns the character printed on success or -1 on error. 979c94d3b3SSoby Mathew * In : w0 - character to be printed 989c94d3b3SSoby Mathew * x1 - console base address 999c94d3b3SSoby Mathew * Out : return -1 on error else return character. 1009c94d3b3SSoby Mathew * Clobber list : x2 1019c94d3b3SSoby Mathew * -------------------------------------------------------- 1029c94d3b3SSoby Mathew */ 1039c94d3b3SSoby Mathewfunc console_core_putc 1049c94d3b3SSoby Mathew /* Check the input parameter */ 1059c94d3b3SSoby Mathew cbz x1, putc_error 1069c94d3b3SSoby Mathew 1079c94d3b3SSoby Mathew /* Prepend '\r' to '\n' */ 1089c94d3b3SSoby Mathew cmp w0, #0xA 1099c94d3b3SSoby Mathew b.ne 2f 1109c94d3b3SSoby Mathew /* Check if the transmit FIFO is full */ 1119c94d3b3SSoby Mathew1: ldr w2, [x1, #UARTLSR] 1129c94d3b3SSoby Mathew and w2, w2, #(UARTLSR_TEMT | UARTLSR_THRE) 1139c94d3b3SSoby Mathew cmp w2, #(UARTLSR_TEMT | UARTLSR_THRE) 1149c94d3b3SSoby Mathew b.ne 1b 1159c94d3b3SSoby Mathew mov w2, #0xD /* '\r' */ 1169c94d3b3SSoby Mathew str w2, [x1, #UARTTX] 1179c94d3b3SSoby Mathew ldr w2, [x1, #UARTFCR] 1189c94d3b3SSoby Mathew orr w2, w2, #UARTFCR_TXCLR 1199c94d3b3SSoby Mathew str w2, [x1, #UARTFCR] 1209c94d3b3SSoby Mathew 1219c94d3b3SSoby Mathew /* Check if the transmit FIFO is full */ 1229c94d3b3SSoby Mathew2: ldr w2, [x1, #UARTLSR] 1239c94d3b3SSoby Mathew and w2, w2, #(UARTLSR_TEMT | UARTLSR_THRE) 1249c94d3b3SSoby Mathew cmp w2, #(UARTLSR_TEMT | UARTLSR_THRE) 1259c94d3b3SSoby Mathew b.ne 2b 1269c94d3b3SSoby Mathew str w0, [x1, #UARTTX] 1279c94d3b3SSoby Mathew ldr w2, [x1, #UARTFCR] 1289c94d3b3SSoby Mathew orr w2, w2, #UARTFCR_TXCLR 1299c94d3b3SSoby Mathew str w2, [x1, #UARTFCR] 1309c94d3b3SSoby Mathew ret 1319c94d3b3SSoby Mathewputc_error: 1329c94d3b3SSoby Mathew mov w0, #-1 1339c94d3b3SSoby Mathew ret 1349c94d3b3SSoby Mathewendfunc console_core_putc 1359c94d3b3SSoby Mathew 1369c94d3b3SSoby Mathew /* --------------------------------------------- 1379c94d3b3SSoby Mathew * int console_core_getc(void) 1389c94d3b3SSoby Mathew * Function to get a character from the console. 1399c94d3b3SSoby Mathew * It returns the character grabbed on success 1409c94d3b3SSoby Mathew * or -1 on error. 1419c94d3b3SSoby Mathew * In : w0 - console base address 1429c94d3b3SSoby Mathew * Out : return -1 on error else return character. 1439c94d3b3SSoby Mathew * Clobber list : x0, x1 1449c94d3b3SSoby Mathew * --------------------------------------------- 1459c94d3b3SSoby Mathew */ 1469c94d3b3SSoby Mathewfunc console_core_getc 1479c94d3b3SSoby Mathew /* Check if the receive FIFO is empty */ 1489c94d3b3SSoby Mathew1: ldr w1, [x0, #UARTLSR] 149*861ac52aSNishanth Menon tbz w1, #UARTLSR_RDR_BIT, 1b 1509c94d3b3SSoby Mathew ldr w0, [x0, #UARTRX] 1519c94d3b3SSoby Mathew ret 1529c94d3b3SSoby Mathewgetc_error: 1539c94d3b3SSoby Mathew mov w0, #-1 1549c94d3b3SSoby Mathew ret 1559c94d3b3SSoby Mathewendfunc console_core_getc 156