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