1e5936205SVenkatesh Yadav Abbarapu /* 2*238eb542SMaheedhar Bollapalli * Copyright (c) 2015-2022, Xilinx Inc. 3*238eb542SMaheedhar Bollapalli * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved. 4e5936205SVenkatesh Yadav Abbarapu * Written by Michal Simek. 5e5936205SVenkatesh Yadav Abbarapu * 6e5936205SVenkatesh Yadav Abbarapu * SPDX-License-Identifier: BSD-3-Clause 7e5936205SVenkatesh Yadav Abbarapu * 8e5936205SVenkatesh Yadav Abbarapu * Redistribution and use in source and binary forms, with or without 9e5936205SVenkatesh Yadav Abbarapu * modification, are permitted provided that the following conditions are met: 10e5936205SVenkatesh Yadav Abbarapu * 11e5936205SVenkatesh Yadav Abbarapu * Redistributions of source code must retain the above copyright notice, this 12e5936205SVenkatesh Yadav Abbarapu * list of conditions and the following disclaimer. 13e5936205SVenkatesh Yadav Abbarapu * 14e5936205SVenkatesh Yadav Abbarapu * Redistributions in binary form must reproduce the above copyright notice, 15e5936205SVenkatesh Yadav Abbarapu * this list of conditions and the following disclaimer in the documentation 16e5936205SVenkatesh Yadav Abbarapu * and/or other materials provided with the distribution. 17e5936205SVenkatesh Yadav Abbarapu * 18e5936205SVenkatesh Yadav Abbarapu * Neither the name of ARM nor the names of its contributors may be used 19e5936205SVenkatesh Yadav Abbarapu * to endorse or promote products derived from this software without specific 20e5936205SVenkatesh Yadav Abbarapu * prior written permission. 21e5936205SVenkatesh Yadav Abbarapu * 22e5936205SVenkatesh Yadav Abbarapu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23e5936205SVenkatesh Yadav Abbarapu * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24e5936205SVenkatesh Yadav Abbarapu * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25e5936205SVenkatesh Yadav Abbarapu * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 26e5936205SVenkatesh Yadav Abbarapu * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27e5936205SVenkatesh Yadav Abbarapu * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28e5936205SVenkatesh Yadav Abbarapu * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29e5936205SVenkatesh Yadav Abbarapu * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30e5936205SVenkatesh Yadav Abbarapu * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31e5936205SVenkatesh Yadav Abbarapu * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32e5936205SVenkatesh Yadav Abbarapu * POSSIBILITY OF SUCH DAMAGE. 33e5936205SVenkatesh Yadav Abbarapu */ 34e5936205SVenkatesh Yadav Abbarapu 35e5936205SVenkatesh Yadav Abbarapu #include <errno.h> 36e5936205SVenkatesh Yadav Abbarapu #include <stddef.h> 37e5936205SVenkatesh Yadav Abbarapu #include <arch_helpers.h> 38e5936205SVenkatesh Yadav Abbarapu #include <drivers/arm/dcc.h> 39e5936205SVenkatesh Yadav Abbarapu #include <drivers/console.h> 40e5936205SVenkatesh Yadav Abbarapu #include <drivers/delay_timer.h> 41e5936205SVenkatesh Yadav Abbarapu #include <lib/mmio.h> 42e5936205SVenkatesh Yadav Abbarapu 43e5936205SVenkatesh Yadav Abbarapu /* DCC Status Bits */ 44e5936205SVenkatesh Yadav Abbarapu #define DCC_STATUS_RX BIT(30) 45e5936205SVenkatesh Yadav Abbarapu #define DCC_STATUS_TX BIT(29) 46e5936205SVenkatesh Yadav Abbarapu #define TIMEOUT_COUNT_US U(0x10624) 47e5936205SVenkatesh Yadav Abbarapu 48e5936205SVenkatesh Yadav Abbarapu struct dcc_console { 49*238eb542SMaheedhar Bollapalli console_t console; 50e5936205SVenkatesh Yadav Abbarapu }; 51e5936205SVenkatesh Yadav Abbarapu 52e5936205SVenkatesh Yadav Abbarapu static inline uint32_t __dcc_getstatus(void) 53e5936205SVenkatesh Yadav Abbarapu { 54e5936205SVenkatesh Yadav Abbarapu return read_mdccsr_el0(); 55e5936205SVenkatesh Yadav Abbarapu } 56e5936205SVenkatesh Yadav Abbarapu 5785bebe18SSandrine Bailleux #if ENABLE_CONSOLE_GETC 58e5936205SVenkatesh Yadav Abbarapu static inline char __dcc_getchar(void) 59e5936205SVenkatesh Yadav Abbarapu { 60e5936205SVenkatesh Yadav Abbarapu char c; 61e5936205SVenkatesh Yadav Abbarapu 62e5936205SVenkatesh Yadav Abbarapu c = read_dbgdtrrx_el0(); 63e5936205SVenkatesh Yadav Abbarapu 64e5936205SVenkatesh Yadav Abbarapu return c; 65e5936205SVenkatesh Yadav Abbarapu } 6685bebe18SSandrine Bailleux #endif 67e5936205SVenkatesh Yadav Abbarapu 68e5936205SVenkatesh Yadav Abbarapu static inline void __dcc_putchar(char c) 69e5936205SVenkatesh Yadav Abbarapu { 70e5936205SVenkatesh Yadav Abbarapu /* 71e5936205SVenkatesh Yadav Abbarapu * The typecast is to make absolutely certain that 'c' is 72e5936205SVenkatesh Yadav Abbarapu * zero-extended. 73e5936205SVenkatesh Yadav Abbarapu */ 74e5936205SVenkatesh Yadav Abbarapu write_dbgdtrtx_el0((unsigned char)c); 75e5936205SVenkatesh Yadav Abbarapu } 76e5936205SVenkatesh Yadav Abbarapu 77e5936205SVenkatesh Yadav Abbarapu static int32_t dcc_status_timeout(uint32_t mask) 78e5936205SVenkatesh Yadav Abbarapu { 79e5936205SVenkatesh Yadav Abbarapu const unsigned int timeout_count = TIMEOUT_COUNT_US; 80e5936205SVenkatesh Yadav Abbarapu uint64_t timeout; 81e5936205SVenkatesh Yadav Abbarapu unsigned int status; 82e5936205SVenkatesh Yadav Abbarapu 83e5936205SVenkatesh Yadav Abbarapu timeout = timeout_init_us(timeout_count); 84e5936205SVenkatesh Yadav Abbarapu 85e5936205SVenkatesh Yadav Abbarapu do { 86e5936205SVenkatesh Yadav Abbarapu status = (__dcc_getstatus() & mask); 87e5936205SVenkatesh Yadav Abbarapu if (timeout_elapsed(timeout)) { 88e5936205SVenkatesh Yadav Abbarapu return -ETIMEDOUT; 89e5936205SVenkatesh Yadav Abbarapu } 90e5936205SVenkatesh Yadav Abbarapu } while ((status != 0U)); 91e5936205SVenkatesh Yadav Abbarapu 92e5936205SVenkatesh Yadav Abbarapu return 0; 93e5936205SVenkatesh Yadav Abbarapu } 94e5936205SVenkatesh Yadav Abbarapu 95e5936205SVenkatesh Yadav Abbarapu static int32_t dcc_console_putc(int32_t ch, struct console *console) 96e5936205SVenkatesh Yadav Abbarapu { 97e5936205SVenkatesh Yadav Abbarapu unsigned int status; 98e5936205SVenkatesh Yadav Abbarapu 99e5936205SVenkatesh Yadav Abbarapu status = dcc_status_timeout(DCC_STATUS_TX); 100e5936205SVenkatesh Yadav Abbarapu if (status != 0U) { 101e5936205SVenkatesh Yadav Abbarapu return status; 102e5936205SVenkatesh Yadav Abbarapu } 103e5936205SVenkatesh Yadav Abbarapu __dcc_putchar(ch); 104e5936205SVenkatesh Yadav Abbarapu 105e5936205SVenkatesh Yadav Abbarapu return ch; 106e5936205SVenkatesh Yadav Abbarapu } 107e5936205SVenkatesh Yadav Abbarapu 10885bebe18SSandrine Bailleux #if ENABLE_CONSOLE_GETC 109e5936205SVenkatesh Yadav Abbarapu static int32_t dcc_console_getc(struct console *console) 110e5936205SVenkatesh Yadav Abbarapu { 111e5936205SVenkatesh Yadav Abbarapu unsigned int status; 112e5936205SVenkatesh Yadav Abbarapu 113e5936205SVenkatesh Yadav Abbarapu status = dcc_status_timeout(DCC_STATUS_RX); 114e5936205SVenkatesh Yadav Abbarapu if (status != 0U) { 115e5936205SVenkatesh Yadav Abbarapu return status; 116e5936205SVenkatesh Yadav Abbarapu } 117e5936205SVenkatesh Yadav Abbarapu 118e5936205SVenkatesh Yadav Abbarapu return __dcc_getchar(); 119e5936205SVenkatesh Yadav Abbarapu } 12085bebe18SSandrine Bailleux #endif 121e5936205SVenkatesh Yadav Abbarapu 122e5936205SVenkatesh Yadav Abbarapu /** 123e5936205SVenkatesh Yadav Abbarapu * dcc_console_flush() - Function to force a write of all buffered data 124e5936205SVenkatesh Yadav Abbarapu * that hasn't been output. 125e5936205SVenkatesh Yadav Abbarapu * @console Console struct 126e5936205SVenkatesh Yadav Abbarapu * 127e5936205SVenkatesh Yadav Abbarapu */ 128e5936205SVenkatesh Yadav Abbarapu static void dcc_console_flush(struct console *console) 129e5936205SVenkatesh Yadav Abbarapu { 130e5936205SVenkatesh Yadav Abbarapu unsigned int status; 131e5936205SVenkatesh Yadav Abbarapu 132e5936205SVenkatesh Yadav Abbarapu status = dcc_status_timeout(DCC_STATUS_TX); 133e5936205SVenkatesh Yadav Abbarapu if (status != 0U) { 134e5936205SVenkatesh Yadav Abbarapu return; 135e5936205SVenkatesh Yadav Abbarapu } 136e5936205SVenkatesh Yadav Abbarapu } 137e5936205SVenkatesh Yadav Abbarapu 138e5936205SVenkatesh Yadav Abbarapu static struct dcc_console dcc_console = { 139e5936205SVenkatesh Yadav Abbarapu .console = { 140e5936205SVenkatesh Yadav Abbarapu .flags = CONSOLE_FLAG_BOOT | 141c6d9186fSMichal Simek CONSOLE_FLAG_RUNTIME | 142c6d9186fSMichal Simek CONSOLE_FLAG_CRASH, 143e5936205SVenkatesh Yadav Abbarapu .putc = dcc_console_putc, 14485bebe18SSandrine Bailleux #if ENABLE_CONSOLE_GETC 145e5936205SVenkatesh Yadav Abbarapu .getc = dcc_console_getc, 14685bebe18SSandrine Bailleux #endif 147e5936205SVenkatesh Yadav Abbarapu .flush = dcc_console_flush, 148e5936205SVenkatesh Yadav Abbarapu }, 149e5936205SVenkatesh Yadav Abbarapu }; 150e5936205SVenkatesh Yadav Abbarapu 151*238eb542SMaheedhar Bollapalli int console_dcc_register(console_t *console) 152e5936205SVenkatesh Yadav Abbarapu { 153*238eb542SMaheedhar Bollapalli memcpy(console, &dcc_console.console, sizeof(console_t)); 154*238eb542SMaheedhar Bollapalli return console_register(console); 155e5936205SVenkatesh Yadav Abbarapu } 1560936abe9SPrasad Kummari 157*238eb542SMaheedhar Bollapalli void console_dcc_unregister(console_t *console) 1580936abe9SPrasad Kummari { 159*238eb542SMaheedhar Bollapalli dcc_console_flush(console); 160*238eb542SMaheedhar Bollapalli (void)console_unregister(console); 1610936abe9SPrasad Kummari } 162