1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
4 * Based on Atheros LSDK/QSDK and u-boot_mod project
5 */
6
7#include <config.h>
8#include <asm/asm.h>
9#include <asm/regdef.h>
10#include <asm/mipsregs.h>
11#include <asm/addrspace.h>
12#include <mach/ar71xx_regs.h>
13
14#define SET_BIT(val, bit)   ((val) | (1 << (bit)))
15#define SET_PLL_PD(val)     SET_BIT(val, 30)
16#define AHB_DIV_TO_4(val)   SET_BIT(SET_BIT(val, 15), 16)
17#define PLL_BYPASS(val)     SET_BIT(val, 2)
18
19#define MK_PLL_CONF(divint, refdiv, range, outdiv) \
20     (((0x3F & divint) << 10) | \
21     ((0x1F & refdiv) << 16) | \
22     ((0x1 & range)   << 21) | \
23     ((0x7 & outdiv)  << 23) )
24
25#define MK_CLK_CNTL(cpudiv, ddrdiv, ahbdiv) \
26    (((0x3 & (cpudiv - 1)) << 5)  | \
27    ((0x3 & (ddrdiv - 1)) << 10) | \
28    ((0x3 & (ahbdiv - 1)) << 15) )
29
30/*
31 * PLL_CPU_CONFIG_VAL
32 *
33 * Bit30 is set (CPU_PLLPWD = 1 -> power down control for CPU PLL)
34 * After PLL configuration we need to clear this bit
35 *
36 * Values written into CPU PLL Configuration (CPU_PLL_CONFIG)
37 *
38 * bits 10..15  (6bit)  DIV_INT (Integer part of the DIV to CPU PLL)
39 *                      =>  32  (0x20)  VCOOUT = XTAL * DIV_INT
40 * bits 16..20  (5bit)  REFDIV  (Reference clock divider)
41 *                      =>  1   (0x1)   [Must start at values 1]
42 * bits 21      (1bit)  RANGE   (VCO frequency range of the CPU PLL)
43 *                      =>  0   (0x0)   [Doesn't impact clock values]
44 * bits 23..25  (3bit)  OUTDIV  (Ratio between VCO and PLL output)
45 *                      =>  1   (0x1)   [0 is illegal!]
46 *                              PLLOUT = VCOOUT * (1/2^OUTDIV)
47 */
48/* DIV_INT=32 (25MHz*32/2=400MHz), REFDIV=1, RANGE=0, OUTDIV=1 */
49#define PLL_CPU_CONFIG_VAL_40M  MK_PLL_CONF(20, 1, 0, 1)
50/* DIV_INT=20 (40MHz*20/2=400MHz), REFDIV=1, RANGE=0, OUTDIV=1 */
51#define PLL_CPU_CONFIG_VAL_25M  MK_PLL_CONF(32, 1, 0, 1)
52
53/*
54 * PLL_CLK_CONTROL_VAL
55 *
56 * In PLL_CLK_CONTROL_VAL bit 2 is set (BYPASS = 1 -> bypass PLL)
57 * After PLL configuration we need to clear this bit
58 *
59 * Values written into CPU Clock Control Register CLOCK_CONTROL
60 *
61 * bits 2       (1bit)  BYPASS (Bypass PLL. This defaults to 1 for test.
62 *                      Software must enable the CPU PLL for normal and
63 *                      then set this bit to 0)
64 * bits 5..6    (2bit)  CPU_POST_DIV    =>  0   (DEFAULT, Ratio = 1)
65 *                      CPU_CLK = PLLOUT / CPU_POST_DIV
66 * bits 10..11  (2bit)  DDR_POST_DIV    =>  0   (DEFAULT, Ratio = 1)
67 *                      DDR_CLK = PLLOUT / DDR_POST_DIV
68 * bits 15..16  (2bit)  AHB_POST_DIV    =>  1   (DEFAULT, Ratio = 2)
69 *                      AHB_CLK = PLLOUT / AHB_POST_DIV
70 *
71 */
72#define PLL_CLK_CONTROL_VAL MK_CLK_CNTL(1, 1, 2)
73
74    .text
75    .set noreorder
76
77LEAF(lowlevel_init)
78	/* These three WLAN_RESET will avoid original issue */
79	li      t3, 0x03
801:
81	li      t0, CKSEG1ADDR(AR71XX_RESET_BASE)
82	lw      t1, AR933X_RESET_REG_RESET_MODULE(t0)
83	ori     t1, t1, 0x0800
84	sw      t1, AR933X_RESET_REG_RESET_MODULE(t0)
85	nop
86	lw      t1, AR933X_RESET_REG_RESET_MODULE(t0)
87	li      t2, 0xfffff7ff
88	and     t1, t1, t2
89	sw      t1, AR933X_RESET_REG_RESET_MODULE(t0)
90	nop
91	addi    t3, t3, -1
92	bnez    t3, 1b
93	nop
94
95	li      t2, 0x20
962:
97	beqz    t2, 1b
98	nop
99	addi    t2, t2, -1
100	lw      t5, AR933X_RESET_REG_BOOTSTRAP(t0)
101	andi    t1, t5, 0x10
102	bnez    t1, 2b
103	nop
104
105	li      t1, 0x02110E
106	sw      t1, AR933X_RESET_REG_BOOTSTRAP(t0)
107	nop
108
109	/* RTC Force Wake */
110	li      t0, CKSEG1ADDR(AR933X_RTC_BASE)
111	li      t1, 0x03
112	sw      t1, AR933X_RTC_REG_FORCE_WAKE(t0)
113	nop
114	nop
115
116	/* RTC Reset */
117	li      t1, 0x00
118	sw      t1, AR933X_RTC_REG_RESET(t0)
119	nop
120	nop
121
122	li      t1, 0x01
123	sw      t1, AR933X_RTC_REG_RESET(t0)
124	nop
125	nop
126
127	/* Wait for RTC in on state */
1281:
129	lw      t1, AR933X_RTC_REG_STATUS(t0)
130	andi    t1, t1, 0x02
131	beqz    t1, 1b
132	nop
133
134	/* Program ki/kd */
135	li      t0, CKSEG1ADDR(AR933X_SRIF_BASE)
136	andi    t1, t5, 0x01            # t5 BOOT_STRAP
137	bnez    t1, 1f
138	nop
139	li      t1, 0x19e82f01
140	b       2f
141	nop
1421:
143	li      t1, 0x18e82f01
1442:
145	sw      t1, AR933X_SRIF_DDR_DPLL2_REG(t0)
146
147	/* Program phase shift */
148	lw      t1, AR933X_SRIF_DDR_DPLL3_REG(t0)
149	li      t2, 0xc07fffff
150	and     t1, t1, t2
151	li      t2, 0x800000
152	or      t1, t1, t2
153	sw      t1, AR933X_SRIF_DDR_DPLL3_REG(t0)
154	nop
155
156	/* in some cases, the SoC doesn't start with higher clock on AHB */
157	li      t0, CKSEG1ADDR(AR71XX_PLL_BASE)
158	li      t1, AHB_DIV_TO_4(PLL_BYPASS(PLL_CLK_CONTROL_VAL))
159	sw      t1, AR933X_PLL_CLK_CTRL_REG(t0)
160	nop
161
162	/* Set SETTLE_TIME in CPU PLL */
163	andi    t1, t5, 0x01            # t5 BOOT_STRAP
164	bnez    t1, 1f
165	nop
166	li      t1, 0x0352
167	b       2f
168	nop
1691:
170	li      t1, 0x0550
1712:
172	sw      t1, AR71XX_PLL_REG_SEC_CONFIG(t0)
173	nop
174
175	/* Set nint, frac, refdiv, outdiv, range according to xtal */
1760:
177	andi    t1, t5, 0x01            # t5 BOOT_STRAP
178	bnez    t1, 1f
179	nop
180	li      t1, SET_PLL_PD(PLL_CPU_CONFIG_VAL_25M)
181	b       2f
182	nop
1831:
184	li      t1, SET_PLL_PD(PLL_CPU_CONFIG_VAL_40M)
1852:
186	sw      t1, AR933X_PLL_CPU_CONFIG_REG(t0)
187	nop
1881:
189	lw      t1, AR933X_PLL_CPU_CONFIG_REG(t0)
190	li      t2, 0x80000000
191	and     t1, t1, t2
192	bnez    t1, 1b
193	nop
194
195	/* Put frac bit19:10 configuration */
196	li      t1, 0x1003E8
197	sw      t1, AR933X_PLL_DITHER_FRAC_REG(t0)
198	nop
199
200	/* Clear PLL power down bit in CPU PLL configuration */
201	andi    t1, t5, 0x01            # t5 BOOT_STRAP
202	bnez    t1, 1f
203	nop
204	li      t1, PLL_CPU_CONFIG_VAL_25M
205	b       2f
206	nop
2071:
208	li      t1, PLL_CPU_CONFIG_VAL_40M
2092:
210	sw      t1, AR933X_PLL_CPU_CONFIG_REG(t0)
211	nop
212
213	/* Wait for PLL update -> bit 31 in CPU_PLL_CONFIG should be 0 */
2141:
215	lw      t1, AR933X_PLL_CPU_CONFIG_REG(t0)
216	li      t2, 0x80000000
217	and     t1, t1, t2
218	bnez    t1, 1b
219	nop
220
221	/* Confirm DDR PLL lock */
222	li      t3, 100
223	li      t4, 0
224
2252:
226	addi    t4, t4, 1
227	bgt     t4, t3, 0b
228	nop
229
230	li      t3, 5
2313:
232	/* Clear do_meas */
233	li      t0, CKSEG1ADDR(AR933X_SRIF_BASE)
234	lw      t1, AR933X_SRIF_DDR_DPLL3_REG(t0)
235	li      t2, 0xBFFFFFFF
236	and     t1, t1, t2
237	sw      t1, AR933X_SRIF_DDR_DPLL3_REG(t0)
238	nop
239
240	li      t2, 10
2411:
242	subu    t2, t2, 1
243	bnez    t2, 1b
244	nop
245
246	/* Set do_meas */
247	li      t2, 0x40000000
248	or      t1, t1, t2
249	sw      t1, AR933X_SRIF_DDR_DPLL3_REG(t0)
250	nop
251
252	/* Check meas_done */
2531:
254	lw      t1, AR933X_SRIF_DDR_DPLL4_REG(t0)
255	andi    t1, t1, 0x8
256	beqz    t1, 1b
257	nop
258
259	lw      t1, AR933X_SRIF_DDR_DPLL3_REG(t0)
260	li      t2, 0x007FFFF8
261	and     t1, t1, t2
262	srl     t1, t1, 3
263	li      t2, 0x4000
264	bgt     t1, t2, 2b
265	nop
266	addi    t3, t3, -1
267	bnez    t3, 3b
268	nop
269
270	/* clear PLL bypass (bit 2) in CPU CLOCK CONTROL register */
271	li      t0, CKSEG1ADDR(AR71XX_PLL_BASE)
272	li      t1, PLL_CLK_CONTROL_VAL
273	sw      t1, AR933X_PLL_CLK_CTRL_REG(t0)
274	nop
275
276	nop
277	jr ra
278	nop
279    END(lowlevel_init)
280