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