blob: 471d7b8084870a65a8be4ca91dfabd96c9eb75c4 [file] [log] [blame]
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +02001/*
2 * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch.h>
8#include <asm_macros.S>
9
10#define SCIF_INTERNAL_CLK 0
11#define SCIF_EXTARNAL_CLK 1
12#define SCIF_CLK SCIF_INTERNAL_CLK
13
14/* product register */
15#define PRR (0xFFF00044)
16#define PRR_PRODUCT_MASK (0x00007F00)
17#define PRR_CUT_MASK (0x000000FF)
18#define PRR_PRODUCT_H3_VER_10 (0x00004F00)
19#define PRR_PRODUCT_E3 (0x00005700)
Marek Vasut9fa925d2019-01-05 14:16:48 +010020#define PRR_PRODUCT_D3 (0x00005800)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +020021
22/* module stop */
23#define CPG_BASE (0xE6150000)
Valentine Barshakf2184142018-10-30 02:06:17 +030024#define CPG_SMSTPCR2 (0x0138)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +020025#define CPG_SMSTPCR3 (0x013C)
Valentine Barshakf2184142018-10-30 02:06:17 +030026#define CPG_MSTPSR2 (0x0040)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +020027#define CPG_MSTPSR3 (0x0048)
Valentine Barshakf2184142018-10-30 02:06:17 +030028#define MSTP207 (1 << 7)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +020029#define MSTP310 (1 << 10)
30#define CPG_CPGWPR (0x0900)
31
32/* scif */
Valentine Barshakf2184142018-10-30 02:06:17 +030033#define SCIF0_BASE (0xE6E60000)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +020034#define SCIF2_BASE (0xE6E88000)
35#define SCIF_SCSMR (0x00)
36#define SCIF_SCBRR (0x04)
37#define SCIF_SCSCR (0x08)
38#define SCIF_SCFTDR (0x0C)
39#define SCIF_SCFSR (0x10)
40#define SCIF_SCFRDR (0x14)
41#define SCIF_SCFCR (0x18)
42#define SCIF_SCFDR (0x1C)
43#define SCIF_SCSPTR (0x20)
44#define SCIF_SCLSR (0x24)
45#define SCIF_DL (0x30)
46#define SCIF_CKS (0x34)
47
Valentine Barshakf2184142018-10-30 02:06:17 +030048#if RCAR_LSI == RCAR_V3M
49#define SCIF_BASE SCIF0_BASE
50#define CPG_SMSTPCR CPG_SMSTPCR2
51#define CPG_MSTPSR CPG_MSTPSR2
52#define MSTP MSTP207
53#else
54#define SCIF_BASE SCIF2_BASE
55#define CPG_SMSTPCR CPG_SMSTPCR3
56#define CPG_MSTPSR CPG_MSTPSR3
57#define MSTP MSTP310
58#endif
59
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +020060/* mode pin */
61#define RST_MODEMR (0xE6160060)
62#define MODEMR_MD12 (0x00001000)
63
64#define SCSMR_CA_MASK (1 << 7)
65#define SCSMR_CA_ASYNC (0x0000)
66#define SCSMR_CHR_MASK (1 << 6)
67#define SCSMR_CHR_8 (0x0000)
68#define SCSMR_PE_MASK (1 << 5)
69#define SCSMR_PE_DIS (0x0000)
70#define SCSMR_STOP_MASK (1 << 3)
71#define SCSMR_STOP_1 (0x0000)
72#define SCSMR_CKS_MASK (3 << 0)
73#define SCSMR_CKS_DIV1 (0x0000)
74#define SCSMR_INIT_DATA (SCSMR_CA_ASYNC + \
75 SCSMR_CHR_8 + \
76 SCSMR_PE_DIS + \
77 SCSMR_STOP_1 + \
78 SCSMR_CKS_DIV1)
79#define SCBRR_115200BPS (17)
Marek Vasut9fa925d2019-01-05 14:16:48 +010080#define SCBRR_115200BPSON (16)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +020081#define SCBRR_115200BPS_E3_SSCG (15)
82#define SCBRR_230400BPS (8)
83
84#define SCSCR_TE_MASK (1 << 5)
85#define SCSCR_TE_DIS (0x0000)
86#define SCSCR_TE_EN (0x0020)
87#define SCSCR_RE_MASK (1 << 4)
88#define SCSCR_RE_DIS (0x0000)
89#define SCSCR_RE_EN (0x0010)
90#define SCSCR_CKE_MASK (3 << 0)
91#define SCSCR_CKE_INT (0x0000)
92#define SCSCR_CKE_BRG (0x0002)
93#if SCIF_CLK == SCIF_EXTARNAL_CLK
94#define SCSCR_CKE_INT_CLK (SCSCR_CKE_BRG)
95#else
Marek Vasutaae2c722018-12-27 20:31:22 +010096#define SCFSR_TEND_MASK (1 << 6)
97#define SCFSR_TEND_TRANS_END (0x0040)
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +020098#define SCSCR_CKE_INT_CLK (SCSCR_CKE_INT)
99#endif
100#define SCFSR_INIT_DATA (0x0000)
101#define SCFCR_TTRG_MASK (3 << 4)
102#define SCFCR_TTRG_8 (0x0000)
103#define SCFCR_TTRG_0 (0x0030)
104#define SCFCR_TFRST_MASK (1 << 2)
105#define SCFCR_TFRST_DIS (0x0000)
106#define SCFCR_TFRST_EN (0x0004)
107#define SCFCR_RFRS_MASK (1 << 1)
108#define SCFCR_RFRS_DIS (0x0000)
109#define SCFCR_RFRS_EN (0x0002)
110#define SCFCR_INIT_DATA (SCFCR_TTRG_8)
111#define SCFDR_T_MASK (0x1f << 8)
112#define DL_INIT_DATA (8)
113#define CKS_CKS_DIV_MASK (1 << 15)
114#define CKS_CKS_DIV_CLK (0x0000)
115#define CKS_XIN_MASK (1 << 14)
116#define CKS_XIN_SCIF_CLK (0x0000)
117#define CKS_INIT_DATA (CKS_CKS_DIV_CLK + CKS_XIN_SCIF_CLK)
118
119 .globl console_init
120 .globl console_uninit
121 .globl console_putc
122 .globl console_core_init
123 .globl console_core_putc
124 .globl console_getc
125 .globl console_flush
126
127 /*
128 * The console base is in the data section and not in .bss
129 * even though it is zero-init. In particular, this allows
130 * the console functions to start using this variable before
131 * the runtime memory is initialized for images which do not
132 * need to copy the .data section from ROM to RAM.
133 */
134 /* -----------------------------------------------
135 * int console_init(unsigned long base_addr,
136 * unsigned int uart_clk, unsigned int baud_rate)
137 * Function to initialize the console without a
138 * C Runtime to print debug information. It saves
139 * the console base to the data section.
140 * In: x0 - console base address
141 * w1 - Uart clock in Hz
142 * w2 - Baud rate
143 * out: return 1 on success.
144 * Clobber list : x1 - x3
145 * -----------------------------------------------
146 */
147func console_init
148 b console_core_init
149endfunc console_init
150
151func console_uninit
152 ret
153endfunc console_uninit
154
155 /* -----------------------------------------------
156 * int console_core_init(unsigned long base_addr,
157 * unsigned int uart_clk, unsigned int baud_rate)
158 * Function to initialize the console without a
159 * C Runtime to print debug information. This
160 * function will be accessed by console_init and
161 * crash reporting.
162 * In: x0 - console base address
163 * w1 - Uart clock in Hz
164 * w2 - Baud rate
165 * Out: return 1 on success
166 * Clobber list : x1, x2
167 * -----------------------------------------------
168 */
169func console_core_init
170 ldr x0, =CPG_BASE
Valentine Barshakf2184142018-10-30 02:06:17 +0300171 ldr w1, [x0, #CPG_SMSTPCR]
172 and w1, w1, #~MSTP
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200173 mvn w2, w1
174 str w2, [x0, #CPG_CPGWPR]
Valentine Barshakf2184142018-10-30 02:06:17 +0300175 str w1, [x0, #CPG_SMSTPCR]
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +02001765:
Valentine Barshakf2184142018-10-30 02:06:17 +0300177 ldr w1, [x0, #CPG_MSTPSR]
178 and w1, w1, #MSTP
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200179 cbnz w1, 5b
180
Valentine Barshakf2184142018-10-30 02:06:17 +0300181 ldr x0, =SCIF_BASE
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200182 /* Clear bits TE and RE in SCSCR to 0 */
183 mov w1, #(SCSCR_TE_DIS + SCSCR_RE_DIS)
184 strh w1, [x0, #SCIF_SCSCR]
185 /* Set bits TFRST and RFRST in SCFCR to 1 */
186 ldrh w1, [x0, #SCIF_SCFCR]
187 orr w1, w1, #(SCFCR_TFRST_EN + SCFCR_RFRS_EN)
188 strh w1, [x0, #SCIF_SCFCR]
189 /* Read flags of ER, DR, BRK, and RDF in SCFSR and those of TO and ORER
190 in SCLSR, then clear them to 0 */
191 mov w1, #SCFSR_INIT_DATA
192 strh w1, [x0, #SCIF_SCFSR]
193 mov w1, #0
194 strh w1, [x0, #SCIF_SCLSR]
195 /* Set bits CKE[1:0] in SCSCR */
196 ldrh w1, [x0, #SCIF_SCSCR]
197 and w1, w1, #~SCSCR_CKE_MASK
198 mov w2, #SCSCR_CKE_INT_CLK
199 orr w1, w1, w2
200 strh w1, [x0, #SCIF_SCSCR]
201 /* Set data transfer format in SCSMR */
202 mov w1, #SCSMR_INIT_DATA
203 strh w1, [x0, #SCIF_SCSMR]
204 /* Set value in SCBRR */
205#if SCIF_CLK == SCIF_INTERNAL_CLK
206 ldr x1, =PRR
207 ldr w1, [x1]
208 and w1, w1, #(PRR_PRODUCT_MASK | PRR_CUT_MASK)
209 mov w2, #PRR_PRODUCT_H3_VER_10
210 cmp w1, w2
211 beq 3f
212 and w1, w1, #PRR_PRODUCT_MASK
Marek Vasut9fa925d2019-01-05 14:16:48 +0100213 mov w2, #PRR_PRODUCT_D3
214 cmp w1, w2
215 beq 4f
216 and w1, w1, #PRR_PRODUCT_MASK
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200217 mov w2, #PRR_PRODUCT_E3
218 cmp w1, w2
Marek Vasut9fa925d2019-01-05 14:16:48 +0100219 bne 5f
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200220
221 ldr x1, =RST_MODEMR
222 ldr w1, [x1]
223 and w1, w1, #MODEMR_MD12
224 mov w2, #MODEMR_MD12
225 cmp w1, w2
Marek Vasut9fa925d2019-01-05 14:16:48 +0100226 bne 5f
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200227
228 mov w1, #SCBRR_115200BPS_E3_SSCG
229 b 2f
Marek Vasut9fa925d2019-01-05 14:16:48 +01002305:
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200231 mov w1, #SCBRR_115200BPS
232 b 2f
Marek Vasut9fa925d2019-01-05 14:16:48 +01002334:
234 mov w1, #SCBRR_115200BPSON
235 b 2f
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +02002363:
237 mov w1, #SCBRR_230400BPS
2382:
239 strb w1, [x0, SCIF_SCBRR]
240#else
241 mov w1, #DL_INIT_DATA
242 strh w1, [x0, #SCIF_DL]
243 mov w1, #CKS_INIT_DATA
244 strh w1, [x0, #SCIF_CKS]
245#endif
246 /* 1-bit interval elapsed */
247 mov w1, #100
2481:
249 subs w1, w1, #1
250 cbnz w1, 1b
251 /*
252 * Set bits RTRG[1:0], TTRG[1:0], and MCE in SCFCR
253 * Clear bits FRST and RFRST to 0
254 */
255 mov w1, #SCFCR_INIT_DATA
256 strh w1, [x0, #SCIF_SCFCR]
257 /* Set bits TE and RE in SCSCR to 1 */
258 ldrh w1, [x0, #SCIF_SCSCR]
259 orr w1, w1, #(SCSCR_TE_EN + SCSCR_RE_EN)
260 strh w1, [x0, #SCIF_SCSCR]
261 mov x0, #1
262
263 ret
264endfunc console_core_init
265
266 /* ---------------------------------------------
267 * int console_putc(int c)
268 * Function to output a character over the
269 * console. It returns the character printed on
270 * success or -1 on error.
271 * In : x0 - character to be printed
272 * Out : return -1 on error else return character.
273 * Clobber list : x1, x2
274 * ---------------------------------------------
275 */
276func console_putc
277 b console_core_putc
278endfunc console_putc
279
280 /* --------------------------------------------------------
281 * int console_core_putc(int c, unsigned int base_addr)
282 * Function to output a character over the console. It
283 * returns the character printed on success or -1 on error.
284 * In : w0 - character to be printed
285 * x1 - console base address
286 * Out : return -1 on error else return character.
287 * Clobber list : x2
288 * --------------------------------------------------------
289 */
290func console_core_putc
Valentine Barshakf2184142018-10-30 02:06:17 +0300291 ldr x1, =SCIF_BASE
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200292 cmp w0, #0xA
293 /* Prepend '\r' to '\n' */
294 bne 2f
2951:
296 /* Check if the transmit FIFO is full */
297 ldrh w2, [x1, #SCIF_SCFDR]
298 ubfx w2, w2, #8, #5
299 cmp w2, #16
300 bcs 1b
301 mov w2, #0x0D
302 strb w2, [x1, #SCIF_SCFTDR]
3032:
304 /* Check if the transmit FIFO is full */
305 ldrh w2, [x1, #SCIF_SCFDR]
306 ubfx w2, w2, #8, #5
307 cmp w2, #16
308 bcs 2b
309 strb w0, [x1, #SCIF_SCFTDR]
310
Marek Vasutaae2c722018-12-27 20:31:22 +0100311 /* Clear TEND flag */
312 ldrh w2, [x1, #SCIF_SCFSR]
313 and w2, w2, #~SCFSR_TEND_MASK
314 strh w2, [x1, #SCIF_SCFSR]
315
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200316 ret
317endfunc console_core_putc
318
319 /* ---------------------------------------------
320 * int console_getc(void)
321 * Function to get a character from the console.
322 * It returns the character grabbed on success
323 * or -1 on error.
324 * Clobber list : x0, x1
325 * ---------------------------------------------
326 */
327func console_getc
328 mov w0, #-1
329 ret
330endfunc console_getc
331
332 /* ---------------------------------------------
333 * int console_flush(void)
334 * Function to force a write of all buffered
335 * data that hasn't been output. It returns 0
336 * upon successful completion, otherwise it
337 * returns -1.
338 * Clobber list : x0, x1
339 * ---------------------------------------------
340 */
341func console_flush
Valentine Barshakf2184142018-10-30 02:06:17 +0300342 ldr x0, =SCIF_BASE
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +02003431:
Marek Vasutaae2c722018-12-27 20:31:22 +0100344 /* Check TEND flag */
345 ldrh w1, [x0, #SCIF_SCFSR]
346 and w1, w1, #SCFSR_TEND_MASK
347 cmp w1, #SCFSR_TEND_TRANS_END
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200348 bne 1b
349
Valentine Barshakf2184142018-10-30 02:06:17 +0300350 ldr x0, =SCIF_BASE
Jorge Ramirez-Ortiz1d753672018-09-23 09:41:53 +0200351 ldrh w1, [x0, #SCIF_SCSCR]
352 and w1, w1, #~(SCSCR_TE_EN + SCSCR_RE_EN)
353 strh w1, [x0, #SCIF_SCSCR]
354
355 mov w0, #0
356 ret
357endfunc console_flush