1*19112b79SKonstantin Porotchkin/* 2*19112b79SKonstantin Porotchkin * Copyright (C) 2016 Marvell International Ltd. 3*19112b79SKonstantin Porotchkin * 4*19112b79SKonstantin Porotchkin * SPDX-License-Identifier: BSD-3-Clause 5*19112b79SKonstantin Porotchkin * https://spdx.org/licenses 6*19112b79SKonstantin Porotchkin */ 7*19112b79SKonstantin Porotchkin 8*19112b79SKonstantin Porotchkin#include <asm_macros.S> 9*19112b79SKonstantin Porotchkin#include <a3700_console.h> 10*19112b79SKonstantin Porotchkin 11*19112b79SKonstantin Porotchkin .globl console_core_init 12*19112b79SKonstantin Porotchkin .globl console_core_putc 13*19112b79SKonstantin Porotchkin .globl console_core_getc 14*19112b79SKonstantin Porotchkin .globl console_core_flush 15*19112b79SKonstantin Porotchkin 16*19112b79SKonstantin Porotchkin /* ----------------------------------------------- 17*19112b79SKonstantin Porotchkin * int console_core_init(unsigned long base_addr, 18*19112b79SKonstantin Porotchkin * unsigned int uart_clk, unsigned int baud_rate) 19*19112b79SKonstantin Porotchkin * Function to initialize the console without a 20*19112b79SKonstantin Porotchkin * C Runtime to print debug information. This 21*19112b79SKonstantin Porotchkin * function will be accessed by console_init and 22*19112b79SKonstantin Porotchkin * crash reporting. 23*19112b79SKonstantin Porotchkin * In: x0 - console base address 24*19112b79SKonstantin Porotchkin * w1 - Uart clock in Hz 25*19112b79SKonstantin Porotchkin * w2 - Baud rate 26*19112b79SKonstantin Porotchkin * Out: return 1 on success 27*19112b79SKonstantin Porotchkin * Clobber list : x1, x2, x3 28*19112b79SKonstantin Porotchkin * ----------------------------------------------- 29*19112b79SKonstantin Porotchkin */ 30*19112b79SKonstantin Porotchkinfunc console_core_init 31*19112b79SKonstantin Porotchkin /* Check the input base address */ 32*19112b79SKonstantin Porotchkin cbz x0, init_fail 33*19112b79SKonstantin Porotchkin /* Check baud rate and uart clock for sanity */ 34*19112b79SKonstantin Porotchkin cbz w1, init_fail 35*19112b79SKonstantin Porotchkin cbz w2, init_fail 36*19112b79SKonstantin Porotchkin 37*19112b79SKonstantin Porotchkin /* Program the baudrate */ 38*19112b79SKonstantin Porotchkin /* Divisor = Uart clock / (16 * baudrate) */ 39*19112b79SKonstantin Porotchkin lsl w2, w2, #4 40*19112b79SKonstantin Porotchkin udiv w2, w1, w2 41*19112b79SKonstantin Porotchkin and w2, w2, #0x3ff 42*19112b79SKonstantin Porotchkin 43*19112b79SKonstantin Porotchkin ldr w3, [x0, #UART_BAUD_REG] 44*19112b79SKonstantin Porotchkin bic w3, w3, 0x3ff 45*19112b79SKonstantin Porotchkin orr w3, w3, w2 46*19112b79SKonstantin Porotchkin str w3, [x0, #UART_BAUD_REG]/* set baud rate divisor */ 47*19112b79SKonstantin Porotchkin 48*19112b79SKonstantin Porotchkin /* Set UART to default 16X scheme */ 49*19112b79SKonstantin Porotchkin mov w3, #0 50*19112b79SKonstantin Porotchkin str w3, [x0, #UART_POSSR_REG] 51*19112b79SKonstantin Porotchkin 52*19112b79SKonstantin Porotchkin /* 53*19112b79SKonstantin Porotchkin * Wait for the TX FIFO to be empty. If wait for 20ms, the TX FIFO is 54*19112b79SKonstantin Porotchkin * still not empty, TX FIFO will reset by all means. 55*19112b79SKonstantin Porotchkin */ 56*19112b79SKonstantin Porotchkin mov w1, #20 /* max time out 20ms */ 57*19112b79SKonstantin Porotchkin2: 58*19112b79SKonstantin Porotchkin /* Check whether TX FIFO is empty */ 59*19112b79SKonstantin Porotchkin ldr w3, [x0, #UART_STATUS_REG] 60*19112b79SKonstantin Porotchkin and w3, w3, #UARTLSR_TXFIFOEMPTY 61*19112b79SKonstantin Porotchkin cmp w3, #0 62*19112b79SKonstantin Porotchkin b.ne 4f 63*19112b79SKonstantin Porotchkin 64*19112b79SKonstantin Porotchkin /* Delay */ 65*19112b79SKonstantin Porotchkin mov w2, #30000 66*19112b79SKonstantin Porotchkin3: 67*19112b79SKonstantin Porotchkin sub w2, w2, #1 68*19112b79SKonstantin Porotchkin cmp w2, #0 69*19112b79SKonstantin Porotchkin b.ne 3b 70*19112b79SKonstantin Porotchkin 71*19112b79SKonstantin Porotchkin /* Check whether 10ms is waited */ 72*19112b79SKonstantin Porotchkin sub w1, w1, #1 73*19112b79SKonstantin Porotchkin cmp w1, #0 74*19112b79SKonstantin Porotchkin b.ne 2b 75*19112b79SKonstantin Porotchkin 76*19112b79SKonstantin Porotchkin4: 77*19112b79SKonstantin Porotchkin /* Reset FIFO */ 78*19112b79SKonstantin Porotchkin mov w3, #UART_CTRL_RXFIFO_RESET 79*19112b79SKonstantin Porotchkin orr w3, w3, #UART_CTRL_TXFIFO_RESET 80*19112b79SKonstantin Porotchkin str w3, [x0, #UART_CTRL_REG] 81*19112b79SKonstantin Porotchkin 82*19112b79SKonstantin Porotchkin /* Delay */ 83*19112b79SKonstantin Porotchkin mov w2, #2000 84*19112b79SKonstantin Porotchkin1: 85*19112b79SKonstantin Porotchkin sub w2, w2, #1 86*19112b79SKonstantin Porotchkin cmp w2, #0 87*19112b79SKonstantin Porotchkin b.ne 1b 88*19112b79SKonstantin Porotchkin 89*19112b79SKonstantin Porotchkin /* No Parity, 1 Stop */ 90*19112b79SKonstantin Porotchkin mov w3, #0 91*19112b79SKonstantin Porotchkin str w3, [x0, #UART_CTRL_REG] 92*19112b79SKonstantin Porotchkin 93*19112b79SKonstantin Porotchkin mov w0, #1 94*19112b79SKonstantin Porotchkin ret 95*19112b79SKonstantin Porotchkininit_fail: 96*19112b79SKonstantin Porotchkin mov w0, #0 97*19112b79SKonstantin Porotchkin ret 98*19112b79SKonstantin Porotchkinendfunc console_core_init 99*19112b79SKonstantin Porotchkin 100*19112b79SKonstantin Porotchkin /* -------------------------------------------------------- 101*19112b79SKonstantin Porotchkin * int console_core_putc(int c, unsigned int base_addr) 102*19112b79SKonstantin Porotchkin * Function to output a character over the console. It 103*19112b79SKonstantin Porotchkin * returns the character printed on success or -1 on error. 104*19112b79SKonstantin Porotchkin * In : w0 - character to be printed 105*19112b79SKonstantin Porotchkin * x1 - console base address 106*19112b79SKonstantin Porotchkin * Out : return -1 on error else return character. 107*19112b79SKonstantin Porotchkin * Clobber list : x2 108*19112b79SKonstantin Porotchkin * -------------------------------------------------------- 109*19112b79SKonstantin Porotchkin */ 110*19112b79SKonstantin Porotchkinfunc console_core_putc 111*19112b79SKonstantin Porotchkin /* Check the input parameter */ 112*19112b79SKonstantin Porotchkin cbz x1, putc_error 113*19112b79SKonstantin Porotchkin 114*19112b79SKonstantin Porotchkin /* Prepend '\r' to '\n' */ 115*19112b79SKonstantin Porotchkin cmp w0, #0xA 116*19112b79SKonstantin Porotchkin b.ne 2f 117*19112b79SKonstantin Porotchkin /* Check if the transmit FIFO is full */ 118*19112b79SKonstantin Porotchkin1: ldr w2, [x1, #UART_STATUS_REG] 119*19112b79SKonstantin Porotchkin and w2, w2, #UARTLSR_TXFIFOFULL 120*19112b79SKonstantin Porotchkin cmp w2, #UARTLSR_TXFIFOFULL 121*19112b79SKonstantin Porotchkin b.eq 1b 122*19112b79SKonstantin Porotchkin mov w2, #0xD /* '\r' */ 123*19112b79SKonstantin Porotchkin str w2, [x1, #UART_TX_REG] 124*19112b79SKonstantin Porotchkin 125*19112b79SKonstantin Porotchkin /* Check if the transmit FIFO is full */ 126*19112b79SKonstantin Porotchkin2: ldr w2, [x1, #UART_STATUS_REG] 127*19112b79SKonstantin Porotchkin and w2, w2, #UARTLSR_TXFIFOFULL 128*19112b79SKonstantin Porotchkin cmp w2, #UARTLSR_TXFIFOFULL 129*19112b79SKonstantin Porotchkin b.eq 2b 130*19112b79SKonstantin Porotchkin str w0, [x1, #UART_TX_REG] 131*19112b79SKonstantin Porotchkin ret 132*19112b79SKonstantin Porotchkinputc_error: 133*19112b79SKonstantin Porotchkin mov w0, #-1 134*19112b79SKonstantin Porotchkin ret 135*19112b79SKonstantin Porotchkinendfunc console_core_putc 136*19112b79SKonstantin Porotchkin 137*19112b79SKonstantin Porotchkin /* --------------------------------------------- 138*19112b79SKonstantin Porotchkin * int console_core_getc(void) 139*19112b79SKonstantin Porotchkin * Function to get a character from the console. 140*19112b79SKonstantin Porotchkin * It returns the character grabbed on success 141*19112b79SKonstantin Porotchkin * or -1 on error. 142*19112b79SKonstantin Porotchkin * In : w0 - console base address 143*19112b79SKonstantin Porotchkin * Out : return -1 on error else return character. 144*19112b79SKonstantin Porotchkin * Clobber list : x0, x1 145*19112b79SKonstantin Porotchkin * --------------------------------------------- 146*19112b79SKonstantin Porotchkin */ 147*19112b79SKonstantin Porotchkinfunc console_core_getc 148*19112b79SKonstantin Porotchkin /* Check if the receive FIFO is empty */ 149*19112b79SKonstantin Porotchkin ret 150*19112b79SKonstantin Porotchkingetc_error: 151*19112b79SKonstantin Porotchkin mov w0, #-1 152*19112b79SKonstantin Porotchkin ret 153*19112b79SKonstantin Porotchkinendfunc console_core_getc 154*19112b79SKonstantin Porotchkin 155*19112b79SKonstantin Porotchkin /* --------------------------------------------- 156*19112b79SKonstantin Porotchkin * int console_core_flush(uintptr_t base_addr) 157*19112b79SKonstantin Porotchkin * Function to force a write of all buffered 158*19112b79SKonstantin Porotchkin * data that hasn't been output. 159*19112b79SKonstantin Porotchkin * In : x0 - console base address 160*19112b79SKonstantin Porotchkin * Out : return -1 on error else return 0. 161*19112b79SKonstantin Porotchkin * Clobber list : x0, x1 162*19112b79SKonstantin Porotchkin * --------------------------------------------- 163*19112b79SKonstantin Porotchkin */ 164*19112b79SKonstantin Porotchkinfunc console_core_flush 165*19112b79SKonstantin Porotchkin /* Placeholder */ 166*19112b79SKonstantin Porotchkin mov w0, #0 167*19112b79SKonstantin Porotchkin ret 168*19112b79SKonstantin Porotchkinendfunc console_core_flush 169