blob: beb8dd83834aa4372c65d1a229cfd7f3f8bb9527 [file] [log] [blame]
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +02001/*
Biju Das42861e82020-12-13 20:10:32 +00002 * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +02003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch.h>
8#include <asm_macros.S>
Marek Vasut0aa268e2019-05-18 19:29:16 +02009#include <console_macros.S>
10#include <drivers/renesas/rcar/console/console.h>
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +020011
Biju Das42861e82020-12-13 20:10:32 +000012#define SCIF_INTERNAL_CLK 0
13#define SCIF_EXTARNAL_CLK 1
14#define SCIF_CLK SCIF_INTERNAL_CLK
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +020015
16/* product register */
Biju Das42861e82020-12-13 20:10:32 +000017#define PRR (0xFFF00044)
18#define PRR_PRODUCT_MASK (0x00007F00)
19#define PRR_CUT_MASK (0x000000FF)
20#define PRR_PRODUCT_H3_VER_10 (0x00004F00)
21#define PRR_PRODUCT_E3 (0x00005700)
22#define PRR_PRODUCT_D3 (0x00005800)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +020023
24/* module stop */
Biju Das42861e82020-12-13 20:10:32 +000025#define CPG_BASE (0xE6150000)
26#define CPG_SMSTPCR2 (0x0138)
27#define CPG_SMSTPCR3 (0x013C)
Valentine Barshakf2184142018-10-30 02:06:17 +030028#define CPG_MSTPSR2 (0x0040)
Biju Das42861e82020-12-13 20:10:32 +000029#define CPG_MSTPSR3 (0x0048)
30#define MSTP207 (1 << 7)
31#define MSTP310 (1 << 10)
32#define CPG_CPGWPR (0x0900)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +020033
34/* scif */
Biju Das42861e82020-12-13 20:10:32 +000035#define SCIF0_BASE (0xE6E60000)
36#define SCIF2_BASE (0xE6E88000)
37#define SCIF_SCSMR (0x00)
38#define SCIF_SCBRR (0x04)
39#define SCIF_SCSCR (0x08)
40#define SCIF_SCFTDR (0x0C)
41#define SCIF_SCFSR (0x10)
42#define SCIF_SCFRDR (0x14)
43#define SCIF_SCFCR (0x18)
44#define SCIF_SCFDR (0x1C)
45#define SCIF_SCSPTR (0x20)
46#define SCIF_SCLSR (0x24)
47#define SCIF_DL (0x30)
48#define SCIF_CKS (0x34)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +020049
Valentine Barshakf2184142018-10-30 02:06:17 +030050#if RCAR_LSI == RCAR_V3M
51#define SCIF_BASE SCIF0_BASE
52#define CPG_SMSTPCR CPG_SMSTPCR2
53#define CPG_MSTPSR CPG_MSTPSR2
54#define MSTP MSTP207
55#else
56#define SCIF_BASE SCIF2_BASE
57#define CPG_SMSTPCR CPG_SMSTPCR3
58#define CPG_MSTPSR CPG_MSTPSR3
59#define MSTP MSTP310
60#endif
61
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +020062/* mode pin */
Biju Das42861e82020-12-13 20:10:32 +000063#define RST_MODEMR (0xE6160060)
64#define MODEMR_MD12 (0x00001000)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +020065
Biju Das42861e82020-12-13 20:10:32 +000066#define SCSMR_CA_MASK (1 << 7)
67#define SCSMR_CA_ASYNC (0x0000)
68#define SCSMR_CHR_MASK (1 << 6)
69#define SCSMR_CHR_8 (0x0000)
70#define SCSMR_PE_MASK (1 << 5)
71#define SCSMR_PE_DIS (0x0000)
72#define SCSMR_STOP_MASK (1 << 3)
73#define SCSMR_STOP_1 (0x0000)
74#define SCSMR_CKS_MASK (3 << 0)
75#define SCSMR_CKS_DIV1 (0x0000)
76#define SCSMR_INIT_DATA (SCSMR_CA_ASYNC + \
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +020077 SCSMR_CHR_8 + \
78 SCSMR_PE_DIS + \
79 SCSMR_STOP_1 + \
80 SCSMR_CKS_DIV1)
Biju Das42861e82020-12-13 20:10:32 +000081#define SCBRR_115200BPS (17)
82#define SCBRR_115200BPSON (16)
83#define SCBRR_115200BPS_E3_SSCG (15)
84#define SCBRR_230400BPS (8)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +020085
Biju Das42861e82020-12-13 20:10:32 +000086#define SCSCR_TE_MASK (1 << 5)
87#define SCSCR_TE_DIS (0x0000)
88#define SCSCR_TE_EN (0x0020)
89#define SCSCR_RE_MASK (1 << 4)
90#define SCSCR_RE_DIS (0x0000)
91#define SCSCR_RE_EN (0x0010)
92#define SCSCR_CKE_MASK (3 << 0)
93#define SCSCR_CKE_INT (0x0000)
94#define SCSCR_CKE_BRG (0x0002)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +020095#if SCIF_CLK == SCIF_EXTARNAL_CLK
Biju Das42861e82020-12-13 20:10:32 +000096#define SCSCR_CKE_INT_CLK (SCSCR_CKE_BRG)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +020097#else
Biju Das42861e82020-12-13 20:10:32 +000098#define SCFSR_TEND_MASK (1 << 6)
99#define SCFSR_TEND_TRANS_END (0x0040)
100#define SCSCR_CKE_INT_CLK (SCSCR_CKE_INT)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200101#endif
Biju Das42861e82020-12-13 20:10:32 +0000102#define SCFSR_INIT_DATA (0x0000)
103#define SCFCR_TTRG_MASK (3 << 4)
104#define SCFCR_TTRG_8 (0x0000)
105#define SCFCR_TTRG_0 (0x0030)
106#define SCFCR_TFRST_MASK (1 << 2)
107#define SCFCR_TFRST_DIS (0x0000)
108#define SCFCR_TFRST_EN (0x0004)
109#define SCFCR_RFRS_MASK (1 << 1)
110#define SCFCR_RFRS_DIS (0x0000)
111#define SCFCR_RFRS_EN (0x0002)
112#define SCFCR_INIT_DATA (SCFCR_TTRG_8)
113#define SCFDR_T_MASK (0x1f << 8)
114#define DL_INIT_DATA (8)
115#define CKS_CKS_DIV_MASK (1 << 15)
116#define CKS_CKS_DIV_CLK (0x0000)
117#define CKS_XIN_MASK (1 << 14)
118#define CKS_XIN_SCIF_CLK (0x0000)
119#define CKS_INIT_DATA (CKS_CKS_DIV_CLK + CKS_XIN_SCIF_CLK)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200120
Marek Vasut0aa268e2019-05-18 19:29:16 +0200121 .globl console_rcar_register
122 .globl console_rcar_init
123 .globl console_rcar_putc
124 .globl console_rcar_flush
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200125
Biju Das42861e82020-12-13 20:10:32 +0000126 /*
127 * -----------------------------------------------
Marek Vasut0aa268e2019-05-18 19:29:16 +0200128 * int console_rcar_register(
129 * uintptr_t base, uint32_t clk, uint32_t baud,
Andre Przywara52fb0492020-01-25 00:58:35 +0000130 * console_t *console)
Marek Vasut0aa268e2019-05-18 19:29:16 +0200131 * Function to initialize and register a new rcar
132 * console. Storage passed in for the console struct
133 * *must* be persistent (i.e. not from the stack).
134 * In: x0 - UART register base address
135 * w1 - UART clock in Hz
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200136 * w2 - Baud rate
Andre Przywara52fb0492020-01-25 00:58:35 +0000137 * x3 - pointer to empty console_t struct
Marek Vasut0aa268e2019-05-18 19:29:16 +0200138 * Out: return 1 on success, 0 on error
139 * Clobber list : x0, x1, x2, x6, x7, x14
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200140 * -----------------------------------------------
141 */
Marek Vasut0aa268e2019-05-18 19:29:16 +0200142func console_rcar_register
143 mov x7, x30
144 mov x6, x3
145 cbz x6, register_fail
Andre Przywara52fb0492020-01-25 00:58:35 +0000146 str x0, [x6, #CONSOLE_T_BASE]
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200147
Marek Vasut0aa268e2019-05-18 19:29:16 +0200148 bl console_rcar_init
149
150 mov x0, x6
151 mov x30, x7
152 finish_console_register rcar, putc=1, getc=0, flush=1
153
154register_fail:
155 ret x7
156endfunc console_rcar_register
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200157
Biju Das42861e82020-12-13 20:10:32 +0000158 /*
Marek Vasut0aa268e2019-05-18 19:29:16 +0200159 * int console_rcar_init(unsigned long base_addr,
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200160 * unsigned int uart_clk, unsigned int baud_rate)
161 * Function to initialize the console without a
162 * C Runtime to print debug information. This
Marek Vasut0aa268e2019-05-18 19:29:16 +0200163 * function will be accessed by console_rcar_register
164 * and crash reporting.
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200165 * In: x0 - console base address
166 * w1 - Uart clock in Hz
167 * w2 - Baud rate
168 * Out: return 1 on success
169 * Clobber list : x1, x2
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200170 */
Marek Vasut0aa268e2019-05-18 19:29:16 +0200171func console_rcar_init
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200172 ldr x0, =CPG_BASE
Valentine Barshakf2184142018-10-30 02:06:17 +0300173 ldr w1, [x0, #CPG_SMSTPCR]
174 and w1, w1, #~MSTP
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200175 mvn w2, w1
176 str w2, [x0, #CPG_CPGWPR]
Valentine Barshakf2184142018-10-30 02:06:17 +0300177 str w1, [x0, #CPG_SMSTPCR]
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +02001785:
Valentine Barshakf2184142018-10-30 02:06:17 +0300179 ldr w1, [x0, #CPG_MSTPSR]
180 and w1, w1, #MSTP
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200181 cbnz w1, 5b
182
Valentine Barshakf2184142018-10-30 02:06:17 +0300183 ldr x0, =SCIF_BASE
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200184 /* Clear bits TE and RE in SCSCR to 0 */
185 mov w1, #(SCSCR_TE_DIS + SCSCR_RE_DIS)
186 strh w1, [x0, #SCIF_SCSCR]
187 /* Set bits TFRST and RFRST in SCFCR to 1 */
188 ldrh w1, [x0, #SCIF_SCFCR]
189 orr w1, w1, #(SCFCR_TFRST_EN + SCFCR_RFRS_EN)
190 strh w1, [x0, #SCIF_SCFCR]
Biju Das42861e82020-12-13 20:10:32 +0000191 /*
192 * Read flags of ER, DR, BRK, and RDF in SCFSR and those of TO and ORER
193 * in SCLSR, then clear them to 0
194 */
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200195 mov w1, #SCFSR_INIT_DATA
196 strh w1, [x0, #SCIF_SCFSR]
197 mov w1, #0
198 strh w1, [x0, #SCIF_SCLSR]
199 /* Set bits CKE[1:0] in SCSCR */
200 ldrh w1, [x0, #SCIF_SCSCR]
201 and w1, w1, #~SCSCR_CKE_MASK
202 mov w2, #SCSCR_CKE_INT_CLK
203 orr w1, w1, w2
204 strh w1, [x0, #SCIF_SCSCR]
205 /* Set data transfer format in SCSMR */
206 mov w1, #SCSMR_INIT_DATA
207 strh w1, [x0, #SCIF_SCSMR]
208 /* Set value in SCBRR */
209#if SCIF_CLK == SCIF_INTERNAL_CLK
210 ldr x1, =PRR
211 ldr w1, [x1]
212 and w1, w1, #(PRR_PRODUCT_MASK | PRR_CUT_MASK)
213 mov w2, #PRR_PRODUCT_H3_VER_10
214 cmp w1, w2
215 beq 3f
216 and w1, w1, #PRR_PRODUCT_MASK
Marek Vasut9fa925d2019-01-05 14:16:48 +0100217 mov w2, #PRR_PRODUCT_D3
218 cmp w1, w2
219 beq 4f
220 and w1, w1, #PRR_PRODUCT_MASK
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200221 mov w2, #PRR_PRODUCT_E3
222 cmp w1, w2
Marek Vasut9fa925d2019-01-05 14:16:48 +0100223 bne 5f
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200224
225 ldr x1, =RST_MODEMR
226 ldr w1, [x1]
227 and w1, w1, #MODEMR_MD12
228 mov w2, #MODEMR_MD12
229 cmp w1, w2
Marek Vasut9fa925d2019-01-05 14:16:48 +0100230 bne 5f
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200231
232 mov w1, #SCBRR_115200BPS_E3_SSCG
233 b 2f
Marek Vasut9fa925d2019-01-05 14:16:48 +01002345:
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200235 mov w1, #SCBRR_115200BPS
236 b 2f
Marek Vasut9fa925d2019-01-05 14:16:48 +01002374:
238 mov w1, #SCBRR_115200BPSON
239 b 2f
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +02002403:
241 mov w1, #SCBRR_230400BPS
2422:
243 strb w1, [x0, SCIF_SCBRR]
244#else
245 mov w1, #DL_INIT_DATA
246 strh w1, [x0, #SCIF_DL]
247 mov w1, #CKS_INIT_DATA
248 strh w1, [x0, #SCIF_CKS]
249#endif
250 /* 1-bit interval elapsed */
251 mov w1, #100
2521:
253 subs w1, w1, #1
254 cbnz w1, 1b
255 /*
256 * Set bits RTRG[1:0], TTRG[1:0], and MCE in SCFCR
257 * Clear bits FRST and RFRST to 0
258 */
259 mov w1, #SCFCR_INIT_DATA
260 strh w1, [x0, #SCIF_SCFCR]
261 /* Set bits TE and RE in SCSCR to 1 */
262 ldrh w1, [x0, #SCIF_SCSCR]
263 orr w1, w1, #(SCSCR_TE_EN + SCSCR_RE_EN)
264 strh w1, [x0, #SCIF_SCSCR]
265 mov x0, #1
266
267 ret
Marek Vasut0aa268e2019-05-18 19:29:16 +0200268endfunc console_rcar_init
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200269
Biju Das42861e82020-12-13 20:10:32 +0000270 /*
Marek Vasut0aa268e2019-05-18 19:29:16 +0200271 * int console_rcar_putc(int c, unsigned int base_addr)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200272 * Function to output a character over the console. It
273 * returns the character printed on success or -1 on error.
274 * In : w0 - character to be printed
Marek Vasut0aa268e2019-05-18 19:29:16 +0200275 * x1 - pointer to console_t structure
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200276 * Out : return -1 on error else return character.
277 * Clobber list : x2
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200278 */
Marek Vasut0aa268e2019-05-18 19:29:16 +0200279func console_rcar_putc
Valentine Barshakf2184142018-10-30 02:06:17 +0300280 ldr x1, =SCIF_BASE
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200281 cmp w0, #0xA
282 /* Prepend '\r' to '\n' */
283 bne 2f
2841:
285 /* Check if the transmit FIFO is full */
286 ldrh w2, [x1, #SCIF_SCFDR]
287 ubfx w2, w2, #8, #5
288 cmp w2, #16
289 bcs 1b
290 mov w2, #0x0D
291 strb w2, [x1, #SCIF_SCFTDR]
2922:
293 /* Check if the transmit FIFO is full */
294 ldrh w2, [x1, #SCIF_SCFDR]
295 ubfx w2, w2, #8, #5
296 cmp w2, #16
297 bcs 2b
298 strb w0, [x1, #SCIF_SCFTDR]
299
Marek Vasutaae2c722018-12-27 20:31:22 +0100300 /* Clear TEND flag */
301 ldrh w2, [x1, #SCIF_SCFSR]
302 and w2, w2, #~SCFSR_TEND_MASK
303 strh w2, [x1, #SCIF_SCFSR]
304
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200305 ret
Marek Vasut0aa268e2019-05-18 19:29:16 +0200306endfunc console_rcar_putc
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200307
Biju Das42861e82020-12-13 20:10:32 +0000308 /*
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500309 * void console_rcar_flush(void)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200310 * Function to force a write of all buffered
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500311 * data that hasn't been output. It returns void
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200312 * Clobber list : x0, x1
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200313 */
Marek Vasut0aa268e2019-05-18 19:29:16 +0200314func console_rcar_flush
Valentine Barshakf2184142018-10-30 02:06:17 +0300315 ldr x0, =SCIF_BASE
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +02003161:
Marek Vasutaae2c722018-12-27 20:31:22 +0100317 /* Check TEND flag */
318 ldrh w1, [x0, #SCIF_SCFSR]
319 and w1, w1, #SCFSR_TEND_MASK
320 cmp w1, #SCFSR_TEND_TRANS_END
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200321 bne 1b
322
Valentine Barshakf2184142018-10-30 02:06:17 +0300323 ldr x0, =SCIF_BASE
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200324 ldrh w1, [x0, #SCIF_SCSCR]
325 and w1, w1, #~(SCSCR_TE_EN + SCSCR_RE_EN)
326 strh w1, [x0, #SCIF_SCSCR]
327
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200328 ret
Marek Vasut0aa268e2019-05-18 19:29:16 +0200329endfunc console_rcar_flush