1b45b5bacSMarek Vasut /* 2b45b5bacSMarek Vasut * Copyright (c) 2021-2025, Renesas Electronics Corporation. All rights reserved. 3b45b5bacSMarek Vasut * 4b45b5bacSMarek Vasut * SPDX-License-Identifier: BSD-3-Clause 5b45b5bacSMarek Vasut */ 6b45b5bacSMarek Vasut 7b45b5bacSMarek Vasut #include <stddef.h> 8b45b5bacSMarek Vasut #include <stdint.h> 9b45b5bacSMarek Vasut 10b45b5bacSMarek Vasut #include <drivers/console.h> 11b45b5bacSMarek Vasut #include <lib/mmio.h> 12b45b5bacSMarek Vasut #include <lib/utils_def.h> 13b45b5bacSMarek Vasut #include "scif.h" 14b45b5bacSMarek Vasut 15b45b5bacSMarek Vasut #include "rcar_def.h" 16b45b5bacSMarek Vasut 17b45b5bacSMarek Vasut /* RST */ 18b45b5bacSMarek Vasut #define RST_BASE (0xE6160000UL + (RCAR_DOMAIN * 0x4000UL)) 19b45b5bacSMarek Vasut #define RST_MODEMR0 RST_BASE 20b45b5bacSMarek Vasut #define RST_MODEMR1 (RST_BASE + 4UL) 21b45b5bacSMarek Vasut #define RST_MODEMR0_MD31 BIT(31) 22b45b5bacSMarek Vasut #define RST_MODEMR1_MD32 BIT(0) 23b45b5bacSMarek Vasut 24b45b5bacSMarek Vasut /* SCIF/HSCIF */ 25b45b5bacSMarek Vasut #define SCIF0_BASE 0xE6E60000UL 26b45b5bacSMarek Vasut #define SCIF3_BASE 0xE6C50000UL 27b45b5bacSMarek Vasut #define HSCIF0_BASE 0xE6540000UL 28b45b5bacSMarek Vasut #define SCIF_SCFSR_TEND BIT(6) 29b45b5bacSMarek Vasut #define SCIF_SCFSR_TDFE BIT(5) 30b45b5bacSMarek Vasut #define TRANS_END_CHECK (SCIF_SCFSR_TEND | SCIF_SCFSR_TDFE) 31b45b5bacSMarek Vasut 32b45b5bacSMarek Vasut /* SCIF */ 33b45b5bacSMarek Vasut #if (RCAR_LSI == RCAR_S4) /* S4 */ 34b45b5bacSMarek Vasut #define SCIF_BASE SCIF3_BASE 35b45b5bacSMarek Vasut #else 36b45b5bacSMarek Vasut #define SCIF_BASE SCIF0_BASE 37b45b5bacSMarek Vasut #endif 38b45b5bacSMarek Vasut #define SCIF_SCFTDR (SCIF_BASE + 0x000CU) /* 8 Transmit FIFO data register */ 39b45b5bacSMarek Vasut #define SCIF_SCFSR (SCIF_BASE + 0x0010U) /* 16 Serial status register */ 40b45b5bacSMarek Vasut 41b45b5bacSMarek Vasut /* HSCIF */ 42b45b5bacSMarek Vasut #define HSCIF_BASE HSCIF0_BASE 43b45b5bacSMarek Vasut #define HSCIF_HSFTDR (HSCIF_BASE + 0x000CU) /* 8 Transmit FIFO data register */ 44b45b5bacSMarek Vasut #define HSCIF_HSFSR (HSCIF_BASE + 0x0010U) /* 16 Serial status register */ 45b45b5bacSMarek Vasut 46b45b5bacSMarek Vasut /* Mode */ 47b45b5bacSMarek Vasut #define MODEMR_SCIF_DLMODE 0U 48b45b5bacSMarek Vasut #define MODEMR_HSCIF_DLMODE_921600 1U 49b45b5bacSMarek Vasut #define MODEMR_HSCIF_DLMODE_1843200 2U 50b45b5bacSMarek Vasut #define MODEMR_HSCIF_DLMODE_3000000 3U 51b45b5bacSMarek Vasut 52*b21216f7SMarek Vasut static uint32_t rcar_putc_fsr; 53*b21216f7SMarek Vasut static uint32_t rcar_putc_tdr; 54b45b5bacSMarek Vasut 55b45b5bacSMarek Vasut static inline void scif_clrbits_16(uintptr_t addr, uint32_t clear) 56b45b5bacSMarek Vasut { 57b45b5bacSMarek Vasut mmio_write_16(addr, mmio_read_16(addr) & ~clear); 58b45b5bacSMarek Vasut } 59b45b5bacSMarek Vasut 60b45b5bacSMarek Vasut static void scif_console_trans_end_poll(uint32_t reg) 61b45b5bacSMarek Vasut { 62b45b5bacSMarek Vasut /* Check that transfer of SCIF is completed */ 63b45b5bacSMarek Vasut while ((mmio_read_16(reg) & TRANS_END_CHECK) != TRANS_END_CHECK) 64b45b5bacSMarek Vasut ; 65b45b5bacSMarek Vasut } 66b45b5bacSMarek Vasut 67*b21216f7SMarek Vasut static void scif_console_putc_common(uint8_t chr) 68b45b5bacSMarek Vasut { 69*b21216f7SMarek Vasut scif_console_trans_end_poll(rcar_putc_fsr); 70*b21216f7SMarek Vasut mmio_write_8(rcar_putc_tdr, chr); /* Transfer one character */ 71*b21216f7SMarek Vasut scif_clrbits_16(rcar_putc_fsr, TRANS_END_CHECK); /* TEND,TDFE clear */ 72*b21216f7SMarek Vasut scif_console_trans_end_poll(rcar_putc_fsr); 73b45b5bacSMarek Vasut } 74b45b5bacSMarek Vasut 75*b21216f7SMarek Vasut static void scif_console_set_regs(uint32_t fsr, uint32_t tdr) 76b45b5bacSMarek Vasut { 77*b21216f7SMarek Vasut rcar_putc_fsr = fsr; 78*b21216f7SMarek Vasut rcar_putc_tdr = tdr; 79b45b5bacSMarek Vasut } 80b45b5bacSMarek Vasut 81b45b5bacSMarek Vasut int console_rcar_init(uintptr_t base_addr, uint32_t uart_clk, 82b45b5bacSMarek Vasut uint32_t baud_rate) 83b45b5bacSMarek Vasut { 84b45b5bacSMarek Vasut uint32_t modemr; 85b45b5bacSMarek Vasut 86b45b5bacSMarek Vasut modemr = ((mmio_read_32(RST_MODEMR0) & RST_MODEMR0_MD31) >> 31U) | 87b45b5bacSMarek Vasut ((mmio_read_32(RST_MODEMR1) & RST_MODEMR1_MD32) << 1U); 88b45b5bacSMarek Vasut 89*b21216f7SMarek Vasut if (modemr == MODEMR_HSCIF_DLMODE_3000000 || 90*b21216f7SMarek Vasut modemr == MODEMR_HSCIF_DLMODE_1843200 || 91*b21216f7SMarek Vasut modemr == MODEMR_HSCIF_DLMODE_921600) { 92*b21216f7SMarek Vasut scif_console_set_regs(HSCIF_HSFSR, HSCIF_HSFTDR); 93*b21216f7SMarek Vasut } else { 94*b21216f7SMarek Vasut scif_console_set_regs(SCIF_SCFSR, SCIF_SCFTDR); 95*b21216f7SMarek Vasut } 96b45b5bacSMarek Vasut 97b45b5bacSMarek Vasut return 1; 98b45b5bacSMarek Vasut } 99b45b5bacSMarek Vasut 100b45b5bacSMarek Vasut int console_rcar_putc(int c, console_t *pconsole) 101b45b5bacSMarek Vasut { 102*b21216f7SMarek Vasut if (rcar_putc_fsr == 0 || rcar_putc_tdr == 0) 103b45b5bacSMarek Vasut return -1; 104b45b5bacSMarek Vasut 105b45b5bacSMarek Vasut if (c == '\n') /* add 'CR' before 'LF' */ 106*b21216f7SMarek Vasut scif_console_putc_common('\r'); 107b45b5bacSMarek Vasut 108*b21216f7SMarek Vasut scif_console_putc_common(c); 109b45b5bacSMarek Vasut 110b45b5bacSMarek Vasut return c; 111b45b5bacSMarek Vasut } 112b45b5bacSMarek Vasut 113b45b5bacSMarek Vasut int console_rcar_flush(console_t *pconsole) 114b45b5bacSMarek Vasut { 115b45b5bacSMarek Vasut /* Nothing to do */ 116b45b5bacSMarek Vasut return 0; 117b45b5bacSMarek Vasut } 118