19c94d3b3SSoby Mathew/* 2831b0e98SJimmy Brisson * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. 39c94d3b3SSoby Mathew * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 59c94d3b3SSoby Mathew */ 69c94d3b3SSoby Mathew#include <arch.h> 79c94d3b3SSoby Mathew#include <asm_macros.S> 838ba8e93SJulius Werner#include <assert_macros.S> 9cc5859caSSoby Mathew#include <console_macros.S> 1009d40e0eSAntonio Nino Diaz#include <drivers/cadence/cdns_uart.h> 119c94d3b3SSoby Mathew 1238ba8e93SJulius Werner /* 1338ba8e93SJulius Werner * "core" functions are low-level implementations that don't require 1438ba8e93SJulius Werner * writable memory and are thus safe to call in BL1 crash context. 1538ba8e93SJulius Werner */ 1638ba8e93SJulius Werner .globl console_cdns_core_init 1738ba8e93SJulius Werner .globl console_cdns_core_putc 1838ba8e93SJulius Werner .globl console_cdns_core_getc 1961d2b40dSAntonio Nino Diaz .globl console_cdns_core_flush 2038ba8e93SJulius Werner 2138ba8e93SJulius Werner .globl console_cdns_putc 2238ba8e93SJulius Werner .globl console_cdns_getc 2361d2b40dSAntonio Nino Diaz .globl console_cdns_flush 249c94d3b3SSoby Mathew 259c94d3b3SSoby Mathew /* ----------------------------------------------- 2638ba8e93SJulius Werner * int console_cdns_core_init(uintptr_t base_addr) 279c94d3b3SSoby Mathew * Function to initialize the console without a 289c94d3b3SSoby Mathew * C Runtime to print debug information. This 299c94d3b3SSoby Mathew * function will be accessed by console_init and 309c94d3b3SSoby Mathew * crash reporting. 319c94d3b3SSoby Mathew * We assume that the bootloader already set up 329c94d3b3SSoby Mathew * the HW (baud, ...) and only enable the trans- 339c94d3b3SSoby Mathew * mitter and receiver here. 349c94d3b3SSoby Mathew * In: x0 - console base address 359c94d3b3SSoby Mathew * Out: return 1 on success else 0 on error 369c94d3b3SSoby Mathew * Clobber list : x1, x2, x3 379c94d3b3SSoby Mathew * ----------------------------------------------- 389c94d3b3SSoby Mathew */ 3938ba8e93SJulius Wernerfunc console_cdns_core_init 409c94d3b3SSoby Mathew /* Check the input base address */ 419c94d3b3SSoby Mathew cbz x0, core_init_fail 429c94d3b3SSoby Mathew 439c94d3b3SSoby Mathew /* RX/TX enabled & reset */ 449c94d3b3SSoby Mathew mov w3, #(R_UART_CR_TX_EN | R_UART_CR_RX_EN | R_UART_CR_TXRST | R_UART_CR_RXRST) 459c94d3b3SSoby Mathew str w3, [x0, #R_UART_CR] 469c94d3b3SSoby Mathew 479c94d3b3SSoby Mathew mov w0, #1 489c94d3b3SSoby Mathew ret 499c94d3b3SSoby Mathewcore_init_fail: 509c94d3b3SSoby Mathew mov w0, wzr 519c94d3b3SSoby Mathew ret 5238ba8e93SJulius Wernerendfunc console_cdns_core_init 5338ba8e93SJulius Werner 5438ba8e93SJulius Werner .globl console_cdns_register 5538ba8e93SJulius Werner 5638ba8e93SJulius Werner /* ----------------------------------------------- 5723b6fa4eSAlexei Colin * int console_cdns_register(uintptr_t baseaddr, 5865199dc8SAntonio Nino Diaz * uint32_t clock, uint32_t baud, 5978b40dceSAndre Przywara * console_t *console); 6038ba8e93SJulius Werner * Function to initialize and register a new CDNS 6138ba8e93SJulius Werner * console. Storage passed in for the console struct 6238ba8e93SJulius Werner * *must* be persistent (i.e. not from the stack). 6338ba8e93SJulius Werner * In: x0 - UART register base address 6423b6fa4eSAlexei Colin * w1 - UART clock in Hz 6523b6fa4eSAlexei Colin * w2 - Baud rate 6678b40dceSAndre Przywara * x3 - pointer to empty console_t struct 6738ba8e93SJulius Werner * Out: return 1 on success, 0 on error 6838ba8e93SJulius Werner * Clobber list : x0, x1, x2, x6, x7, x14 6938ba8e93SJulius Werner * ----------------------------------------------- 7038ba8e93SJulius Werner */ 7138ba8e93SJulius Wernerfunc console_cdns_register 7238ba8e93SJulius Werner mov x7, x30 7323b6fa4eSAlexei Colin mov x6, x3 7438ba8e93SJulius Werner cbz x6, register_fail 7578b40dceSAndre Przywara str x0, [x6, #CONSOLE_T_BASE] 7638ba8e93SJulius Werner 7738ba8e93SJulius Werner bl console_cdns_core_init 7838ba8e93SJulius Werner cbz x0, register_fail 7938ba8e93SJulius Werner 8038ba8e93SJulius Werner mov x0, x6 8123b6fa4eSAlexei Colin mov x30, x7 82*85bebe18SSandrine Bailleux finish_console_register cdns putc=1, getc=ENABLE_CONSOLE_GETC, flush=1 8338ba8e93SJulius Werner 8438ba8e93SJulius Wernerregister_fail: 8538ba8e93SJulius Werner ret x7 8638ba8e93SJulius Wernerendfunc console_cdns_register 879c94d3b3SSoby Mathew 889c94d3b3SSoby Mathew /* -------------------------------------------------------- 8938ba8e93SJulius Werner * int console_cdns_core_putc(int c, uintptr_t base_addr) 909c94d3b3SSoby Mathew * Function to output a character over the console. It 919c94d3b3SSoby Mathew * returns the character printed on success or -1 on error. 929c94d3b3SSoby Mathew * In : w0 - character to be printed 939c94d3b3SSoby Mathew * x1 - console base address 949c94d3b3SSoby Mathew * Out : return -1 on error else return character. 959c94d3b3SSoby Mathew * Clobber list : x2 969c94d3b3SSoby Mathew * -------------------------------------------------------- 979c94d3b3SSoby Mathew */ 9838ba8e93SJulius Wernerfunc console_cdns_core_putc 9938ba8e93SJulius Werner#if ENABLE_ASSERTIONS 10038ba8e93SJulius Werner cmp x1, #0 10138ba8e93SJulius Werner ASM_ASSERT(ne) 10238ba8e93SJulius Werner#endif /* ENABLE_ASSERTIONS */ 10338ba8e93SJulius Werner 1049c94d3b3SSoby Mathew /* Prepend '\r' to '\n' */ 1059c94d3b3SSoby Mathew cmp w0, #0xA 1069c94d3b3SSoby Mathew b.ne 2f 1079c94d3b3SSoby Mathew1: 1080b3d4273SMichal Simek /* Check if the transmit FIFO is empty */ 1099c94d3b3SSoby Mathew ldr w2, [x1, #R_UART_SR] 1100b3d4273SMichal Simek tbz w2, #UART_SR_INTR_TEMPTY_BIT, 1b 1119c94d3b3SSoby Mathew mov w2, #0xD 1129c94d3b3SSoby Mathew str w2, [x1, #R_UART_TX] 1139c94d3b3SSoby Mathew2: 1140b3d4273SMichal Simek /* Check if the transmit FIFO is empty */ 1159c94d3b3SSoby Mathew ldr w2, [x1, #R_UART_SR] 1160b3d4273SMichal Simek tbz w2, #UART_SR_INTR_TEMPTY_BIT, 2b 1179c94d3b3SSoby Mathew str w0, [x1, #R_UART_TX] 1189c94d3b3SSoby Mathew ret 11938ba8e93SJulius Wernerendfunc console_cdns_core_putc 12038ba8e93SJulius Werner 12138ba8e93SJulius Werner /* -------------------------------------------------------- 12278b40dceSAndre Przywara * int console_cdns_putc(int c, console_t *cdns) 12338ba8e93SJulius Werner * Function to output a character over the console. It 12438ba8e93SJulius Werner * returns the character printed on success or -1 on error. 12538ba8e93SJulius Werner * In : w0 - character to be printed 12638ba8e93SJulius Werner * x1 - pointer to console_t structure 12738ba8e93SJulius Werner * Out : return -1 on error else return character. 12838ba8e93SJulius Werner * Clobber list : x2 12938ba8e93SJulius Werner * -------------------------------------------------------- 13038ba8e93SJulius Werner */ 13138ba8e93SJulius Wernerfunc console_cdns_putc 13238ba8e93SJulius Werner#if ENABLE_ASSERTIONS 13338ba8e93SJulius Werner cmp x1, #0 13438ba8e93SJulius Werner ASM_ASSERT(ne) 13538ba8e93SJulius Werner#endif /* ENABLE_ASSERTIONS */ 13678b40dceSAndre Przywara ldr x1, [x1, #CONSOLE_T_BASE] 13738ba8e93SJulius Werner b console_cdns_core_putc 13838ba8e93SJulius Wernerendfunc console_cdns_putc 1399c94d3b3SSoby Mathew 1409c94d3b3SSoby Mathew /* --------------------------------------------- 14138ba8e93SJulius Werner * int console_cdns_core_getc(uintptr_t base_addr) 1429c94d3b3SSoby Mathew * Function to get a character from the console. 1439c94d3b3SSoby Mathew * It returns the character grabbed on success 14438ba8e93SJulius Werner * or -1 if no character is available. 1459c94d3b3SSoby Mathew * In : x0 - console base address 14638ba8e93SJulius Werner * Out: w0 - character if available, else -1 1479c94d3b3SSoby Mathew * Clobber list : x0, x1 1489c94d3b3SSoby Mathew * --------------------------------------------- 1499c94d3b3SSoby Mathew */ 15038ba8e93SJulius Wernerfunc console_cdns_core_getc 15138ba8e93SJulius Werner#if ENABLE_ASSERTIONS 15238ba8e93SJulius Werner cmp x0, #0 15338ba8e93SJulius Werner ASM_ASSERT(ne) 15438ba8e93SJulius Werner#endif /* ENABLE_ASSERTIONS */ 15538ba8e93SJulius Werner 1569c94d3b3SSoby Mathew /* Check if the receive FIFO is empty */ 1579c94d3b3SSoby Mathew ldr w1, [x0, #R_UART_SR] 15838ba8e93SJulius Werner tbnz w1, #UART_SR_INTR_REMPTY_BIT, no_char 1599c94d3b3SSoby Mathew ldr w1, [x0, #R_UART_RX] 1609c94d3b3SSoby Mathew mov w0, w1 1619c94d3b3SSoby Mathew ret 16238ba8e93SJulius Wernerno_char: 16338ba8e93SJulius Werner mov w0, #ERROR_NO_PENDING_CHAR 1649c94d3b3SSoby Mathew ret 16538ba8e93SJulius Wernerendfunc console_cdns_core_getc 16638ba8e93SJulius Werner 16738ba8e93SJulius Werner /* --------------------------------------------- 16878b40dceSAndre Przywara * int console_cdns_getc(console_t *console) 16938ba8e93SJulius Werner * Function to get a character from the console. 17038ba8e93SJulius Werner * It returns the character grabbed on success 17138ba8e93SJulius Werner * or -1 if no character is available. 17238ba8e93SJulius Werner * In : x0 - pointer to console_t structure 17338ba8e93SJulius Werner * Out: w0 - character if available, else -1 17438ba8e93SJulius Werner * Clobber list : x0, x1 17538ba8e93SJulius Werner * --------------------------------------------- 17638ba8e93SJulius Werner */ 17738ba8e93SJulius Wernerfunc console_cdns_getc 17838ba8e93SJulius Werner#if ENABLE_ASSERTIONS 17938ba8e93SJulius Werner cmp x0, #0 18038ba8e93SJulius Werner ASM_ASSERT(ne) 18138ba8e93SJulius Werner#endif /* ENABLE_ASSERTIONS */ 18278b40dceSAndre Przywara ldr x0, [x0, #CONSOLE_T_BASE] 18338ba8e93SJulius Werner b console_cdns_core_getc 18438ba8e93SJulius Wernerendfunc console_cdns_getc 185ad4c2ec6SAntonio Nino Diaz 186ad4c2ec6SAntonio Nino Diaz /* --------------------------------------------- 187831b0e98SJimmy Brisson * void console_cdns_core_flush(uintptr_t base_addr) 188ad4c2ec6SAntonio Nino Diaz * Function to force a write of all buffered 189ad4c2ec6SAntonio Nino Diaz * data that hasn't been output. 190ad4c2ec6SAntonio Nino Diaz * In : x0 - console base address 191831b0e98SJimmy Brisson * Out : void 192ad4c2ec6SAntonio Nino Diaz * Clobber list : x0, x1 193ad4c2ec6SAntonio Nino Diaz * --------------------------------------------- 194ad4c2ec6SAntonio Nino Diaz */ 19561d2b40dSAntonio Nino Diazfunc console_cdns_core_flush 19661d2b40dSAntonio Nino Diaz#if ENABLE_ASSERTIONS 19761d2b40dSAntonio Nino Diaz cmp x0, #0 19861d2b40dSAntonio Nino Diaz ASM_ASSERT(ne) 19961d2b40dSAntonio Nino Diaz#endif /* ENABLE_ASSERTIONS */ 200e27bebb0SPrasad Kummari /* Loop until the transmit FIFO is empty */ 201e27bebb0SPrasad Kummaricheck_txfifo_empty: 202e27bebb0SPrasad Kummari ldr w2, [x0, #R_UART_SR] 203e27bebb0SPrasad Kummari tbz w2, #UART_SR_INTR_TEMPTY_BIT, check_txfifo_empty 204e27bebb0SPrasad Kummari /* Wait until the Transmit is Inactive */ 205e27bebb0SPrasad Kummaricheck_tx_inactive_state: 206e27bebb0SPrasad Kummari ldr w2, [x0, #R_UART_SR] 207e27bebb0SPrasad Kummari tbnz w2, #UART_SR_INTR_TACTIVE_BIT, check_tx_inactive_state 208ad4c2ec6SAntonio Nino Diaz ret 20961d2b40dSAntonio Nino Diazendfunc console_cdns_core_flush 21061d2b40dSAntonio Nino Diaz 21161d2b40dSAntonio Nino Diaz /* --------------------------------------------- 212831b0e98SJimmy Brisson * void console_cdns_flush(console_t *console) 21361d2b40dSAntonio Nino Diaz * Function to force a write of all buffered 21461d2b40dSAntonio Nino Diaz * data that hasn't been output. 21561d2b40dSAntonio Nino Diaz * In : x0 - pointer to console_t structure 216831b0e98SJimmy Brisson * Out : void. 21761d2b40dSAntonio Nino Diaz * Clobber list : x0, x1 21861d2b40dSAntonio Nino Diaz * --------------------------------------------- 21961d2b40dSAntonio Nino Diaz */ 22061d2b40dSAntonio Nino Diazfunc console_cdns_flush 22161d2b40dSAntonio Nino Diaz#if ENABLE_ASSERTIONS 22261d2b40dSAntonio Nino Diaz cmp x0, #0 22361d2b40dSAntonio Nino Diaz ASM_ASSERT(ne) 22461d2b40dSAntonio Nino Diaz#endif /* ENABLE_ASSERTIONS */ 22578b40dceSAndre Przywara ldr x0, [x0, #CONSOLE_T_BASE] 22661d2b40dSAntonio Nino Diaz b console_cdns_core_flush 22761d2b40dSAntonio Nino Diazendfunc console_cdns_flush 228