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