1*83d290c5STom Rini /* SPDX-License-Identifier: GPL-2.0+ */ 22f964aa7SSimon Glass /* 32f964aa7SSimon Glass * Early debug UART support 42f964aa7SSimon Glass * 52f964aa7SSimon Glass * (C) Copyright 2014 Google, Inc 62f964aa7SSimon Glass * Writte by Simon Glass <sjg@chromium.org> 72f964aa7SSimon Glass */ 82f964aa7SSimon Glass 92f964aa7SSimon Glass #ifndef _DEBUG_UART_H 102f964aa7SSimon Glass #define _DEBUG_UART_H 112f964aa7SSimon Glass 122f964aa7SSimon Glass /* 132f964aa7SSimon Glass * The debug UART is intended for use very early in U-Boot to debug problems 142f964aa7SSimon Glass * when an ICE or other debug mechanism is not available. 152f964aa7SSimon Glass * 162f964aa7SSimon Glass * To use it you should: 172f964aa7SSimon Glass * - Make sure your UART supports this interface 182f964aa7SSimon Glass * - Enable CONFIG_DEBUG_UART 192f964aa7SSimon Glass * - Enable the CONFIG for your UART to tell it to provide this interface 202f964aa7SSimon Glass * (e.g. CONFIG_DEBUG_UART_NS16550) 212f964aa7SSimon Glass * - Define the required settings as needed (see below) 222f964aa7SSimon Glass * - Call debug_uart_init() before use 232f964aa7SSimon Glass * - Call printch() to output a character 242f964aa7SSimon Glass * 252f964aa7SSimon Glass * Depending on your platform it may be possible to use this UART before a 262f964aa7SSimon Glass * stack is available. 272f964aa7SSimon Glass * 282f964aa7SSimon Glass * If your UART does not support this interface you can probably add support 292f964aa7SSimon Glass * quite easily. Remember that you cannot use driver model and it is preferred 302f964aa7SSimon Glass * to use no stack. 312f964aa7SSimon Glass * 322f964aa7SSimon Glass * You must not use this UART once driver model is working and the serial 332f964aa7SSimon Glass * drivers are up and running (done in serial_init()). Otherwise the drivers 342f964aa7SSimon Glass * may conflict and you will get strange output. 352f964aa7SSimon Glass * 362f964aa7SSimon Glass * 372f964aa7SSimon Glass * To enable the debug UART in your serial driver: 382f964aa7SSimon Glass * 392f964aa7SSimon Glass * - #include <debug_uart.h> 4097b05973SSimon Glass * - Define _debug_uart_init(), trying to avoid using the stack 412f964aa7SSimon Glass * - Define _debug_uart_putc() as static inline (avoiding stack usage) 422f964aa7SSimon Glass * - Immediately afterwards, add DEBUG_UART_FUNCS to define the rest of the 432f964aa7SSimon Glass * functionality (printch(), etc.) 440e977bc1SSimon Glass * 450e977bc1SSimon Glass * If your board needs additional init for the UART to work, enable 460e977bc1SSimon Glass * CONFIG_DEBUG_UART_BOARD_INIT and write a function called 470e977bc1SSimon Glass * board_debug_uart_init() to perform that init. When debug_uart_init() is 480e977bc1SSimon Glass * called, the init will happen automatically. 492f964aa7SSimon Glass */ 502f964aa7SSimon Glass 512f964aa7SSimon Glass /** 522f964aa7SSimon Glass * debug_uart_init() - Set up the debug UART ready for use 532f964aa7SSimon Glass * 542f964aa7SSimon Glass * This sets up the UART with the correct baud rate, etc. 552f964aa7SSimon Glass * 562f964aa7SSimon Glass * Available CONFIG is: 572f964aa7SSimon Glass * 582f964aa7SSimon Glass * - CONFIG_DEBUG_UART_BASE: Base address of UART 592f964aa7SSimon Glass * - CONFIG_BAUDRATE: Requested baud rate 602f964aa7SSimon Glass * - CONFIG_DEBUG_UART_CLOCK: Input clock for UART 612f964aa7SSimon Glass */ 622f964aa7SSimon Glass void debug_uart_init(void); 632f964aa7SSimon Glass 640e977bc1SSimon Glass #ifdef CONFIG_DEBUG_UART_BOARD_INIT 650e977bc1SSimon Glass void board_debug_uart_init(void); 660e977bc1SSimon Glass #else 670e977bc1SSimon Glass static inline void board_debug_uart_init(void) 680e977bc1SSimon Glass { 690e977bc1SSimon Glass } 700e977bc1SSimon Glass #endif 710e977bc1SSimon Glass 722f964aa7SSimon Glass /** 732f964aa7SSimon Glass * printch() - Output a character to the debug UART 742f964aa7SSimon Glass * 752f964aa7SSimon Glass * @ch: Character to output 762f964aa7SSimon Glass */ 77d0d73614SSimon Glass void printch(int ch); 782f964aa7SSimon Glass 792f964aa7SSimon Glass /** 802f964aa7SSimon Glass * printascii() - Output an ASCII string to the debug UART 812f964aa7SSimon Glass * 822f964aa7SSimon Glass * @str: String to output 832f964aa7SSimon Glass */ 84d0d73614SSimon Glass void printascii(const char *str); 852f964aa7SSimon Glass 862f964aa7SSimon Glass /** 872f964aa7SSimon Glass * printhex2() - Output a 2-digit hex value 882f964aa7SSimon Glass * 892f964aa7SSimon Glass * @value: Value to output 902f964aa7SSimon Glass */ 91d0d73614SSimon Glass void printhex2(uint value); 922f964aa7SSimon Glass 932f964aa7SSimon Glass /** 942f964aa7SSimon Glass * printhex4() - Output a 4-digit hex value 952f964aa7SSimon Glass * 962f964aa7SSimon Glass * @value: Value to output 972f964aa7SSimon Glass */ 98d0d73614SSimon Glass void printhex4(uint value); 992f964aa7SSimon Glass 1002f964aa7SSimon Glass /** 1012f964aa7SSimon Glass * printhex8() - Output a 8-digit hex value 1022f964aa7SSimon Glass * 1032f964aa7SSimon Glass * @value: Value to output 1042f964aa7SSimon Glass */ 105d0d73614SSimon Glass void printhex8(uint value); 1062f964aa7SSimon Glass 107c7fefcb9SSimon Glass #ifdef CONFIG_DEBUG_UART_ANNOUNCE 108c7fefcb9SSimon Glass #define _DEBUG_UART_ANNOUNCE printascii("<debug_uart> "); 109c7fefcb9SSimon Glass #else 110c7fefcb9SSimon Glass #define _DEBUG_UART_ANNOUNCE 111c7fefcb9SSimon Glass #endif 112c7fefcb9SSimon Glass 113a52cf086SLokesh Vutla #define serial_dout(reg, value) \ 114a52cf086SLokesh Vutla serial_out_shift((char *)com_port + \ 115a52cf086SLokesh Vutla ((char *)reg - (char *)com_port) * \ 116a52cf086SLokesh Vutla (1 << CONFIG_DEBUG_UART_SHIFT), \ 117a52cf086SLokesh Vutla CONFIG_DEBUG_UART_SHIFT, value) 118a52cf086SLokesh Vutla #define serial_din(reg) \ 119a52cf086SLokesh Vutla serial_in_shift((char *)com_port + \ 120a52cf086SLokesh Vutla ((char *)reg - (char *)com_port) * \ 121a52cf086SLokesh Vutla (1 << CONFIG_DEBUG_UART_SHIFT), \ 122a52cf086SLokesh Vutla CONFIG_DEBUG_UART_SHIFT) 123a52cf086SLokesh Vutla 1242f964aa7SSimon Glass /* 1252f964aa7SSimon Glass * Now define some functions - this should be inserted into the serial driver 1262f964aa7SSimon Glass */ 1272f964aa7SSimon Glass #define DEBUG_UART_FUNCS \ 1286bacc736Stim.chick \ 1296bacc736Stim.chick static inline void _printch(int ch) \ 1302f964aa7SSimon Glass { \ 131b391d743SMasahiro Yamada if (ch == '\n') \ 132b391d743SMasahiro Yamada _debug_uart_putc('\r'); \ 1332f964aa7SSimon Glass _debug_uart_putc(ch); \ 1342f964aa7SSimon Glass } \ 1352f964aa7SSimon Glass \ 1366bacc736Stim.chick void printch(int ch) \ 1376bacc736Stim.chick { \ 1386bacc736Stim.chick _printch(ch); \ 1396bacc736Stim.chick } \ 1406bacc736Stim.chick \ 141d0d73614SSimon Glass void printascii(const char *str) \ 1422f964aa7SSimon Glass { \ 1432f964aa7SSimon Glass while (*str) \ 1446bacc736Stim.chick _printch(*str++); \ 1452f964aa7SSimon Glass } \ 1462f964aa7SSimon Glass \ 1472f964aa7SSimon Glass static inline void printhex1(uint digit) \ 1482f964aa7SSimon Glass { \ 1492f964aa7SSimon Glass digit &= 0xf; \ 1502f964aa7SSimon Glass _debug_uart_putc(digit > 9 ? digit - 10 + 'a' : digit + '0'); \ 1512f964aa7SSimon Glass } \ 1522f964aa7SSimon Glass \ 1532f964aa7SSimon Glass static inline void printhex(uint value, int digits) \ 1542f964aa7SSimon Glass { \ 1552f964aa7SSimon Glass while (digits-- > 0) \ 1562f964aa7SSimon Glass printhex1(value >> (4 * digits)); \ 1572f964aa7SSimon Glass } \ 1582f964aa7SSimon Glass \ 159d0d73614SSimon Glass void printhex2(uint value) \ 1602f964aa7SSimon Glass { \ 1612f964aa7SSimon Glass printhex(value, 2); \ 1622f964aa7SSimon Glass } \ 1632f964aa7SSimon Glass \ 164d0d73614SSimon Glass void printhex4(uint value) \ 1652f964aa7SSimon Glass { \ 1662f964aa7SSimon Glass printhex(value, 4); \ 1672f964aa7SSimon Glass } \ 1682f964aa7SSimon Glass \ 169d0d73614SSimon Glass void printhex8(uint value) \ 1702f964aa7SSimon Glass { \ 1712f964aa7SSimon Glass printhex(value, 8); \ 17297b05973SSimon Glass } \ 17397b05973SSimon Glass \ 17497b05973SSimon Glass void debug_uart_init(void) \ 17597b05973SSimon Glass { \ 1760e977bc1SSimon Glass board_debug_uart_init(); \ 17797b05973SSimon Glass _debug_uart_init(); \ 178c7fefcb9SSimon Glass _DEBUG_UART_ANNOUNCE \ 17997b05973SSimon Glass } \ 1802f964aa7SSimon Glass 1812f964aa7SSimon Glass #endif 182