blob: ae26cc40233acf6db4243cacea89dffb20a03d9c [file] [log] [blame]
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +02001/*
Marek Vasut0aa268e2019-05-18 19:29:16 +02002 * Copyright (c) 2015-2019, 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
12#define SCIF_INTERNAL_CLK 0
13#define SCIF_EXTARNAL_CLK 1
14#define SCIF_CLK SCIF_INTERNAL_CLK
15
16/* product register */
17#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)
Marek Vasut9fa925d2019-01-05 14:16:48 +010022#define PRR_PRODUCT_D3 (0x00005800)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +020023
24/* module stop */
25#define CPG_BASE (0xE6150000)
Valentine Barshakf2184142018-10-30 02:06:17 +030026#define CPG_SMSTPCR2 (0x0138)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +020027#define CPG_SMSTPCR3 (0x013C)
Valentine Barshakf2184142018-10-30 02:06:17 +030028#define CPG_MSTPSR2 (0x0040)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +020029#define CPG_MSTPSR3 (0x0048)
Valentine Barshakf2184142018-10-30 02:06:17 +030030#define MSTP207 (1 << 7)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +020031#define MSTP310 (1 << 10)
32#define CPG_CPGWPR (0x0900)
33
34/* scif */
Valentine Barshakf2184142018-10-30 02:06:17 +030035#define SCIF0_BASE (0xE6E60000)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +020036#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)
49
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 */
63#define RST_MODEMR (0xE6160060)
64#define MODEMR_MD12 (0x00001000)
65
66#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 + \
77 SCSMR_CHR_8 + \
78 SCSMR_PE_DIS + \
79 SCSMR_STOP_1 + \
80 SCSMR_CKS_DIV1)
81#define SCBRR_115200BPS (17)
Marek Vasut9fa925d2019-01-05 14:16:48 +010082#define SCBRR_115200BPSON (16)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +020083#define SCBRR_115200BPS_E3_SSCG (15)
84#define SCBRR_230400BPS (8)
85
86#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)
95#if SCIF_CLK == SCIF_EXTARNAL_CLK
96#define SCSCR_CKE_INT_CLK (SCSCR_CKE_BRG)
97#else
Marek Vasutaae2c722018-12-27 20:31:22 +010098#define SCFSR_TEND_MASK (1 << 6)
99#define SCFSR_TEND_TRANS_END (0x0040)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200100#define SCSCR_CKE_INT_CLK (SCSCR_CKE_INT)
101#endif
102#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)
120
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
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200126 /* -----------------------------------------------
Marek Vasut0aa268e2019-05-18 19:29:16 +0200127 * int console_rcar_register(
128 * uintptr_t base, uint32_t clk, uint32_t baud,
Andre Przywara52fb0492020-01-25 00:58:35 +0000129 * console_t *console)
Marek Vasut0aa268e2019-05-18 19:29:16 +0200130 * Function to initialize and register a new rcar
131 * console. Storage passed in for the console struct
132 * *must* be persistent (i.e. not from the stack).
133 * In: x0 - UART register base address
134 * w1 - UART clock in Hz
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200135 * w2 - Baud rate
Andre Przywara52fb0492020-01-25 00:58:35 +0000136 * x3 - pointer to empty console_t struct
Marek Vasut0aa268e2019-05-18 19:29:16 +0200137 * Out: return 1 on success, 0 on error
138 * Clobber list : x0, x1, x2, x6, x7, x14
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200139 * -----------------------------------------------
140 */
Marek Vasut0aa268e2019-05-18 19:29:16 +0200141func console_rcar_register
142 mov x7, x30
143 mov x6, x3
144 cbz x6, register_fail
Andre Przywara52fb0492020-01-25 00:58:35 +0000145 str x0, [x6, #CONSOLE_T_BASE]
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200146
Marek Vasut0aa268e2019-05-18 19:29:16 +0200147 bl console_rcar_init
148
149 mov x0, x6
150 mov x30, x7
151 finish_console_register rcar, putc=1, getc=0, flush=1
152
153register_fail:
154 ret x7
155endfunc console_rcar_register
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200156
157 /* -----------------------------------------------
Marek Vasut0aa268e2019-05-18 19:29:16 +0200158 * int console_rcar_init(unsigned long base_addr,
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200159 * unsigned int uart_clk, unsigned int baud_rate)
160 * Function to initialize the console without a
161 * C Runtime to print debug information. This
Marek Vasut0aa268e2019-05-18 19:29:16 +0200162 * function will be accessed by console_rcar_register
163 * and crash reporting.
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200164 * In: x0 - console base address
165 * w1 - Uart clock in Hz
166 * w2 - Baud rate
167 * Out: return 1 on success
168 * Clobber list : x1, x2
169 * -----------------------------------------------
170 */
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]
191 /* Read flags of ER, DR, BRK, and RDF in SCFSR and those of TO and ORER
192 in SCLSR, then clear them to 0 */
193 mov w1, #SCFSR_INIT_DATA
194 strh w1, [x0, #SCIF_SCFSR]
195 mov w1, #0
196 strh w1, [x0, #SCIF_SCLSR]
197 /* Set bits CKE[1:0] in SCSCR */
198 ldrh w1, [x0, #SCIF_SCSCR]
199 and w1, w1, #~SCSCR_CKE_MASK
200 mov w2, #SCSCR_CKE_INT_CLK
201 orr w1, w1, w2
202 strh w1, [x0, #SCIF_SCSCR]
203 /* Set data transfer format in SCSMR */
204 mov w1, #SCSMR_INIT_DATA
205 strh w1, [x0, #SCIF_SCSMR]
206 /* Set value in SCBRR */
207#if SCIF_CLK == SCIF_INTERNAL_CLK
208 ldr x1, =PRR
209 ldr w1, [x1]
210 and w1, w1, #(PRR_PRODUCT_MASK | PRR_CUT_MASK)
211 mov w2, #PRR_PRODUCT_H3_VER_10
212 cmp w1, w2
213 beq 3f
214 and w1, w1, #PRR_PRODUCT_MASK
Marek Vasut9fa925d2019-01-05 14:16:48 +0100215 mov w2, #PRR_PRODUCT_D3
216 cmp w1, w2
217 beq 4f
218 and w1, w1, #PRR_PRODUCT_MASK
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200219 mov w2, #PRR_PRODUCT_E3
220 cmp w1, w2
Marek Vasut9fa925d2019-01-05 14:16:48 +0100221 bne 5f
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200222
223 ldr x1, =RST_MODEMR
224 ldr w1, [x1]
225 and w1, w1, #MODEMR_MD12
226 mov w2, #MODEMR_MD12
227 cmp w1, w2
Marek Vasut9fa925d2019-01-05 14:16:48 +0100228 bne 5f
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200229
230 mov w1, #SCBRR_115200BPS_E3_SSCG
231 b 2f
Marek Vasut9fa925d2019-01-05 14:16:48 +01002325:
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200233 mov w1, #SCBRR_115200BPS
234 b 2f
Marek Vasut9fa925d2019-01-05 14:16:48 +01002354:
236 mov w1, #SCBRR_115200BPSON
237 b 2f
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +02002383:
239 mov w1, #SCBRR_230400BPS
2402:
241 strb w1, [x0, SCIF_SCBRR]
242#else
243 mov w1, #DL_INIT_DATA
244 strh w1, [x0, #SCIF_DL]
245 mov w1, #CKS_INIT_DATA
246 strh w1, [x0, #SCIF_CKS]
247#endif
248 /* 1-bit interval elapsed */
249 mov w1, #100
2501:
251 subs w1, w1, #1
252 cbnz w1, 1b
253 /*
254 * Set bits RTRG[1:0], TTRG[1:0], and MCE in SCFCR
255 * Clear bits FRST and RFRST to 0
256 */
257 mov w1, #SCFCR_INIT_DATA
258 strh w1, [x0, #SCIF_SCFCR]
259 /* Set bits TE and RE in SCSCR to 1 */
260 ldrh w1, [x0, #SCIF_SCSCR]
261 orr w1, w1, #(SCSCR_TE_EN + SCSCR_RE_EN)
262 strh w1, [x0, #SCIF_SCSCR]
263 mov x0, #1
264
265 ret
Marek Vasut0aa268e2019-05-18 19:29:16 +0200266endfunc console_rcar_init
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200267
268 /* --------------------------------------------------------
Marek Vasut0aa268e2019-05-18 19:29:16 +0200269 * int console_rcar_putc(int c, unsigned int base_addr)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200270 * Function to output a character over the console. It
271 * returns the character printed on success or -1 on error.
272 * In : w0 - character to be printed
Marek Vasut0aa268e2019-05-18 19:29:16 +0200273 * x1 - pointer to console_t structure
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200274 * Out : return -1 on error else return character.
275 * Clobber list : x2
276 * --------------------------------------------------------
277 */
Marek Vasut0aa268e2019-05-18 19:29:16 +0200278func console_rcar_putc
Valentine Barshakf2184142018-10-30 02:06:17 +0300279 ldr x1, =SCIF_BASE
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200280 cmp w0, #0xA
281 /* Prepend '\r' to '\n' */
282 bne 2f
2831:
284 /* Check if the transmit FIFO is full */
285 ldrh w2, [x1, #SCIF_SCFDR]
286 ubfx w2, w2, #8, #5
287 cmp w2, #16
288 bcs 1b
289 mov w2, #0x0D
290 strb w2, [x1, #SCIF_SCFTDR]
2912:
292 /* Check if the transmit FIFO is full */
293 ldrh w2, [x1, #SCIF_SCFDR]
294 ubfx w2, w2, #8, #5
295 cmp w2, #16
296 bcs 2b
297 strb w0, [x1, #SCIF_SCFTDR]
298
Marek Vasutaae2c722018-12-27 20:31:22 +0100299 /* Clear TEND flag */
300 ldrh w2, [x1, #SCIF_SCFSR]
301 and w2, w2, #~SCFSR_TEND_MASK
302 strh w2, [x1, #SCIF_SCFSR]
303
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200304 ret
Marek Vasut0aa268e2019-05-18 19:29:16 +0200305endfunc console_rcar_putc
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200306
307 /* ---------------------------------------------
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500308 * void console_rcar_flush(void)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200309 * Function to force a write of all buffered
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500310 * data that hasn't been output. It returns void
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200311 * Clobber list : x0, x1
312 * ---------------------------------------------
313 */
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