xref: /rk3399_ARM-atf/drivers/renesas/common/scif/scif.S (revision 14f0a0817297905c03ddf2c4c6040482ef71d744)
1865e3474SBiju Das/*
2*14f0a081SToshiyuki Ogasahara * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
3865e3474SBiju Das *
4865e3474SBiju Das * SPDX-License-Identifier: BSD-3-Clause
5865e3474SBiju Das */
6865e3474SBiju Das
7865e3474SBiju Das#include <arch.h>
8865e3474SBiju Das#include <asm_macros.S>
9865e3474SBiju Das#include <console_macros.S>
10865e3474SBiju Das#include <drivers/renesas/rcar/console/console.h>
11865e3474SBiju Das
12865e3474SBiju Das#define SCIF_INTERNAL_CLK	0
13865e3474SBiju Das#define SCIF_EXTARNAL_CLK	1
14865e3474SBiju Das#define SCIF_CLK		SCIF_INTERNAL_CLK
15865e3474SBiju Das
16865e3474SBiju Das/* product register */
17865e3474SBiju Das#define PRR			(0xFFF00044)
18865e3474SBiju Das#define PRR_PRODUCT_MASK	(0x00007F00)
19865e3474SBiju Das#define PRR_CUT_MASK		(0x000000FF)
20865e3474SBiju Das#define PRR_PRODUCT_H3_VER_10	(0x00004F00)
21865e3474SBiju Das#define PRR_PRODUCT_E3		(0x00005700)
22865e3474SBiju Das#define PRR_PRODUCT_D3		(0x00005800)
23865e3474SBiju Das
24865e3474SBiju Das/* module stop */
25865e3474SBiju Das#define CPG_BASE		(0xE6150000)
26865e3474SBiju Das#define CPG_SMSTPCR2		(0x0138)
27865e3474SBiju Das#define CPG_SMSTPCR3		(0x013C)
28865e3474SBiju Das#define CPG_MSTPSR2		(0x0040)
29865e3474SBiju Das#define CPG_MSTPSR3		(0x0048)
30865e3474SBiju Das#define MSTP207			(1 << 7)
31865e3474SBiju Das#define MSTP310			(1 << 10)
32865e3474SBiju Das#define CPG_CPGWPR		(0x0900)
33865e3474SBiju Das
34865e3474SBiju Das/* scif */
35865e3474SBiju Das#define SCIF0_BASE		(0xE6E60000)
36865e3474SBiju Das#define SCIF2_BASE		(0xE6E88000)
37865e3474SBiju Das#define SCIF_SCSMR		(0x00)
38865e3474SBiju Das#define SCIF_SCBRR		(0x04)
39865e3474SBiju Das#define SCIF_SCSCR		(0x08)
40865e3474SBiju Das#define SCIF_SCFTDR		(0x0C)
41865e3474SBiju Das#define SCIF_SCFSR		(0x10)
42865e3474SBiju Das#define SCIF_SCFRDR		(0x14)
43865e3474SBiju Das#define SCIF_SCFCR		(0x18)
44865e3474SBiju Das#define SCIF_SCFDR		(0x1C)
45865e3474SBiju Das#define SCIF_SCSPTR		(0x20)
46865e3474SBiju Das#define SCIF_SCLSR		(0x24)
47865e3474SBiju Das#define SCIF_DL			(0x30)
48865e3474SBiju Das#define SCIF_CKS		(0x34)
49865e3474SBiju Das
50865e3474SBiju Das#if RCAR_LSI == RCAR_V3M
51865e3474SBiju Das#define SCIF_BASE		SCIF0_BASE
52865e3474SBiju Das#define CPG_SMSTPCR		CPG_SMSTPCR2
53865e3474SBiju Das#define CPG_MSTPSR		CPG_MSTPSR2
54865e3474SBiju Das#define MSTP			MSTP207
55865e3474SBiju Das#else
56865e3474SBiju Das#define SCIF_BASE		SCIF2_BASE
57865e3474SBiju Das#define CPG_SMSTPCR		CPG_SMSTPCR3
58865e3474SBiju Das#define CPG_MSTPSR		CPG_MSTPSR3
59865e3474SBiju Das#define MSTP			MSTP310
60865e3474SBiju Das#endif
61865e3474SBiju Das
62865e3474SBiju Das/* mode pin */
63865e3474SBiju Das#define RST_MODEMR		(0xE6160060)
64865e3474SBiju Das#define MODEMR_MD12		(0x00001000)
65865e3474SBiju Das
66865e3474SBiju Das#define SCSMR_CA_MASK		(1 << 7)
67865e3474SBiju Das#define SCSMR_CA_ASYNC		(0x0000)
68865e3474SBiju Das#define SCSMR_CHR_MASK		(1 << 6)
69865e3474SBiju Das#define SCSMR_CHR_8		(0x0000)
70865e3474SBiju Das#define SCSMR_PE_MASK		(1 << 5)
71865e3474SBiju Das#define SCSMR_PE_DIS		(0x0000)
72865e3474SBiju Das#define SCSMR_STOP_MASK		(1 << 3)
73865e3474SBiju Das#define SCSMR_STOP_1		(0x0000)
74865e3474SBiju Das#define SCSMR_CKS_MASK		(3 << 0)
75865e3474SBiju Das#define SCSMR_CKS_DIV1		(0x0000)
76865e3474SBiju Das#define SCSMR_INIT_DATA		(SCSMR_CA_ASYNC +	\
77865e3474SBiju Das					 SCSMR_CHR_8 +		\
78865e3474SBiju Das					 SCSMR_PE_DIS +		\
79865e3474SBiju Das					 SCSMR_STOP_1 +		\
80865e3474SBiju Das					 SCSMR_CKS_DIV1)
81865e3474SBiju Das#define SCBRR_115200BPS		(17)
82*14f0a081SToshiyuki Ogasahara#define SCBRR_115200BPS_D3_SSCG	(16)
83865e3474SBiju Das#define SCBRR_115200BPS_E3_SSCG	(15)
84865e3474SBiju Das#define SCBRR_230400BPS		(8)
85865e3474SBiju Das
86865e3474SBiju Das#define SCSCR_TE_MASK		(1 << 5)
87865e3474SBiju Das#define SCSCR_TE_DIS		(0x0000)
88865e3474SBiju Das#define SCSCR_TE_EN		(0x0020)
89865e3474SBiju Das#define SCSCR_RE_MASK		(1 << 4)
90865e3474SBiju Das#define SCSCR_RE_DIS		(0x0000)
91865e3474SBiju Das#define SCSCR_RE_EN		(0x0010)
92865e3474SBiju Das#define SCSCR_CKE_MASK		(3 << 0)
93865e3474SBiju Das#define SCSCR_CKE_INT		(0x0000)
94865e3474SBiju Das#define SCSCR_CKE_BRG		(0x0002)
95865e3474SBiju Das#if SCIF_CLK == SCIF_EXTARNAL_CLK
96865e3474SBiju Das#define SCSCR_CKE_INT_CLK	(SCSCR_CKE_BRG)
97865e3474SBiju Das#else
98865e3474SBiju Das#define SCFSR_TEND_MASK		(1 << 6)
99865e3474SBiju Das#define SCFSR_TEND_TRANS_END	(0x0040)
100865e3474SBiju Das#define SCSCR_CKE_INT_CLK	(SCSCR_CKE_INT)
101865e3474SBiju Das#endif
102865e3474SBiju Das#define SCFSR_INIT_DATA		(0x0000)
103865e3474SBiju Das#define SCFCR_TTRG_MASK		(3 << 4)
104865e3474SBiju Das#define SCFCR_TTRG_8		(0x0000)
105865e3474SBiju Das#define SCFCR_TTRG_0		(0x0030)
106865e3474SBiju Das#define SCFCR_TFRST_MASK	(1 << 2)
107865e3474SBiju Das#define SCFCR_TFRST_DIS		(0x0000)
108865e3474SBiju Das#define SCFCR_TFRST_EN		(0x0004)
109865e3474SBiju Das#define SCFCR_RFRS_MASK		(1 << 1)
110865e3474SBiju Das#define SCFCR_RFRS_DIS		(0x0000)
111865e3474SBiju Das#define SCFCR_RFRS_EN		(0x0002)
112865e3474SBiju Das#define SCFCR_INIT_DATA		(SCFCR_TTRG_8)
113865e3474SBiju Das#define SCFDR_T_MASK		(0x1f << 8)
114865e3474SBiju Das#define DL_INIT_DATA		(8)
115865e3474SBiju Das#define CKS_CKS_DIV_MASK	(1 << 15)
116865e3474SBiju Das#define CKS_CKS_DIV_CLK		(0x0000)
117865e3474SBiju Das#define CKS_XIN_MASK		(1 << 14)
118865e3474SBiju Das#define CKS_XIN_SCIF_CLK	(0x0000)
119865e3474SBiju Das#define CKS_INIT_DATA		(CKS_CKS_DIV_CLK + CKS_XIN_SCIF_CLK)
120865e3474SBiju Das
121865e3474SBiju Das	.globl	console_rcar_register
122865e3474SBiju Das	.globl	console_rcar_init
123865e3474SBiju Das	.globl	console_rcar_putc
124865e3474SBiju Das	.globl	console_rcar_flush
125865e3474SBiju Das
126865e3474SBiju Das	/*
127865e3474SBiju Das	 * -----------------------------------------------
128865e3474SBiju Das	 * int console_rcar_register(
129865e3474SBiju Das	 *      uintptr_t base, uint32_t clk, uint32_t baud,
130865e3474SBiju Das	 *      console_t *console)
131865e3474SBiju Das	 * Function to initialize and register a new rcar
132865e3474SBiju Das	 * console. Storage passed in for the console struct
133865e3474SBiju Das	 * *must* be persistent (i.e. not from the stack).
134865e3474SBiju Das	 * In: x0 - UART register base address
135865e3474SBiju Das	 *     w1 - UART clock in Hz
136865e3474SBiju Das	 *     w2 - Baud rate
137865e3474SBiju Das	 *     x3 - pointer to empty console_t struct
138865e3474SBiju Das	 * Out: return 1 on success, 0 on error
139865e3474SBiju Das	 * Clobber list : x0, x1, x2, x6, x7, x14
140865e3474SBiju Das	 * -----------------------------------------------
141865e3474SBiju Das	 */
142865e3474SBiju Dasfunc console_rcar_register
143865e3474SBiju Das	mov	x7, x30
144865e3474SBiju Das	mov	x6, x3
145865e3474SBiju Das	cbz	x6, register_fail
146865e3474SBiju Das	str	x0, [x6, #CONSOLE_T_BASE]
147865e3474SBiju Das
148865e3474SBiju Das	bl	console_rcar_init
149865e3474SBiju Das
150865e3474SBiju Das	mov	x0, x6
151865e3474SBiju Das	mov	x30, x7
152865e3474SBiju Das	finish_console_register rcar, putc=1, getc=0, flush=1
153865e3474SBiju Das
154865e3474SBiju Dasregister_fail:
155865e3474SBiju Das	ret	x7
156865e3474SBiju Dasendfunc console_rcar_register
157865e3474SBiju Das
158865e3474SBiju Das	/*
159865e3474SBiju Das	 * int console_rcar_init(unsigned long base_addr,
160865e3474SBiju Das	 * unsigned int uart_clk, unsigned int baud_rate)
161865e3474SBiju Das	 * Function to initialize the console without a
162865e3474SBiju Das	 * C Runtime to print debug information. This
163865e3474SBiju Das	 * function will be accessed by console_rcar_register
164865e3474SBiju Das	 * and crash reporting.
165865e3474SBiju Das	 * In: x0 - console base address
166865e3474SBiju Das	 *     w1 - Uart clock in Hz
167865e3474SBiju Das	 *     w2 - Baud rate
168865e3474SBiju Das	 * Out: return 1 on success
169865e3474SBiju Das	 * Clobber list : x1, x2
170865e3474SBiju Das	 */
171865e3474SBiju Dasfunc console_rcar_init
172865e3474SBiju Das	ldr	x0, =CPG_BASE
173865e3474SBiju Das	ldr	w1, [x0, #CPG_SMSTPCR]
174865e3474SBiju Das	and	w1, w1, #~MSTP
175865e3474SBiju Das	mvn	w2, w1
176865e3474SBiju Das	str	w2, [x0, #CPG_CPGWPR]
177865e3474SBiju Das	str	w1, [x0, #CPG_SMSTPCR]
178865e3474SBiju Das5:
179865e3474SBiju Das	ldr w1, [x0, #CPG_MSTPSR]
180865e3474SBiju Das	and w1, w1, #MSTP
181865e3474SBiju Das	cbnz w1, 5b
182865e3474SBiju Das
183865e3474SBiju Das	ldr	x0, =SCIF_BASE
184865e3474SBiju Das	/* Clear bits TE and RE in SCSCR to 0 */
185865e3474SBiju Das	mov	w1, #(SCSCR_TE_DIS + SCSCR_RE_DIS)
186865e3474SBiju Das	strh	w1, [x0, #SCIF_SCSCR]
187865e3474SBiju Das	/* Set bits TFRST and RFRST in SCFCR to 1 */
188865e3474SBiju Das	ldrh	w1, [x0, #SCIF_SCFCR]
189865e3474SBiju Das	orr	w1, w1, #(SCFCR_TFRST_EN + SCFCR_RFRS_EN)
190865e3474SBiju Das	strh	w1, [x0, #SCIF_SCFCR]
191865e3474SBiju Das	/*
192865e3474SBiju Das	 * Read flags of ER, DR, BRK, and RDF in SCFSR and those of TO and ORER
193865e3474SBiju Das	 * in SCLSR, then clear them to 0
194865e3474SBiju Das	 */
195865e3474SBiju Das	mov	w1, #SCFSR_INIT_DATA
196865e3474SBiju Das	strh	w1, [x0, #SCIF_SCFSR]
197865e3474SBiju Das	mov	w1, #0
198865e3474SBiju Das	strh	w1, [x0, #SCIF_SCLSR]
199865e3474SBiju Das	/* Set bits CKE[1:0] in SCSCR */
200865e3474SBiju Das	ldrh	w1, [x0, #SCIF_SCSCR]
201865e3474SBiju Das	and	w1, w1, #~SCSCR_CKE_MASK
202865e3474SBiju Das	mov	w2, #SCSCR_CKE_INT_CLK
203865e3474SBiju Das	orr	w1, w1, w2
204865e3474SBiju Das	strh	w1, [x0, #SCIF_SCSCR]
205865e3474SBiju Das	/* Set data transfer format in SCSMR */
206865e3474SBiju Das	mov	w1, #SCSMR_INIT_DATA
207865e3474SBiju Das	strh	w1, [x0, #SCIF_SCSMR]
208865e3474SBiju Das	/* Set value in SCBRR */
209865e3474SBiju Das#if SCIF_CLK == SCIF_INTERNAL_CLK
210865e3474SBiju Das	ldr	x1, =PRR
211865e3474SBiju Das	ldr	w1, [x1]
212865e3474SBiju Das	and	w1, w1, #(PRR_PRODUCT_MASK | PRR_CUT_MASK)
213865e3474SBiju Das	mov	w2, #PRR_PRODUCT_H3_VER_10
214865e3474SBiju Das	cmp	w1, w2
215865e3474SBiju Das	beq	3f
216865e3474SBiju Das	and	w1, w1, #PRR_PRODUCT_MASK
217865e3474SBiju Das	mov	w2, #PRR_PRODUCT_D3
218865e3474SBiju Das	cmp	w1, w2
219*14f0a081SToshiyuki Ogasahara	beq	5f
220865e3474SBiju Das	and	w1, w1, #PRR_PRODUCT_MASK
221865e3474SBiju Das	mov	w2, #PRR_PRODUCT_E3
222865e3474SBiju Das	cmp	w1, w2
223*14f0a081SToshiyuki Ogasahara	bne	4f
224865e3474SBiju Das
225*14f0a081SToshiyuki Ogasahara	/* When SSCG(MD12) on (E3) */
226865e3474SBiju Das	ldr	x1, =RST_MODEMR
227865e3474SBiju Das	ldr	w1, [x1]
228865e3474SBiju Das	and	w1, w1, #MODEMR_MD12
229865e3474SBiju Das	mov	w2, #MODEMR_MD12
230865e3474SBiju Das	cmp	w1, w2
231*14f0a081SToshiyuki Ogasahara	bne	4f
232865e3474SBiju Das
233*14f0a081SToshiyuki Ogasahara	/* When SSCG(MD12) on (E3) */
234865e3474SBiju Das	mov	w1, #SCBRR_115200BPS_E3_SSCG
235865e3474SBiju Das	b	2f
236865e3474SBiju Das5:
237*14f0a081SToshiyuki Ogasahara	/* In case of D3 */
238*14f0a081SToshiyuki Ogasahara	ldr	x1, =RST_MODEMR
239*14f0a081SToshiyuki Ogasahara	ldr	w1, [x1]
240*14f0a081SToshiyuki Ogasahara	and	w1, w1, #MODEMR_MD12
241*14f0a081SToshiyuki Ogasahara	mov	w2, #MODEMR_MD12
242*14f0a081SToshiyuki Ogasahara	cmp	w1, w2
243*14f0a081SToshiyuki Ogasahara	bne	4f
244*14f0a081SToshiyuki Ogasahara
245*14f0a081SToshiyuki Ogasahara	/* When SSCG(MD12) on (D3) */
246*14f0a081SToshiyuki Ogasahara	mov	w1, #SCBRR_115200BPS_D3_SSCG
247865e3474SBiju Das	b	2f
248865e3474SBiju Das4:
249*14f0a081SToshiyuki Ogasahara	/* In case of H3/M3/M3N or when SSCG(MD12) is off in E3/D3 */
250*14f0a081SToshiyuki Ogasahara	mov	w1, #SCBRR_115200BPS
251865e3474SBiju Das	b	2f
252865e3474SBiju Das3:
253865e3474SBiju Das	mov	w1, #SCBRR_230400BPS
254865e3474SBiju Das2:
255865e3474SBiju Das	strb	w1, [x0, SCIF_SCBRR]
256865e3474SBiju Das#else
257865e3474SBiju Das	mov	w1, #DL_INIT_DATA
258865e3474SBiju Das	strh	w1, [x0, #SCIF_DL]
259865e3474SBiju Das	mov	w1, #CKS_INIT_DATA
260865e3474SBiju Das	strh	w1, [x0, #SCIF_CKS]
261865e3474SBiju Das#endif
262865e3474SBiju Das	/* 1-bit interval elapsed */
263865e3474SBiju Das	mov	w1, #100
264865e3474SBiju Das1:
265865e3474SBiju Das	subs	w1, w1, #1
266865e3474SBiju Das	cbnz	w1, 1b
267865e3474SBiju Das	/*
268865e3474SBiju Das	 * Set bits RTRG[1:0], TTRG[1:0], and MCE in SCFCR
269865e3474SBiju Das	 * Clear bits FRST and RFRST to 0
270865e3474SBiju Das	 */
271865e3474SBiju Das	mov	w1, #SCFCR_INIT_DATA
272865e3474SBiju Das	strh	w1, [x0, #SCIF_SCFCR]
273865e3474SBiju Das	/* Set bits TE and RE in SCSCR to 1 */
274865e3474SBiju Das	ldrh	w1, [x0, #SCIF_SCSCR]
275865e3474SBiju Das	orr	w1, w1, #(SCSCR_TE_EN + SCSCR_RE_EN)
276865e3474SBiju Das	strh	w1, [x0, #SCIF_SCSCR]
277865e3474SBiju Das	mov	x0, #1
278865e3474SBiju Das
279865e3474SBiju Das	ret
280865e3474SBiju Dasendfunc console_rcar_init
281865e3474SBiju Das
282865e3474SBiju Das	/*
283865e3474SBiju Das	 * int console_rcar_putc(int c, unsigned int base_addr)
284865e3474SBiju Das	 * Function to output a character over the console. It
285865e3474SBiju Das	 * returns the character printed on success or -1 on error.
286865e3474SBiju Das	 * In : w0 - character to be printed
287865e3474SBiju Das	 *      x1 - pointer to console_t structure
288865e3474SBiju Das	 * Out : return -1 on error else return character.
289865e3474SBiju Das	 * Clobber list : x2
290865e3474SBiju Das	 */
291865e3474SBiju Dasfunc console_rcar_putc
292865e3474SBiju Das	ldr	x1, =SCIF_BASE
293865e3474SBiju Das	cmp	w0, #0xA
294865e3474SBiju Das	/* Prepend '\r' to '\n' */
295865e3474SBiju Das	bne	2f
296865e3474SBiju Das1:
297865e3474SBiju Das	/* Check if the transmit FIFO is full */
298865e3474SBiju Das	ldrh	w2, [x1, #SCIF_SCFDR]
299865e3474SBiju Das	ubfx	w2, w2, #8, #5
300865e3474SBiju Das	cmp	w2, #16
301865e3474SBiju Das	bcs	1b
302865e3474SBiju Das	mov	w2, #0x0D
303865e3474SBiju Das	strb	w2, [x1, #SCIF_SCFTDR]
304865e3474SBiju Das2:
305865e3474SBiju Das	/* Check if the transmit FIFO is full */
306865e3474SBiju Das	ldrh	w2, [x1, #SCIF_SCFDR]
307865e3474SBiju Das	ubfx	w2, w2, #8, #5
308865e3474SBiju Das	cmp	w2, #16
309865e3474SBiju Das	bcs	2b
310865e3474SBiju Das	strb	w0, [x1, #SCIF_SCFTDR]
311865e3474SBiju Das
312865e3474SBiju Das	/* Clear TEND flag */
313865e3474SBiju Das	ldrh	w2, [x1, #SCIF_SCFSR]
314865e3474SBiju Das	and	w2, w2, #~SCFSR_TEND_MASK
315865e3474SBiju Das	strh	w2, [x1, #SCIF_SCFSR]
316865e3474SBiju Das
317865e3474SBiju Das	ret
318865e3474SBiju Dasendfunc console_rcar_putc
319865e3474SBiju Das
320865e3474SBiju Das	/*
321865e3474SBiju Das	 * void console_rcar_flush(void)
322865e3474SBiju Das	 * Function to force a write of all buffered
323865e3474SBiju Das	 * data that hasn't been output. It returns void
324865e3474SBiju Das	 * Clobber list : x0, x1
325865e3474SBiju Das	 */
326865e3474SBiju Dasfunc console_rcar_flush
327865e3474SBiju Das	ldr	x0, =SCIF_BASE
328865e3474SBiju Das1:
329865e3474SBiju Das	/* Check TEND flag */
330865e3474SBiju Das	ldrh	w1, [x0, #SCIF_SCFSR]
331865e3474SBiju Das	and	w1, w1, #SCFSR_TEND_MASK
332865e3474SBiju Das	cmp	w1, #SCFSR_TEND_TRANS_END
333865e3474SBiju Das	bne	1b
334865e3474SBiju Das
335865e3474SBiju Das	ldr	x0, =SCIF_BASE
336865e3474SBiju Das	ldrh	w1, [x0, #SCIF_SCSCR]
337865e3474SBiju Das	and	w1, w1, #~(SCSCR_TE_EN + SCSCR_RE_EN)
338865e3474SBiju Das	strh	w1, [x0, #SCIF_SCSCR]
339865e3474SBiju Das
340865e3474SBiju Das	ret
341865e3474SBiju Dasendfunc console_rcar_flush
342