1 /*
2 * Copyright (c) 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 #include "cpg_registers.h"
16 #include "rcar_def.h"
17 #include "rcar_private.h"
18
19 /* CPG */
20 #define CPG_MSTPSR2_SCIF0 BIT(7)
21 #define CPG_MSTPSR3_SCIF2 BIT(10)
22
23 /* SCIF */
24 #define SCIF0_BASE 0xE6E60000UL
25 #define SCIF2_BASE 0xE6E88000UL
26
27 /* SCIF */
28 #define SCIF_SCSMR 0x00
29 #define SCIF_SCBRR 0x04
30 #define SCIF_SCSCR 0x08
31 #define SCIF_SCFTDR 0x0C
32 #define SCIF_SCFSR 0x10
33 #define SCIF_SCFCR 0x18
34 #define SCIF_SCLSR 0x24
35
36 /* MODE pin */
37 #define MODEMR_MD12 BIT(12)
38
39 #define SCBRR_115200BPS 17
40 #define SCBRR_115200BPS_D3_SSCG 16
41 #define SCBRR_115200BPS_E3_SSCG 15
42 #define SCBRR_230400BPS 8
43
44 #define SCSCR_TE_EN BIT(5)
45 #define SCSCR_RE_EN BIT(4)
46 #define SCSCR_CKE_MASK 3
47 #define SCSCR_CKE_INT_CLK 0
48 #define SCFCR_TFRST_EN BIT(2)
49 #define SCFCR_RFRS_EN BIT(1)
50
console_renesas_init(uintptr_t base_addr,uint32_t uart_clk,uint32_t baud_rate)51 void console_renesas_init(uintptr_t base_addr, uint32_t uart_clk,
52 uint32_t baud_rate)
53 {
54 uint32_t prr = mmio_read_32(PRR);
55 uint32_t base;
56 int i;
57
58 if ((prr & PRR_PRODUCT_MASK) == PRR_PRODUCT_V3M) { /* V3M */
59 base = SCIF0_BASE;
60 /* Enable SCIF clock */
61 mstpcr_write(CPG_SMSTPCR2, CPG_MSTPSR2, CPG_MSTPSR2_SCIF0);
62 } else {
63 base = SCIF2_BASE;
64 /* Enable SCIF clock */
65 mstpcr_write(CPG_SMSTPCR3, CPG_MSTPSR3, CPG_MSTPSR3_SCIF2);
66 }
67
68 scif_console_set_regs(base + SCIF_SCFSR, base + SCIF_SCFTDR);
69
70 /* Clear bits TE and RE in SCSCR to 0 */
71 mmio_write_16(base + SCIF_SCSCR, 0);
72
73 /* Set bits TFRST and RFRST in SCFCR to 1 */
74 mmio_clrsetbits_16(base + SCIF_SCFCR,
75 SCFCR_TFRST_EN | SCFCR_RFRS_EN,
76 SCFCR_TFRST_EN | SCFCR_RFRS_EN);
77
78 /*
79 * Read flags of ER, DR, BRK, and RDF in SCFSR and those
80 * of TO and ORER in SCLSR, then clear them to 0.
81 */
82 mmio_write_16(base + SCIF_SCFSR, 0);
83 mmio_write_16(base + SCIF_SCLSR, 0);
84
85 /* Set bits CKE[1:0] in SCSCR */
86 mmio_clrsetbits_16(base + SCIF_SCSCR, SCSCR_CKE_MASK,
87 SCSCR_CKE_INT_CLK);
88
89 /* Set data transfer format in SCSMR */
90 mmio_write_16(base + SCIF_SCSMR, 0);
91
92 /* Set value in SCBRR */
93 if ((prr & (PRR_PRODUCT_MASK | PRR_CUT_MASK)) == PRR_PRODUCT_H3_CUT10) {
94 /* H3 ES 1.0 */
95 mmio_write_8(base + SCIF_SCBRR, SCBRR_230400BPS);
96 } else if (((prr & PRR_PRODUCT_MASK) == PRR_PRODUCT_D3) &&
97 (mmio_read_32(RST_MODEMR) & MODEMR_MD12)) {
98 /* D3 with SSCG(MD12) ON */
99 mmio_write_8(base + SCIF_SCBRR, SCBRR_115200BPS_D3_SSCG);
100 } else if (((prr & PRR_PRODUCT_MASK) == PRR_PRODUCT_E3) &&
101 (mmio_read_32(RST_MODEMR) & MODEMR_MD12)) {
102 /* E3 with SSCG(MD12) ON */
103 mmio_write_8(base + SCIF_SCBRR, SCBRR_115200BPS_E3_SSCG);
104 } else {
105 /* H3/M3/M3N or when SSCG(MD12) is off in E3/D3 */
106 mmio_write_8(base + SCIF_SCBRR, SCBRR_115200BPS);
107 }
108
109 /* 1-bit interval elapsed */
110 for (i = 0; i < 100; i++)
111 asm volatile("nop");
112
113 /*
114 * Set bits RTRG[1:0], TTRG[1:0], and MCE in SCFCR
115 * Clear bits FRST and RFRST to 0
116 */
117 mmio_write_16(base + SCIF_SCFCR, 0);
118
119 /* Set bits TE and RE in SCSCR to 1 */
120 mmio_clrsetbits_16(base + SCIF_SCSCR, SCSCR_TE_EN | SCSCR_RE_EN,
121 SCSCR_TE_EN | SCSCR_RE_EN);
122 }
123