xref: /rk3399_ARM-atf/drivers/renesas/common/scif/scif.S (revision 865e34741b02b3a9ddf9f652f2649407f33debb0)
1*865e3474SBiju Das/*
2*865e3474SBiju Das * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved.
3*865e3474SBiju Das *
4*865e3474SBiju Das * SPDX-License-Identifier: BSD-3-Clause
5*865e3474SBiju Das */
6*865e3474SBiju Das
7*865e3474SBiju Das#include <arch.h>
8*865e3474SBiju Das#include <asm_macros.S>
9*865e3474SBiju Das#include <console_macros.S>
10*865e3474SBiju Das#include <drivers/renesas/rcar/console/console.h>
11*865e3474SBiju Das
12*865e3474SBiju Das#define SCIF_INTERNAL_CLK	0
13*865e3474SBiju Das#define SCIF_EXTARNAL_CLK	1
14*865e3474SBiju Das#define SCIF_CLK		SCIF_INTERNAL_CLK
15*865e3474SBiju Das
16*865e3474SBiju Das/* product register */
17*865e3474SBiju Das#define PRR			(0xFFF00044)
18*865e3474SBiju Das#define PRR_PRODUCT_MASK	(0x00007F00)
19*865e3474SBiju Das#define PRR_CUT_MASK		(0x000000FF)
20*865e3474SBiju Das#define PRR_PRODUCT_H3_VER_10	(0x00004F00)
21*865e3474SBiju Das#define PRR_PRODUCT_E3		(0x00005700)
22*865e3474SBiju Das#define PRR_PRODUCT_D3		(0x00005800)
23*865e3474SBiju Das
24*865e3474SBiju Das/* module stop */
25*865e3474SBiju Das#define CPG_BASE		(0xE6150000)
26*865e3474SBiju Das#define CPG_SMSTPCR2		(0x0138)
27*865e3474SBiju Das#define CPG_SMSTPCR3		(0x013C)
28*865e3474SBiju Das#define CPG_MSTPSR2		(0x0040)
29*865e3474SBiju Das#define CPG_MSTPSR3		(0x0048)
30*865e3474SBiju Das#define MSTP207			(1 << 7)
31*865e3474SBiju Das#define MSTP310			(1 << 10)
32*865e3474SBiju Das#define CPG_CPGWPR		(0x0900)
33*865e3474SBiju Das
34*865e3474SBiju Das/* scif */
35*865e3474SBiju Das#define SCIF0_BASE		(0xE6E60000)
36*865e3474SBiju Das#define SCIF2_BASE		(0xE6E88000)
37*865e3474SBiju Das#define SCIF_SCSMR		(0x00)
38*865e3474SBiju Das#define SCIF_SCBRR		(0x04)
39*865e3474SBiju Das#define SCIF_SCSCR		(0x08)
40*865e3474SBiju Das#define SCIF_SCFTDR		(0x0C)
41*865e3474SBiju Das#define SCIF_SCFSR		(0x10)
42*865e3474SBiju Das#define SCIF_SCFRDR		(0x14)
43*865e3474SBiju Das#define SCIF_SCFCR		(0x18)
44*865e3474SBiju Das#define SCIF_SCFDR		(0x1C)
45*865e3474SBiju Das#define SCIF_SCSPTR		(0x20)
46*865e3474SBiju Das#define SCIF_SCLSR		(0x24)
47*865e3474SBiju Das#define SCIF_DL			(0x30)
48*865e3474SBiju Das#define SCIF_CKS		(0x34)
49*865e3474SBiju Das
50*865e3474SBiju Das#if RCAR_LSI == RCAR_V3M
51*865e3474SBiju Das#define SCIF_BASE		SCIF0_BASE
52*865e3474SBiju Das#define CPG_SMSTPCR		CPG_SMSTPCR2
53*865e3474SBiju Das#define CPG_MSTPSR		CPG_MSTPSR2
54*865e3474SBiju Das#define MSTP			MSTP207
55*865e3474SBiju Das#else
56*865e3474SBiju Das#define SCIF_BASE		SCIF2_BASE
57*865e3474SBiju Das#define CPG_SMSTPCR		CPG_SMSTPCR3
58*865e3474SBiju Das#define CPG_MSTPSR		CPG_MSTPSR3
59*865e3474SBiju Das#define MSTP			MSTP310
60*865e3474SBiju Das#endif
61*865e3474SBiju Das
62*865e3474SBiju Das/* mode pin */
63*865e3474SBiju Das#define RST_MODEMR		(0xE6160060)
64*865e3474SBiju Das#define MODEMR_MD12		(0x00001000)
65*865e3474SBiju Das
66*865e3474SBiju Das#define SCSMR_CA_MASK		(1 << 7)
67*865e3474SBiju Das#define SCSMR_CA_ASYNC		(0x0000)
68*865e3474SBiju Das#define SCSMR_CHR_MASK		(1 << 6)
69*865e3474SBiju Das#define SCSMR_CHR_8		(0x0000)
70*865e3474SBiju Das#define SCSMR_PE_MASK		(1 << 5)
71*865e3474SBiju Das#define SCSMR_PE_DIS		(0x0000)
72*865e3474SBiju Das#define SCSMR_STOP_MASK		(1 << 3)
73*865e3474SBiju Das#define SCSMR_STOP_1		(0x0000)
74*865e3474SBiju Das#define SCSMR_CKS_MASK		(3 << 0)
75*865e3474SBiju Das#define SCSMR_CKS_DIV1		(0x0000)
76*865e3474SBiju Das#define SCSMR_INIT_DATA		(SCSMR_CA_ASYNC +	\
77*865e3474SBiju Das					 SCSMR_CHR_8 +		\
78*865e3474SBiju Das					 SCSMR_PE_DIS +		\
79*865e3474SBiju Das					 SCSMR_STOP_1 +		\
80*865e3474SBiju Das					 SCSMR_CKS_DIV1)
81*865e3474SBiju Das#define SCBRR_115200BPS		(17)
82*865e3474SBiju Das#define SCBRR_115200BPSON	(16)
83*865e3474SBiju Das#define SCBRR_115200BPS_E3_SSCG	(15)
84*865e3474SBiju Das#define SCBRR_230400BPS		(8)
85*865e3474SBiju Das
86*865e3474SBiju Das#define SCSCR_TE_MASK		(1 << 5)
87*865e3474SBiju Das#define SCSCR_TE_DIS		(0x0000)
88*865e3474SBiju Das#define SCSCR_TE_EN		(0x0020)
89*865e3474SBiju Das#define SCSCR_RE_MASK		(1 << 4)
90*865e3474SBiju Das#define SCSCR_RE_DIS		(0x0000)
91*865e3474SBiju Das#define SCSCR_RE_EN		(0x0010)
92*865e3474SBiju Das#define SCSCR_CKE_MASK		(3 << 0)
93*865e3474SBiju Das#define SCSCR_CKE_INT		(0x0000)
94*865e3474SBiju Das#define SCSCR_CKE_BRG		(0x0002)
95*865e3474SBiju Das#if SCIF_CLK == SCIF_EXTARNAL_CLK
96*865e3474SBiju Das#define SCSCR_CKE_INT_CLK	(SCSCR_CKE_BRG)
97*865e3474SBiju Das#else
98*865e3474SBiju Das#define SCFSR_TEND_MASK		(1 << 6)
99*865e3474SBiju Das#define SCFSR_TEND_TRANS_END	(0x0040)
100*865e3474SBiju Das#define SCSCR_CKE_INT_CLK	(SCSCR_CKE_INT)
101*865e3474SBiju Das#endif
102*865e3474SBiju Das#define SCFSR_INIT_DATA		(0x0000)
103*865e3474SBiju Das#define SCFCR_TTRG_MASK		(3 << 4)
104*865e3474SBiju Das#define SCFCR_TTRG_8		(0x0000)
105*865e3474SBiju Das#define SCFCR_TTRG_0		(0x0030)
106*865e3474SBiju Das#define SCFCR_TFRST_MASK	(1 << 2)
107*865e3474SBiju Das#define SCFCR_TFRST_DIS		(0x0000)
108*865e3474SBiju Das#define SCFCR_TFRST_EN		(0x0004)
109*865e3474SBiju Das#define SCFCR_RFRS_MASK		(1 << 1)
110*865e3474SBiju Das#define SCFCR_RFRS_DIS		(0x0000)
111*865e3474SBiju Das#define SCFCR_RFRS_EN		(0x0002)
112*865e3474SBiju Das#define SCFCR_INIT_DATA		(SCFCR_TTRG_8)
113*865e3474SBiju Das#define SCFDR_T_MASK		(0x1f << 8)
114*865e3474SBiju Das#define DL_INIT_DATA		(8)
115*865e3474SBiju Das#define CKS_CKS_DIV_MASK	(1 << 15)
116*865e3474SBiju Das#define CKS_CKS_DIV_CLK		(0x0000)
117*865e3474SBiju Das#define CKS_XIN_MASK		(1 << 14)
118*865e3474SBiju Das#define CKS_XIN_SCIF_CLK	(0x0000)
119*865e3474SBiju Das#define CKS_INIT_DATA		(CKS_CKS_DIV_CLK + CKS_XIN_SCIF_CLK)
120*865e3474SBiju Das
121*865e3474SBiju Das	.globl	console_rcar_register
122*865e3474SBiju Das	.globl	console_rcar_init
123*865e3474SBiju Das	.globl	console_rcar_putc
124*865e3474SBiju Das	.globl	console_rcar_flush
125*865e3474SBiju Das
126*865e3474SBiju Das	/*
127*865e3474SBiju Das	 * -----------------------------------------------
128*865e3474SBiju Das	 * int console_rcar_register(
129*865e3474SBiju Das	 *      uintptr_t base, uint32_t clk, uint32_t baud,
130*865e3474SBiju Das	 *      console_t *console)
131*865e3474SBiju Das	 * Function to initialize and register a new rcar
132*865e3474SBiju Das	 * console. Storage passed in for the console struct
133*865e3474SBiju Das	 * *must* be persistent (i.e. not from the stack).
134*865e3474SBiju Das	 * In: x0 - UART register base address
135*865e3474SBiju Das	 *     w1 - UART clock in Hz
136*865e3474SBiju Das	 *     w2 - Baud rate
137*865e3474SBiju Das	 *     x3 - pointer to empty console_t struct
138*865e3474SBiju Das	 * Out: return 1 on success, 0 on error
139*865e3474SBiju Das	 * Clobber list : x0, x1, x2, x6, x7, x14
140*865e3474SBiju Das	 * -----------------------------------------------
141*865e3474SBiju Das	 */
142*865e3474SBiju Dasfunc console_rcar_register
143*865e3474SBiju Das	mov	x7, x30
144*865e3474SBiju Das	mov	x6, x3
145*865e3474SBiju Das	cbz	x6, register_fail
146*865e3474SBiju Das	str	x0, [x6, #CONSOLE_T_BASE]
147*865e3474SBiju Das
148*865e3474SBiju Das	bl	console_rcar_init
149*865e3474SBiju Das
150*865e3474SBiju Das	mov	x0, x6
151*865e3474SBiju Das	mov	x30, x7
152*865e3474SBiju Das	finish_console_register rcar, putc=1, getc=0, flush=1
153*865e3474SBiju Das
154*865e3474SBiju Dasregister_fail:
155*865e3474SBiju Das	ret	x7
156*865e3474SBiju Dasendfunc console_rcar_register
157*865e3474SBiju Das
158*865e3474SBiju Das	/*
159*865e3474SBiju Das	 * int console_rcar_init(unsigned long base_addr,
160*865e3474SBiju Das	 * unsigned int uart_clk, unsigned int baud_rate)
161*865e3474SBiju Das	 * Function to initialize the console without a
162*865e3474SBiju Das	 * C Runtime to print debug information. This
163*865e3474SBiju Das	 * function will be accessed by console_rcar_register
164*865e3474SBiju Das	 * and crash reporting.
165*865e3474SBiju Das	 * In: x0 - console base address
166*865e3474SBiju Das	 *     w1 - Uart clock in Hz
167*865e3474SBiju Das	 *     w2 - Baud rate
168*865e3474SBiju Das	 * Out: return 1 on success
169*865e3474SBiju Das	 * Clobber list : x1, x2
170*865e3474SBiju Das	 */
171*865e3474SBiju Dasfunc console_rcar_init
172*865e3474SBiju Das	ldr	x0, =CPG_BASE
173*865e3474SBiju Das	ldr	w1, [x0, #CPG_SMSTPCR]
174*865e3474SBiju Das	and	w1, w1, #~MSTP
175*865e3474SBiju Das	mvn	w2, w1
176*865e3474SBiju Das	str	w2, [x0, #CPG_CPGWPR]
177*865e3474SBiju Das	str	w1, [x0, #CPG_SMSTPCR]
178*865e3474SBiju Das5:
179*865e3474SBiju Das	ldr w1, [x0, #CPG_MSTPSR]
180*865e3474SBiju Das	and w1, w1, #MSTP
181*865e3474SBiju Das	cbnz w1, 5b
182*865e3474SBiju Das
183*865e3474SBiju Das	ldr	x0, =SCIF_BASE
184*865e3474SBiju Das	/* Clear bits TE and RE in SCSCR to 0 */
185*865e3474SBiju Das	mov	w1, #(SCSCR_TE_DIS + SCSCR_RE_DIS)
186*865e3474SBiju Das	strh	w1, [x0, #SCIF_SCSCR]
187*865e3474SBiju Das	/* Set bits TFRST and RFRST in SCFCR to 1 */
188*865e3474SBiju Das	ldrh	w1, [x0, #SCIF_SCFCR]
189*865e3474SBiju Das	orr	w1, w1, #(SCFCR_TFRST_EN + SCFCR_RFRS_EN)
190*865e3474SBiju Das	strh	w1, [x0, #SCIF_SCFCR]
191*865e3474SBiju Das	/*
192*865e3474SBiju Das	 * Read flags of ER, DR, BRK, and RDF in SCFSR and those of TO and ORER
193*865e3474SBiju Das	 * in SCLSR, then clear them to 0
194*865e3474SBiju Das	 */
195*865e3474SBiju Das	mov	w1, #SCFSR_INIT_DATA
196*865e3474SBiju Das	strh	w1, [x0, #SCIF_SCFSR]
197*865e3474SBiju Das	mov	w1, #0
198*865e3474SBiju Das	strh	w1, [x0, #SCIF_SCLSR]
199*865e3474SBiju Das	/* Set bits CKE[1:0] in SCSCR */
200*865e3474SBiju Das	ldrh	w1, [x0, #SCIF_SCSCR]
201*865e3474SBiju Das	and	w1, w1, #~SCSCR_CKE_MASK
202*865e3474SBiju Das	mov	w2, #SCSCR_CKE_INT_CLK
203*865e3474SBiju Das	orr	w1, w1, w2
204*865e3474SBiju Das	strh	w1, [x0, #SCIF_SCSCR]
205*865e3474SBiju Das	/* Set data transfer format in SCSMR */
206*865e3474SBiju Das	mov	w1, #SCSMR_INIT_DATA
207*865e3474SBiju Das	strh	w1, [x0, #SCIF_SCSMR]
208*865e3474SBiju Das	/* Set value in SCBRR */
209*865e3474SBiju Das#if SCIF_CLK == SCIF_INTERNAL_CLK
210*865e3474SBiju Das	ldr	x1, =PRR
211*865e3474SBiju Das	ldr	w1, [x1]
212*865e3474SBiju Das	and	w1, w1, #(PRR_PRODUCT_MASK | PRR_CUT_MASK)
213*865e3474SBiju Das	mov	w2, #PRR_PRODUCT_H3_VER_10
214*865e3474SBiju Das	cmp	w1, w2
215*865e3474SBiju Das	beq	3f
216*865e3474SBiju Das	and	w1, w1, #PRR_PRODUCT_MASK
217*865e3474SBiju Das	mov	w2, #PRR_PRODUCT_D3
218*865e3474SBiju Das	cmp	w1, w2
219*865e3474SBiju Das	beq	4f
220*865e3474SBiju Das	and	w1, w1, #PRR_PRODUCT_MASK
221*865e3474SBiju Das	mov	w2, #PRR_PRODUCT_E3
222*865e3474SBiju Das	cmp	w1, w2
223*865e3474SBiju Das	bne	5f
224*865e3474SBiju Das
225*865e3474SBiju Das	ldr	x1, =RST_MODEMR
226*865e3474SBiju Das	ldr	w1, [x1]
227*865e3474SBiju Das	and	w1, w1, #MODEMR_MD12
228*865e3474SBiju Das	mov	w2, #MODEMR_MD12
229*865e3474SBiju Das	cmp	w1, w2
230*865e3474SBiju Das	bne	5f
231*865e3474SBiju Das
232*865e3474SBiju Das	mov	w1, #SCBRR_115200BPS_E3_SSCG
233*865e3474SBiju Das	b	2f
234*865e3474SBiju Das5:
235*865e3474SBiju Das	mov	w1, #SCBRR_115200BPS
236*865e3474SBiju Das	b	2f
237*865e3474SBiju Das4:
238*865e3474SBiju Das	mov	w1, #SCBRR_115200BPSON
239*865e3474SBiju Das	b	2f
240*865e3474SBiju Das3:
241*865e3474SBiju Das	mov	w1, #SCBRR_230400BPS
242*865e3474SBiju Das2:
243*865e3474SBiju Das	strb	w1, [x0, SCIF_SCBRR]
244*865e3474SBiju Das#else
245*865e3474SBiju Das	mov	w1, #DL_INIT_DATA
246*865e3474SBiju Das	strh	w1, [x0, #SCIF_DL]
247*865e3474SBiju Das	mov	w1, #CKS_INIT_DATA
248*865e3474SBiju Das	strh	w1, [x0, #SCIF_CKS]
249*865e3474SBiju Das#endif
250*865e3474SBiju Das	/* 1-bit interval elapsed */
251*865e3474SBiju Das	mov	w1, #100
252*865e3474SBiju Das1:
253*865e3474SBiju Das	subs	w1, w1, #1
254*865e3474SBiju Das	cbnz	w1, 1b
255*865e3474SBiju Das	/*
256*865e3474SBiju Das	 * Set bits RTRG[1:0], TTRG[1:0], and MCE in SCFCR
257*865e3474SBiju Das	 * Clear bits FRST and RFRST to 0
258*865e3474SBiju Das	 */
259*865e3474SBiju Das	mov	w1, #SCFCR_INIT_DATA
260*865e3474SBiju Das	strh	w1, [x0, #SCIF_SCFCR]
261*865e3474SBiju Das	/* Set bits TE and RE in SCSCR to 1 */
262*865e3474SBiju Das	ldrh	w1, [x0, #SCIF_SCSCR]
263*865e3474SBiju Das	orr	w1, w1, #(SCSCR_TE_EN + SCSCR_RE_EN)
264*865e3474SBiju Das	strh	w1, [x0, #SCIF_SCSCR]
265*865e3474SBiju Das	mov	x0, #1
266*865e3474SBiju Das
267*865e3474SBiju Das	ret
268*865e3474SBiju Dasendfunc console_rcar_init
269*865e3474SBiju Das
270*865e3474SBiju Das	/*
271*865e3474SBiju Das	 * int console_rcar_putc(int c, unsigned int base_addr)
272*865e3474SBiju Das	 * Function to output a character over the console. It
273*865e3474SBiju Das	 * returns the character printed on success or -1 on error.
274*865e3474SBiju Das	 * In : w0 - character to be printed
275*865e3474SBiju Das	 *      x1 - pointer to console_t structure
276*865e3474SBiju Das	 * Out : return -1 on error else return character.
277*865e3474SBiju Das	 * Clobber list : x2
278*865e3474SBiju Das	 */
279*865e3474SBiju Dasfunc console_rcar_putc
280*865e3474SBiju Das	ldr	x1, =SCIF_BASE
281*865e3474SBiju Das	cmp	w0, #0xA
282*865e3474SBiju Das	/* Prepend '\r' to '\n' */
283*865e3474SBiju Das	bne	2f
284*865e3474SBiju Das1:
285*865e3474SBiju Das	/* Check if the transmit FIFO is full */
286*865e3474SBiju Das	ldrh	w2, [x1, #SCIF_SCFDR]
287*865e3474SBiju Das	ubfx	w2, w2, #8, #5
288*865e3474SBiju Das	cmp	w2, #16
289*865e3474SBiju Das	bcs	1b
290*865e3474SBiju Das	mov	w2, #0x0D
291*865e3474SBiju Das	strb	w2, [x1, #SCIF_SCFTDR]
292*865e3474SBiju Das2:
293*865e3474SBiju Das	/* Check if the transmit FIFO is full */
294*865e3474SBiju Das	ldrh	w2, [x1, #SCIF_SCFDR]
295*865e3474SBiju Das	ubfx	w2, w2, #8, #5
296*865e3474SBiju Das	cmp	w2, #16
297*865e3474SBiju Das	bcs	2b
298*865e3474SBiju Das	strb	w0, [x1, #SCIF_SCFTDR]
299*865e3474SBiju Das
300*865e3474SBiju Das	/* Clear TEND flag */
301*865e3474SBiju Das	ldrh	w2, [x1, #SCIF_SCFSR]
302*865e3474SBiju Das	and	w2, w2, #~SCFSR_TEND_MASK
303*865e3474SBiju Das	strh	w2, [x1, #SCIF_SCFSR]
304*865e3474SBiju Das
305*865e3474SBiju Das	ret
306*865e3474SBiju Dasendfunc console_rcar_putc
307*865e3474SBiju Das
308*865e3474SBiju Das	/*
309*865e3474SBiju Das	 * void console_rcar_flush(void)
310*865e3474SBiju Das	 * Function to force a write of all buffered
311*865e3474SBiju Das	 * data that hasn't been output. It returns void
312*865e3474SBiju Das	 * Clobber list : x0, x1
313*865e3474SBiju Das	 */
314*865e3474SBiju Dasfunc console_rcar_flush
315*865e3474SBiju Das	ldr	x0, =SCIF_BASE
316*865e3474SBiju Das1:
317*865e3474SBiju Das	/* Check TEND flag */
318*865e3474SBiju Das	ldrh	w1, [x0, #SCIF_SCFSR]
319*865e3474SBiju Das	and	w1, w1, #SCFSR_TEND_MASK
320*865e3474SBiju Das	cmp	w1, #SCFSR_TEND_TRANS_END
321*865e3474SBiju Das	bne	1b
322*865e3474SBiju Das
323*865e3474SBiju Das	ldr	x0, =SCIF_BASE
324*865e3474SBiju Das	ldrh	w1, [x0, #SCIF_SCSCR]
325*865e3474SBiju Das	and	w1, w1, #~(SCSCR_TE_EN + SCSCR_RE_EN)
326*865e3474SBiju Das	strh	w1, [x0, #SCIF_SCSCR]
327*865e3474SBiju Das
328*865e3474SBiju Das	ret
329*865e3474SBiju Dasendfunc console_rcar_flush
330