xref: /rk3399_ARM-atf/plat/hisilicon/hikey/hikey_ddr.c (revision 32e9fc1a325952738af33b2b3e73fd0448636034)
1*32e9fc1aSHaojian Zhuang /*
2*32e9fc1aSHaojian Zhuang  * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
3*32e9fc1aSHaojian Zhuang  *
4*32e9fc1aSHaojian Zhuang  * SPDX-License-Identifier: BSD-3-Clause
5*32e9fc1aSHaojian Zhuang  */
6*32e9fc1aSHaojian Zhuang 
7*32e9fc1aSHaojian Zhuang #include <arch_helpers.h>
8*32e9fc1aSHaojian Zhuang #include <debug.h>
9*32e9fc1aSHaojian Zhuang #include <errno.h>
10*32e9fc1aSHaojian Zhuang #include <hi6220.h>
11*32e9fc1aSHaojian Zhuang #include <hi6553.h>
12*32e9fc1aSHaojian Zhuang #include <mmio.h>
13*32e9fc1aSHaojian Zhuang #include <sp804_delay_timer.h>
14*32e9fc1aSHaojian Zhuang 
15*32e9fc1aSHaojian Zhuang enum {
16*32e9fc1aSHaojian Zhuang 	DDR_FREQ_533M = 0,
17*32e9fc1aSHaojian Zhuang 	DDR_FREQ_800M,
18*32e9fc1aSHaojian Zhuang };
19*32e9fc1aSHaojian Zhuang 
20*32e9fc1aSHaojian Zhuang static void init_pll(void)
21*32e9fc1aSHaojian Zhuang {
22*32e9fc1aSHaojian Zhuang 	unsigned int data;
23*32e9fc1aSHaojian Zhuang 
24*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x000));
25*32e9fc1aSHaojian Zhuang 	data |= 0x1;
26*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x000), data);
27*32e9fc1aSHaojian Zhuang 	dsb();
28*32e9fc1aSHaojian Zhuang 	do {
29*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7032000 + 0x000));
30*32e9fc1aSHaojian Zhuang 	} while (!(data & (1 << 28)));
31*32e9fc1aSHaojian Zhuang 
32*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7800000 + 0x000));
33*32e9fc1aSHaojian Zhuang 	data &= ~0x007;
34*32e9fc1aSHaojian Zhuang 	data |= 0x004;
35*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7800000 + 0x000), data);
36*32e9fc1aSHaojian Zhuang 	dsb();
37*32e9fc1aSHaojian Zhuang 	do {
38*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7800000 + 0x014));
39*32e9fc1aSHaojian Zhuang 		data &= 0x007;
40*32e9fc1aSHaojian Zhuang 	} while (data != 0x004);
41*32e9fc1aSHaojian Zhuang 
42*32e9fc1aSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2101);
43*32e9fc1aSHaojian Zhuang 	data = mmio_read_32(PERI_SC_PERIPH_STAT1);
44*32e9fc1aSHaojian Zhuang 	mmio_write_32(0xf7032000 + 0x02c, 0x5110103e);
45*32e9fc1aSHaojian Zhuang 	data = mmio_read_32(0xf7032000 + 0x050);
46*32e9fc1aSHaojian Zhuang 	data |= 1 << 28;
47*32e9fc1aSHaojian Zhuang 	mmio_write_32(0xf7032000 + 0x050, data);
48*32e9fc1aSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2101);
49*32e9fc1aSHaojian Zhuang 	mdelay(1);
50*32e9fc1aSHaojian Zhuang 	data = mmio_read_32(PERI_SC_PERIPH_STAT1);
51*32e9fc1aSHaojian Zhuang 	NOTICE("syspll frequency:%dHz\n", data);
52*32e9fc1aSHaojian Zhuang }
53*32e9fc1aSHaojian Zhuang 
54*32e9fc1aSHaojian Zhuang static void init_freq(void)
55*32e9fc1aSHaojian Zhuang {
56*32e9fc1aSHaojian Zhuang 	unsigned int data, tmp;
57*32e9fc1aSHaojian Zhuang 	unsigned int cpuext_cfg, ddr_cfg;
58*32e9fc1aSHaojian Zhuang 
59*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x374), 0x4a);
60*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x368), 0xda);
61*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x36c), 0x01);
62*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x370), 0x01);
63*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x360), 0x60);
64*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x364), 0x60);
65*32e9fc1aSHaojian Zhuang 
66*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x114), 0x1000);
67*32e9fc1aSHaojian Zhuang 
68*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x110));
69*32e9fc1aSHaojian Zhuang 	data |= (3 << 12);
70*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x110), data);
71*32e9fc1aSHaojian Zhuang 
72*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x110));
73*32e9fc1aSHaojian Zhuang 	data |= (1 << 4);
74*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x110), data);
75*32e9fc1aSHaojian Zhuang 
76*32e9fc1aSHaojian Zhuang 
77*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x110));
78*32e9fc1aSHaojian Zhuang 	data &= ~0x7;
79*32e9fc1aSHaojian Zhuang 	data |= 0x5;
80*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x110), data);
81*32e9fc1aSHaojian Zhuang 	dsb();
82*32e9fc1aSHaojian Zhuang 	mdelay(10);
83*32e9fc1aSHaojian Zhuang 
84*32e9fc1aSHaojian Zhuang 
85*32e9fc1aSHaojian Zhuang 	do {
86*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf6504000 + 0x008));
87*32e9fc1aSHaojian Zhuang 		data &= (3 << 20);
88*32e9fc1aSHaojian Zhuang 	} while (data != (3 << 20));
89*32e9fc1aSHaojian Zhuang 	dsb();
90*32e9fc1aSHaojian Zhuang 	mdelay(10);
91*32e9fc1aSHaojian Zhuang 
92*32e9fc1aSHaojian Zhuang 
93*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf6504000 + 0x054));
94*32e9fc1aSHaojian Zhuang 	data &= ~((1 << 0) | (1 << 11));
95*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf6504000 + 0x054), data);
96*32e9fc1aSHaojian Zhuang 	mdelay(10);
97*32e9fc1aSHaojian Zhuang 
98*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x104));
99*32e9fc1aSHaojian Zhuang 	data &= ~(3 << 8);
100*32e9fc1aSHaojian Zhuang 	data |= (1 << 8);
101*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x104), data);
102*32e9fc1aSHaojian Zhuang 
103*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x100));
104*32e9fc1aSHaojian Zhuang 	data |= (1 << 0);
105*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x100), data);
106*32e9fc1aSHaojian Zhuang 	dsb();
107*32e9fc1aSHaojian Zhuang 
108*32e9fc1aSHaojian Zhuang 	do {
109*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7032000 + 0x100));
110*32e9fc1aSHaojian Zhuang 		data &= (1 << 2);
111*32e9fc1aSHaojian Zhuang 	} while (data != (1 << 2));
112*32e9fc1aSHaojian Zhuang 
113*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf6504000 + 0x06c));
114*32e9fc1aSHaojian Zhuang 	data &= ~0xffff;
115*32e9fc1aSHaojian Zhuang 	data |= 0x56;
116*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf6504000 + 0x06c), data);
117*32e9fc1aSHaojian Zhuang 
118*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf6504000 + 0x06c));
119*32e9fc1aSHaojian Zhuang 	data &= ~(0xffffff << 8);
120*32e9fc1aSHaojian Zhuang 	data |= 0xc7a << 8;
121*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf6504000 + 0x06c), data);
122*32e9fc1aSHaojian Zhuang 
123*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf6504000 + 0x058));
124*32e9fc1aSHaojian Zhuang 	data &= ((1 << 13) - 1);
125*32e9fc1aSHaojian Zhuang 	data |= 0xccb;
126*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf6504000 + 0x058), data);
127*32e9fc1aSHaojian Zhuang 
128*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf6504000 + 0x060), 0x1fff);
129*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf6504000 + 0x064), 0x1ffffff);
130*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf6504000 + 0x068), 0x7fffffff);
131*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf6504000 + 0x05c), 0x1);
132*32e9fc1aSHaojian Zhuang 
133*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf6504000 + 0x054));
134*32e9fc1aSHaojian Zhuang 	data &= ~(0xf << 12);
135*32e9fc1aSHaojian Zhuang 	data |= 1 << 12;
136*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf6504000 + 0x054), data);
137*32e9fc1aSHaojian Zhuang 	dsb();
138*32e9fc1aSHaojian Zhuang 
139*32e9fc1aSHaojian Zhuang 
140*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x000));
141*32e9fc1aSHaojian Zhuang 	data &= ~(1 << 0);
142*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x000), data);
143*32e9fc1aSHaojian Zhuang 
144*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x004), 0x5110207d);
145*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x134), 0x10000005);
146*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x134));
147*32e9fc1aSHaojian Zhuang 
148*32e9fc1aSHaojian Zhuang 
149*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x000));
150*32e9fc1aSHaojian Zhuang 	data |= (1 << 0);
151*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x000), data);
152*32e9fc1aSHaojian Zhuang 
153*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x368), 0x100da);
154*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x378));
155*32e9fc1aSHaojian Zhuang 	data &= ~((1 << 7) - 1);
156*32e9fc1aSHaojian Zhuang 	data |= 0x6b;
157*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x378), data);
158*32e9fc1aSHaojian Zhuang 	dsb();
159*32e9fc1aSHaojian Zhuang 	do {
160*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7032000 + 0x378));
161*32e9fc1aSHaojian Zhuang 		tmp = data & 0x7f;
162*32e9fc1aSHaojian Zhuang 		data = (data & (0x7f << 8)) >> 8;
163*32e9fc1aSHaojian Zhuang 		if (data != tmp)
164*32e9fc1aSHaojian Zhuang 			continue;
165*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7032000 + 0x37c));
166*32e9fc1aSHaojian Zhuang 	} while (!(data & 1));
167*32e9fc1aSHaojian Zhuang 
168*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x104));
169*32e9fc1aSHaojian Zhuang 	data &= ~((3 << 0) |
170*32e9fc1aSHaojian Zhuang 			(3 << 8));
171*32e9fc1aSHaojian Zhuang 	cpuext_cfg = 1;
172*32e9fc1aSHaojian Zhuang 	ddr_cfg = 1;
173*32e9fc1aSHaojian Zhuang 	data |= cpuext_cfg | (ddr_cfg << 8);
174*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x104), data);
175*32e9fc1aSHaojian Zhuang 	dsb();
176*32e9fc1aSHaojian Zhuang 
177*32e9fc1aSHaojian Zhuang 	do {
178*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7032000 + 0x104));
179*32e9fc1aSHaojian Zhuang 		tmp = (data & (3 << 16)) >> 16;
180*32e9fc1aSHaojian Zhuang 		if (cpuext_cfg != tmp)
181*32e9fc1aSHaojian Zhuang 			continue;
182*32e9fc1aSHaojian Zhuang 		tmp = (data & (3 << 24)) >> 24;
183*32e9fc1aSHaojian Zhuang 		if (ddr_cfg != tmp)
184*32e9fc1aSHaojian Zhuang 			continue;
185*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7032000 + 0x000));
186*32e9fc1aSHaojian Zhuang 		data &= 1 << 28;
187*32e9fc1aSHaojian Zhuang 	} while (!data);
188*32e9fc1aSHaojian Zhuang 
189*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x100));
190*32e9fc1aSHaojian Zhuang 	data &= ~(1 << 0);
191*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x100), data);
192*32e9fc1aSHaojian Zhuang 	dsb();
193*32e9fc1aSHaojian Zhuang 	do {
194*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7032000 + 0x100));
195*32e9fc1aSHaojian Zhuang 		data &= (1 << 1);
196*32e9fc1aSHaojian Zhuang 	} while (data != (1 << 1));
197*32e9fc1aSHaojian Zhuang 	mdelay(1000);
198*32e9fc1aSHaojian Zhuang 
199*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf6504000 + 0x054));
200*32e9fc1aSHaojian Zhuang 	data &= ~(1 << 28);
201*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf6504000 + 0x054), data);
202*32e9fc1aSHaojian Zhuang 	dsb();
203*32e9fc1aSHaojian Zhuang 
204*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x110));
205*32e9fc1aSHaojian Zhuang 	data &= ~((1 << 4) |
206*32e9fc1aSHaojian Zhuang 			(3 << 12));
207*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x110), data);
208*32e9fc1aSHaojian Zhuang }
209*32e9fc1aSHaojian Zhuang 
210*32e9fc1aSHaojian Zhuang int cat_533mhz_800mhz(void)
211*32e9fc1aSHaojian Zhuang {
212*32e9fc1aSHaojian Zhuang 	unsigned int data, i;
213*32e9fc1aSHaojian Zhuang 	unsigned int bdl[5];
214*32e9fc1aSHaojian Zhuang 
215*32e9fc1aSHaojian Zhuang 
216*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x1c8));
217*32e9fc1aSHaojian Zhuang 	data &= 0xfffff0f0;
218*32e9fc1aSHaojian Zhuang 	data |= 0x100f0f;
219*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x1c8), data);
220*32e9fc1aSHaojian Zhuang 
221*32e9fc1aSHaojian Zhuang 	for (i = 0; i < 0x20; i++) {
222*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x1d4), 0xc0000);
223*32e9fc1aSHaojian Zhuang 		data = (i << 0x10) + i;
224*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x140), data);
225*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x144), data);
226*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x148), data);
227*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x14c), data);
228*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x150), data);
229*32e9fc1aSHaojian Zhuang 
230*32e9fc1aSHaojian Zhuang 
231*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x070));
232*32e9fc1aSHaojian Zhuang 		data |= 0x80000;
233*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x070), data);
234*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x070));
235*32e9fc1aSHaojian Zhuang 		data &= 0xfff7ffff;
236*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x070), data);
237*32e9fc1aSHaojian Zhuang 
238*32e9fc1aSHaojian Zhuang 
239*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x004), 0x8000);
240*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x004), 0x0);
241*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x004), 0x801);
242*32e9fc1aSHaojian Zhuang 		do {
243*32e9fc1aSHaojian Zhuang 			data = mmio_read_32((0xf712c000 + 0x004));
244*32e9fc1aSHaojian Zhuang 		} while (data & 1);
245*32e9fc1aSHaojian Zhuang 
246*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x008));
247*32e9fc1aSHaojian Zhuang 		if (!(data & 0x400)) {
248*32e9fc1aSHaojian Zhuang 			mdelay(10);
249*32e9fc1aSHaojian Zhuang 			return 0;
250*32e9fc1aSHaojian Zhuang 		}
251*32e9fc1aSHaojian Zhuang 		WARN("lpddr3 cat fail\n");
252*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x1d4));
253*32e9fc1aSHaojian Zhuang 		if ((data & 0x1f00) && ((data & 0x1f) == 0)) {
254*32e9fc1aSHaojian Zhuang 			bdl[0] = mmio_read_32((0xf712c000 + 0x140));
255*32e9fc1aSHaojian Zhuang 			bdl[1] = mmio_read_32((0xf712c000 + 0x144));
256*32e9fc1aSHaojian Zhuang 			bdl[2] = mmio_read_32((0xf712c000 + 0x148));
257*32e9fc1aSHaojian Zhuang 			bdl[3] = mmio_read_32((0xf712c000 + 0x14c));
258*32e9fc1aSHaojian Zhuang 			bdl[4] = mmio_read_32((0xf712c000 + 0x150));
259*32e9fc1aSHaojian Zhuang 			if ((!(bdl[0] & 0x1f001f)) || (!(bdl[1] & 0x1f001f)) ||
260*32e9fc1aSHaojian Zhuang 					(!(bdl[2] & 0x1f001f)) || (!(bdl[3] & 0x1f001f)) ||
261*32e9fc1aSHaojian Zhuang 					(!(bdl[4] & 0x1f001f))) {
262*32e9fc1aSHaojian Zhuang 				WARN("lpddr3 cat deskew error\n");
263*32e9fc1aSHaojian Zhuang 				if (i == 0x1f) {
264*32e9fc1aSHaojian Zhuang 					WARN("addrnbdl is max\n");
265*32e9fc1aSHaojian Zhuang 					return -EINVAL;
266*32e9fc1aSHaojian Zhuang 				}
267*32e9fc1aSHaojian Zhuang 				mmio_write_32((0xf712c000 + 0x008), 0x400);
268*32e9fc1aSHaojian Zhuang 			} else {
269*32e9fc1aSHaojian Zhuang 				WARN("lpddr3 cat other error1\n");
270*32e9fc1aSHaojian Zhuang 				return -EINVAL;
271*32e9fc1aSHaojian Zhuang 			}
272*32e9fc1aSHaojian Zhuang 		} else {
273*32e9fc1aSHaojian Zhuang 			WARN("lpddr3 cat other error2\n");
274*32e9fc1aSHaojian Zhuang 			return -EINVAL;
275*32e9fc1aSHaojian Zhuang 		}
276*32e9fc1aSHaojian Zhuang 	}
277*32e9fc1aSHaojian Zhuang 	return -EINVAL;
278*32e9fc1aSHaojian Zhuang }
279*32e9fc1aSHaojian Zhuang 
280*32e9fc1aSHaojian Zhuang static void ddrx_rdet(void)
281*32e9fc1aSHaojian Zhuang {
282*32e9fc1aSHaojian Zhuang 	unsigned int data, rdet, bdl[4];
283*32e9fc1aSHaojian Zhuang 
284*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x0d0));
285*32e9fc1aSHaojian Zhuang 	data &= 0xf800ffff;
286*32e9fc1aSHaojian Zhuang 	data |= 0x8f0000;
287*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x0d0), data);
288*32e9fc1aSHaojian Zhuang 
289*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x0dc));
290*32e9fc1aSHaojian Zhuang 	data &= 0xfffffff0;
291*32e9fc1aSHaojian Zhuang 	data |= 0xf;
292*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x0dc), data);
293*32e9fc1aSHaojian Zhuang 
294*32e9fc1aSHaojian Zhuang 
295*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x070));
296*32e9fc1aSHaojian Zhuang 	data |= 0x80000;
297*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x070), data);
298*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x070));
299*32e9fc1aSHaojian Zhuang 	data &= 0xfff7ffff;
300*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x070), data);
301*32e9fc1aSHaojian Zhuang 
302*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x004), 0x8000);
303*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x004), 0);
304*32e9fc1aSHaojian Zhuang 
305*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x0d0));
306*32e9fc1aSHaojian Zhuang 	data &= ~0xf0000000;
307*32e9fc1aSHaojian Zhuang 	data |= 0x80000000;
308*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x0d0), data);
309*32e9fc1aSHaojian Zhuang 
310*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x004), 0x101);
311*32e9fc1aSHaojian Zhuang 	do {
312*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x004));
313*32e9fc1aSHaojian Zhuang 	} while (!(data & 1));
314*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x008));
315*32e9fc1aSHaojian Zhuang 	if (data & 0x100)
316*32e9fc1aSHaojian Zhuang 		WARN("rdet lbs fail\n");
317*32e9fc1aSHaojian Zhuang 
318*32e9fc1aSHaojian Zhuang 	bdl[0] = mmio_read_32((0xf712c000 + 0x22c)) & 0x7f;
319*32e9fc1aSHaojian Zhuang 	bdl[1] = mmio_read_32((0xf712c000 + 0x2ac)) & 0x7f;
320*32e9fc1aSHaojian Zhuang 	bdl[2] = mmio_read_32((0xf712c000 + 0x32c)) & 0x7f;
321*32e9fc1aSHaojian Zhuang 	bdl[3] = mmio_read_32((0xf712c000 + 0x3ac)) & 0x7f;
322*32e9fc1aSHaojian Zhuang 	do {
323*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x22c));
324*32e9fc1aSHaojian Zhuang 		data &= ~0x7f;
325*32e9fc1aSHaojian Zhuang 		data |= bdl[0];
326*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x22c), data);
327*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x2ac));
328*32e9fc1aSHaojian Zhuang 		data &= ~0x7f;
329*32e9fc1aSHaojian Zhuang 		data |= bdl[1];
330*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x2ac), data);
331*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x32c));
332*32e9fc1aSHaojian Zhuang 		data &= ~0x7f;
333*32e9fc1aSHaojian Zhuang 		data |= bdl[2];
334*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x32c), data);
335*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x3ac));
336*32e9fc1aSHaojian Zhuang 		data &= ~0x7f;
337*32e9fc1aSHaojian Zhuang 		data |= bdl[3];
338*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x3ac), data);
339*32e9fc1aSHaojian Zhuang 
340*32e9fc1aSHaojian Zhuang 
341*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x070));
342*32e9fc1aSHaojian Zhuang 		data |= 0x80000;
343*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x070), data);
344*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x070));
345*32e9fc1aSHaojian Zhuang 		data &= 0xfff7ffff;
346*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x070), data);
347*32e9fc1aSHaojian Zhuang 
348*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x004), 0x8000);
349*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x004), 0);
350*32e9fc1aSHaojian Zhuang 
351*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x0d0));
352*32e9fc1aSHaojian Zhuang 		data &= ~0xf0000000;
353*32e9fc1aSHaojian Zhuang 		data |= 0x40000000;
354*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x0d0), data);
355*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x004), 0x101);
356*32e9fc1aSHaojian Zhuang 		do {
357*32e9fc1aSHaojian Zhuang 			data = mmio_read_32((0xf712c000 + 0x004));
358*32e9fc1aSHaojian Zhuang 		} while (data & 1);
359*32e9fc1aSHaojian Zhuang 
360*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x008));
361*32e9fc1aSHaojian Zhuang 		rdet = data & 0x100;
362*32e9fc1aSHaojian Zhuang 		if (rdet) {
363*32e9fc1aSHaojian Zhuang 			INFO("rdet ds fail\n");
364*32e9fc1aSHaojian Zhuang 			mmio_write_32((0xf712c000 + 0x008), 0x100);
365*32e9fc1aSHaojian Zhuang 		}
366*32e9fc1aSHaojian Zhuang 		bdl[0]++;
367*32e9fc1aSHaojian Zhuang 		bdl[1]++;
368*32e9fc1aSHaojian Zhuang 		bdl[2]++;
369*32e9fc1aSHaojian Zhuang 		bdl[3]++;
370*32e9fc1aSHaojian Zhuang 	} while (rdet);
371*32e9fc1aSHaojian Zhuang 
372*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x0d0));
373*32e9fc1aSHaojian Zhuang 	data &= ~0xf0000000;
374*32e9fc1aSHaojian Zhuang 	data |= 0x30000000;
375*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x0d0), data);
376*32e9fc1aSHaojian Zhuang 
377*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x004), 0x101);
378*32e9fc1aSHaojian Zhuang 	do {
379*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x004));
380*32e9fc1aSHaojian Zhuang 	} while (data & 1);
381*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x008));
382*32e9fc1aSHaojian Zhuang 	if (data & 0x100)
383*32e9fc1aSHaojian Zhuang 		INFO("rdet rbs av fail\n");
384*32e9fc1aSHaojian Zhuang }
385*32e9fc1aSHaojian Zhuang 
386*32e9fc1aSHaojian Zhuang static void ddrx_wdet(void)
387*32e9fc1aSHaojian Zhuang {
388*32e9fc1aSHaojian Zhuang 	unsigned int data, wdet, zero_bdl, dq[4];
389*32e9fc1aSHaojian Zhuang 	int i;
390*32e9fc1aSHaojian Zhuang 
391*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x0d0));
392*32e9fc1aSHaojian Zhuang 	data &= ~0xf;
393*32e9fc1aSHaojian Zhuang 	data |= 0xf;
394*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x0d0), data);
395*32e9fc1aSHaojian Zhuang 
396*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x070));
397*32e9fc1aSHaojian Zhuang 	data |= 0x80000;
398*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x070), data);
399*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x070));
400*32e9fc1aSHaojian Zhuang 	data &= ~0x80000;
401*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x070), data);
402*32e9fc1aSHaojian Zhuang 
403*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x004), 0x8000);
404*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x004), 0);
405*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x0d0));
406*32e9fc1aSHaojian Zhuang 	data &= ~0xf000;
407*32e9fc1aSHaojian Zhuang 	data |= 0x8000;
408*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x0d0), data);
409*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x004), 0x201);
410*32e9fc1aSHaojian Zhuang 	do {
411*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x004));
412*32e9fc1aSHaojian Zhuang 	} while (data & 1);
413*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x008));
414*32e9fc1aSHaojian Zhuang 	if (data & 0x200)
415*32e9fc1aSHaojian Zhuang 		INFO("wdet lbs fail\n");
416*32e9fc1aSHaojian Zhuang 
417*32e9fc1aSHaojian Zhuang 	dq[0] = mmio_read_32((0xf712c000 + 0x234)) & 0x1f00;
418*32e9fc1aSHaojian Zhuang 	dq[1] = mmio_read_32((0xf712c000 + 0x2b4)) & 0x1f00;
419*32e9fc1aSHaojian Zhuang 	dq[2] = mmio_read_32((0xf712c000 + 0x334)) & 0x1f00;
420*32e9fc1aSHaojian Zhuang 	dq[3] = mmio_read_32((0xf712c000 + 0x3b4)) & 0x1f00;
421*32e9fc1aSHaojian Zhuang 
422*32e9fc1aSHaojian Zhuang 	do {
423*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x234), dq[0]);
424*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x2b4), dq[1]);
425*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x334), dq[2]);
426*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x3b4), dq[3]);
427*32e9fc1aSHaojian Zhuang 
428*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x070));
429*32e9fc1aSHaojian Zhuang 		data |= 0x80000;
430*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x070), data);
431*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x070));
432*32e9fc1aSHaojian Zhuang 		data &= ~0x80000;
433*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x070), data);
434*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x004), 0x8000);
435*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x004), 0);
436*32e9fc1aSHaojian Zhuang 
437*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x0d0));
438*32e9fc1aSHaojian Zhuang 		data &= ~0xf000;
439*32e9fc1aSHaojian Zhuang 		data |= 0x4000;
440*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x0d0), data);
441*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x004), 0x201);
442*32e9fc1aSHaojian Zhuang 		do {
443*32e9fc1aSHaojian Zhuang 			data = mmio_read_32((0xf712c000 + 0x004));
444*32e9fc1aSHaojian Zhuang 		} while (data & 1);
445*32e9fc1aSHaojian Zhuang 
446*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x008));
447*32e9fc1aSHaojian Zhuang 		wdet = data & 0x200;
448*32e9fc1aSHaojian Zhuang 		if (wdet) {
449*32e9fc1aSHaojian Zhuang 			INFO("wdet ds fail\n");
450*32e9fc1aSHaojian Zhuang 			mmio_write_32((0xf712c000 + 0x008), 0x200);
451*32e9fc1aSHaojian Zhuang 		}
452*32e9fc1aSHaojian Zhuang 		mdelay(10);
453*32e9fc1aSHaojian Zhuang 
454*32e9fc1aSHaojian Zhuang 		for (i = 0; i < 4; i++) {
455*32e9fc1aSHaojian Zhuang 			data = mmio_read_32((0xf712c000 + 0x210 + i * 0x80));
456*32e9fc1aSHaojian Zhuang 			if ((!(data & 0x1f)) || (!(data & 0x1f00)) ||
457*32e9fc1aSHaojian Zhuang 					(!(data & 0x1f0000)) || (!(data & 0x1f000000)))
458*32e9fc1aSHaojian Zhuang 				zero_bdl = 1;
459*32e9fc1aSHaojian Zhuang 			data = mmio_read_32((0xf712c000 + 0x214 + i * 0x80));
460*32e9fc1aSHaojian Zhuang 			if ((!(data & 0x1f)) || (!(data & 0x1f00)) ||
461*32e9fc1aSHaojian Zhuang 					(!(data & 0x1f0000)) || (!(data & 0x1f000000)))
462*32e9fc1aSHaojian Zhuang 				zero_bdl = 1;
463*32e9fc1aSHaojian Zhuang 			data = mmio_read_32((0xf712c000 + 0x218 + i * 0x80));
464*32e9fc1aSHaojian Zhuang 			if (!(data & 0x1f))
465*32e9fc1aSHaojian Zhuang 				zero_bdl = 1;
466*32e9fc1aSHaojian Zhuang 			if (zero_bdl) {
467*32e9fc1aSHaojian Zhuang 				if (i == 0)
468*32e9fc1aSHaojian Zhuang 					dq[0] = dq[0] - 0x100;
469*32e9fc1aSHaojian Zhuang 				if (i == 1)
470*32e9fc1aSHaojian Zhuang 					dq[1] = dq[1] - 0x100;
471*32e9fc1aSHaojian Zhuang 				if (i == 2)
472*32e9fc1aSHaojian Zhuang 					dq[2] = dq[2] - 0x100;
473*32e9fc1aSHaojian Zhuang 				if (i == 3)
474*32e9fc1aSHaojian Zhuang 					dq[3] = dq[3] - 0x100;
475*32e9fc1aSHaojian Zhuang 			}
476*32e9fc1aSHaojian Zhuang 		}
477*32e9fc1aSHaojian Zhuang 	} while (wdet);
478*32e9fc1aSHaojian Zhuang 
479*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x0d0));
480*32e9fc1aSHaojian Zhuang 	data &= ~0xf000;
481*32e9fc1aSHaojian Zhuang 	data |= 0x3000;
482*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x0d0), data);
483*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x004), 0x201);
484*32e9fc1aSHaojian Zhuang 	do {
485*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x004));
486*32e9fc1aSHaojian Zhuang 	} while (data & 1);
487*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x008));
488*32e9fc1aSHaojian Zhuang 	if (data & 0x200)
489*32e9fc1aSHaojian Zhuang 		INFO("wdet rbs av fail\n");
490*32e9fc1aSHaojian Zhuang }
491*32e9fc1aSHaojian Zhuang 
492*32e9fc1aSHaojian Zhuang static void set_ddrc_533mhz(void)
493*32e9fc1aSHaojian Zhuang {
494*32e9fc1aSHaojian Zhuang 	unsigned int data;
495*32e9fc1aSHaojian Zhuang 
496*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x580), 0x3);
497*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x5a8), 0x11111);
498*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x104));
499*32e9fc1aSHaojian Zhuang 	data |= 0x100;
500*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x104), data);
501*32e9fc1aSHaojian Zhuang 
502*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7030000 + 0x050), 0x30);
503*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7030000 + 0x240), 0x5ffff);
504*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7030000 + 0x344), 0xf5ff);
505*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x00c), 0x400);
506*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x018), 0x7);
507*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x090), 0x6400000);
508*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x258), 0x640);
509*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x2d8), 0x640);
510*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x358), 0x640);
511*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x3d8), 0x640);
512*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x018), 0x0);
513*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x0b0), 0xf00000f);
514*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x0b4), 0xf);
515*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x088), 0x3fff801);
516*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x070), 0x8940000);
517*32e9fc1aSHaojian Zhuang 
518*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x078));
519*32e9fc1aSHaojian Zhuang 	data |= 4;
520*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x078), data);
521*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x01c), 0x8000080);
522*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x020));
523*32e9fc1aSHaojian Zhuang 	data &= 0xfffffffe;
524*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x020), data);
525*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x1d4), 0xc0000);
526*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x010), 0x500000f);
527*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x014), 0x10);
528*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x1e4));
529*32e9fc1aSHaojian Zhuang 	data &= 0xffffff00;
530*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x1e4), data);
531*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x030), 0x9dd87855);
532*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x034), 0xa7138bb);
533*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x038), 0x20091477);
534*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x03c), 0x84534e16);
535*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x040), 0x3008817);
536*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x064), 0x106c3);
537*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x068), 0xff0a0000);
538*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x070));
539*32e9fc1aSHaojian Zhuang 	data &= 0xffff0000;
540*32e9fc1aSHaojian Zhuang 	data |= 0x305;
541*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x070), data);
542*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x048));
543*32e9fc1aSHaojian Zhuang 	data |= 0x40000000;
544*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x048), data);
545*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x020));
546*32e9fc1aSHaojian Zhuang 	data &= ~0x10;
547*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x020), data);
548*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x080));
549*32e9fc1aSHaojian Zhuang 	data &= ~0x2000;
550*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x080), data);
551*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x270), 0x3);
552*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x2f0), 0x3);
553*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x370), 0x3);
554*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x3f0), 0x3);
555*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x048), 0xd0420900);
556*32e9fc1aSHaojian Zhuang 
557*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x040), 0x0);
558*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x004), 0x140f);
559*32e9fc1aSHaojian Zhuang 	do {
560*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x004));
561*32e9fc1aSHaojian Zhuang 	} while (data & 1);
562*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x008));
563*32e9fc1aSHaojian Zhuang 	if (data & 0x7fe) {
564*32e9fc1aSHaojian Zhuang 		NOTICE("failed to init lpddr3 rank0 dram phy\n");
565*32e9fc1aSHaojian Zhuang 		return;
566*32e9fc1aSHaojian Zhuang 	}
567*32e9fc1aSHaojian Zhuang 	NOTICE("succeed to init lpddr3 rank0 dram phy\n");
568*32e9fc1aSHaojian Zhuang }
569*32e9fc1aSHaojian Zhuang 
570*32e9fc1aSHaojian Zhuang static void set_ddrc_800mhz(void)
571*32e9fc1aSHaojian Zhuang {
572*32e9fc1aSHaojian Zhuang 	unsigned int data;
573*32e9fc1aSHaojian Zhuang 
574*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x580), 0x2);
575*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x5a8), 0x1003);
576*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x104));
577*32e9fc1aSHaojian Zhuang 	data &= 0xfffffcff;
578*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x104), data);
579*32e9fc1aSHaojian Zhuang 
580*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7030000 + 0x050), 0x30);
581*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7030000 + 0x240), 0x5ffff);
582*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7030000 + 0x344), 0xf5ff);
583*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x00c), 0x400);
584*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x018), 0x7);
585*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x090), 0x5400000);
586*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x258), 0x540);
587*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x2d8), 0x540);
588*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x358), 0x540);
589*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x3d8), 0x540);
590*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x018), 0x0);
591*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x0b0), 0xf00000f);
592*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x0b4), 0xf);
593*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x088), 0x3fff801);
594*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x070), 0x8940000);
595*32e9fc1aSHaojian Zhuang 
596*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x078));
597*32e9fc1aSHaojian Zhuang 	data |= 4;
598*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x078), data);
599*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x01c), 0x8000080);
600*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x020));
601*32e9fc1aSHaojian Zhuang 	data &= 0xfffffffe;
602*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x020), data);
603*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x1d4), 0xc0000);
604*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x010), 0x500000f);
605*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x014), 0x10);
606*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x1e4));
607*32e9fc1aSHaojian Zhuang 	data &= 0xffffff00;
608*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x1e4), data);
609*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x030), 0xe663ab77);
610*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x034), 0xea952db);
611*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x038), 0x200d1cb1);
612*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x03c), 0xc67d0721);
613*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x040), 0x3008aa1);
614*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x064), 0x11a43);
615*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x068), 0xff0a0000);
616*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x070));
617*32e9fc1aSHaojian Zhuang 	data &= 0xffff0000;
618*32e9fc1aSHaojian Zhuang 	data |= 0x507;
619*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x070), data);
620*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x048));
621*32e9fc1aSHaojian Zhuang 	data |= 0x40000000;
622*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x048), data);
623*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x020));
624*32e9fc1aSHaojian Zhuang 	data &= 0xffffffef;
625*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x020), data);
626*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x080));
627*32e9fc1aSHaojian Zhuang 	data &= 0xffffdfff;
628*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x080), data);
629*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x270), 0x3);
630*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x2f0), 0x3);
631*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x370), 0x3);
632*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x3f0), 0x3);
633*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x048), 0xd0420900);
634*32e9fc1aSHaojian Zhuang 
635*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x040), 0x2001);
636*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x004), 0x140f);
637*32e9fc1aSHaojian Zhuang 	do {
638*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x004));
639*32e9fc1aSHaojian Zhuang 	} while (data & 1);
640*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x008));
641*32e9fc1aSHaojian Zhuang 	if (data & 0x7fe) {
642*32e9fc1aSHaojian Zhuang 		WARN("failed to init lpddr3 rank0 dram phy\n");
643*32e9fc1aSHaojian Zhuang 		return;
644*32e9fc1aSHaojian Zhuang 	}
645*32e9fc1aSHaojian Zhuang }
646*32e9fc1aSHaojian Zhuang 
647*32e9fc1aSHaojian Zhuang static void ddrc_common_init(int ddr800)
648*32e9fc1aSHaojian Zhuang {
649*32e9fc1aSHaojian Zhuang 	unsigned int data;
650*32e9fc1aSHaojian Zhuang 
651*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x020), 0x1);
652*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x100), 0x1700);
653*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x104), 0x71040004);
654*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7121400 + 0x104), 0xf);
655*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7121800 + 0x104), 0xf);
656*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7121800 + 0x104), 0xf);
657*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7121c00 + 0x104), 0xf);
658*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7122000 + 0x104), 0xf);
659*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x02c), 0x6);
660*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x020), 0x1);
661*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x028), 0x310201);
662*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x1e4), 0xfe007600);
663*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x01c), 0xaf001);
664*32e9fc1aSHaojian Zhuang 
665*32e9fc1aSHaojian Zhuang 
666*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7128000 + 0x280));
667*32e9fc1aSHaojian Zhuang 	data |= 1 << 7;
668*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x280), data);
669*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x244), 0x3);
670*32e9fc1aSHaojian Zhuang 
671*32e9fc1aSHaojian Zhuang 	if (ddr800)
672*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x240), 167 * 400000 / 1024);
673*32e9fc1aSHaojian Zhuang 	else
674*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x240), 167 * 533000 / 1024);
675*32e9fc1aSHaojian Zhuang 
676*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x080));
677*32e9fc1aSHaojian Zhuang 	data &= 0xffff;
678*32e9fc1aSHaojian Zhuang 	data |= 0x4002000;
679*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x080), data);
680*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x000), 0x0);
681*32e9fc1aSHaojian Zhuang 	do {
682*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7128000 + 0x294));
683*32e9fc1aSHaojian Zhuang 	} while (data & 1);
684*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x000), 0x2);
685*32e9fc1aSHaojian Zhuang }
686*32e9fc1aSHaojian Zhuang 
687*32e9fc1aSHaojian Zhuang 
688*32e9fc1aSHaojian Zhuang static int dienum_det_and_rowcol_cfg(void)
689*32e9fc1aSHaojian Zhuang {
690*32e9fc1aSHaojian Zhuang 	unsigned int data;
691*32e9fc1aSHaojian Zhuang 
692*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x210), 0x87);
693*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x218), 0x10000);
694*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x00c), 0x1);
695*32e9fc1aSHaojian Zhuang 	do {
696*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7128000 + 0x00c));
697*32e9fc1aSHaojian Zhuang 	} while (data & 1);
698*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7128000 + 0x4a8)) & 0xfc;
699*32e9fc1aSHaojian Zhuang 	switch (data) {
700*32e9fc1aSHaojian Zhuang 	case 0x18:
701*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x060), 0x132);
702*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x064), 0x132);
703*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7120000 + 0x100), 0x1600);
704*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7120000 + 0x104), 0x71040004);
705*32e9fc1aSHaojian Zhuang 		break;
706*32e9fc1aSHaojian Zhuang 	case 0x1c:
707*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x060), 0x142);
708*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x064), 0x142);
709*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7120000 + 0x100), 0x1700);
710*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7120000 + 0x104), 0x71040004);
711*32e9fc1aSHaojian Zhuang 		break;
712*32e9fc1aSHaojian Zhuang 	case 0x58:
713*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x060), 0x133);
714*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x064), 0x133);
715*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7120000 + 0x100), 0x1700);
716*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7120000 + 0x104), 0x71040004);
717*32e9fc1aSHaojian Zhuang 		break;
718*32e9fc1aSHaojian Zhuang 	default:
719*32e9fc1aSHaojian Zhuang 		break;
720*32e9fc1aSHaojian Zhuang 	}
721*32e9fc1aSHaojian Zhuang 	if (!data)
722*32e9fc1aSHaojian Zhuang 		return -EINVAL;
723*32e9fc1aSHaojian Zhuang 	return 0;
724*32e9fc1aSHaojian Zhuang }
725*32e9fc1aSHaojian Zhuang 
726*32e9fc1aSHaojian Zhuang static int detect_ddr_chip_info(void)
727*32e9fc1aSHaojian Zhuang {
728*32e9fc1aSHaojian Zhuang 	unsigned int data, mr5, mr6, mr7;
729*32e9fc1aSHaojian Zhuang 
730*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x210), 0x57);
731*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x218), 0x10000);
732*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x00c), 0x1);
733*32e9fc1aSHaojian Zhuang 
734*32e9fc1aSHaojian Zhuang 	do {
735*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7128000 + 0x00c));
736*32e9fc1aSHaojian Zhuang 	} while (data & 1);
737*32e9fc1aSHaojian Zhuang 
738*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7128000 + 0x4a8));
739*32e9fc1aSHaojian Zhuang 	mr5 = data & 0xff;
740*32e9fc1aSHaojian Zhuang 	switch (mr5) {
741*32e9fc1aSHaojian Zhuang 	case 1:
742*32e9fc1aSHaojian Zhuang 		INFO("Samsung DDR\n");
743*32e9fc1aSHaojian Zhuang 		break;
744*32e9fc1aSHaojian Zhuang 	case 6:
745*32e9fc1aSHaojian Zhuang 		INFO("Hynix DDR\n");
746*32e9fc1aSHaojian Zhuang 		break;
747*32e9fc1aSHaojian Zhuang 	case 3:
748*32e9fc1aSHaojian Zhuang 		INFO("Elpida DDR\n");
749*32e9fc1aSHaojian Zhuang 		break;
750*32e9fc1aSHaojian Zhuang 	default:
751*32e9fc1aSHaojian Zhuang 		INFO("DDR from other vendors\n");
752*32e9fc1aSHaojian Zhuang 		break;
753*32e9fc1aSHaojian Zhuang 	}
754*32e9fc1aSHaojian Zhuang 
755*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x210), 0x67);
756*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x218), 0x10000);
757*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x00c), 0x1);
758*32e9fc1aSHaojian Zhuang 	do {
759*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7128000 + 0x00c));
760*32e9fc1aSHaojian Zhuang 	} while (data & 1);
761*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7128000 + 0x4a8));
762*32e9fc1aSHaojian Zhuang 	mr6 = data & 0xff;
763*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x210), 0x77);
764*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x218), 0x10000);
765*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x00c), 0x1);
766*32e9fc1aSHaojian Zhuang 	do {
767*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7128000 + 0x00c));
768*32e9fc1aSHaojian Zhuang 	} while (data & 1);
769*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7128000 + 0x4a8));
770*32e9fc1aSHaojian Zhuang 	mr7 = data & 0xff;
771*32e9fc1aSHaojian Zhuang 	data = mr5 + (mr6 << 8) + (mr7 << 16);
772*32e9fc1aSHaojian Zhuang 	return data;
773*32e9fc1aSHaojian Zhuang }
774*32e9fc1aSHaojian Zhuang 
775*32e9fc1aSHaojian Zhuang int lpddr3_freq_init(int freq)
776*32e9fc1aSHaojian Zhuang {
777*32e9fc1aSHaojian Zhuang 	unsigned int data;
778*32e9fc1aSHaojian Zhuang 
779*32e9fc1aSHaojian Zhuang 	if (freq == DDR_FREQ_800M) {
780*32e9fc1aSHaojian Zhuang 		set_ddrc_800mhz();
781*32e9fc1aSHaojian Zhuang 		INFO("%s, set ddrc 800mhz\n", __func__);
782*32e9fc1aSHaojian Zhuang 	} else {
783*32e9fc1aSHaojian Zhuang 		set_ddrc_533mhz();
784*32e9fc1aSHaojian Zhuang 		INFO("%s, set ddrc 533mhz\n", __func__);
785*32e9fc1aSHaojian Zhuang 	}
786*32e9fc1aSHaojian Zhuang 
787*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x004), 0xf1);
788*32e9fc1aSHaojian Zhuang 	if (freq == DDR_FREQ_800M)
789*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x050), 0x100023);
790*32e9fc1aSHaojian Zhuang 	else
791*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x050), 0x100123);
792*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x060), 0x133);
793*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x064), 0x133);
794*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x200), 0xa1000);
795*32e9fc1aSHaojian Zhuang 
796*32e9fc1aSHaojian Zhuang 	if (freq == DDR_FREQ_800M) {
797*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x100), 0x755a9d12);
798*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x104), 0x1753b055);
799*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x108), 0x7401505f);
800*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x10c), 0x578ca244);
801*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x110), 0x10700000);
802*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x114), 0x13141306);
803*32e9fc1aSHaojian Zhuang 	} else {
804*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x100), 0xb77b6718);
805*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x104), 0x1e82a071);
806*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x108), 0x9501c07e);
807*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x10c), 0xaf50c255);
808*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x110), 0x10b00000);
809*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x114), 0x13181908);
810*32e9fc1aSHaojian Zhuang 	}
811*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x118), 0x44);
812*32e9fc1aSHaojian Zhuang 	do {
813*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x004));
814*32e9fc1aSHaojian Zhuang 	} while (data & 1);
815*32e9fc1aSHaojian Zhuang 
816*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x008));
817*32e9fc1aSHaojian Zhuang 	if (data & 0x7fe) {
818*32e9fc1aSHaojian Zhuang 		NOTICE("fail to init ddr3 rank0\n");
819*32e9fc1aSHaojian Zhuang 		return -EFAULT;
820*32e9fc1aSHaojian Zhuang 	}
821*32e9fc1aSHaojian Zhuang 	INFO("init ddr3 rank0\n");
822*32e9fc1aSHaojian Zhuang 	ddrx_rdet();
823*32e9fc1aSHaojian Zhuang 	ddrx_wdet();
824*32e9fc1aSHaojian Zhuang 
825*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x048));
826*32e9fc1aSHaojian Zhuang 	data |= 1;
827*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x048), data);
828*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x004), 0x21);
829*32e9fc1aSHaojian Zhuang 	do {
830*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x004));
831*32e9fc1aSHaojian Zhuang 	} while (data & 1);
832*32e9fc1aSHaojian Zhuang 
833*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x008));
834*32e9fc1aSHaojian Zhuang 	if (data & 0x7fe)
835*32e9fc1aSHaojian Zhuang 		NOTICE("ddr3 rank1 init failure\n");
836*32e9fc1aSHaojian Zhuang 	else
837*32e9fc1aSHaojian Zhuang 		INFO("ddr3 rank1 init pass\n");
838*32e9fc1aSHaojian Zhuang 
839*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x048));
840*32e9fc1aSHaojian Zhuang 	data &= ~0xf;
841*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x048), data);
842*32e9fc1aSHaojian Zhuang 	return 0;
843*32e9fc1aSHaojian Zhuang }
844*32e9fc1aSHaojian Zhuang 
845*32e9fc1aSHaojian Zhuang static void init_ddr(int freq)
846*32e9fc1aSHaojian Zhuang {
847*32e9fc1aSHaojian Zhuang 	unsigned int data;
848*32e9fc1aSHaojian Zhuang 	int ret;
849*32e9fc1aSHaojian Zhuang 
850*32e9fc1aSHaojian Zhuang 
851*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x030));
852*32e9fc1aSHaojian Zhuang 	data |= 1;
853*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x030), data);
854*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x010));
855*32e9fc1aSHaojian Zhuang 	data |= 1;
856*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x010), data);
857*32e9fc1aSHaojian Zhuang 
858*32e9fc1aSHaojian Zhuang 	udelay(100);
859*32e9fc1aSHaojian Zhuang 	do {
860*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7032000 + 0x030));
861*32e9fc1aSHaojian Zhuang 		data &= 3 << 28;
862*32e9fc1aSHaojian Zhuang 	} while (data != (3 << 28));
863*32e9fc1aSHaojian Zhuang 	do {
864*32e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7032000 + 0x010));
865*32e9fc1aSHaojian Zhuang 		data &= 3 << 28;
866*32e9fc1aSHaojian Zhuang 	} while (data != (3 << 28));
867*32e9fc1aSHaojian Zhuang 
868*32e9fc1aSHaojian Zhuang 	ret = lpddr3_freq_init(freq);
869*32e9fc1aSHaojian Zhuang 	if (ret)
870*32e9fc1aSHaojian Zhuang 		return;
871*32e9fc1aSHaojian Zhuang }
872*32e9fc1aSHaojian Zhuang 
873*32e9fc1aSHaojian Zhuang static void init_ddrc_qos(void)
874*32e9fc1aSHaojian Zhuang {
875*32e9fc1aSHaojian Zhuang 	unsigned int port, data;
876*32e9fc1aSHaojian Zhuang 
877*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x088), 1);
878*32e9fc1aSHaojian Zhuang 
879*32e9fc1aSHaojian Zhuang 	port = 0;
880*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x200 + port * 0x10), 0x1210);
881*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x204 + port * 0x10), 0x11111111);
882*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x208 + port * 0x10), 0x11111111);
883*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x400 + 0 * 0x10), 0x001d0007);
884*32e9fc1aSHaojian Zhuang 
885*32e9fc1aSHaojian Zhuang 	for (port = 3; port <= 4; port++) {
886*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7120000 + 0x200 + port * 0x10), 0x1210);
887*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7120000 + 0x204 + port * 0x10), 0x77777777);
888*32e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7120000 + 0x208 + port * 0x10), 0x77777777);
889*32e9fc1aSHaojian Zhuang 	}
890*32e9fc1aSHaojian Zhuang 
891*32e9fc1aSHaojian Zhuang 	port = 1;
892*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x200 + port * 0x10), 0x30000);
893*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x204 + port * 0x10), 0x1234567);
894*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x208 + port * 0x10), 0x1234567);
895*32e9fc1aSHaojian Zhuang 
896*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x1f0), 0);
897*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x0bc), 0x3020100);
898*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x0d0), 0x3020100);
899*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x1f4), 0x01000100);
900*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x08c + 0 * 4), 0xd0670402);
901*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x068 + 0 * 4), 0x31);
902*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x000), 0x7);
903*32e9fc1aSHaojian Zhuang 
904*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7124000 + 0x09c));
905*32e9fc1aSHaojian Zhuang 	data &= ~0xff0000;
906*32e9fc1aSHaojian Zhuang 	data |= 0x400000;
907*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x09c), data);
908*32e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7124000 + 0x0ac));
909*32e9fc1aSHaojian Zhuang 	data &= ~0xff0000;
910*32e9fc1aSHaojian Zhuang 	data |= 0x400000;
911*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x0ac), data);
912*32e9fc1aSHaojian Zhuang 	port = 2;
913*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x200 + port * 0x10), 0x30000);
914*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x204 + port * 0x10), 0x1234567);
915*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x208 + port * 0x10), 0x1234567);
916*32e9fc1aSHaojian Zhuang 
917*32e9fc1aSHaojian Zhuang 
918*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x09c), 0xff7fff);
919*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x0a0), 0xff);
920*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x0ac), 0xff7fff);
921*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x0b0), 0xff);
922*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x0bc), 0x3020100);
923*32e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x0d0), 0x3020100);
924*32e9fc1aSHaojian Zhuang }
925*32e9fc1aSHaojian Zhuang 
926*32e9fc1aSHaojian Zhuang static void ddr_phy_reset(void)
927*32e9fc1aSHaojian Zhuang {
928*32e9fc1aSHaojian Zhuang 	mmio_write_32(0xf7030340, 0xa000);
929*32e9fc1aSHaojian Zhuang 	mmio_write_32(0xf7030344, 0xa000);
930*32e9fc1aSHaojian Zhuang }
931*32e9fc1aSHaojian Zhuang 
932*32e9fc1aSHaojian Zhuang void hikey_ddr_init(void)
933*32e9fc1aSHaojian Zhuang {
934*32e9fc1aSHaojian Zhuang 	uint32_t data;
935*32e9fc1aSHaojian Zhuang 
936*32e9fc1aSHaojian Zhuang 	init_pll();
937*32e9fc1aSHaojian Zhuang 	init_freq();
938*32e9fc1aSHaojian Zhuang 
939*32e9fc1aSHaojian Zhuang 	/*
940*32e9fc1aSHaojian Zhuang 	 * Init DDR with 533MHz. Otherwise, DDR initialization
941*32e9fc1aSHaojian Zhuang 	 * may fail on 800MHz on some boards.
942*32e9fc1aSHaojian Zhuang 	 */
943*32e9fc1aSHaojian Zhuang 	ddr_phy_reset();
944*32e9fc1aSHaojian Zhuang 	init_ddr(DDR_FREQ_533M);
945*32e9fc1aSHaojian Zhuang 	/* Init DDR with 800MHz. */
946*32e9fc1aSHaojian Zhuang 	ddr_phy_reset();
947*32e9fc1aSHaojian Zhuang 	init_ddr(DDR_FREQ_800M);
948*32e9fc1aSHaojian Zhuang 
949*32e9fc1aSHaojian Zhuang 
950*32e9fc1aSHaojian Zhuang 	ddrc_common_init(1);
951*32e9fc1aSHaojian Zhuang 	dienum_det_and_rowcol_cfg();
952*32e9fc1aSHaojian Zhuang 	detect_ddr_chip_info();
953*32e9fc1aSHaojian Zhuang 
954*32e9fc1aSHaojian Zhuang 	data = mmio_read_32(0xf7032000 + 0x010);
955*32e9fc1aSHaojian Zhuang 	data &= ~0x1;
956*32e9fc1aSHaojian Zhuang 	mmio_write_32(0xf7032000 + 0x010, data);
957*32e9fc1aSHaojian Zhuang 	data = mmio_read_32(0xf7032000 + 0x010);
958*32e9fc1aSHaojian Zhuang 
959*32e9fc1aSHaojian Zhuang 	/*
960*32e9fc1aSHaojian Zhuang 	 * Test memory access. Do not use address 0x0 because the compiler
961*32e9fc1aSHaojian Zhuang 	 * may assume it is not a valid address and generate incorrect code
962*32e9fc1aSHaojian Zhuang 	 * (GCC 4.9.1 without -fno-delete-null-pointer-checks for instance).
963*32e9fc1aSHaojian Zhuang 	 */
964*32e9fc1aSHaojian Zhuang 	mmio_write_32(0x4, 0xa5a55a5a);
965*32e9fc1aSHaojian Zhuang 	INFO("ddr test value:0x%x\n", mmio_read_32(0x4));
966*32e9fc1aSHaojian Zhuang 	init_ddrc_qos();
967*32e9fc1aSHaojian Zhuang }
968