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