1/*
2 * On-chip UART initializaion for low-level debugging
3 *
4 * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
5 *
6 * SPDX-License-Identifier:	GPL-2.0+
7 */
8
9#include <linux/serial_reg.h>
10#include <linux/linkage.h>
11
12#include "../bcu/bcu-regs.h"
13#include "../sc-regs.h"
14#include "../sg-regs.h"
15
16#if !defined(CONFIG_DEBUG_SEMIHOSTING)
17#include CONFIG_DEBUG_LL_INCLUDE
18#endif
19
20#define BAUDRATE		115200
21#define DIV_ROUND(x, d)		(((x) + ((d) / 2)) / (d))
22
23ENTRY(debug_ll_init)
24	ldr		r0, =SG_REVISION
25	ldr		r1, [r0]
26	and		r1, r1, #SG_REVISION_TYPE_MASK
27	mov		r1, r1, lsr #SG_REVISION_TYPE_SHIFT
28
29#if defined(CONFIG_ARCH_UNIPHIER_LD4)
30#define UNIPHIER_LD4_UART_CLK		36864000
31	cmp		r1, #0x26
32	bne		ld4_end
33
34	ldr		r0, =SG_IECTRL
35	ldr		r1, [r0]
36	orr		r1, r1, #1
37	str		r1, [r0]
38
39	sg_set_pinsel	88, 1, 8, 4, r0, r1	@ HSDOUT6 -> TXD0
40
41	ldr		r3, =DIV_ROUND(UNIPHIER_LD4_UART_CLK, 16 * BAUDRATE)
42
43	b		init_uart
44ld4_end:
45#endif
46#if defined(CONFIG_ARCH_UNIPHIER_PRO4)
47#define UNIPHIER_PRO4_UART_CLK		73728000
48	cmp		r1, #0x28
49	bne		pro4_end
50
51	sg_set_pinsel	128, 0, 4, 8, r0, r1	@ TXD0 -> TXD0
52
53	ldr		r0, =SG_LOADPINCTRL
54	mov		r1, #1
55	str		r1, [r0]
56
57	ldr		r0, =SC_CLKCTRL
58	ldr		r1, [r0]
59	orr		r1, r1, #SC_CLKCTRL_CEN_PERI
60	str		r1, [r0]
61
62	ldr		r3, =DIV_ROUND(UNIPHIER_PRO4_UART_CLK, 16 * BAUDRATE)
63
64	b		init_uart
65pro4_end:
66#endif
67#if defined(CONFIG_ARCH_UNIPHIER_SLD8)
68#define UNIPHIER_SLD8_UART_CLK		80000000
69	cmp		r1, #0x29
70	bne		sld8_end
71
72	ldr		r0, =SG_IECTRL
73	ldr		r1, [r0]
74	orr		r1, r1, #1
75	str		r1, [r0]
76
77	sg_set_pinsel	70, 3, 8, 4, r0, r1	@ HSDOUT0 -> TXD0
78
79	ldr		r3, =DIV_ROUND(UNIPHIER_SLD8_UART_CLK, 16 * BAUDRATE)
80
81	b		init_uart
82sld8_end:
83#endif
84#if defined(CONFIG_ARCH_UNIPHIER_PRO5)
85#define UNIPHIER_PRO5_UART_CLK		73728000
86	cmp		r1, #0x2A
87	bne		pro5_end
88
89	sg_set_pinsel	47, 0, 4, 8, r0, r1	@ TXD0 -> TXD0
90	sg_set_pinsel	49, 0, 4, 8, r0, r1	@ TXD1 -> TXD1
91	sg_set_pinsel	51, 0, 4, 8, r0, r1	@ TXD2 -> TXD2
92	sg_set_pinsel	53, 0, 4, 8, r0, r1	@ TXD3 -> TXD3
93
94	ldr		r0, =SG_LOADPINCTRL
95	mov		r1, #1
96	str		r1, [r0]
97
98	ldr		r0, =SC_CLKCTRL
99	ldr		r1, [r0]
100	orr		r1, r1, #SC_CLKCTRL_CEN_PERI
101	str		r1, [r0]
102
103	ldr		r3, =DIV_ROUND(UNIPHIER_PRO5_UART_CLK, 16 * BAUDRATE)
104
105	b		init_uart
106pro5_end:
107#endif
108#if defined(CONFIG_ARCH_UNIPHIER_PXS2)
109#define UNIPHIER_PXS2_UART_CLK		88900000
110	cmp		r1, #0x2E
111	bne		pxs2_end
112
113	ldr		r0, =SG_IECTRL
114	ldr		r1, [r0]
115	orr		r1, r1, #1
116	str		r1, [r0]
117
118	sg_set_pinsel	217, 8, 8, 4, r0, r1	@ TXD0 -> TXD0
119	sg_set_pinsel	115, 8, 8, 4, r0, r1	@ TXD1 -> TXD1
120	sg_set_pinsel	113, 8, 8, 4, r0, r1	@ TXD2 -> TXD2
121	sg_set_pinsel	219, 8, 8, 4, r0, r1	@ TXD3 -> TXD3
122
123	ldr		r0, =SC_CLKCTRL
124	ldr		r1, [r0]
125	orr		r1, r1, #SC_CLKCTRL_CEN_PERI
126	str		r1, [r0]
127
128	ldr		r3, =DIV_ROUND(UNIPHIER_PXS2_UART_CLK, 16 * BAUDRATE)
129
130	b		init_uart
131pxs2_end:
132#endif
133#if defined(CONFIG_ARCH_UNIPHIER_LD6B)
134#define UNIPHIER_LD6B_UART_CLK		88900000
135	cmp		r1, #0x2F
136	bne		ld6b_end
137
138	ldr		r0, =SG_IECTRL
139	ldr		r1, [r0]
140	orr		r1, r1, #1
141	str		r1, [r0]
142
143	sg_set_pinsel	135, 3, 8, 4, r0, r1	@ PORT10 -> TXD0
144	sg_set_pinsel	115, 0, 8, 4, r0, r1	@ TXD1 -> TXD1
145	sg_set_pinsel	113, 2, 8, 4, r0, r1	@ SBO0 -> TXD2
146
147	ldr		r0, =SC_CLKCTRL
148	ldr		r1, [r0]
149	orr		r1, r1, #SC_CLKCTRL_CEN_PERI
150	str		r1, [r0]
151
152	ldr		r3, =DIV_ROUND(UNIPHIER_LD6B_UART_CLK, 16 * BAUDRATE)
153
154	b		init_uart
155ld6b_end:
156#endif
157	mov		pc, lr
158
159init_uart:
160	addruart	r0, r1, r2
161	mov		r1, #UART_LCR_WLEN8 << 8
162	str		r1, [r0, #0x10]
163	str		r3, [r0, #0x24]
164
165	mov		pc, lr
166ENDPROC(debug_ll_init)
167