1e5936205SVenkatesh Yadav Abbarapu /* 2238eb542SMaheedhar Bollapalli * Copyright (c) 2015-2022, Xilinx Inc. 3238eb542SMaheedhar 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 { 49238eb542SMaheedhar 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 99*d17b69dbSSaivardhan Thatikonda (void)console; 100*d17b69dbSSaivardhan Thatikonda 101e5936205SVenkatesh Yadav Abbarapu status = dcc_status_timeout(DCC_STATUS_TX); 102e5936205SVenkatesh Yadav Abbarapu if (status != 0U) { 103e5936205SVenkatesh Yadav Abbarapu return status; 104e5936205SVenkatesh Yadav Abbarapu } 105e5936205SVenkatesh Yadav Abbarapu __dcc_putchar(ch); 106e5936205SVenkatesh Yadav Abbarapu 107e5936205SVenkatesh Yadav Abbarapu return ch; 108e5936205SVenkatesh Yadav Abbarapu } 109e5936205SVenkatesh Yadav Abbarapu 11085bebe18SSandrine Bailleux #if ENABLE_CONSOLE_GETC 111e5936205SVenkatesh Yadav Abbarapu static int32_t dcc_console_getc(struct console *console) 112e5936205SVenkatesh Yadav Abbarapu { 113e5936205SVenkatesh Yadav Abbarapu unsigned int status; 114e5936205SVenkatesh Yadav Abbarapu 115e5936205SVenkatesh Yadav Abbarapu status = dcc_status_timeout(DCC_STATUS_RX); 116e5936205SVenkatesh Yadav Abbarapu if (status != 0U) { 117e5936205SVenkatesh Yadav Abbarapu return status; 118e5936205SVenkatesh Yadav Abbarapu } 119e5936205SVenkatesh Yadav Abbarapu 120e5936205SVenkatesh Yadav Abbarapu return __dcc_getchar(); 121e5936205SVenkatesh Yadav Abbarapu } 12285bebe18SSandrine Bailleux #endif 123e5936205SVenkatesh Yadav Abbarapu 124e5936205SVenkatesh Yadav Abbarapu /** 125e5936205SVenkatesh Yadav Abbarapu * dcc_console_flush() - Function to force a write of all buffered data 126e5936205SVenkatesh Yadav Abbarapu * that hasn't been output. 127e5936205SVenkatesh Yadav Abbarapu * @console Console struct 128e5936205SVenkatesh Yadav Abbarapu * 129e5936205SVenkatesh Yadav Abbarapu */ 130e5936205SVenkatesh Yadav Abbarapu static void dcc_console_flush(struct console *console) 131e5936205SVenkatesh Yadav Abbarapu { 132e5936205SVenkatesh Yadav Abbarapu unsigned int status; 133e5936205SVenkatesh Yadav Abbarapu 134*d17b69dbSSaivardhan Thatikonda (void)console; 135*d17b69dbSSaivardhan Thatikonda 136e5936205SVenkatesh Yadav Abbarapu status = dcc_status_timeout(DCC_STATUS_TX); 137e5936205SVenkatesh Yadav Abbarapu if (status != 0U) { 138e5936205SVenkatesh Yadav Abbarapu return; 139e5936205SVenkatesh Yadav Abbarapu } 140e5936205SVenkatesh Yadav Abbarapu } 141e5936205SVenkatesh Yadav Abbarapu 142e5936205SVenkatesh Yadav Abbarapu static struct dcc_console dcc_console = { 143e5936205SVenkatesh Yadav Abbarapu .console = { 144e5936205SVenkatesh Yadav Abbarapu .flags = CONSOLE_FLAG_BOOT | 145c6d9186fSMichal Simek CONSOLE_FLAG_RUNTIME | 146c6d9186fSMichal Simek CONSOLE_FLAG_CRASH, 147e5936205SVenkatesh Yadav Abbarapu .putc = dcc_console_putc, 14885bebe18SSandrine Bailleux #if ENABLE_CONSOLE_GETC 149e5936205SVenkatesh Yadav Abbarapu .getc = dcc_console_getc, 15085bebe18SSandrine Bailleux #endif 151e5936205SVenkatesh Yadav Abbarapu .flush = dcc_console_flush, 152e5936205SVenkatesh Yadav Abbarapu }, 153e5936205SVenkatesh Yadav Abbarapu }; 154e5936205SVenkatesh Yadav Abbarapu 155238eb542SMaheedhar Bollapalli int console_dcc_register(console_t *console) 156e5936205SVenkatesh Yadav Abbarapu { 157238eb542SMaheedhar Bollapalli memcpy(console, &dcc_console.console, sizeof(console_t)); 158238eb542SMaheedhar Bollapalli return console_register(console); 159e5936205SVenkatesh Yadav Abbarapu } 1600936abe9SPrasad Kummari 161238eb542SMaheedhar Bollapalli void console_dcc_unregister(console_t *console) 1620936abe9SPrasad Kummari { 163238eb542SMaheedhar Bollapalli dcc_console_flush(console); 164238eb542SMaheedhar Bollapalli (void)console_unregister(console); 1650936abe9SPrasad Kummari } 166