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