xref: /rk3399_ARM-atf/drivers/renesas/rcar_gen4/scif/scif.c (revision b21216f716e0ad975ed65e70735f82e05d55b5ca)
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