1*9c94d3b3SSoby Mathew/* 2*9c94d3b3SSoby Mathew * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. 3*9c94d3b3SSoby Mathew * 4*9c94d3b3SSoby Mathew * Redistribution and use in source and binary forms, with or without 5*9c94d3b3SSoby Mathew * modification, are permitted provided that the following conditions are met: 6*9c94d3b3SSoby Mathew * 7*9c94d3b3SSoby Mathew * Redistributions of source code must retain the above copyright notice, this 8*9c94d3b3SSoby Mathew * list of conditions and the following disclaimer. 9*9c94d3b3SSoby Mathew * 10*9c94d3b3SSoby Mathew * Redistributions in binary form must reproduce the above copyright notice, 11*9c94d3b3SSoby Mathew * this list of conditions and the following disclaimer in the documentation 12*9c94d3b3SSoby Mathew * and/or other materials provided with the distribution. 13*9c94d3b3SSoby Mathew * 14*9c94d3b3SSoby Mathew * Neither the name of ARM nor the names of its contributors may be used 15*9c94d3b3SSoby Mathew * to endorse or promote products derived from this software without specific 16*9c94d3b3SSoby Mathew * prior written permission. 17*9c94d3b3SSoby Mathew * 18*9c94d3b3SSoby Mathew * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19*9c94d3b3SSoby Mathew * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*9c94d3b3SSoby Mathew * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*9c94d3b3SSoby Mathew * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22*9c94d3b3SSoby Mathew * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23*9c94d3b3SSoby Mathew * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24*9c94d3b3SSoby Mathew * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25*9c94d3b3SSoby Mathew * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26*9c94d3b3SSoby Mathew * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27*9c94d3b3SSoby Mathew * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28*9c94d3b3SSoby Mathew * POSSIBILITY OF SUCH DAMAGE. 29*9c94d3b3SSoby Mathew */ 30*9c94d3b3SSoby Mathew 31*9c94d3b3SSoby Mathew#include <arch.h> 32*9c94d3b3SSoby Mathew#include <asm_macros.S> 33*9c94d3b3SSoby Mathew#include <uart_16550.h> 34*9c94d3b3SSoby Mathew 35*9c94d3b3SSoby Mathew .globl console_core_init 36*9c94d3b3SSoby Mathew .globl console_core_putc 37*9c94d3b3SSoby Mathew .globl console_core_getc 38*9c94d3b3SSoby Mathew 39*9c94d3b3SSoby Mathew /* ----------------------------------------------- 40*9c94d3b3SSoby Mathew * int console_core_init(unsigned long base_addr, 41*9c94d3b3SSoby Mathew * unsigned int uart_clk, unsigned int baud_rate) 42*9c94d3b3SSoby Mathew * Function to initialize the console without a 43*9c94d3b3SSoby Mathew * C Runtime to print debug information. This 44*9c94d3b3SSoby Mathew * function will be accessed by console_init and 45*9c94d3b3SSoby Mathew * crash reporting. 46*9c94d3b3SSoby Mathew * In: x0 - console base address 47*9c94d3b3SSoby Mathew * w1 - Uart clock in Hz 48*9c94d3b3SSoby Mathew * w2 - Baud rate 49*9c94d3b3SSoby Mathew * Out: return 1 on success 50*9c94d3b3SSoby Mathew * Clobber list : x1, x2, x3 51*9c94d3b3SSoby Mathew * ----------------------------------------------- 52*9c94d3b3SSoby Mathew */ 53*9c94d3b3SSoby Mathewfunc console_core_init 54*9c94d3b3SSoby Mathew /* Check the input base address */ 55*9c94d3b3SSoby Mathew cbz x0, init_fail 56*9c94d3b3SSoby Mathew /* Check baud rate and uart clock for sanity */ 57*9c94d3b3SSoby Mathew cbz w1, init_fail 58*9c94d3b3SSoby Mathew cbz w2, init_fail 59*9c94d3b3SSoby Mathew 60*9c94d3b3SSoby Mathew /* Program the baudrate */ 61*9c94d3b3SSoby Mathew /* Divisor = Uart clock / (16 * baudrate) */ 62*9c94d3b3SSoby Mathew lsl w2, w2, #4 63*9c94d3b3SSoby Mathew udiv w2, w1, w2 64*9c94d3b3SSoby Mathew and w1, w2, #0xff /* w1 = DLL */ 65*9c94d3b3SSoby Mathew lsr w2, w2, #8 66*9c94d3b3SSoby Mathew and w2, w2, #0xff /* w2 = DLLM */ 67*9c94d3b3SSoby Mathew ldr w3, [x0, #UARTLCR] 68*9c94d3b3SSoby Mathew orr w3, w3, #UARTLCR_DLAB 69*9c94d3b3SSoby Mathew str w3, [x0, #UARTLCR] /* enable DLL, DLLM programming */ 70*9c94d3b3SSoby Mathew str w1, [x0, #UARTDLL] /* program DLL */ 71*9c94d3b3SSoby Mathew str w2, [x0, #UARTDLLM] /* program DLLM */ 72*9c94d3b3SSoby Mathew mov w2, #~UARTLCR_DLAB 73*9c94d3b3SSoby Mathew and w3, w3, w2 74*9c94d3b3SSoby Mathew str w3, [x0, #UARTLCR] /* disable DLL, DLLM programming */ 75*9c94d3b3SSoby Mathew 76*9c94d3b3SSoby Mathew /* 8n1 */ 77*9c94d3b3SSoby Mathew mov w3, #3 78*9c94d3b3SSoby Mathew str w3, [x0, #UARTLCR] 79*9c94d3b3SSoby Mathew /* no interrupt */ 80*9c94d3b3SSoby Mathew mov w3, #0 81*9c94d3b3SSoby Mathew str w3, [x0, #UARTIER] 82*9c94d3b3SSoby Mathew /* enable fifo, DMA */ 83*9c94d3b3SSoby Mathew mov w3, #(UARTFCR_FIFOEN | UARTFCR_DMAEN) 84*9c94d3b3SSoby Mathew str w3, [x0, #UARTFCR] 85*9c94d3b3SSoby Mathew /* DTR + RTS */ 86*9c94d3b3SSoby Mathew mov w3, #3 87*9c94d3b3SSoby Mathew str w3, [x0, #UARTMCR] 88*9c94d3b3SSoby Mathew mov w0, #1 89*9c94d3b3SSoby Mathewinit_fail: 90*9c94d3b3SSoby Mathew ret 91*9c94d3b3SSoby Mathewendfunc console_core_init 92*9c94d3b3SSoby Mathew 93*9c94d3b3SSoby Mathew /* -------------------------------------------------------- 94*9c94d3b3SSoby Mathew * int console_core_putc(int c, unsigned int base_addr) 95*9c94d3b3SSoby Mathew * Function to output a character over the console. It 96*9c94d3b3SSoby Mathew * returns the character printed on success or -1 on error. 97*9c94d3b3SSoby Mathew * In : w0 - character to be printed 98*9c94d3b3SSoby Mathew * x1 - console base address 99*9c94d3b3SSoby Mathew * Out : return -1 on error else return character. 100*9c94d3b3SSoby Mathew * Clobber list : x2 101*9c94d3b3SSoby Mathew * -------------------------------------------------------- 102*9c94d3b3SSoby Mathew */ 103*9c94d3b3SSoby Mathewfunc console_core_putc 104*9c94d3b3SSoby Mathew /* Check the input parameter */ 105*9c94d3b3SSoby Mathew cbz x1, putc_error 106*9c94d3b3SSoby Mathew 107*9c94d3b3SSoby Mathew /* Prepend '\r' to '\n' */ 108*9c94d3b3SSoby Mathew cmp w0, #0xA 109*9c94d3b3SSoby Mathew b.ne 2f 110*9c94d3b3SSoby Mathew /* Check if the transmit FIFO is full */ 111*9c94d3b3SSoby Mathew1: ldr w2, [x1, #UARTLSR] 112*9c94d3b3SSoby Mathew and w2, w2, #(UARTLSR_TEMT | UARTLSR_THRE) 113*9c94d3b3SSoby Mathew cmp w2, #(UARTLSR_TEMT | UARTLSR_THRE) 114*9c94d3b3SSoby Mathew b.ne 1b 115*9c94d3b3SSoby Mathew mov w2, #0xD /* '\r' */ 116*9c94d3b3SSoby Mathew str w2, [x1, #UARTTX] 117*9c94d3b3SSoby Mathew ldr w2, [x1, #UARTFCR] 118*9c94d3b3SSoby Mathew orr w2, w2, #UARTFCR_TXCLR 119*9c94d3b3SSoby Mathew str w2, [x1, #UARTFCR] 120*9c94d3b3SSoby Mathew 121*9c94d3b3SSoby Mathew /* Check if the transmit FIFO is full */ 122*9c94d3b3SSoby Mathew2: ldr w2, [x1, #UARTLSR] 123*9c94d3b3SSoby Mathew and w2, w2, #(UARTLSR_TEMT | UARTLSR_THRE) 124*9c94d3b3SSoby Mathew cmp w2, #(UARTLSR_TEMT | UARTLSR_THRE) 125*9c94d3b3SSoby Mathew b.ne 2b 126*9c94d3b3SSoby Mathew str w0, [x1, #UARTTX] 127*9c94d3b3SSoby Mathew ldr w2, [x1, #UARTFCR] 128*9c94d3b3SSoby Mathew orr w2, w2, #UARTFCR_TXCLR 129*9c94d3b3SSoby Mathew str w2, [x1, #UARTFCR] 130*9c94d3b3SSoby Mathew ret 131*9c94d3b3SSoby Mathewputc_error: 132*9c94d3b3SSoby Mathew mov w0, #-1 133*9c94d3b3SSoby Mathew ret 134*9c94d3b3SSoby Mathewendfunc console_core_putc 135*9c94d3b3SSoby Mathew 136*9c94d3b3SSoby Mathew /* --------------------------------------------- 137*9c94d3b3SSoby Mathew * int console_core_getc(void) 138*9c94d3b3SSoby Mathew * Function to get a character from the console. 139*9c94d3b3SSoby Mathew * It returns the character grabbed on success 140*9c94d3b3SSoby Mathew * or -1 on error. 141*9c94d3b3SSoby Mathew * In : w0 - console base address 142*9c94d3b3SSoby Mathew * Out : return -1 on error else return character. 143*9c94d3b3SSoby Mathew * Clobber list : x0, x1 144*9c94d3b3SSoby Mathew * --------------------------------------------- 145*9c94d3b3SSoby Mathew */ 146*9c94d3b3SSoby Mathewfunc console_core_getc 147*9c94d3b3SSoby Mathew /* Check if the receive FIFO is empty */ 148*9c94d3b3SSoby Mathew1: ldr w1, [x0, #UARTLSR] 149*9c94d3b3SSoby Mathew tbz w1, #UARTLSR_RDR, 1b 150*9c94d3b3SSoby Mathew ldr w0, [x0, #UARTRX] 151*9c94d3b3SSoby Mathew ret 152*9c94d3b3SSoby Mathewgetc_error: 153*9c94d3b3SSoby Mathew mov w0, #-1 154*9c94d3b3SSoby Mathew ret 155*9c94d3b3SSoby Mathewendfunc console_core_getc 156