xref: /rk3399_ARM-atf/drivers/renesas/common/scif/scif-common.c (revision 3c6170b649a23d60ca4dcb9d256cc3c53f90cc70)
1*3c6170b6SMarek Vasut /*
2*3c6170b6SMarek Vasut  * Copyright (c) 2021-2025, Renesas Electronics Corporation. All rights reserved.
3*3c6170b6SMarek Vasut  *
4*3c6170b6SMarek Vasut  * SPDX-License-Identifier: BSD-3-Clause
5*3c6170b6SMarek Vasut  */
6*3c6170b6SMarek Vasut 
7*3c6170b6SMarek Vasut #include <stddef.h>
8*3c6170b6SMarek Vasut #include <stdint.h>
9*3c6170b6SMarek Vasut 
10*3c6170b6SMarek Vasut #include <drivers/console.h>
11*3c6170b6SMarek Vasut #include <lib/mmio.h>
12*3c6170b6SMarek Vasut #include <lib/utils_def.h>
13*3c6170b6SMarek Vasut #include "scif.h"
14*3c6170b6SMarek Vasut 
15*3c6170b6SMarek Vasut /* SCIF/HSCIF */
16*3c6170b6SMarek Vasut #define SCIF_SCFSR_TEND		BIT(6)
17*3c6170b6SMarek Vasut #define SCIF_SCFSR_TDFE		BIT(5)
18*3c6170b6SMarek Vasut #define TRANS_END_CHECK		(SCIF_SCFSR_TEND | SCIF_SCFSR_TDFE)
19*3c6170b6SMarek Vasut 
20*3c6170b6SMarek Vasut static uint32_t rcar_putc_fsr;
21*3c6170b6SMarek Vasut static uint32_t rcar_putc_tdr;
22*3c6170b6SMarek Vasut 
23*3c6170b6SMarek Vasut static inline void scif_clrbits_16(uintptr_t addr, uint32_t clear)
24*3c6170b6SMarek Vasut {
25*3c6170b6SMarek Vasut 	mmio_write_16(addr, mmio_read_16(addr) & ~clear);
26*3c6170b6SMarek Vasut }
27*3c6170b6SMarek Vasut 
28*3c6170b6SMarek Vasut static void scif_console_trans_end_poll(uint32_t reg)
29*3c6170b6SMarek Vasut {
30*3c6170b6SMarek Vasut 	/* Check that transfer of SCIF is completed */
31*3c6170b6SMarek Vasut 	while ((mmio_read_16(reg) & TRANS_END_CHECK) != TRANS_END_CHECK)
32*3c6170b6SMarek Vasut 		;
33*3c6170b6SMarek Vasut }
34*3c6170b6SMarek Vasut 
35*3c6170b6SMarek Vasut static void scif_console_putc_common(uint8_t chr)
36*3c6170b6SMarek Vasut {
37*3c6170b6SMarek Vasut 	scif_console_trans_end_poll(rcar_putc_fsr);
38*3c6170b6SMarek Vasut 	mmio_write_8(rcar_putc_tdr, chr);	/* Transfer one character */
39*3c6170b6SMarek Vasut 	scif_clrbits_16(rcar_putc_fsr, TRANS_END_CHECK); /* TEND,TDFE clear */
40*3c6170b6SMarek Vasut 	scif_console_trans_end_poll(rcar_putc_fsr);
41*3c6170b6SMarek Vasut }
42*3c6170b6SMarek Vasut 
43*3c6170b6SMarek Vasut void scif_console_set_regs(uint32_t fsr, uint32_t tdr)
44*3c6170b6SMarek Vasut {
45*3c6170b6SMarek Vasut 	rcar_putc_fsr = fsr;
46*3c6170b6SMarek Vasut 	rcar_putc_tdr = tdr;
47*3c6170b6SMarek Vasut }
48*3c6170b6SMarek Vasut 
49*3c6170b6SMarek Vasut int console_rcar_putc(int c, console_t *pconsole)
50*3c6170b6SMarek Vasut {
51*3c6170b6SMarek Vasut 	if (rcar_putc_fsr == 0 || rcar_putc_tdr == 0)
52*3c6170b6SMarek Vasut 		return -1;
53*3c6170b6SMarek Vasut 
54*3c6170b6SMarek Vasut 	if (c == '\n')	/* add 'CR' before 'LF' */
55*3c6170b6SMarek Vasut 		scif_console_putc_common('\r');
56*3c6170b6SMarek Vasut 
57*3c6170b6SMarek Vasut 	scif_console_putc_common(c);
58*3c6170b6SMarek Vasut 
59*3c6170b6SMarek Vasut 	return c;
60*3c6170b6SMarek Vasut }
61*3c6170b6SMarek Vasut 
62*3c6170b6SMarek Vasut int console_rcar_flush(console_t *pconsole)
63*3c6170b6SMarek Vasut {
64*3c6170b6SMarek Vasut 	/* Nothing to do */
65*3c6170b6SMarek Vasut 	return 0;
66*3c6170b6SMarek Vasut }
67