xref: /rk3399_ARM-atf/plat/hisilicon/hikey/hikey_ddr.c (revision 22db0167670f4f3d6858656ccd47fd5c8320f9a8)
132e9fc1aSHaojian Zhuang /*
232e9fc1aSHaojian Zhuang  * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
332e9fc1aSHaojian Zhuang  *
432e9fc1aSHaojian Zhuang  * SPDX-License-Identifier: BSD-3-Clause
532e9fc1aSHaojian Zhuang  */
632e9fc1aSHaojian Zhuang 
732e9fc1aSHaojian Zhuang #include <arch_helpers.h>
832e9fc1aSHaojian Zhuang #include <debug.h>
932e9fc1aSHaojian Zhuang #include <errno.h>
1032e9fc1aSHaojian Zhuang #include <hi6220.h>
1132e9fc1aSHaojian Zhuang #include <hi6553.h>
1232e9fc1aSHaojian Zhuang #include <mmio.h>
1332e9fc1aSHaojian Zhuang #include <sp804_delay_timer.h>
1432e9fc1aSHaojian Zhuang 
1532e9fc1aSHaojian Zhuang enum {
1632e9fc1aSHaojian Zhuang 	DDR_FREQ_533M = 0,
1732e9fc1aSHaojian Zhuang 	DDR_FREQ_800M,
1832e9fc1aSHaojian Zhuang };
1932e9fc1aSHaojian Zhuang 
2032e9fc1aSHaojian Zhuang static void init_pll(void)
2132e9fc1aSHaojian Zhuang {
2232e9fc1aSHaojian Zhuang 	unsigned int data;
2332e9fc1aSHaojian Zhuang 
2432e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x000));
2532e9fc1aSHaojian Zhuang 	data |= 0x1;
2632e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x000), data);
2732e9fc1aSHaojian Zhuang 	dsb();
2832e9fc1aSHaojian Zhuang 	do {
2932e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7032000 + 0x000));
3032e9fc1aSHaojian Zhuang 	} while (!(data & (1 << 28)));
3132e9fc1aSHaojian Zhuang 
3232e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7800000 + 0x000));
3332e9fc1aSHaojian Zhuang 	data &= ~0x007;
3432e9fc1aSHaojian Zhuang 	data |= 0x004;
3532e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7800000 + 0x000), data);
3632e9fc1aSHaojian Zhuang 	dsb();
3732e9fc1aSHaojian Zhuang 	do {
3832e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7800000 + 0x014));
3932e9fc1aSHaojian Zhuang 		data &= 0x007;
4032e9fc1aSHaojian Zhuang 	} while (data != 0x004);
4132e9fc1aSHaojian Zhuang 
4232e9fc1aSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2101);
4332e9fc1aSHaojian Zhuang 	data = mmio_read_32(PERI_SC_PERIPH_STAT1);
4432e9fc1aSHaojian Zhuang 	mmio_write_32(0xf7032000 + 0x02c, 0x5110103e);
4532e9fc1aSHaojian Zhuang 	data = mmio_read_32(0xf7032000 + 0x050);
4632e9fc1aSHaojian Zhuang 	data |= 1 << 28;
4732e9fc1aSHaojian Zhuang 	mmio_write_32(0xf7032000 + 0x050, data);
4832e9fc1aSHaojian Zhuang 	mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2101);
4932e9fc1aSHaojian Zhuang 	mdelay(1);
5032e9fc1aSHaojian Zhuang 	data = mmio_read_32(PERI_SC_PERIPH_STAT1);
5132e9fc1aSHaojian Zhuang 	NOTICE("syspll frequency:%dHz\n", data);
5232e9fc1aSHaojian Zhuang }
5332e9fc1aSHaojian Zhuang 
5432e9fc1aSHaojian Zhuang static void init_freq(void)
5532e9fc1aSHaojian Zhuang {
5632e9fc1aSHaojian Zhuang 	unsigned int data, tmp;
5732e9fc1aSHaojian Zhuang 	unsigned int cpuext_cfg, ddr_cfg;
5832e9fc1aSHaojian Zhuang 
5932e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x374), 0x4a);
6032e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x368), 0xda);
6132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x36c), 0x01);
6232e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x370), 0x01);
6332e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x360), 0x60);
6432e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x364), 0x60);
6532e9fc1aSHaojian Zhuang 
6632e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x114), 0x1000);
6732e9fc1aSHaojian Zhuang 
6832e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x110));
6932e9fc1aSHaojian Zhuang 	data |= (3 << 12);
7032e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x110), data);
7132e9fc1aSHaojian Zhuang 
7232e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x110));
7332e9fc1aSHaojian Zhuang 	data |= (1 << 4);
7432e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x110), data);
7532e9fc1aSHaojian Zhuang 
7632e9fc1aSHaojian Zhuang 
7732e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x110));
7832e9fc1aSHaojian Zhuang 	data &= ~0x7;
7932e9fc1aSHaojian Zhuang 	data |= 0x5;
8032e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x110), data);
8132e9fc1aSHaojian Zhuang 	dsb();
8232e9fc1aSHaojian Zhuang 	mdelay(10);
8332e9fc1aSHaojian Zhuang 
8432e9fc1aSHaojian Zhuang 
8532e9fc1aSHaojian Zhuang 	do {
8632e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf6504000 + 0x008));
8732e9fc1aSHaojian Zhuang 		data &= (3 << 20);
8832e9fc1aSHaojian Zhuang 	} while (data != (3 << 20));
8932e9fc1aSHaojian Zhuang 	dsb();
9032e9fc1aSHaojian Zhuang 	mdelay(10);
9132e9fc1aSHaojian Zhuang 
9232e9fc1aSHaojian Zhuang 
9332e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf6504000 + 0x054));
9432e9fc1aSHaojian Zhuang 	data &= ~((1 << 0) | (1 << 11));
9532e9fc1aSHaojian Zhuang 	mmio_write_32((0xf6504000 + 0x054), data);
9632e9fc1aSHaojian Zhuang 	mdelay(10);
9732e9fc1aSHaojian Zhuang 
9832e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x104));
9932e9fc1aSHaojian Zhuang 	data &= ~(3 << 8);
10032e9fc1aSHaojian Zhuang 	data |= (1 << 8);
10132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x104), data);
10232e9fc1aSHaojian Zhuang 
10332e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x100));
10432e9fc1aSHaojian Zhuang 	data |= (1 << 0);
10532e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x100), data);
10632e9fc1aSHaojian Zhuang 	dsb();
10732e9fc1aSHaojian Zhuang 
10832e9fc1aSHaojian Zhuang 	do {
10932e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7032000 + 0x100));
11032e9fc1aSHaojian Zhuang 		data &= (1 << 2);
11132e9fc1aSHaojian Zhuang 	} while (data != (1 << 2));
11232e9fc1aSHaojian Zhuang 
11332e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf6504000 + 0x06c));
11432e9fc1aSHaojian Zhuang 	data &= ~0xffff;
11532e9fc1aSHaojian Zhuang 	data |= 0x56;
11632e9fc1aSHaojian Zhuang 	mmio_write_32((0xf6504000 + 0x06c), data);
11732e9fc1aSHaojian Zhuang 
11832e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf6504000 + 0x06c));
11932e9fc1aSHaojian Zhuang 	data &= ~(0xffffff << 8);
12032e9fc1aSHaojian Zhuang 	data |= 0xc7a << 8;
12132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf6504000 + 0x06c), data);
12232e9fc1aSHaojian Zhuang 
12332e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf6504000 + 0x058));
12432e9fc1aSHaojian Zhuang 	data &= ((1 << 13) - 1);
12532e9fc1aSHaojian Zhuang 	data |= 0xccb;
12632e9fc1aSHaojian Zhuang 	mmio_write_32((0xf6504000 + 0x058), data);
12732e9fc1aSHaojian Zhuang 
12832e9fc1aSHaojian Zhuang 	mmio_write_32((0xf6504000 + 0x060), 0x1fff);
12932e9fc1aSHaojian Zhuang 	mmio_write_32((0xf6504000 + 0x064), 0x1ffffff);
13032e9fc1aSHaojian Zhuang 	mmio_write_32((0xf6504000 + 0x068), 0x7fffffff);
13132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf6504000 + 0x05c), 0x1);
13232e9fc1aSHaojian Zhuang 
13332e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf6504000 + 0x054));
13432e9fc1aSHaojian Zhuang 	data &= ~(0xf << 12);
13532e9fc1aSHaojian Zhuang 	data |= 1 << 12;
13632e9fc1aSHaojian Zhuang 	mmio_write_32((0xf6504000 + 0x054), data);
13732e9fc1aSHaojian Zhuang 	dsb();
13832e9fc1aSHaojian Zhuang 
13932e9fc1aSHaojian Zhuang 
14032e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x000));
14132e9fc1aSHaojian Zhuang 	data &= ~(1 << 0);
14232e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x000), data);
14332e9fc1aSHaojian Zhuang 
14432e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x004), 0x5110207d);
14532e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x134), 0x10000005);
14632e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x134));
14732e9fc1aSHaojian Zhuang 
14832e9fc1aSHaojian Zhuang 
14932e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x000));
15032e9fc1aSHaojian Zhuang 	data |= (1 << 0);
15132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x000), data);
15232e9fc1aSHaojian Zhuang 
15332e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x368), 0x100da);
15432e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x378));
15532e9fc1aSHaojian Zhuang 	data &= ~((1 << 7) - 1);
15632e9fc1aSHaojian Zhuang 	data |= 0x6b;
15732e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x378), data);
15832e9fc1aSHaojian Zhuang 	dsb();
15932e9fc1aSHaojian Zhuang 	do {
16032e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7032000 + 0x378));
16132e9fc1aSHaojian Zhuang 		tmp = data & 0x7f;
16232e9fc1aSHaojian Zhuang 		data = (data & (0x7f << 8)) >> 8;
16332e9fc1aSHaojian Zhuang 		if (data != tmp)
16432e9fc1aSHaojian Zhuang 			continue;
16532e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7032000 + 0x37c));
16632e9fc1aSHaojian Zhuang 	} while (!(data & 1));
16732e9fc1aSHaojian Zhuang 
16832e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x104));
16932e9fc1aSHaojian Zhuang 	data &= ~((3 << 0) |
17032e9fc1aSHaojian Zhuang 			(3 << 8));
17132e9fc1aSHaojian Zhuang 	cpuext_cfg = 1;
17232e9fc1aSHaojian Zhuang 	ddr_cfg = 1;
17332e9fc1aSHaojian Zhuang 	data |= cpuext_cfg | (ddr_cfg << 8);
17432e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x104), data);
17532e9fc1aSHaojian Zhuang 	dsb();
17632e9fc1aSHaojian Zhuang 
17732e9fc1aSHaojian Zhuang 	do {
17832e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7032000 + 0x104));
17932e9fc1aSHaojian Zhuang 		tmp = (data & (3 << 16)) >> 16;
18032e9fc1aSHaojian Zhuang 		if (cpuext_cfg != tmp)
18132e9fc1aSHaojian Zhuang 			continue;
18232e9fc1aSHaojian Zhuang 		tmp = (data & (3 << 24)) >> 24;
18332e9fc1aSHaojian Zhuang 		if (ddr_cfg != tmp)
18432e9fc1aSHaojian Zhuang 			continue;
18532e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7032000 + 0x000));
18632e9fc1aSHaojian Zhuang 		data &= 1 << 28;
18732e9fc1aSHaojian Zhuang 	} while (!data);
18832e9fc1aSHaojian Zhuang 
18932e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x100));
19032e9fc1aSHaojian Zhuang 	data &= ~(1 << 0);
19132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x100), data);
19232e9fc1aSHaojian Zhuang 	dsb();
19332e9fc1aSHaojian Zhuang 	do {
19432e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7032000 + 0x100));
19532e9fc1aSHaojian Zhuang 		data &= (1 << 1);
19632e9fc1aSHaojian Zhuang 	} while (data != (1 << 1));
19732e9fc1aSHaojian Zhuang 	mdelay(1000);
19832e9fc1aSHaojian Zhuang 
19932e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf6504000 + 0x054));
20032e9fc1aSHaojian Zhuang 	data &= ~(1 << 28);
20132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf6504000 + 0x054), data);
20232e9fc1aSHaojian Zhuang 	dsb();
20332e9fc1aSHaojian Zhuang 
20432e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x110));
20532e9fc1aSHaojian Zhuang 	data &= ~((1 << 4) |
20632e9fc1aSHaojian Zhuang 			(3 << 12));
20732e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x110), data);
20832e9fc1aSHaojian Zhuang }
20932e9fc1aSHaojian Zhuang 
21032e9fc1aSHaojian Zhuang int cat_533mhz_800mhz(void)
21132e9fc1aSHaojian Zhuang {
21232e9fc1aSHaojian Zhuang 	unsigned int data, i;
21332e9fc1aSHaojian Zhuang 	unsigned int bdl[5];
21432e9fc1aSHaojian Zhuang 
21532e9fc1aSHaojian Zhuang 
21632e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x1c8));
21732e9fc1aSHaojian Zhuang 	data &= 0xfffff0f0;
21832e9fc1aSHaojian Zhuang 	data |= 0x100f0f;
21932e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x1c8), data);
22032e9fc1aSHaojian Zhuang 
22132e9fc1aSHaojian Zhuang 	for (i = 0; i < 0x20; i++) {
22232e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x1d4), 0xc0000);
22332e9fc1aSHaojian Zhuang 		data = (i << 0x10) + i;
22432e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x140), data);
22532e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x144), data);
22632e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x148), data);
22732e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x14c), data);
22832e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x150), data);
22932e9fc1aSHaojian Zhuang 
23032e9fc1aSHaojian Zhuang 
23132e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x070));
23232e9fc1aSHaojian Zhuang 		data |= 0x80000;
23332e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x070), data);
23432e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x070));
23532e9fc1aSHaojian Zhuang 		data &= 0xfff7ffff;
23632e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x070), data);
23732e9fc1aSHaojian Zhuang 
23832e9fc1aSHaojian Zhuang 
23932e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x004), 0x8000);
24032e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x004), 0x0);
24132e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x004), 0x801);
24232e9fc1aSHaojian Zhuang 		do {
24332e9fc1aSHaojian Zhuang 			data = mmio_read_32((0xf712c000 + 0x004));
24432e9fc1aSHaojian Zhuang 		} while (data & 1);
24532e9fc1aSHaojian Zhuang 
24632e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x008));
24732e9fc1aSHaojian Zhuang 		if (!(data & 0x400)) {
24832e9fc1aSHaojian Zhuang 			mdelay(10);
24932e9fc1aSHaojian Zhuang 			return 0;
25032e9fc1aSHaojian Zhuang 		}
25132e9fc1aSHaojian Zhuang 		WARN("lpddr3 cat fail\n");
25232e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x1d4));
25332e9fc1aSHaojian Zhuang 		if ((data & 0x1f00) && ((data & 0x1f) == 0)) {
25432e9fc1aSHaojian Zhuang 			bdl[0] = mmio_read_32((0xf712c000 + 0x140));
25532e9fc1aSHaojian Zhuang 			bdl[1] = mmio_read_32((0xf712c000 + 0x144));
25632e9fc1aSHaojian Zhuang 			bdl[2] = mmio_read_32((0xf712c000 + 0x148));
25732e9fc1aSHaojian Zhuang 			bdl[3] = mmio_read_32((0xf712c000 + 0x14c));
25832e9fc1aSHaojian Zhuang 			bdl[4] = mmio_read_32((0xf712c000 + 0x150));
25932e9fc1aSHaojian Zhuang 			if ((!(bdl[0] & 0x1f001f)) || (!(bdl[1] & 0x1f001f)) ||
26032e9fc1aSHaojian Zhuang 					(!(bdl[2] & 0x1f001f)) || (!(bdl[3] & 0x1f001f)) ||
26132e9fc1aSHaojian Zhuang 					(!(bdl[4] & 0x1f001f))) {
26232e9fc1aSHaojian Zhuang 				WARN("lpddr3 cat deskew error\n");
26332e9fc1aSHaojian Zhuang 				if (i == 0x1f) {
26432e9fc1aSHaojian Zhuang 					WARN("addrnbdl is max\n");
26532e9fc1aSHaojian Zhuang 					return -EINVAL;
26632e9fc1aSHaojian Zhuang 				}
26732e9fc1aSHaojian Zhuang 				mmio_write_32((0xf712c000 + 0x008), 0x400);
26832e9fc1aSHaojian Zhuang 			} else {
26932e9fc1aSHaojian Zhuang 				WARN("lpddr3 cat other error1\n");
27032e9fc1aSHaojian Zhuang 				return -EINVAL;
27132e9fc1aSHaojian Zhuang 			}
27232e9fc1aSHaojian Zhuang 		} else {
27332e9fc1aSHaojian Zhuang 			WARN("lpddr3 cat other error2\n");
27432e9fc1aSHaojian Zhuang 			return -EINVAL;
27532e9fc1aSHaojian Zhuang 		}
27632e9fc1aSHaojian Zhuang 	}
27732e9fc1aSHaojian Zhuang 	return -EINVAL;
27832e9fc1aSHaojian Zhuang }
27932e9fc1aSHaojian Zhuang 
28032e9fc1aSHaojian Zhuang static void ddrx_rdet(void)
28132e9fc1aSHaojian Zhuang {
28232e9fc1aSHaojian Zhuang 	unsigned int data, rdet, bdl[4];
28332e9fc1aSHaojian Zhuang 
28432e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x0d0));
28532e9fc1aSHaojian Zhuang 	data &= 0xf800ffff;
28632e9fc1aSHaojian Zhuang 	data |= 0x8f0000;
28732e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x0d0), data);
28832e9fc1aSHaojian Zhuang 
28932e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x0dc));
29032e9fc1aSHaojian Zhuang 	data &= 0xfffffff0;
29132e9fc1aSHaojian Zhuang 	data |= 0xf;
29232e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x0dc), data);
29332e9fc1aSHaojian Zhuang 
29432e9fc1aSHaojian Zhuang 
29532e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x070));
29632e9fc1aSHaojian Zhuang 	data |= 0x80000;
29732e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x070), data);
29832e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x070));
29932e9fc1aSHaojian Zhuang 	data &= 0xfff7ffff;
30032e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x070), data);
30132e9fc1aSHaojian Zhuang 
30232e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x004), 0x8000);
30332e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x004), 0);
30432e9fc1aSHaojian Zhuang 
30532e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x0d0));
30632e9fc1aSHaojian Zhuang 	data &= ~0xf0000000;
30732e9fc1aSHaojian Zhuang 	data |= 0x80000000;
30832e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x0d0), data);
30932e9fc1aSHaojian Zhuang 
31032e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x004), 0x101);
31132e9fc1aSHaojian Zhuang 	do {
31232e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x004));
31332e9fc1aSHaojian Zhuang 	} while (!(data & 1));
31432e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x008));
31532e9fc1aSHaojian Zhuang 	if (data & 0x100)
31632e9fc1aSHaojian Zhuang 		WARN("rdet lbs fail\n");
31732e9fc1aSHaojian Zhuang 
31832e9fc1aSHaojian Zhuang 	bdl[0] = mmio_read_32((0xf712c000 + 0x22c)) & 0x7f;
31932e9fc1aSHaojian Zhuang 	bdl[1] = mmio_read_32((0xf712c000 + 0x2ac)) & 0x7f;
32032e9fc1aSHaojian Zhuang 	bdl[2] = mmio_read_32((0xf712c000 + 0x32c)) & 0x7f;
32132e9fc1aSHaojian Zhuang 	bdl[3] = mmio_read_32((0xf712c000 + 0x3ac)) & 0x7f;
32232e9fc1aSHaojian Zhuang 	do {
32332e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x22c));
32432e9fc1aSHaojian Zhuang 		data &= ~0x7f;
32532e9fc1aSHaojian Zhuang 		data |= bdl[0];
32632e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x22c), data);
32732e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x2ac));
32832e9fc1aSHaojian Zhuang 		data &= ~0x7f;
32932e9fc1aSHaojian Zhuang 		data |= bdl[1];
33032e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x2ac), data);
33132e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x32c));
33232e9fc1aSHaojian Zhuang 		data &= ~0x7f;
33332e9fc1aSHaojian Zhuang 		data |= bdl[2];
33432e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x32c), data);
33532e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x3ac));
33632e9fc1aSHaojian Zhuang 		data &= ~0x7f;
33732e9fc1aSHaojian Zhuang 		data |= bdl[3];
33832e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x3ac), data);
33932e9fc1aSHaojian Zhuang 
34032e9fc1aSHaojian Zhuang 
34132e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x070));
34232e9fc1aSHaojian Zhuang 		data |= 0x80000;
34332e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x070), data);
34432e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x070));
34532e9fc1aSHaojian Zhuang 		data &= 0xfff7ffff;
34632e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x070), data);
34732e9fc1aSHaojian Zhuang 
34832e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x004), 0x8000);
34932e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x004), 0);
35032e9fc1aSHaojian Zhuang 
35132e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x0d0));
35232e9fc1aSHaojian Zhuang 		data &= ~0xf0000000;
35332e9fc1aSHaojian Zhuang 		data |= 0x40000000;
35432e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x0d0), data);
35532e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x004), 0x101);
35632e9fc1aSHaojian Zhuang 		do {
35732e9fc1aSHaojian Zhuang 			data = mmio_read_32((0xf712c000 + 0x004));
35832e9fc1aSHaojian Zhuang 		} while (data & 1);
35932e9fc1aSHaojian Zhuang 
36032e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x008));
36132e9fc1aSHaojian Zhuang 		rdet = data & 0x100;
36232e9fc1aSHaojian Zhuang 		if (rdet) {
36332e9fc1aSHaojian Zhuang 			INFO("rdet ds fail\n");
36432e9fc1aSHaojian Zhuang 			mmio_write_32((0xf712c000 + 0x008), 0x100);
36532e9fc1aSHaojian Zhuang 		}
36632e9fc1aSHaojian Zhuang 		bdl[0]++;
36732e9fc1aSHaojian Zhuang 		bdl[1]++;
36832e9fc1aSHaojian Zhuang 		bdl[2]++;
36932e9fc1aSHaojian Zhuang 		bdl[3]++;
37032e9fc1aSHaojian Zhuang 	} while (rdet);
37132e9fc1aSHaojian Zhuang 
37232e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x0d0));
37332e9fc1aSHaojian Zhuang 	data &= ~0xf0000000;
37432e9fc1aSHaojian Zhuang 	data |= 0x30000000;
37532e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x0d0), data);
37632e9fc1aSHaojian Zhuang 
37732e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x004), 0x101);
37832e9fc1aSHaojian Zhuang 	do {
37932e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x004));
38032e9fc1aSHaojian Zhuang 	} while (data & 1);
38132e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x008));
38232e9fc1aSHaojian Zhuang 	if (data & 0x100)
38332e9fc1aSHaojian Zhuang 		INFO("rdet rbs av fail\n");
38432e9fc1aSHaojian Zhuang }
38532e9fc1aSHaojian Zhuang 
38632e9fc1aSHaojian Zhuang static void ddrx_wdet(void)
38732e9fc1aSHaojian Zhuang {
388*22db0167SHaojian Zhuang 	unsigned int data, wdet, zero_bdl = 0, dq[4];
38932e9fc1aSHaojian Zhuang 	int i;
39032e9fc1aSHaojian Zhuang 
39132e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x0d0));
39232e9fc1aSHaojian Zhuang 	data &= ~0xf;
39332e9fc1aSHaojian Zhuang 	data |= 0xf;
39432e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x0d0), data);
39532e9fc1aSHaojian Zhuang 
39632e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x070));
39732e9fc1aSHaojian Zhuang 	data |= 0x80000;
39832e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x070), data);
39932e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x070));
40032e9fc1aSHaojian Zhuang 	data &= ~0x80000;
40132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x070), data);
40232e9fc1aSHaojian Zhuang 
40332e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x004), 0x8000);
40432e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x004), 0);
40532e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x0d0));
40632e9fc1aSHaojian Zhuang 	data &= ~0xf000;
40732e9fc1aSHaojian Zhuang 	data |= 0x8000;
40832e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x0d0), data);
40932e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x004), 0x201);
41032e9fc1aSHaojian Zhuang 	do {
41132e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x004));
41232e9fc1aSHaojian Zhuang 	} while (data & 1);
41332e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x008));
41432e9fc1aSHaojian Zhuang 	if (data & 0x200)
41532e9fc1aSHaojian Zhuang 		INFO("wdet lbs fail\n");
41632e9fc1aSHaojian Zhuang 
41732e9fc1aSHaojian Zhuang 	dq[0] = mmio_read_32((0xf712c000 + 0x234)) & 0x1f00;
41832e9fc1aSHaojian Zhuang 	dq[1] = mmio_read_32((0xf712c000 + 0x2b4)) & 0x1f00;
41932e9fc1aSHaojian Zhuang 	dq[2] = mmio_read_32((0xf712c000 + 0x334)) & 0x1f00;
42032e9fc1aSHaojian Zhuang 	dq[3] = mmio_read_32((0xf712c000 + 0x3b4)) & 0x1f00;
42132e9fc1aSHaojian Zhuang 
42232e9fc1aSHaojian Zhuang 	do {
42332e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x234), dq[0]);
42432e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x2b4), dq[1]);
42532e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x334), dq[2]);
42632e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x3b4), dq[3]);
42732e9fc1aSHaojian Zhuang 
42832e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x070));
42932e9fc1aSHaojian Zhuang 		data |= 0x80000;
43032e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x070), data);
43132e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x070));
43232e9fc1aSHaojian Zhuang 		data &= ~0x80000;
43332e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x070), data);
43432e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x004), 0x8000);
43532e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x004), 0);
43632e9fc1aSHaojian Zhuang 
43732e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x0d0));
43832e9fc1aSHaojian Zhuang 		data &= ~0xf000;
43932e9fc1aSHaojian Zhuang 		data |= 0x4000;
44032e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x0d0), data);
44132e9fc1aSHaojian Zhuang 		mmio_write_32((0xf712c000 + 0x004), 0x201);
44232e9fc1aSHaojian Zhuang 		do {
44332e9fc1aSHaojian Zhuang 			data = mmio_read_32((0xf712c000 + 0x004));
44432e9fc1aSHaojian Zhuang 		} while (data & 1);
44532e9fc1aSHaojian Zhuang 
44632e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x008));
44732e9fc1aSHaojian Zhuang 		wdet = data & 0x200;
44832e9fc1aSHaojian Zhuang 		if (wdet) {
44932e9fc1aSHaojian Zhuang 			INFO("wdet ds fail\n");
45032e9fc1aSHaojian Zhuang 			mmio_write_32((0xf712c000 + 0x008), 0x200);
45132e9fc1aSHaojian Zhuang 		}
45232e9fc1aSHaojian Zhuang 		mdelay(10);
45332e9fc1aSHaojian Zhuang 
45432e9fc1aSHaojian Zhuang 		for (i = 0; i < 4; i++) {
45532e9fc1aSHaojian Zhuang 			data = mmio_read_32((0xf712c000 + 0x210 + i * 0x80));
45632e9fc1aSHaojian Zhuang 			if ((!(data & 0x1f)) || (!(data & 0x1f00)) ||
45732e9fc1aSHaojian Zhuang 			    (!(data & 0x1f0000)) || (!(data & 0x1f000000)))
45832e9fc1aSHaojian Zhuang 				zero_bdl = 1;
45932e9fc1aSHaojian Zhuang 			data = mmio_read_32((0xf712c000 + 0x214 + i * 0x80));
46032e9fc1aSHaojian Zhuang 			if ((!(data & 0x1f)) || (!(data & 0x1f00)) ||
46132e9fc1aSHaojian Zhuang 			    (!(data & 0x1f0000)) || (!(data & 0x1f000000)))
46232e9fc1aSHaojian Zhuang 				zero_bdl = 1;
46332e9fc1aSHaojian Zhuang 			data = mmio_read_32((0xf712c000 + 0x218 + i * 0x80));
46432e9fc1aSHaojian Zhuang 			if (!(data & 0x1f))
46532e9fc1aSHaojian Zhuang 				zero_bdl = 1;
46632e9fc1aSHaojian Zhuang 			if (zero_bdl) {
46732e9fc1aSHaojian Zhuang 				if (i == 0)
46832e9fc1aSHaojian Zhuang 					dq[0] = dq[0] - 0x100;
46932e9fc1aSHaojian Zhuang 				if (i == 1)
47032e9fc1aSHaojian Zhuang 					dq[1] = dq[1] - 0x100;
47132e9fc1aSHaojian Zhuang 				if (i == 2)
47232e9fc1aSHaojian Zhuang 					dq[2] = dq[2] - 0x100;
47332e9fc1aSHaojian Zhuang 				if (i == 3)
47432e9fc1aSHaojian Zhuang 					dq[3] = dq[3] - 0x100;
47532e9fc1aSHaojian Zhuang 			}
47632e9fc1aSHaojian Zhuang 		}
47732e9fc1aSHaojian Zhuang 	} while (wdet);
47832e9fc1aSHaojian Zhuang 
47932e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x0d0));
48032e9fc1aSHaojian Zhuang 	data &= ~0xf000;
48132e9fc1aSHaojian Zhuang 	data |= 0x3000;
48232e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x0d0), data);
48332e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x004), 0x201);
48432e9fc1aSHaojian Zhuang 	do {
48532e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x004));
48632e9fc1aSHaojian Zhuang 	} while (data & 1);
48732e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x008));
48832e9fc1aSHaojian Zhuang 	if (data & 0x200)
48932e9fc1aSHaojian Zhuang 		INFO("wdet rbs av fail\n");
49032e9fc1aSHaojian Zhuang }
49132e9fc1aSHaojian Zhuang 
49232e9fc1aSHaojian Zhuang static void set_ddrc_533mhz(void)
49332e9fc1aSHaojian Zhuang {
49432e9fc1aSHaojian Zhuang 	unsigned int data;
49532e9fc1aSHaojian Zhuang 
49632e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x580), 0x3);
49732e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x5a8), 0x11111);
49832e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x104));
49932e9fc1aSHaojian Zhuang 	data |= 0x100;
50032e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x104), data);
50132e9fc1aSHaojian Zhuang 
50232e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7030000 + 0x050), 0x30);
50332e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7030000 + 0x240), 0x5ffff);
50432e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7030000 + 0x344), 0xf5ff);
50532e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x00c), 0x400);
50632e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x018), 0x7);
50732e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x090), 0x6400000);
50832e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x258), 0x640);
50932e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x2d8), 0x640);
51032e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x358), 0x640);
51132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x3d8), 0x640);
51232e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x018), 0x0);
51332e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x0b0), 0xf00000f);
51432e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x0b4), 0xf);
51532e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x088), 0x3fff801);
51632e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x070), 0x8940000);
51732e9fc1aSHaojian Zhuang 
51832e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x078));
51932e9fc1aSHaojian Zhuang 	data |= 4;
52032e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x078), data);
52132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x01c), 0x8000080);
52232e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x020));
52332e9fc1aSHaojian Zhuang 	data &= 0xfffffffe;
52432e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x020), data);
52532e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x1d4), 0xc0000);
52632e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x010), 0x500000f);
52732e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x014), 0x10);
52832e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x1e4));
52932e9fc1aSHaojian Zhuang 	data &= 0xffffff00;
53032e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x1e4), data);
53132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x030), 0x9dd87855);
53232e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x034), 0xa7138bb);
53332e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x038), 0x20091477);
53432e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x03c), 0x84534e16);
53532e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x040), 0x3008817);
53632e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x064), 0x106c3);
53732e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x068), 0xff0a0000);
53832e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x070));
53932e9fc1aSHaojian Zhuang 	data &= 0xffff0000;
54032e9fc1aSHaojian Zhuang 	data |= 0x305;
54132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x070), data);
54232e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x048));
54332e9fc1aSHaojian Zhuang 	data |= 0x40000000;
54432e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x048), data);
54532e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x020));
54632e9fc1aSHaojian Zhuang 	data &= ~0x10;
54732e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x020), data);
54832e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x080));
54932e9fc1aSHaojian Zhuang 	data &= ~0x2000;
55032e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x080), data);
55132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x270), 0x3);
55232e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x2f0), 0x3);
55332e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x370), 0x3);
55432e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x3f0), 0x3);
55532e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x048), 0xd0420900);
55632e9fc1aSHaojian Zhuang 
55732e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x040), 0x0);
55832e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x004), 0x140f);
55932e9fc1aSHaojian Zhuang 	do {
56032e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x004));
56132e9fc1aSHaojian Zhuang 	} while (data & 1);
56232e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x008));
56332e9fc1aSHaojian Zhuang 	if (data & 0x7fe) {
56432e9fc1aSHaojian Zhuang 		NOTICE("failed to init lpddr3 rank0 dram phy\n");
56532e9fc1aSHaojian Zhuang 		return;
56632e9fc1aSHaojian Zhuang 	}
56732e9fc1aSHaojian Zhuang 	NOTICE("succeed to init lpddr3 rank0 dram phy\n");
56832e9fc1aSHaojian Zhuang }
56932e9fc1aSHaojian Zhuang 
57032e9fc1aSHaojian Zhuang static void set_ddrc_800mhz(void)
57132e9fc1aSHaojian Zhuang {
57232e9fc1aSHaojian Zhuang 	unsigned int data;
57332e9fc1aSHaojian Zhuang 
57432e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x580), 0x2);
57532e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x5a8), 0x1003);
57632e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x104));
57732e9fc1aSHaojian Zhuang 	data &= 0xfffffcff;
57832e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x104), data);
57932e9fc1aSHaojian Zhuang 
58032e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7030000 + 0x050), 0x30);
58132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7030000 + 0x240), 0x5ffff);
58232e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7030000 + 0x344), 0xf5ff);
58332e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x00c), 0x400);
58432e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x018), 0x7);
58532e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x090), 0x5400000);
58632e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x258), 0x540);
58732e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x2d8), 0x540);
58832e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x358), 0x540);
58932e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x3d8), 0x540);
59032e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x018), 0x0);
59132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x0b0), 0xf00000f);
59232e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x0b4), 0xf);
59332e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x088), 0x3fff801);
59432e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x070), 0x8940000);
59532e9fc1aSHaojian Zhuang 
59632e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x078));
59732e9fc1aSHaojian Zhuang 	data |= 4;
59832e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x078), data);
59932e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x01c), 0x8000080);
60032e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x020));
60132e9fc1aSHaojian Zhuang 	data &= 0xfffffffe;
60232e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x020), data);
60332e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x1d4), 0xc0000);
60432e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x010), 0x500000f);
60532e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x014), 0x10);
60632e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x1e4));
60732e9fc1aSHaojian Zhuang 	data &= 0xffffff00;
60832e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x1e4), data);
60932e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x030), 0xe663ab77);
61032e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x034), 0xea952db);
61132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x038), 0x200d1cb1);
61232e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x03c), 0xc67d0721);
61332e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x040), 0x3008aa1);
61432e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x064), 0x11a43);
61532e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x068), 0xff0a0000);
61632e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x070));
61732e9fc1aSHaojian Zhuang 	data &= 0xffff0000;
61832e9fc1aSHaojian Zhuang 	data |= 0x507;
61932e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x070), data);
62032e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x048));
62132e9fc1aSHaojian Zhuang 	data |= 0x40000000;
62232e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x048), data);
62332e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x020));
62432e9fc1aSHaojian Zhuang 	data &= 0xffffffef;
62532e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x020), data);
62632e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x080));
62732e9fc1aSHaojian Zhuang 	data &= 0xffffdfff;
62832e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x080), data);
62932e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x270), 0x3);
63032e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x2f0), 0x3);
63132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x370), 0x3);
63232e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x3f0), 0x3);
63332e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x048), 0xd0420900);
63432e9fc1aSHaojian Zhuang 
63532e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x040), 0x2001);
63632e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x004), 0x140f);
63732e9fc1aSHaojian Zhuang 	do {
63832e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x004));
63932e9fc1aSHaojian Zhuang 	} while (data & 1);
64032e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x008));
64132e9fc1aSHaojian Zhuang 	if (data & 0x7fe) {
64232e9fc1aSHaojian Zhuang 		WARN("failed to init lpddr3 rank0 dram phy\n");
64332e9fc1aSHaojian Zhuang 		return;
64432e9fc1aSHaojian Zhuang 	}
64532e9fc1aSHaojian Zhuang }
64632e9fc1aSHaojian Zhuang 
64732e9fc1aSHaojian Zhuang static void ddrc_common_init(int ddr800)
64832e9fc1aSHaojian Zhuang {
64932e9fc1aSHaojian Zhuang 	unsigned int data;
65032e9fc1aSHaojian Zhuang 
65132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x020), 0x1);
65232e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x100), 0x1700);
65332e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x104), 0x71040004);
65432e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7121400 + 0x104), 0xf);
65532e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7121800 + 0x104), 0xf);
65632e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7121800 + 0x104), 0xf);
65732e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7121c00 + 0x104), 0xf);
65832e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7122000 + 0x104), 0xf);
65932e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x02c), 0x6);
66032e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x020), 0x1);
66132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x028), 0x310201);
66232e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x1e4), 0xfe007600);
66332e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x01c), 0xaf001);
66432e9fc1aSHaojian Zhuang 
66532e9fc1aSHaojian Zhuang 
66632e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7128000 + 0x280));
66732e9fc1aSHaojian Zhuang 	data |= 1 << 7;
66832e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x280), data);
66932e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x244), 0x3);
67032e9fc1aSHaojian Zhuang 
67132e9fc1aSHaojian Zhuang 	if (ddr800)
67232e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x240), 167 * 400000 / 1024);
67332e9fc1aSHaojian Zhuang 	else
67432e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x240), 167 * 533000 / 1024);
67532e9fc1aSHaojian Zhuang 
67632e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x080));
67732e9fc1aSHaojian Zhuang 	data &= 0xffff;
67832e9fc1aSHaojian Zhuang 	data |= 0x4002000;
67932e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x080), data);
68032e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x000), 0x0);
68132e9fc1aSHaojian Zhuang 	do {
68232e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7128000 + 0x294));
68332e9fc1aSHaojian Zhuang 	} while (data & 1);
68432e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x000), 0x2);
68532e9fc1aSHaojian Zhuang }
68632e9fc1aSHaojian Zhuang 
68732e9fc1aSHaojian Zhuang 
68832e9fc1aSHaojian Zhuang static int dienum_det_and_rowcol_cfg(void)
68932e9fc1aSHaojian Zhuang {
69032e9fc1aSHaojian Zhuang 	unsigned int data;
69132e9fc1aSHaojian Zhuang 
69232e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x210), 0x87);
69332e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x218), 0x10000);
69432e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x00c), 0x1);
69532e9fc1aSHaojian Zhuang 	do {
69632e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7128000 + 0x00c));
69732e9fc1aSHaojian Zhuang 	} while (data & 1);
69832e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7128000 + 0x4a8)) & 0xfc;
69932e9fc1aSHaojian Zhuang 	switch (data) {
70032e9fc1aSHaojian Zhuang 	case 0x18:
70132e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x060), 0x132);
70232e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x064), 0x132);
70332e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7120000 + 0x100), 0x1600);
70432e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7120000 + 0x104), 0x71040004);
70532e9fc1aSHaojian Zhuang 		break;
70632e9fc1aSHaojian Zhuang 	case 0x1c:
70732e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x060), 0x142);
70832e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x064), 0x142);
70932e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7120000 + 0x100), 0x1700);
71032e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7120000 + 0x104), 0x71040004);
71132e9fc1aSHaojian Zhuang 		break;
71232e9fc1aSHaojian Zhuang 	case 0x58:
71332e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x060), 0x133);
71432e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x064), 0x133);
71532e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7120000 + 0x100), 0x1700);
71632e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7120000 + 0x104), 0x71040004);
71732e9fc1aSHaojian Zhuang 		break;
71832e9fc1aSHaojian Zhuang 	default:
71932e9fc1aSHaojian Zhuang 		break;
72032e9fc1aSHaojian Zhuang 	}
72132e9fc1aSHaojian Zhuang 	if (!data)
72232e9fc1aSHaojian Zhuang 		return -EINVAL;
72332e9fc1aSHaojian Zhuang 	return 0;
72432e9fc1aSHaojian Zhuang }
72532e9fc1aSHaojian Zhuang 
72632e9fc1aSHaojian Zhuang static int detect_ddr_chip_info(void)
72732e9fc1aSHaojian Zhuang {
72832e9fc1aSHaojian Zhuang 	unsigned int data, mr5, mr6, mr7;
72932e9fc1aSHaojian Zhuang 
73032e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x210), 0x57);
73132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x218), 0x10000);
73232e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x00c), 0x1);
73332e9fc1aSHaojian Zhuang 
73432e9fc1aSHaojian Zhuang 	do {
73532e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7128000 + 0x00c));
73632e9fc1aSHaojian Zhuang 	} while (data & 1);
73732e9fc1aSHaojian Zhuang 
73832e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7128000 + 0x4a8));
73932e9fc1aSHaojian Zhuang 	mr5 = data & 0xff;
74032e9fc1aSHaojian Zhuang 	switch (mr5) {
74132e9fc1aSHaojian Zhuang 	case 1:
74232e9fc1aSHaojian Zhuang 		INFO("Samsung DDR\n");
74332e9fc1aSHaojian Zhuang 		break;
74432e9fc1aSHaojian Zhuang 	case 6:
74532e9fc1aSHaojian Zhuang 		INFO("Hynix DDR\n");
74632e9fc1aSHaojian Zhuang 		break;
74732e9fc1aSHaojian Zhuang 	case 3:
74832e9fc1aSHaojian Zhuang 		INFO("Elpida DDR\n");
74932e9fc1aSHaojian Zhuang 		break;
75032e9fc1aSHaojian Zhuang 	default:
75132e9fc1aSHaojian Zhuang 		INFO("DDR from other vendors\n");
75232e9fc1aSHaojian Zhuang 		break;
75332e9fc1aSHaojian Zhuang 	}
75432e9fc1aSHaojian Zhuang 
75532e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x210), 0x67);
75632e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x218), 0x10000);
75732e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x00c), 0x1);
75832e9fc1aSHaojian Zhuang 	do {
75932e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7128000 + 0x00c));
76032e9fc1aSHaojian Zhuang 	} while (data & 1);
76132e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7128000 + 0x4a8));
76232e9fc1aSHaojian Zhuang 	mr6 = data & 0xff;
76332e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x210), 0x77);
76432e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x218), 0x10000);
76532e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x00c), 0x1);
76632e9fc1aSHaojian Zhuang 	do {
76732e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7128000 + 0x00c));
76832e9fc1aSHaojian Zhuang 	} while (data & 1);
76932e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7128000 + 0x4a8));
77032e9fc1aSHaojian Zhuang 	mr7 = data & 0xff;
77132e9fc1aSHaojian Zhuang 	data = mr5 + (mr6 << 8) + (mr7 << 16);
77232e9fc1aSHaojian Zhuang 	return data;
77332e9fc1aSHaojian Zhuang }
77432e9fc1aSHaojian Zhuang 
77532e9fc1aSHaojian Zhuang int lpddr3_freq_init(int freq)
77632e9fc1aSHaojian Zhuang {
77732e9fc1aSHaojian Zhuang 	unsigned int data;
77832e9fc1aSHaojian Zhuang 
77932e9fc1aSHaojian Zhuang 	if (freq == DDR_FREQ_800M) {
78032e9fc1aSHaojian Zhuang 		set_ddrc_800mhz();
78132e9fc1aSHaojian Zhuang 		INFO("%s, set ddrc 800mhz\n", __func__);
78232e9fc1aSHaojian Zhuang 	} else {
78332e9fc1aSHaojian Zhuang 		set_ddrc_533mhz();
78432e9fc1aSHaojian Zhuang 		INFO("%s, set ddrc 533mhz\n", __func__);
78532e9fc1aSHaojian Zhuang 	}
78632e9fc1aSHaojian Zhuang 
78732e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x004), 0xf1);
78832e9fc1aSHaojian Zhuang 	if (freq == DDR_FREQ_800M)
78932e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x050), 0x100023);
79032e9fc1aSHaojian Zhuang 	else
79132e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x050), 0x100123);
79232e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x060), 0x133);
79332e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x064), 0x133);
79432e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x200), 0xa1000);
79532e9fc1aSHaojian Zhuang 
79632e9fc1aSHaojian Zhuang 	if (freq == DDR_FREQ_800M) {
79732e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x100), 0x755a9d12);
79832e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x104), 0x1753b055);
79932e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x108), 0x7401505f);
80032e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x10c), 0x578ca244);
80132e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x110), 0x10700000);
80232e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x114), 0x13141306);
80332e9fc1aSHaojian Zhuang 	} else {
80432e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x100), 0xb77b6718);
80532e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x104), 0x1e82a071);
80632e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x108), 0x9501c07e);
80732e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x10c), 0xaf50c255);
80832e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x110), 0x10b00000);
80932e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7128000 + 0x114), 0x13181908);
81032e9fc1aSHaojian Zhuang 	}
81132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7128000 + 0x118), 0x44);
81232e9fc1aSHaojian Zhuang 	do {
81332e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x004));
81432e9fc1aSHaojian Zhuang 	} while (data & 1);
81532e9fc1aSHaojian Zhuang 
81632e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x008));
81732e9fc1aSHaojian Zhuang 	if (data & 0x7fe) {
81832e9fc1aSHaojian Zhuang 		NOTICE("fail to init ddr3 rank0\n");
81932e9fc1aSHaojian Zhuang 		return -EFAULT;
82032e9fc1aSHaojian Zhuang 	}
82132e9fc1aSHaojian Zhuang 	INFO("init ddr3 rank0\n");
82232e9fc1aSHaojian Zhuang 	ddrx_rdet();
82332e9fc1aSHaojian Zhuang 	ddrx_wdet();
82432e9fc1aSHaojian Zhuang 
82532e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x048));
82632e9fc1aSHaojian Zhuang 	data |= 1;
82732e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x048), data);
82832e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x004), 0x21);
82932e9fc1aSHaojian Zhuang 	do {
83032e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf712c000 + 0x004));
83132e9fc1aSHaojian Zhuang 	} while (data & 1);
83232e9fc1aSHaojian Zhuang 
83332e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x008));
83432e9fc1aSHaojian Zhuang 	if (data & 0x7fe)
83532e9fc1aSHaojian Zhuang 		NOTICE("ddr3 rank1 init failure\n");
83632e9fc1aSHaojian Zhuang 	else
83732e9fc1aSHaojian Zhuang 		INFO("ddr3 rank1 init pass\n");
83832e9fc1aSHaojian Zhuang 
83932e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf712c000 + 0x048));
84032e9fc1aSHaojian Zhuang 	data &= ~0xf;
84132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf712c000 + 0x048), data);
84232e9fc1aSHaojian Zhuang 	return 0;
84332e9fc1aSHaojian Zhuang }
84432e9fc1aSHaojian Zhuang 
84532e9fc1aSHaojian Zhuang static void init_ddr(int freq)
84632e9fc1aSHaojian Zhuang {
84732e9fc1aSHaojian Zhuang 	unsigned int data;
84832e9fc1aSHaojian Zhuang 	int ret;
84932e9fc1aSHaojian Zhuang 
85032e9fc1aSHaojian Zhuang 
85132e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x030));
85232e9fc1aSHaojian Zhuang 	data |= 1;
85332e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x030), data);
85432e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7032000 + 0x010));
85532e9fc1aSHaojian Zhuang 	data |= 1;
85632e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7032000 + 0x010), data);
85732e9fc1aSHaojian Zhuang 
85832e9fc1aSHaojian Zhuang 	udelay(100);
85932e9fc1aSHaojian Zhuang 	do {
86032e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7032000 + 0x030));
86132e9fc1aSHaojian Zhuang 		data &= 3 << 28;
86232e9fc1aSHaojian Zhuang 	} while (data != (3 << 28));
86332e9fc1aSHaojian Zhuang 	do {
86432e9fc1aSHaojian Zhuang 		data = mmio_read_32((0xf7032000 + 0x010));
86532e9fc1aSHaojian Zhuang 		data &= 3 << 28;
86632e9fc1aSHaojian Zhuang 	} while (data != (3 << 28));
86732e9fc1aSHaojian Zhuang 
86832e9fc1aSHaojian Zhuang 	ret = lpddr3_freq_init(freq);
86932e9fc1aSHaojian Zhuang 	if (ret)
87032e9fc1aSHaojian Zhuang 		return;
87132e9fc1aSHaojian Zhuang }
87232e9fc1aSHaojian Zhuang 
87332e9fc1aSHaojian Zhuang static void init_ddrc_qos(void)
87432e9fc1aSHaojian Zhuang {
87532e9fc1aSHaojian Zhuang 	unsigned int port, data;
87632e9fc1aSHaojian Zhuang 
87732e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x088), 1);
87832e9fc1aSHaojian Zhuang 
87932e9fc1aSHaojian Zhuang 	port = 0;
88032e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x200 + port * 0x10), 0x1210);
88132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x204 + port * 0x10), 0x11111111);
88232e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x208 + port * 0x10), 0x11111111);
88332e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x400 + 0 * 0x10), 0x001d0007);
88432e9fc1aSHaojian Zhuang 
88532e9fc1aSHaojian Zhuang 	for (port = 3; port <= 4; port++) {
88632e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7120000 + 0x200 + port * 0x10), 0x1210);
88732e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7120000 + 0x204 + port * 0x10), 0x77777777);
88832e9fc1aSHaojian Zhuang 		mmio_write_32((0xf7120000 + 0x208 + port * 0x10), 0x77777777);
88932e9fc1aSHaojian Zhuang 	}
89032e9fc1aSHaojian Zhuang 
89132e9fc1aSHaojian Zhuang 	port = 1;
89232e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x200 + port * 0x10), 0x30000);
89332e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x204 + port * 0x10), 0x1234567);
89432e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x208 + port * 0x10), 0x1234567);
89532e9fc1aSHaojian Zhuang 
89632e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x1f0), 0);
89732e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x0bc), 0x3020100);
89832e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x0d0), 0x3020100);
89932e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x1f4), 0x01000100);
90032e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x08c + 0 * 4), 0xd0670402);
90132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x068 + 0 * 4), 0x31);
90232e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x000), 0x7);
90332e9fc1aSHaojian Zhuang 
90432e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7124000 + 0x09c));
90532e9fc1aSHaojian Zhuang 	data &= ~0xff0000;
90632e9fc1aSHaojian Zhuang 	data |= 0x400000;
90732e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x09c), data);
90832e9fc1aSHaojian Zhuang 	data = mmio_read_32((0xf7124000 + 0x0ac));
90932e9fc1aSHaojian Zhuang 	data &= ~0xff0000;
91032e9fc1aSHaojian Zhuang 	data |= 0x400000;
91132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x0ac), data);
91232e9fc1aSHaojian Zhuang 	port = 2;
91332e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x200 + port * 0x10), 0x30000);
91432e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x204 + port * 0x10), 0x1234567);
91532e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7120000 + 0x208 + port * 0x10), 0x1234567);
91632e9fc1aSHaojian Zhuang 
91732e9fc1aSHaojian Zhuang 
91832e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x09c), 0xff7fff);
91932e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x0a0), 0xff);
92032e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x0ac), 0xff7fff);
92132e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x0b0), 0xff);
92232e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x0bc), 0x3020100);
92332e9fc1aSHaojian Zhuang 	mmio_write_32((0xf7124000 + 0x0d0), 0x3020100);
92432e9fc1aSHaojian Zhuang }
92532e9fc1aSHaojian Zhuang 
92632e9fc1aSHaojian Zhuang static void ddr_phy_reset(void)
92732e9fc1aSHaojian Zhuang {
92832e9fc1aSHaojian Zhuang 	mmio_write_32(0xf7030340, 0xa000);
92932e9fc1aSHaojian Zhuang 	mmio_write_32(0xf7030344, 0xa000);
93032e9fc1aSHaojian Zhuang }
93132e9fc1aSHaojian Zhuang 
93232e9fc1aSHaojian Zhuang void hikey_ddr_init(void)
93332e9fc1aSHaojian Zhuang {
93432e9fc1aSHaojian Zhuang 	uint32_t data;
93532e9fc1aSHaojian Zhuang 
93632e9fc1aSHaojian Zhuang 	init_pll();
93732e9fc1aSHaojian Zhuang 	init_freq();
93832e9fc1aSHaojian Zhuang 
93932e9fc1aSHaojian Zhuang 	/*
94032e9fc1aSHaojian Zhuang 	 * Init DDR with 533MHz. Otherwise, DDR initialization
94132e9fc1aSHaojian Zhuang 	 * may fail on 800MHz on some boards.
94232e9fc1aSHaojian Zhuang 	 */
94332e9fc1aSHaojian Zhuang 	ddr_phy_reset();
94432e9fc1aSHaojian Zhuang 	init_ddr(DDR_FREQ_533M);
94532e9fc1aSHaojian Zhuang 	/* Init DDR with 800MHz. */
94632e9fc1aSHaojian Zhuang 	ddr_phy_reset();
94732e9fc1aSHaojian Zhuang 	init_ddr(DDR_FREQ_800M);
94832e9fc1aSHaojian Zhuang 
94932e9fc1aSHaojian Zhuang 
95032e9fc1aSHaojian Zhuang 	ddrc_common_init(1);
95132e9fc1aSHaojian Zhuang 	dienum_det_and_rowcol_cfg();
95232e9fc1aSHaojian Zhuang 	detect_ddr_chip_info();
95332e9fc1aSHaojian Zhuang 
95432e9fc1aSHaojian Zhuang 	data = mmio_read_32(0xf7032000 + 0x010);
95532e9fc1aSHaojian Zhuang 	data &= ~0x1;
95632e9fc1aSHaojian Zhuang 	mmio_write_32(0xf7032000 + 0x010, data);
95732e9fc1aSHaojian Zhuang 	data = mmio_read_32(0xf7032000 + 0x010);
95832e9fc1aSHaojian Zhuang 
95932e9fc1aSHaojian Zhuang 	/*
96032e9fc1aSHaojian Zhuang 	 * Test memory access. Do not use address 0x0 because the compiler
96132e9fc1aSHaojian Zhuang 	 * may assume it is not a valid address and generate incorrect code
96232e9fc1aSHaojian Zhuang 	 * (GCC 4.9.1 without -fno-delete-null-pointer-checks for instance).
96332e9fc1aSHaojian Zhuang 	 */
96432e9fc1aSHaojian Zhuang 	mmio_write_32(0x4, 0xa5a55a5a);
96532e9fc1aSHaojian Zhuang 	INFO("ddr test value:0x%x\n", mmio_read_32(0x4));
96632e9fc1aSHaojian Zhuang 	init_ddrc_qos();
96732e9fc1aSHaojian Zhuang }
968