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
7483dce7eSHaojian Zhuang #include <assert.h>
832e9fc1aSHaojian Zhuang #include <errno.h>
909d40e0eSAntonio Nino Diaz
1009d40e0eSAntonio Nino Diaz #include <arch_helpers.h>
1109d40e0eSAntonio Nino Diaz #include <common/debug.h>
1209d40e0eSAntonio Nino Diaz #include <drivers/arm/sp804_delay_timer.h>
1309d40e0eSAntonio Nino Diaz #include <lib/mmio.h>
1409d40e0eSAntonio Nino Diaz
1532e9fc1aSHaojian Zhuang #include <hi6220.h>
1632e9fc1aSHaojian Zhuang #include <hi6553.h>
171d999558SHaojian Zhuang #include <hisi_sram_map.h>
18483dce7eSHaojian Zhuang #include "hikey_private.h"
1932e9fc1aSHaojian Zhuang
init_pll(void)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 do {
2832e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x000));
2932e9fc1aSHaojian Zhuang } while (!(data & (1 << 28)));
3032e9fc1aSHaojian Zhuang
3132e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7800000 + 0x000));
3232e9fc1aSHaojian Zhuang data &= ~0x007;
3332e9fc1aSHaojian Zhuang data |= 0x004;
3432e9fc1aSHaojian Zhuang mmio_write_32((0xf7800000 + 0x000), data);
3532e9fc1aSHaojian Zhuang do {
3632e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7800000 + 0x014));
3732e9fc1aSHaojian Zhuang data &= 0x007;
3832e9fc1aSHaojian Zhuang } while (data != 0x004);
3932e9fc1aSHaojian Zhuang
4032e9fc1aSHaojian Zhuang mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2101);
41483dce7eSHaojian Zhuang dsb();
42483dce7eSHaojian Zhuang isb();
43483dce7eSHaojian Zhuang udelay(10);
44483dce7eSHaojian Zhuang mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2001);
45483dce7eSHaojian Zhuang dsb();
46483dce7eSHaojian Zhuang isb();
47483dce7eSHaojian Zhuang udelay(10);
48483dce7eSHaojian Zhuang mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2201);
49483dce7eSHaojian Zhuang dsb();
50483dce7eSHaojian Zhuang isb();
51483dce7eSHaojian Zhuang udelay(10);
5232e9fc1aSHaojian Zhuang mmio_write_32(0xf7032000 + 0x02c, 0x5110103e);
53483dce7eSHaojian Zhuang dsb();
54483dce7eSHaojian Zhuang isb();
55483dce7eSHaojian Zhuang udelay(10);
5632e9fc1aSHaojian Zhuang data = mmio_read_32(0xf7032000 + 0x050);
5732e9fc1aSHaojian Zhuang data |= 1 << 28;
5832e9fc1aSHaojian Zhuang mmio_write_32(0xf7032000 + 0x050, data);
59483dce7eSHaojian Zhuang dsb();
60483dce7eSHaojian Zhuang isb();
61483dce7eSHaojian Zhuang udelay(10);
6232e9fc1aSHaojian Zhuang mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2101);
63483dce7eSHaojian Zhuang dsb();
64483dce7eSHaojian Zhuang isb();
65483dce7eSHaojian Zhuang udelay(10);
66483dce7eSHaojian Zhuang mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2001);
67483dce7eSHaojian Zhuang dsb();
68483dce7eSHaojian Zhuang isb();
69483dce7eSHaojian Zhuang udelay(10);
70483dce7eSHaojian Zhuang mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2201);
71483dce7eSHaojian Zhuang dsb();
72483dce7eSHaojian Zhuang isb();
73483dce7eSHaojian Zhuang udelay(10);
7432e9fc1aSHaojian Zhuang }
7532e9fc1aSHaojian Zhuang
init_freq(void)7632e9fc1aSHaojian Zhuang static void init_freq(void)
7732e9fc1aSHaojian Zhuang {
7832e9fc1aSHaojian Zhuang unsigned int data, tmp;
7932e9fc1aSHaojian Zhuang unsigned int cpuext_cfg, ddr_cfg;
8032e9fc1aSHaojian Zhuang
8132e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x374), 0x4a);
8232e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x368), 0xda);
8332e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x36c), 0x01);
8432e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x370), 0x01);
8532e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x360), 0x60);
8632e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x364), 0x60);
8732e9fc1aSHaojian Zhuang
8832e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x114), 0x1000);
8932e9fc1aSHaojian Zhuang
9032e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x110));
9132e9fc1aSHaojian Zhuang data |= (3 << 12);
9232e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x110), data);
9332e9fc1aSHaojian Zhuang
9432e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x110));
9532e9fc1aSHaojian Zhuang data |= (1 << 4);
9632e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x110), data);
9732e9fc1aSHaojian Zhuang
9832e9fc1aSHaojian Zhuang
9932e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x110));
10032e9fc1aSHaojian Zhuang data &= ~0x7;
10132e9fc1aSHaojian Zhuang data |= 0x5;
10232e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x110), data);
10332e9fc1aSHaojian Zhuang dsb();
10432e9fc1aSHaojian Zhuang mdelay(10);
10532e9fc1aSHaojian Zhuang
10632e9fc1aSHaojian Zhuang
10732e9fc1aSHaojian Zhuang do {
10832e9fc1aSHaojian Zhuang data = mmio_read_32((0xf6504000 + 0x008));
10932e9fc1aSHaojian Zhuang data &= (3 << 20);
11032e9fc1aSHaojian Zhuang } while (data != (3 << 20));
11132e9fc1aSHaojian Zhuang dsb();
11232e9fc1aSHaojian Zhuang mdelay(10);
11332e9fc1aSHaojian Zhuang
11432e9fc1aSHaojian Zhuang
11532e9fc1aSHaojian Zhuang data = mmio_read_32((0xf6504000 + 0x054));
11632e9fc1aSHaojian Zhuang data &= ~((1 << 0) | (1 << 11));
11732e9fc1aSHaojian Zhuang mmio_write_32((0xf6504000 + 0x054), data);
11832e9fc1aSHaojian Zhuang mdelay(10);
11932e9fc1aSHaojian Zhuang
12032e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x104));
12132e9fc1aSHaojian Zhuang data &= ~(3 << 8);
12232e9fc1aSHaojian Zhuang data |= (1 << 8);
12332e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x104), data);
12432e9fc1aSHaojian Zhuang
12532e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x100));
12632e9fc1aSHaojian Zhuang data |= (1 << 0);
12732e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x100), data);
12832e9fc1aSHaojian Zhuang dsb();
12932e9fc1aSHaojian Zhuang
13032e9fc1aSHaojian Zhuang do {
13132e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x100));
13232e9fc1aSHaojian Zhuang data &= (1 << 2);
13332e9fc1aSHaojian Zhuang } while (data != (1 << 2));
13432e9fc1aSHaojian Zhuang
13532e9fc1aSHaojian Zhuang data = mmio_read_32((0xf6504000 + 0x06c));
13632e9fc1aSHaojian Zhuang data &= ~0xffff;
13732e9fc1aSHaojian Zhuang data |= 0x56;
13832e9fc1aSHaojian Zhuang mmio_write_32((0xf6504000 + 0x06c), data);
13932e9fc1aSHaojian Zhuang
14032e9fc1aSHaojian Zhuang data = mmio_read_32((0xf6504000 + 0x06c));
141*d3b6df7cSJustin Chadwell data &= ~(0xffffffu << 8);
14232e9fc1aSHaojian Zhuang data |= 0xc7a << 8;
14332e9fc1aSHaojian Zhuang mmio_write_32((0xf6504000 + 0x06c), data);
14432e9fc1aSHaojian Zhuang
14532e9fc1aSHaojian Zhuang data = mmio_read_32((0xf6504000 + 0x058));
14632e9fc1aSHaojian Zhuang data &= ((1 << 13) - 1);
14732e9fc1aSHaojian Zhuang data |= 0xccb;
14832e9fc1aSHaojian Zhuang mmio_write_32((0xf6504000 + 0x058), data);
14932e9fc1aSHaojian Zhuang
15032e9fc1aSHaojian Zhuang mmio_write_32((0xf6504000 + 0x060), 0x1fff);
15132e9fc1aSHaojian Zhuang mmio_write_32((0xf6504000 + 0x064), 0x1ffffff);
15232e9fc1aSHaojian Zhuang mmio_write_32((0xf6504000 + 0x068), 0x7fffffff);
15332e9fc1aSHaojian Zhuang mmio_write_32((0xf6504000 + 0x05c), 0x1);
15432e9fc1aSHaojian Zhuang
15532e9fc1aSHaojian Zhuang data = mmio_read_32((0xf6504000 + 0x054));
15632e9fc1aSHaojian Zhuang data &= ~(0xf << 12);
15732e9fc1aSHaojian Zhuang data |= 1 << 12;
15832e9fc1aSHaojian Zhuang mmio_write_32((0xf6504000 + 0x054), data);
15932e9fc1aSHaojian Zhuang dsb();
16032e9fc1aSHaojian Zhuang
16132e9fc1aSHaojian Zhuang
16232e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x000));
16332e9fc1aSHaojian Zhuang data &= ~(1 << 0);
16432e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x000), data);
16532e9fc1aSHaojian Zhuang
16632e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x004), 0x5110207d);
16732e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x134), 0x10000005);
16832e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x134));
16932e9fc1aSHaojian Zhuang
17032e9fc1aSHaojian Zhuang
17132e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x000));
17232e9fc1aSHaojian Zhuang data |= (1 << 0);
17332e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x000), data);
17432e9fc1aSHaojian Zhuang
17532e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x368), 0x100da);
17632e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x378));
17732e9fc1aSHaojian Zhuang data &= ~((1 << 7) - 1);
17832e9fc1aSHaojian Zhuang data |= 0x6b;
17932e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x378), data);
18032e9fc1aSHaojian Zhuang dsb();
18132e9fc1aSHaojian Zhuang do {
18232e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x378));
18332e9fc1aSHaojian Zhuang tmp = data & 0x7f;
18432e9fc1aSHaojian Zhuang data = (data & (0x7f << 8)) >> 8;
18532e9fc1aSHaojian Zhuang if (data != tmp)
18632e9fc1aSHaojian Zhuang continue;
18732e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x37c));
18832e9fc1aSHaojian Zhuang } while (!(data & 1));
18932e9fc1aSHaojian Zhuang
19032e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x104));
19132e9fc1aSHaojian Zhuang data &= ~((3 << 0) |
19232e9fc1aSHaojian Zhuang (3 << 8));
19332e9fc1aSHaojian Zhuang cpuext_cfg = 1;
19432e9fc1aSHaojian Zhuang ddr_cfg = 1;
19532e9fc1aSHaojian Zhuang data |= cpuext_cfg | (ddr_cfg << 8);
19632e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x104), data);
19732e9fc1aSHaojian Zhuang dsb();
19832e9fc1aSHaojian Zhuang
19932e9fc1aSHaojian Zhuang do {
20032e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x104));
20132e9fc1aSHaojian Zhuang tmp = (data & (3 << 16)) >> 16;
20232e9fc1aSHaojian Zhuang if (cpuext_cfg != tmp)
20332e9fc1aSHaojian Zhuang continue;
20432e9fc1aSHaojian Zhuang tmp = (data & (3 << 24)) >> 24;
20532e9fc1aSHaojian Zhuang if (ddr_cfg != tmp)
20632e9fc1aSHaojian Zhuang continue;
20732e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x000));
20832e9fc1aSHaojian Zhuang data &= 1 << 28;
20932e9fc1aSHaojian Zhuang } while (!data);
21032e9fc1aSHaojian Zhuang
21132e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x100));
21232e9fc1aSHaojian Zhuang data &= ~(1 << 0);
21332e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x100), data);
21432e9fc1aSHaojian Zhuang dsb();
21532e9fc1aSHaojian Zhuang do {
21632e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x100));
21732e9fc1aSHaojian Zhuang data &= (1 << 1);
21832e9fc1aSHaojian Zhuang } while (data != (1 << 1));
21932e9fc1aSHaojian Zhuang mdelay(1000);
22032e9fc1aSHaojian Zhuang
22132e9fc1aSHaojian Zhuang data = mmio_read_32((0xf6504000 + 0x054));
22232e9fc1aSHaojian Zhuang data &= ~(1 << 28);
22332e9fc1aSHaojian Zhuang mmio_write_32((0xf6504000 + 0x054), data);
22432e9fc1aSHaojian Zhuang dsb();
22532e9fc1aSHaojian Zhuang
22632e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x110));
22732e9fc1aSHaojian Zhuang data &= ~((1 << 4) |
22832e9fc1aSHaojian Zhuang (3 << 12));
22932e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x110), data);
23032e9fc1aSHaojian Zhuang }
23132e9fc1aSHaojian Zhuang
cat_533mhz_800mhz(void)23232e9fc1aSHaojian Zhuang int cat_533mhz_800mhz(void)
23332e9fc1aSHaojian Zhuang {
23432e9fc1aSHaojian Zhuang unsigned int data, i;
23532e9fc1aSHaojian Zhuang unsigned int bdl[5];
23632e9fc1aSHaojian Zhuang
23732e9fc1aSHaojian Zhuang
23832e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x1c8));
23932e9fc1aSHaojian Zhuang data &= 0xfffff0f0;
240483dce7eSHaojian Zhuang data |= 0x100f01;
24132e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x1c8), data);
24232e9fc1aSHaojian Zhuang
24332e9fc1aSHaojian Zhuang for (i = 0; i < 0x20; i++) {
24432e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x1d4), 0xc0000);
24532e9fc1aSHaojian Zhuang data = (i << 0x10) + i;
24632e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x140), data);
24732e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x144), data);
24832e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x148), data);
24932e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x14c), data);
25032e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x150), data);
25132e9fc1aSHaojian Zhuang
25232e9fc1aSHaojian Zhuang
25332e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x070));
25432e9fc1aSHaojian Zhuang data |= 0x80000;
25532e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x070), data);
25632e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x070));
25732e9fc1aSHaojian Zhuang data &= 0xfff7ffff;
25832e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x070), data);
25932e9fc1aSHaojian Zhuang
26032e9fc1aSHaojian Zhuang
26132e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0x8000);
26232e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0x0);
26332e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0x801);
26432e9fc1aSHaojian Zhuang do {
26532e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x004));
26632e9fc1aSHaojian Zhuang } while (data & 1);
26732e9fc1aSHaojian Zhuang
26832e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x008));
269483dce7eSHaojian Zhuang if ((data & 0x400) == 0) {
27032e9fc1aSHaojian Zhuang mdelay(10);
27132e9fc1aSHaojian Zhuang return 0;
27232e9fc1aSHaojian Zhuang }
27332e9fc1aSHaojian Zhuang WARN("lpddr3 cat fail\n");
27432e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x1d4));
27532e9fc1aSHaojian Zhuang if ((data & 0x1f00) && ((data & 0x1f) == 0)) {
27632e9fc1aSHaojian Zhuang bdl[0] = mmio_read_32((0xf712c000 + 0x140));
27732e9fc1aSHaojian Zhuang bdl[1] = mmio_read_32((0xf712c000 + 0x144));
27832e9fc1aSHaojian Zhuang bdl[2] = mmio_read_32((0xf712c000 + 0x148));
27932e9fc1aSHaojian Zhuang bdl[3] = mmio_read_32((0xf712c000 + 0x14c));
28032e9fc1aSHaojian Zhuang bdl[4] = mmio_read_32((0xf712c000 + 0x150));
28132e9fc1aSHaojian Zhuang if ((!(bdl[0] & 0x1f001f)) || (!(bdl[1] & 0x1f001f)) ||
28232e9fc1aSHaojian Zhuang (!(bdl[2] & 0x1f001f)) || (!(bdl[3] & 0x1f001f)) ||
28332e9fc1aSHaojian Zhuang (!(bdl[4] & 0x1f001f))) {
28432e9fc1aSHaojian Zhuang WARN("lpddr3 cat deskew error\n");
28532e9fc1aSHaojian Zhuang if (i == 0x1f) {
28632e9fc1aSHaojian Zhuang WARN("addrnbdl is max\n");
28732e9fc1aSHaojian Zhuang return -EINVAL;
28832e9fc1aSHaojian Zhuang }
28932e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x008), 0x400);
29032e9fc1aSHaojian Zhuang } else {
29132e9fc1aSHaojian Zhuang WARN("lpddr3 cat other error1\n");
29232e9fc1aSHaojian Zhuang return -EINVAL;
29332e9fc1aSHaojian Zhuang }
29432e9fc1aSHaojian Zhuang } else {
29532e9fc1aSHaojian Zhuang WARN("lpddr3 cat other error2\n");
29632e9fc1aSHaojian Zhuang return -EINVAL;
29732e9fc1aSHaojian Zhuang }
29832e9fc1aSHaojian Zhuang }
29932e9fc1aSHaojian Zhuang return -EINVAL;
30032e9fc1aSHaojian Zhuang }
30132e9fc1aSHaojian Zhuang
ddrx_rdet(void)30232e9fc1aSHaojian Zhuang static void ddrx_rdet(void)
30332e9fc1aSHaojian Zhuang {
30432e9fc1aSHaojian Zhuang unsigned int data, rdet, bdl[4];
30532e9fc1aSHaojian Zhuang
30632e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x0d0));
30732e9fc1aSHaojian Zhuang data &= 0xf800ffff;
30832e9fc1aSHaojian Zhuang data |= 0x8f0000;
30932e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x0d0), data);
31032e9fc1aSHaojian Zhuang
31132e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x0dc));
31232e9fc1aSHaojian Zhuang data &= 0xfffffff0;
31332e9fc1aSHaojian Zhuang data |= 0xf;
31432e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x0dc), data);
31532e9fc1aSHaojian Zhuang
31632e9fc1aSHaojian Zhuang
31732e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x070));
31832e9fc1aSHaojian Zhuang data |= 0x80000;
31932e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x070), data);
32032e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x070));
32132e9fc1aSHaojian Zhuang data &= 0xfff7ffff;
32232e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x070), data);
32332e9fc1aSHaojian Zhuang
32432e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0x8000);
32532e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0);
32632e9fc1aSHaojian Zhuang
32732e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x0d0));
32832e9fc1aSHaojian Zhuang data &= ~0xf0000000;
32932e9fc1aSHaojian Zhuang data |= 0x80000000;
33032e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x0d0), data);
33132e9fc1aSHaojian Zhuang
33232e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0x101);
33332e9fc1aSHaojian Zhuang do {
33432e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x004));
33532e9fc1aSHaojian Zhuang } while (!(data & 1));
33632e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x008));
33732e9fc1aSHaojian Zhuang if (data & 0x100)
33832e9fc1aSHaojian Zhuang WARN("rdet lbs fail\n");
33932e9fc1aSHaojian Zhuang
34032e9fc1aSHaojian Zhuang bdl[0] = mmio_read_32((0xf712c000 + 0x22c)) & 0x7f;
34132e9fc1aSHaojian Zhuang bdl[1] = mmio_read_32((0xf712c000 + 0x2ac)) & 0x7f;
34232e9fc1aSHaojian Zhuang bdl[2] = mmio_read_32((0xf712c000 + 0x32c)) & 0x7f;
34332e9fc1aSHaojian Zhuang bdl[3] = mmio_read_32((0xf712c000 + 0x3ac)) & 0x7f;
34432e9fc1aSHaojian Zhuang do {
34532e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x22c));
34632e9fc1aSHaojian Zhuang data &= ~0x7f;
34732e9fc1aSHaojian Zhuang data |= bdl[0];
34832e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x22c), data);
34932e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x2ac));
35032e9fc1aSHaojian Zhuang data &= ~0x7f;
35132e9fc1aSHaojian Zhuang data |= bdl[1];
35232e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x2ac), data);
35332e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x32c));
35432e9fc1aSHaojian Zhuang data &= ~0x7f;
35532e9fc1aSHaojian Zhuang data |= bdl[2];
35632e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x32c), data);
35732e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x3ac));
35832e9fc1aSHaojian Zhuang data &= ~0x7f;
35932e9fc1aSHaojian Zhuang data |= bdl[3];
36032e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x3ac), data);
36132e9fc1aSHaojian Zhuang
36232e9fc1aSHaojian Zhuang
36332e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x070));
36432e9fc1aSHaojian Zhuang data |= 0x80000;
36532e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x070), data);
36632e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x070));
36732e9fc1aSHaojian Zhuang data &= 0xfff7ffff;
36832e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x070), data);
36932e9fc1aSHaojian Zhuang
37032e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0x8000);
37132e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0);
37232e9fc1aSHaojian Zhuang
37332e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x0d0));
37432e9fc1aSHaojian Zhuang data &= ~0xf0000000;
37532e9fc1aSHaojian Zhuang data |= 0x40000000;
37632e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x0d0), data);
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
38232e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x008));
38332e9fc1aSHaojian Zhuang rdet = data & 0x100;
38432e9fc1aSHaojian Zhuang if (rdet) {
38532e9fc1aSHaojian Zhuang INFO("rdet ds fail\n");
38632e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x008), 0x100);
38732e9fc1aSHaojian Zhuang }
38832e9fc1aSHaojian Zhuang bdl[0]++;
38932e9fc1aSHaojian Zhuang bdl[1]++;
39032e9fc1aSHaojian Zhuang bdl[2]++;
39132e9fc1aSHaojian Zhuang bdl[3]++;
39232e9fc1aSHaojian Zhuang } while (rdet);
39332e9fc1aSHaojian Zhuang
39432e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x0d0));
39532e9fc1aSHaojian Zhuang data &= ~0xf0000000;
39632e9fc1aSHaojian Zhuang data |= 0x30000000;
39732e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x0d0), data);
39832e9fc1aSHaojian Zhuang
39932e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0x101);
40032e9fc1aSHaojian Zhuang do {
40132e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x004));
40232e9fc1aSHaojian Zhuang } while (data & 1);
40332e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x008));
40432e9fc1aSHaojian Zhuang if (data & 0x100)
40532e9fc1aSHaojian Zhuang INFO("rdet rbs av fail\n");
40632e9fc1aSHaojian Zhuang }
40732e9fc1aSHaojian Zhuang
ddrx_wdet(void)40832e9fc1aSHaojian Zhuang static void ddrx_wdet(void)
40932e9fc1aSHaojian Zhuang {
41022db0167SHaojian Zhuang unsigned int data, wdet, zero_bdl = 0, dq[4];
41132e9fc1aSHaojian Zhuang int i;
41232e9fc1aSHaojian Zhuang
41332e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x0d0));
41432e9fc1aSHaojian Zhuang data &= ~0xf;
41532e9fc1aSHaojian Zhuang data |= 0xf;
41632e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x0d0), data);
41732e9fc1aSHaojian Zhuang
41832e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x070));
41932e9fc1aSHaojian Zhuang data |= 0x80000;
42032e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x070), data);
42132e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x070));
42232e9fc1aSHaojian Zhuang data &= ~0x80000;
42332e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x070), data);
42432e9fc1aSHaojian Zhuang
42532e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0x8000);
42632e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0);
42732e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x0d0));
42832e9fc1aSHaojian Zhuang data &= ~0xf000;
42932e9fc1aSHaojian Zhuang data |= 0x8000;
43032e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x0d0), data);
43132e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0x201);
43232e9fc1aSHaojian Zhuang do {
43332e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x004));
43432e9fc1aSHaojian Zhuang } while (data & 1);
43532e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x008));
43632e9fc1aSHaojian Zhuang if (data & 0x200)
43732e9fc1aSHaojian Zhuang INFO("wdet lbs fail\n");
43832e9fc1aSHaojian Zhuang
43932e9fc1aSHaojian Zhuang dq[0] = mmio_read_32((0xf712c000 + 0x234)) & 0x1f00;
44032e9fc1aSHaojian Zhuang dq[1] = mmio_read_32((0xf712c000 + 0x2b4)) & 0x1f00;
44132e9fc1aSHaojian Zhuang dq[2] = mmio_read_32((0xf712c000 + 0x334)) & 0x1f00;
44232e9fc1aSHaojian Zhuang dq[3] = mmio_read_32((0xf712c000 + 0x3b4)) & 0x1f00;
44332e9fc1aSHaojian Zhuang
44432e9fc1aSHaojian Zhuang do {
44532e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x234), dq[0]);
44632e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x2b4), dq[1]);
44732e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x334), dq[2]);
44832e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x3b4), dq[3]);
44932e9fc1aSHaojian Zhuang
45032e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x070));
45132e9fc1aSHaojian Zhuang data |= 0x80000;
45232e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x070), data);
45332e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x070));
45432e9fc1aSHaojian Zhuang data &= ~0x80000;
45532e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x070), data);
45632e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0x8000);
45732e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0);
45832e9fc1aSHaojian Zhuang
45932e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x0d0));
46032e9fc1aSHaojian Zhuang data &= ~0xf000;
46132e9fc1aSHaojian Zhuang data |= 0x4000;
46232e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x0d0), data);
46332e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0x201);
46432e9fc1aSHaojian Zhuang do {
46532e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x004));
46632e9fc1aSHaojian Zhuang } while (data & 1);
46732e9fc1aSHaojian Zhuang
46832e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x008));
46932e9fc1aSHaojian Zhuang wdet = data & 0x200;
47032e9fc1aSHaojian Zhuang if (wdet) {
47132e9fc1aSHaojian Zhuang INFO("wdet ds fail\n");
47232e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x008), 0x200);
47332e9fc1aSHaojian Zhuang }
47432e9fc1aSHaojian Zhuang mdelay(10);
47532e9fc1aSHaojian Zhuang
47632e9fc1aSHaojian Zhuang for (i = 0; i < 4; i++) {
47732e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x210 + i * 0x80));
47832e9fc1aSHaojian Zhuang if ((!(data & 0x1f)) || (!(data & 0x1f00)) ||
47932e9fc1aSHaojian Zhuang (!(data & 0x1f0000)) || (!(data & 0x1f000000)))
48032e9fc1aSHaojian Zhuang zero_bdl = 1;
48132e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x214 + i * 0x80));
48232e9fc1aSHaojian Zhuang if ((!(data & 0x1f)) || (!(data & 0x1f00)) ||
48332e9fc1aSHaojian Zhuang (!(data & 0x1f0000)) || (!(data & 0x1f000000)))
48432e9fc1aSHaojian Zhuang zero_bdl = 1;
48532e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x218 + i * 0x80));
48632e9fc1aSHaojian Zhuang if (!(data & 0x1f))
48732e9fc1aSHaojian Zhuang zero_bdl = 1;
48832e9fc1aSHaojian Zhuang if (zero_bdl) {
48932e9fc1aSHaojian Zhuang if (i == 0)
49032e9fc1aSHaojian Zhuang dq[0] = dq[0] - 0x100;
49132e9fc1aSHaojian Zhuang if (i == 1)
49232e9fc1aSHaojian Zhuang dq[1] = dq[1] - 0x100;
49332e9fc1aSHaojian Zhuang if (i == 2)
49432e9fc1aSHaojian Zhuang dq[2] = dq[2] - 0x100;
49532e9fc1aSHaojian Zhuang if (i == 3)
49632e9fc1aSHaojian Zhuang dq[3] = dq[3] - 0x100;
49732e9fc1aSHaojian Zhuang }
49832e9fc1aSHaojian Zhuang }
49932e9fc1aSHaojian Zhuang } while (wdet);
50032e9fc1aSHaojian Zhuang
50132e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x0d0));
50232e9fc1aSHaojian Zhuang data &= ~0xf000;
50332e9fc1aSHaojian Zhuang data |= 0x3000;
50432e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x0d0), data);
50532e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0x201);
50632e9fc1aSHaojian Zhuang do {
50732e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x004));
50832e9fc1aSHaojian Zhuang } while (data & 1);
50932e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x008));
51032e9fc1aSHaojian Zhuang if (data & 0x200)
51132e9fc1aSHaojian Zhuang INFO("wdet rbs av fail\n");
51232e9fc1aSHaojian Zhuang }
51332e9fc1aSHaojian Zhuang
set_ddrc_150mhz(void)514483dce7eSHaojian Zhuang void set_ddrc_150mhz(void)
515483dce7eSHaojian Zhuang {
516483dce7eSHaojian Zhuang unsigned int data;
517483dce7eSHaojian Zhuang
518483dce7eSHaojian Zhuang mmio_write_32((0xf7032000 + 0x580), 0x1);
519483dce7eSHaojian Zhuang mmio_write_32((0xf7032000 + 0x5a8), 0x7);
520483dce7eSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x104));
521483dce7eSHaojian Zhuang data &= 0xfffffcff;
522483dce7eSHaojian Zhuang mmio_write_32((0xf7032000 + 0x104), data);
523483dce7eSHaojian Zhuang
524483dce7eSHaojian Zhuang mmio_write_32((0xf7030000 + 0x050), 0x31);
525483dce7eSHaojian Zhuang mmio_write_32((0xf7030000 + 0x240), 0x5ffff);
526483dce7eSHaojian Zhuang mmio_write_32((0xf7030000 + 0x344), 0xf5ff);
527483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x00c), 0x80000f0f);
528483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x00c), 0xf0f);
529483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x018), 0x7);
530483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x090), 0x7200000);
531483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x258), 0x720);
532483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x2d8), 0x720);
533483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x358), 0x720);
534483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x3d8), 0x720);
535483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x018), 0x7);
536483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x0b0), 0xf00000f);
537483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x0b4), 0xf);
538483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x088), 0x3fff801);
539483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x070), 0x8940000);
540483dce7eSHaojian Zhuang
541483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x078));
542483dce7eSHaojian Zhuang data |= 4;
543483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x078), data);
544483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x01c), 0x8000080);
545483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x020));
546483dce7eSHaojian Zhuang data &= 0xfffffffe;
547483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x020), data);
548483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x1d4), 0xc0000);
549483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x010), 0x500000f);
550483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x014), 0x10);
551483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x1e4));
552483dce7eSHaojian Zhuang data &= 0xffffff00;
553483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x1e4), data);
554483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x030), 0x30c82355);
555483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x034), 0x62112bb);
556483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x038), 0x20041022);
557483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x03c), 0x63177497);
558483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x040), 0x3008407);
559483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x064), 0x10483);
560483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x068), 0xff0a0000);
561483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x070));
562483dce7eSHaojian Zhuang data &= 0xffff0000;
563483dce7eSHaojian Zhuang data |= 0x184;
564483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x070), data);
565483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x048));
566483dce7eSHaojian Zhuang data &= 0xbfffffff;
567483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x048), data);
568483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x020));
569483dce7eSHaojian Zhuang data &= ~0x10;
570483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x020), data);
571483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x080));
572483dce7eSHaojian Zhuang data &= ~0x2000;
573483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x080), data);
574483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x270), 0x3);
575483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x2f0), 0x3);
576483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x370), 0x3);
577483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x3f0), 0x3);
578483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x048), 0x90420880);
579483dce7eSHaojian Zhuang
580483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x040), 0x0);
581483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0x146d);
582483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x050), 0x100123);
583483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x060), 0x133);
584483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x064), 0x133);
585483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x200), 0xa1000);
586483dce7eSHaojian Zhuang
587483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x100), 0xb3290d08);
588483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x104), 0x9621821);
589483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x108), 0x45009023);
590483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x10c), 0xaf44c145);
591483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x110), 0x10b00000);
592483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x114), 0x11080806);
593483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x118), 0x44);
594483dce7eSHaojian Zhuang do {
595483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x004));
596483dce7eSHaojian Zhuang } while (data & 1);
597483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x008));
598483dce7eSHaojian Zhuang if (data & 8) {
599483dce7eSHaojian Zhuang NOTICE("fail to init ddr3 rank0\n");
600483dce7eSHaojian Zhuang return;
601483dce7eSHaojian Zhuang }
602483dce7eSHaojian Zhuang
603483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x048));
604483dce7eSHaojian Zhuang data |= 1;
605483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x048), data);
606483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0x21);
607483dce7eSHaojian Zhuang do {
608483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x004));
609483dce7eSHaojian Zhuang } while (data & 1);
610483dce7eSHaojian Zhuang
611483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x008));
612483dce7eSHaojian Zhuang if (data & 0x8)
613483dce7eSHaojian Zhuang NOTICE("ddr3 rank1 init failure\n");
614483dce7eSHaojian Zhuang else
615483dce7eSHaojian Zhuang INFO("ddr3 rank1 init pass\n");
616483dce7eSHaojian Zhuang
617483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x048));
618483dce7eSHaojian Zhuang data &= ~0xf;
619483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x048), data);
620483dce7eSHaojian Zhuang INFO("succeed to set ddrc 150mhz\n");
621483dce7eSHaojian Zhuang }
622483dce7eSHaojian Zhuang
set_ddrc_266mhz(void)623483dce7eSHaojian Zhuang void set_ddrc_266mhz(void)
624483dce7eSHaojian Zhuang {
625483dce7eSHaojian Zhuang unsigned int data;
626483dce7eSHaojian Zhuang
627483dce7eSHaojian Zhuang mmio_write_32((0xf7032000 + 0x580), 0x3);
628483dce7eSHaojian Zhuang mmio_write_32((0xf7032000 + 0x5a8), 0x1003);
629483dce7eSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x104));
630483dce7eSHaojian Zhuang data &= 0xfffffcff;
631483dce7eSHaojian Zhuang mmio_write_32((0xf7032000 + 0x104), data);
632483dce7eSHaojian Zhuang
633483dce7eSHaojian Zhuang mmio_write_32((0xf7030000 + 0x050), 0x31);
634483dce7eSHaojian Zhuang mmio_write_32((0xf7030000 + 0x240), 0x5ffff);
635483dce7eSHaojian Zhuang mmio_write_32((0xf7030000 + 0x344), 0xf5ff);
636483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x00c), 0x80000f0f);
637483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x00c), 0xf0f);
638483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x018), 0x7);
639483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x090), 0x7200000);
640483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x258), 0x720);
641483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x2d8), 0x720);
642483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x358), 0x720);
643483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x3d8), 0x720);
644483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x018), 0x7);
645483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x0b0), 0xf00000f);
646483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x0b4), 0xf);
647483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x088), 0x3fff801);
648483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x070), 0x8940000);
649483dce7eSHaojian Zhuang
650483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x078));
651483dce7eSHaojian Zhuang data |= 4;
652483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x078), data);
653483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x01c), 0x8000080);
654483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x020));
655483dce7eSHaojian Zhuang data &= 0xfffffffe;
656483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x020), data);
657483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x1d4), 0xc0000);
658483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x010), 0x500000f);
659483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x014), 0x10);
660483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x1e4));
661483dce7eSHaojian Zhuang data &= 0xffffff00;
662483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x1e4), data);
663483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x030), 0x510d4455);
664483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x034), 0x8391ebb);
665483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x038), 0x2005103c);
666483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x03c), 0x6329950b);
667483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x040), 0x300858c);
668483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x064), 0x10483);
669483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x068), 0xff0a0000);
670483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x070));
671483dce7eSHaojian Zhuang data &= 0xffff0000;
672483dce7eSHaojian Zhuang data |= 0x184;
673483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x070), data);
674483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x048));
675483dce7eSHaojian Zhuang data &= 0xbfffffff;
676483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x048), data);
677483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x020));
678483dce7eSHaojian Zhuang data &= ~0x10;
679483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x020), data);
680483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x080));
681483dce7eSHaojian Zhuang data &= ~0x2000;
682483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x080), data);
683483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x270), 0x3);
684483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x2f0), 0x3);
685483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x370), 0x3);
686483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x3f0), 0x3);
687483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x048), 0x90420880);
688483dce7eSHaojian Zhuang
689483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x040), 0x0);
690483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0x146d);
691483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x050), 0x100123);
692483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x060), 0x133);
693483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x064), 0x133);
694483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x200), 0xa1000);
695483dce7eSHaojian Zhuang
696483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x100), 0xb441d50d);
697483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x104), 0xf721839);
698483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x108), 0x5500f03f);
699483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x10c), 0xaf486145);
700483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x110), 0x10b00000);
701483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x114), 0x12080d06);
702483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x118), 0x44);
703483dce7eSHaojian Zhuang do {
704483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x004));
705483dce7eSHaojian Zhuang } while (data & 1);
706483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x008));
707483dce7eSHaojian Zhuang if (data & 8) {
708483dce7eSHaojian Zhuang NOTICE("fail to init ddr3 rank0\n");
709483dce7eSHaojian Zhuang return;
710483dce7eSHaojian Zhuang }
711483dce7eSHaojian Zhuang
712483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x048));
713483dce7eSHaojian Zhuang data |= 1;
714483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x048), data);
715483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0x21);
716483dce7eSHaojian Zhuang do {
717483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x004));
718483dce7eSHaojian Zhuang } while (data & 1);
719483dce7eSHaojian Zhuang
720483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x008));
721483dce7eSHaojian Zhuang if (data & 0x8)
722483dce7eSHaojian Zhuang NOTICE("ddr3 rank1 init failure\n");
723483dce7eSHaojian Zhuang else
724483dce7eSHaojian Zhuang INFO("ddr3 rank1 init pass\n");
725483dce7eSHaojian Zhuang
726483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x048));
727483dce7eSHaojian Zhuang data &= ~0xf;
728483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x048), data);
729483dce7eSHaojian Zhuang INFO("succeed to set ddrc 266mhz\n");
730483dce7eSHaojian Zhuang }
731483dce7eSHaojian Zhuang
set_ddrc_400mhz(void)732483dce7eSHaojian Zhuang void set_ddrc_400mhz(void)
733483dce7eSHaojian Zhuang {
734483dce7eSHaojian Zhuang unsigned int data;
735483dce7eSHaojian Zhuang
736483dce7eSHaojian Zhuang mmio_write_32((0xf7032000 + 0x580), 0x2);
737483dce7eSHaojian Zhuang mmio_write_32((0xf7032000 + 0x5a8), 0x1003);
738483dce7eSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x104));
739483dce7eSHaojian Zhuang data &= 0xfffffcff;
740483dce7eSHaojian Zhuang mmio_write_32((0xf7032000 + 0x104), data);
741483dce7eSHaojian Zhuang
742483dce7eSHaojian Zhuang mmio_write_32((0xf7030000 + 0x050), 0x31);
743483dce7eSHaojian Zhuang mmio_write_32((0xf7030000 + 0x240), 0x5ffff);
744483dce7eSHaojian Zhuang mmio_write_32((0xf7030000 + 0x344), 0xf5ff);
745483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x00c), 0x80000f0f);
746483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x00c), 0xf0f);
747483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x018), 0x7);
748483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x090), 0x7200000);
749483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x258), 0x720);
750483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x2d8), 0x720);
751483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x358), 0x720);
752483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x3d8), 0x720);
753483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x018), 0x7);
754483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x0b0), 0xf00000f);
755483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x0b4), 0xf);
756483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x088), 0x3fff801);
757483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x070), 0x8940000);
758483dce7eSHaojian Zhuang
759483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x078));
760483dce7eSHaojian Zhuang data |= 4;
761483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x078), data);
762483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x01c), 0x8000080);
763483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x020));
764483dce7eSHaojian Zhuang data &= 0xfffffffe;
765483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x020), data);
766483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x1d4), 0xc0000);
767483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x010), 0x500000f);
768483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x014), 0x10);
769483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x1e4));
770483dce7eSHaojian Zhuang data &= 0xffffff00;
771483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x1e4), data);
772483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x030), 0x75525655);
773483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x034), 0xa552abb);
774483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x038), 0x20071059);
775483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x03c), 0x633e8591);
776483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x040), 0x3008691);
777483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x064), 0x10483);
778483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x068), 0xff0a0000);
779483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x070));
780483dce7eSHaojian Zhuang data &= 0xffff0000;
781483dce7eSHaojian Zhuang data |= 0x184;
782483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x070), data);
783483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x048));
784483dce7eSHaojian Zhuang data &= 0xbfffffff;
785483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x048), data);
786483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x020));
787483dce7eSHaojian Zhuang data &= ~0x10;
788483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x020), data);
789483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x080));
790483dce7eSHaojian Zhuang data &= ~0x2000;
791483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x080), data);
792483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x270), 0x3);
793483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x2f0), 0x3);
794483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x370), 0x3);
795483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x3f0), 0x3);
796483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x048), 0x90420880);
797483dce7eSHaojian Zhuang
798483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x040), 0x0);
799483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0x146d);
800483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x050), 0x100123);
801483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x060), 0x133);
802483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x064), 0x133);
803483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x200), 0xa1000);
804483dce7eSHaojian Zhuang
805483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x100), 0xb55a9d12);
806483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x104), 0x17721855);
807483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x108), 0x7501505f);
808483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x10c), 0xaf4ca245);
809483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x110), 0x10b00000);
810483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x114), 0x13081306);
811483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x118), 0x44);
812483dce7eSHaojian Zhuang do {
813483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x004));
814483dce7eSHaojian Zhuang } while (data & 1);
815483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x008));
816483dce7eSHaojian Zhuang if (data & 8) {
817483dce7eSHaojian Zhuang NOTICE("fail to init ddr3 rank0\n");
818483dce7eSHaojian Zhuang return;
819483dce7eSHaojian Zhuang }
820483dce7eSHaojian Zhuang
821483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x048));
822483dce7eSHaojian Zhuang data |= 1;
823483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x048), data);
824483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0x21);
825483dce7eSHaojian Zhuang do {
826483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x004));
827483dce7eSHaojian Zhuang } while (data & 1);
828483dce7eSHaojian Zhuang
829483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x008));
830483dce7eSHaojian Zhuang if (data & 0x8)
831483dce7eSHaojian Zhuang NOTICE("ddr3 rank1 init failure\n");
832483dce7eSHaojian Zhuang else
833483dce7eSHaojian Zhuang INFO("ddr3 rank1 init pass\n");
834483dce7eSHaojian Zhuang
835483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x048));
836483dce7eSHaojian Zhuang data &= ~0xf;
837483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x048), data);
838483dce7eSHaojian Zhuang INFO("succeed to set ddrc 400mhz\n");
839483dce7eSHaojian Zhuang }
840483dce7eSHaojian Zhuang
set_ddrc_533mhz(void)841483dce7eSHaojian Zhuang void set_ddrc_533mhz(void)
84232e9fc1aSHaojian Zhuang {
84332e9fc1aSHaojian Zhuang unsigned int data;
84432e9fc1aSHaojian Zhuang
84532e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x580), 0x3);
84632e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x5a8), 0x11111);
84732e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x104));
84832e9fc1aSHaojian Zhuang data |= 0x100;
84932e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x104), data);
85032e9fc1aSHaojian Zhuang
85132e9fc1aSHaojian Zhuang mmio_write_32((0xf7030000 + 0x050), 0x30);
85232e9fc1aSHaojian Zhuang mmio_write_32((0xf7030000 + 0x240), 0x5ffff);
85332e9fc1aSHaojian Zhuang mmio_write_32((0xf7030000 + 0x344), 0xf5ff);
85432e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x00c), 0x400);
855483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x00c), 0x400);
85632e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x018), 0x7);
85732e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x090), 0x6400000);
85832e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x258), 0x640);
85932e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x2d8), 0x640);
86032e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x358), 0x640);
86132e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x3d8), 0x640);
86232e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x018), 0x0);
86332e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x0b0), 0xf00000f);
86432e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x0b4), 0xf);
86532e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x088), 0x3fff801);
86632e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x070), 0x8940000);
86732e9fc1aSHaojian Zhuang
86832e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x078));
86932e9fc1aSHaojian Zhuang data |= 4;
87032e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x078), data);
87132e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x01c), 0x8000080);
87232e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x020));
87332e9fc1aSHaojian Zhuang data &= 0xfffffffe;
87432e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x020), data);
87532e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x1d4), 0xc0000);
87632e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x010), 0x500000f);
87732e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x014), 0x10);
87832e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x1e4));
87932e9fc1aSHaojian Zhuang data &= 0xffffff00;
88032e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x1e4), data);
88132e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x030), 0x9dd87855);
88232e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x034), 0xa7138bb);
88332e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x038), 0x20091477);
88432e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x03c), 0x84534e16);
88532e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x040), 0x3008817);
88632e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x064), 0x106c3);
88732e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x068), 0xff0a0000);
88832e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x070));
88932e9fc1aSHaojian Zhuang data &= 0xffff0000;
89032e9fc1aSHaojian Zhuang data |= 0x305;
89132e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x070), data);
89232e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x048));
89332e9fc1aSHaojian Zhuang data |= 0x40000000;
89432e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x048), data);
89532e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x020));
89632e9fc1aSHaojian Zhuang data &= ~0x10;
89732e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x020), data);
89832e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x080));
89932e9fc1aSHaojian Zhuang data &= ~0x2000;
90032e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x080), data);
90132e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x270), 0x3);
90232e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x2f0), 0x3);
90332e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x370), 0x3);
90432e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x3f0), 0x3);
90532e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x048), 0xd0420900);
90632e9fc1aSHaojian Zhuang
90732e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x040), 0x0);
90832e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0x140f);
90932e9fc1aSHaojian Zhuang do {
91032e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x004));
91132e9fc1aSHaojian Zhuang } while (data & 1);
91232e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x008));
91332e9fc1aSHaojian Zhuang if (data & 0x7fe) {
91432e9fc1aSHaojian Zhuang NOTICE("failed to init lpddr3 rank0 dram phy\n");
91532e9fc1aSHaojian Zhuang return;
91632e9fc1aSHaojian Zhuang }
917483dce7eSHaojian Zhuang cat_533mhz_800mhz();
918483dce7eSHaojian Zhuang
919483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0xf1);
920483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x050), 0x100123);
921483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x060), 0x133);
922483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x064), 0x133);
923483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x200), 0xa1000);
924483dce7eSHaojian Zhuang
925483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x100), 0xb77b6718);
926483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x104), 0x1e82a071);
927483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x108), 0x9501c07e);
928483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x10c), 0xaf50c255);
929483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x110), 0x10b00000);
930483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x114), 0x13181908);
931483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x118), 0x44);
932483dce7eSHaojian Zhuang do {
933483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x004));
934483dce7eSHaojian Zhuang } while (data & 1);
935483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x008));
936483dce7eSHaojian Zhuang if (data & 0x7fe) {
937483dce7eSHaojian Zhuang NOTICE("fail to init ddr3 rank0\n");
938483dce7eSHaojian Zhuang return;
939483dce7eSHaojian Zhuang }
940483dce7eSHaojian Zhuang ddrx_rdet();
941483dce7eSHaojian Zhuang ddrx_wdet();
942483dce7eSHaojian Zhuang
943483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x048));
944483dce7eSHaojian Zhuang data |= 1;
945483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x048), data);
946483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0x21);
947483dce7eSHaojian Zhuang do {
948483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x004));
949483dce7eSHaojian Zhuang } while (data & 1);
950483dce7eSHaojian Zhuang
951483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x008));
952483dce7eSHaojian Zhuang if (data & 0x7fe)
953483dce7eSHaojian Zhuang NOTICE("ddr3 rank1 init failure\n");
954483dce7eSHaojian Zhuang else
955483dce7eSHaojian Zhuang INFO("ddr3 rank1 init pass\n");
956483dce7eSHaojian Zhuang
957483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x048));
958483dce7eSHaojian Zhuang data &= ~0xf;
959483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x048), data);
960483dce7eSHaojian Zhuang INFO("succeed to set ddrc 533mhz\n");
96132e9fc1aSHaojian Zhuang }
96232e9fc1aSHaojian Zhuang
set_ddrc_800mhz(void)963483dce7eSHaojian Zhuang void set_ddrc_800mhz(void)
96432e9fc1aSHaojian Zhuang {
96532e9fc1aSHaojian Zhuang unsigned int data;
96632e9fc1aSHaojian Zhuang
96732e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x580), 0x2);
96832e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x5a8), 0x1003);
96932e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x104));
97032e9fc1aSHaojian Zhuang data &= 0xfffffcff;
97132e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x104), data);
97232e9fc1aSHaojian Zhuang
97332e9fc1aSHaojian Zhuang mmio_write_32((0xf7030000 + 0x050), 0x30);
97432e9fc1aSHaojian Zhuang mmio_write_32((0xf7030000 + 0x240), 0x5ffff);
97532e9fc1aSHaojian Zhuang mmio_write_32((0xf7030000 + 0x344), 0xf5ff);
97632e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x00c), 0x400);
977483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x00c), 0x400);
97832e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x018), 0x7);
97932e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x090), 0x5400000);
98032e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x258), 0x540);
98132e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x2d8), 0x540);
98232e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x358), 0x540);
98332e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x3d8), 0x540);
98432e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x018), 0x0);
98532e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x0b0), 0xf00000f);
98632e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x0b4), 0xf);
98732e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x088), 0x3fff801);
98832e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x070), 0x8940000);
98932e9fc1aSHaojian Zhuang
99032e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x078));
99132e9fc1aSHaojian Zhuang data |= 4;
99232e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x078), data);
99332e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x01c), 0x8000080);
99432e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x020));
99532e9fc1aSHaojian Zhuang data &= 0xfffffffe;
99632e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x020), data);
99732e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x1d4), 0xc0000);
99832e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x010), 0x500000f);
99932e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x014), 0x10);
100032e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x1e4));
100132e9fc1aSHaojian Zhuang data &= 0xffffff00;
100232e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x1e4), data);
100332e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x030), 0xe663ab77);
100432e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x034), 0xea952db);
100532e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x038), 0x200d1cb1);
100632e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x03c), 0xc67d0721);
100732e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x040), 0x3008aa1);
100832e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x064), 0x11a43);
100932e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x068), 0xff0a0000);
101032e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x070));
101132e9fc1aSHaojian Zhuang data &= 0xffff0000;
101232e9fc1aSHaojian Zhuang data |= 0x507;
101332e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x070), data);
101432e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x048));
101532e9fc1aSHaojian Zhuang data |= 0x40000000;
101632e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x048), data);
101732e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x020));
101832e9fc1aSHaojian Zhuang data &= 0xffffffef;
101932e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x020), data);
102032e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x080));
102132e9fc1aSHaojian Zhuang data &= 0xffffdfff;
102232e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x080), data);
102332e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x270), 0x3);
102432e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x2f0), 0x3);
102532e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x370), 0x3);
102632e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x3f0), 0x3);
102732e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x048), 0xd0420900);
102832e9fc1aSHaojian Zhuang
102932e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x040), 0x2001);
103032e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0x140f);
103132e9fc1aSHaojian Zhuang do {
103232e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x004));
103332e9fc1aSHaojian Zhuang } while (data & 1);
103432e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x008));
103532e9fc1aSHaojian Zhuang if (data & 0x7fe) {
103632e9fc1aSHaojian Zhuang WARN("failed to init lpddr3 rank0 dram phy\n");
103732e9fc1aSHaojian Zhuang return;
103832e9fc1aSHaojian Zhuang }
1039483dce7eSHaojian Zhuang cat_533mhz_800mhz();
1040483dce7eSHaojian Zhuang
1041483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0xf1);
1042483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x050), 0x100023);
1043483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x060), 0x133);
1044483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x064), 0x133);
1045483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x200), 0xa1000);
1046483dce7eSHaojian Zhuang
1047483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x100), 0x755a9d12);
1048483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x104), 0x1753b055);
1049483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x108), 0x7401505f);
1050483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x10c), 0x578ca244);
1051483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x110), 0x10700000);
1052483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x114), 0x13141306);
1053483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x118), 0x44);
1054483dce7eSHaojian Zhuang do {
1055483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x004));
1056483dce7eSHaojian Zhuang } while (data & 1);
1057483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x008));
1058483dce7eSHaojian Zhuang if (data & 0x7fe) {
1059483dce7eSHaojian Zhuang NOTICE("fail to init ddr3 rank0\n");
1060483dce7eSHaojian Zhuang return;
1061483dce7eSHaojian Zhuang }
1062483dce7eSHaojian Zhuang ddrx_rdet();
1063483dce7eSHaojian Zhuang ddrx_wdet();
1064483dce7eSHaojian Zhuang
1065483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x048));
1066483dce7eSHaojian Zhuang data |= 1;
1067483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x048), data);
1068483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x004), 0x21);
1069483dce7eSHaojian Zhuang do {
1070483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x004));
1071483dce7eSHaojian Zhuang } while (data & 1);
1072483dce7eSHaojian Zhuang
1073483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x008));
1074483dce7eSHaojian Zhuang if (data & 0x7fe)
1075483dce7eSHaojian Zhuang NOTICE("ddr3 rank1 init failure\n");
1076483dce7eSHaojian Zhuang else
1077483dce7eSHaojian Zhuang INFO("ddr3 rank1 init pass\n");
1078483dce7eSHaojian Zhuang
1079483dce7eSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x048));
1080483dce7eSHaojian Zhuang data &= ~0xf;
1081483dce7eSHaojian Zhuang mmio_write_32((0xf712c000 + 0x048), data);
1082483dce7eSHaojian Zhuang INFO("succeed to set ddrc 800mhz\n");
108332e9fc1aSHaojian Zhuang }
108432e9fc1aSHaojian Zhuang
ddrc_common_init(int freq)1085483dce7eSHaojian Zhuang static void ddrc_common_init(int freq)
108632e9fc1aSHaojian Zhuang {
108732e9fc1aSHaojian Zhuang unsigned int data;
108832e9fc1aSHaojian Zhuang
108932e9fc1aSHaojian Zhuang mmio_write_32((0xf7120000 + 0x020), 0x1);
109032e9fc1aSHaojian Zhuang mmio_write_32((0xf7120000 + 0x100), 0x1700);
109132e9fc1aSHaojian Zhuang mmio_write_32((0xf7120000 + 0x104), 0x71040004);
109232e9fc1aSHaojian Zhuang mmio_write_32((0xf7121400 + 0x104), 0xf);
109332e9fc1aSHaojian Zhuang mmio_write_32((0xf7121800 + 0x104), 0xf);
109432e9fc1aSHaojian Zhuang mmio_write_32((0xf7121c00 + 0x104), 0xf);
109532e9fc1aSHaojian Zhuang mmio_write_32((0xf7122000 + 0x104), 0xf);
109632e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x02c), 0x6);
1097483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x020), 0x30003);
109832e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x028), 0x310201);
109932e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x1e4), 0xfe007600);
110032e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x01c), 0xaf001);
110132e9fc1aSHaojian Zhuang
110232e9fc1aSHaojian Zhuang
110332e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7128000 + 0x280));
110432e9fc1aSHaojian Zhuang data |= 1 << 7;
110532e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x280), data);
110632e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x244), 0x3);
110732e9fc1aSHaojian Zhuang
1108483dce7eSHaojian Zhuang if (freq == DDR_FREQ_800M)
1109483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x240), 167 * (freq / 2) / 1024);
111032e9fc1aSHaojian Zhuang else
1111483dce7eSHaojian Zhuang mmio_write_32((0xf7128000 + 0x240), 167 * freq / 1024);
111232e9fc1aSHaojian Zhuang
111332e9fc1aSHaojian Zhuang data = mmio_read_32((0xf712c000 + 0x080));
111432e9fc1aSHaojian Zhuang data &= 0xffff;
111532e9fc1aSHaojian Zhuang data |= 0x4002000;
111632e9fc1aSHaojian Zhuang mmio_write_32((0xf712c000 + 0x080), data);
111732e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x000), 0x0);
111832e9fc1aSHaojian Zhuang do {
111932e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7128000 + 0x294));
112032e9fc1aSHaojian Zhuang } while (data & 1);
112132e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x000), 0x2);
112232e9fc1aSHaojian Zhuang }
112332e9fc1aSHaojian Zhuang
112432e9fc1aSHaojian Zhuang
dienum_det_and_rowcol_cfg(void)112532e9fc1aSHaojian Zhuang static int dienum_det_and_rowcol_cfg(void)
112632e9fc1aSHaojian Zhuang {
112732e9fc1aSHaojian Zhuang unsigned int data;
112832e9fc1aSHaojian Zhuang
112932e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x210), 0x87);
113032e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x218), 0x10000);
113132e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x00c), 0x1);
113232e9fc1aSHaojian Zhuang do {
113332e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7128000 + 0x00c));
113432e9fc1aSHaojian Zhuang } while (data & 1);
113532e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7128000 + 0x4a8)) & 0xfc;
113632e9fc1aSHaojian Zhuang switch (data) {
113732e9fc1aSHaojian Zhuang case 0x18:
113832e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x060), 0x132);
113932e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x064), 0x132);
114032e9fc1aSHaojian Zhuang mmio_write_32((0xf7120000 + 0x100), 0x1600);
114132e9fc1aSHaojian Zhuang mmio_write_32((0xf7120000 + 0x104), 0x71040004);
11421d999558SHaojian Zhuang mmio_write_32(MEMORY_AXI_DDR_CAPACITY_ADDR, 0x40000000);
114332e9fc1aSHaojian Zhuang break;
114432e9fc1aSHaojian Zhuang case 0x1c:
114532e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x060), 0x142);
114632e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x064), 0x142);
114732e9fc1aSHaojian Zhuang mmio_write_32((0xf7120000 + 0x100), 0x1700);
114832e9fc1aSHaojian Zhuang mmio_write_32((0xf7120000 + 0x104), 0x71040004);
11491d999558SHaojian Zhuang mmio_write_32(MEMORY_AXI_DDR_CAPACITY_ADDR, 0x80000000);
115032e9fc1aSHaojian Zhuang break;
115132e9fc1aSHaojian Zhuang case 0x58:
115232e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x060), 0x133);
115332e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x064), 0x133);
115432e9fc1aSHaojian Zhuang mmio_write_32((0xf7120000 + 0x100), 0x1700);
115532e9fc1aSHaojian Zhuang mmio_write_32((0xf7120000 + 0x104), 0x71040004);
11561d999558SHaojian Zhuang mmio_write_32(MEMORY_AXI_DDR_CAPACITY_ADDR, 0x80000000);
115732e9fc1aSHaojian Zhuang break;
115832e9fc1aSHaojian Zhuang default:
11591d999558SHaojian Zhuang mmio_write_32(MEMORY_AXI_DDR_CAPACITY_ADDR, 0x80000000);
116032e9fc1aSHaojian Zhuang break;
116132e9fc1aSHaojian Zhuang }
116232e9fc1aSHaojian Zhuang if (!data)
116332e9fc1aSHaojian Zhuang return -EINVAL;
116432e9fc1aSHaojian Zhuang return 0;
116532e9fc1aSHaojian Zhuang }
116632e9fc1aSHaojian Zhuang
detect_ddr_chip_info(void)116732e9fc1aSHaojian Zhuang static int detect_ddr_chip_info(void)
116832e9fc1aSHaojian Zhuang {
116932e9fc1aSHaojian Zhuang unsigned int data, mr5, mr6, mr7;
117032e9fc1aSHaojian Zhuang
117132e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x210), 0x57);
117232e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x218), 0x10000);
117332e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x00c), 0x1);
117432e9fc1aSHaojian Zhuang
117532e9fc1aSHaojian Zhuang do {
117632e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7128000 + 0x00c));
117732e9fc1aSHaojian Zhuang } while (data & 1);
117832e9fc1aSHaojian Zhuang
117932e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7128000 + 0x4a8));
118032e9fc1aSHaojian Zhuang mr5 = data & 0xff;
118132e9fc1aSHaojian Zhuang switch (mr5) {
118232e9fc1aSHaojian Zhuang case 1:
118332e9fc1aSHaojian Zhuang INFO("Samsung DDR\n");
118432e9fc1aSHaojian Zhuang break;
118532e9fc1aSHaojian Zhuang case 6:
118632e9fc1aSHaojian Zhuang INFO("Hynix DDR\n");
118732e9fc1aSHaojian Zhuang break;
118832e9fc1aSHaojian Zhuang case 3:
118932e9fc1aSHaojian Zhuang INFO("Elpida DDR\n");
119032e9fc1aSHaojian Zhuang break;
119132e9fc1aSHaojian Zhuang default:
119232e9fc1aSHaojian Zhuang INFO("DDR from other vendors\n");
119332e9fc1aSHaojian Zhuang break;
119432e9fc1aSHaojian Zhuang }
119532e9fc1aSHaojian Zhuang
119632e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x210), 0x67);
119732e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x218), 0x10000);
119832e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x00c), 0x1);
119932e9fc1aSHaojian Zhuang do {
120032e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7128000 + 0x00c));
120132e9fc1aSHaojian Zhuang } while (data & 1);
120232e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7128000 + 0x4a8));
120332e9fc1aSHaojian Zhuang mr6 = data & 0xff;
120432e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x210), 0x77);
120532e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x218), 0x10000);
120632e9fc1aSHaojian Zhuang mmio_write_32((0xf7128000 + 0x00c), 0x1);
120732e9fc1aSHaojian Zhuang do {
120832e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7128000 + 0x00c));
120932e9fc1aSHaojian Zhuang } while (data & 1);
121032e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7128000 + 0x4a8));
121132e9fc1aSHaojian Zhuang mr7 = data & 0xff;
121232e9fc1aSHaojian Zhuang data = mr5 + (mr6 << 8) + (mr7 << 16);
121332e9fc1aSHaojian Zhuang return data;
121432e9fc1aSHaojian Zhuang }
121532e9fc1aSHaojian Zhuang
ddr_phy_reset(void)1216483dce7eSHaojian Zhuang void ddr_phy_reset(void)
1217483dce7eSHaojian Zhuang {
1218483dce7eSHaojian Zhuang mmio_write_32(0xf7030340, 0xa000);
1219483dce7eSHaojian Zhuang mmio_write_32(0xf7030344, 0xa000);
1220483dce7eSHaojian Zhuang }
1221483dce7eSHaojian Zhuang
lpddrx_save_ddl_para_bypass(uint32_t * ddr_ddl_para,unsigned int index)12221d999558SHaojian Zhuang void lpddrx_save_ddl_para_bypass(uint32_t *ddr_ddl_para, unsigned int index)
12231d999558SHaojian Zhuang {
12241d999558SHaojian Zhuang uint32_t value;
12251d999558SHaojian Zhuang uint32_t cnt = index;
12261d999558SHaojian Zhuang uint32_t i;
12271d999558SHaojian Zhuang
12281d999558SHaojian Zhuang for (i = 0; i < 4; i++) {
12291d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x22c + i * 0x80);
12301d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12311d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x23c + i * 0x80);
12321d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12331d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x240 + i * 0x80);
12341d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12351d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x640 + i * 0x80);
12361d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12371d999558SHaojian Zhuang }
12381d999558SHaojian Zhuang }
12391d999558SHaojian Zhuang
lpddrx_save_ddl_para_mission(uint32_t * ddr_ddl_para,unsigned int index)12401d999558SHaojian Zhuang void lpddrx_save_ddl_para_mission(uint32_t *ddr_ddl_para, unsigned int index)
12411d999558SHaojian Zhuang {
12421d999558SHaojian Zhuang uint32_t value;
12431d999558SHaojian Zhuang uint32_t cnt = index;
12441d999558SHaojian Zhuang uint32_t i;
12451d999558SHaojian Zhuang
12461d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x140);
12471d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12481d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x144);
12491d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12501d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x148);
12511d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12521d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x14c);
12531d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12541d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x150);
12551d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12561d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x1d4);
12571d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12581d999558SHaojian Zhuang for (i = 0; i < 4; i++) {
12591d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x210 + i * 0x80);
12601d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12611d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x214 + i * 0x80);
12621d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12631d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x218 + i * 0x80);
12641d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12651d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x21c + i * 0x80);
12661d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12671d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x220 + i * 0x80);
12681d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12691d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x224 + i * 0x80);
12701d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12711d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x228 + i * 0x80);
12721d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12731d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x22c + i * 0x80);
12741d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12751d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x230 + i * 0x80);
12761d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12771d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x234 + i * 0x80);
12781d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12791d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x238 + i * 0x80);
12801d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12811d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x23c + i * 0x80);
12821d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12831d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x240 + i * 0x80);
12841d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12851d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x640 + i * 0x80);
12861d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12871d999558SHaojian Zhuang }
12881d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x168);
12891d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12901d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x24c + 0 * 0x80);
12911d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12921d999558SHaojian Zhuang value = mmio_read_32(0xf712c000 + 0x24c + 2 * 0x80);
12931d999558SHaojian Zhuang ddr_ddl_para[cnt++] = value;
12941d999558SHaojian Zhuang }
12951d999558SHaojian Zhuang
lpddr3_freq_init(int freq)129632e9fc1aSHaojian Zhuang int lpddr3_freq_init(int freq)
129732e9fc1aSHaojian Zhuang {
1298483dce7eSHaojian Zhuang set_ddrc_150mhz();
12991d999558SHaojian Zhuang lpddrx_save_ddl_para_bypass((uint32_t *)MEMORY_AXI_DDR_DDL_ADDR, 0);
1300483dce7eSHaojian Zhuang if (freq > DDR_FREQ_150M) {
1301483dce7eSHaojian Zhuang ddr_phy_reset();
1302483dce7eSHaojian Zhuang set_ddrc_266mhz();
13031d999558SHaojian Zhuang lpddrx_save_ddl_para_bypass((uint32_t *)MEMORY_AXI_DDR_DDL_ADDR,
13041d999558SHaojian Zhuang 16);
1305483dce7eSHaojian Zhuang }
1306483dce7eSHaojian Zhuang if (freq > DDR_FREQ_266M) {
1307483dce7eSHaojian Zhuang ddr_phy_reset();
1308483dce7eSHaojian Zhuang set_ddrc_400mhz();
13091d999558SHaojian Zhuang lpddrx_save_ddl_para_bypass((uint32_t *)MEMORY_AXI_DDR_DDL_ADDR,
13101d999558SHaojian Zhuang 16 * 2);
1311483dce7eSHaojian Zhuang }
1312483dce7eSHaojian Zhuang if (freq > DDR_FREQ_400M) {
1313483dce7eSHaojian Zhuang ddr_phy_reset();
131432e9fc1aSHaojian Zhuang set_ddrc_533mhz();
13151d999558SHaojian Zhuang lpddrx_save_ddl_para_mission((uint32_t *)MEMORY_AXI_DDR_DDL_ADDR,
13161d999558SHaojian Zhuang 16 * 3);
131732e9fc1aSHaojian Zhuang }
1318483dce7eSHaojian Zhuang if (freq > DDR_FREQ_533M) {
1319483dce7eSHaojian Zhuang ddr_phy_reset();
1320483dce7eSHaojian Zhuang set_ddrc_800mhz();
13211d999558SHaojian Zhuang lpddrx_save_ddl_para_mission((uint32_t *)MEMORY_AXI_DDR_DDL_ADDR,
13221d999558SHaojian Zhuang 16 * 3 + 61);
132332e9fc1aSHaojian Zhuang }
132432e9fc1aSHaojian Zhuang return 0;
132532e9fc1aSHaojian Zhuang }
132632e9fc1aSHaojian Zhuang
init_ddr(int freq)132732e9fc1aSHaojian Zhuang static void init_ddr(int freq)
132832e9fc1aSHaojian Zhuang {
132932e9fc1aSHaojian Zhuang unsigned int data;
133032e9fc1aSHaojian Zhuang int ret;
133132e9fc1aSHaojian Zhuang
133232e9fc1aSHaojian Zhuang
133332e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x030));
133432e9fc1aSHaojian Zhuang data |= 1;
133532e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x030), data);
133632e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x010));
133732e9fc1aSHaojian Zhuang data |= 1;
133832e9fc1aSHaojian Zhuang mmio_write_32((0xf7032000 + 0x010), data);
133932e9fc1aSHaojian Zhuang
1340483dce7eSHaojian Zhuang udelay(300);
134132e9fc1aSHaojian Zhuang do {
134232e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x030));
134332e9fc1aSHaojian Zhuang data &= 3 << 28;
134432e9fc1aSHaojian Zhuang } while (data != (3 << 28));
134532e9fc1aSHaojian Zhuang do {
134632e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7032000 + 0x010));
134732e9fc1aSHaojian Zhuang data &= 3 << 28;
134832e9fc1aSHaojian Zhuang } while (data != (3 << 28));
134932e9fc1aSHaojian Zhuang
135032e9fc1aSHaojian Zhuang ret = lpddr3_freq_init(freq);
135132e9fc1aSHaojian Zhuang if (ret)
135232e9fc1aSHaojian Zhuang return;
135332e9fc1aSHaojian Zhuang }
135432e9fc1aSHaojian Zhuang
init_ddrc_qos(void)135532e9fc1aSHaojian Zhuang static void init_ddrc_qos(void)
135632e9fc1aSHaojian Zhuang {
135732e9fc1aSHaojian Zhuang unsigned int port, data;
135832e9fc1aSHaojian Zhuang
135932e9fc1aSHaojian Zhuang mmio_write_32((0xf7124000 + 0x088), 1);
136032e9fc1aSHaojian Zhuang
136132e9fc1aSHaojian Zhuang port = 0;
136232e9fc1aSHaojian Zhuang mmio_write_32((0xf7120000 + 0x200 + port * 0x10), 0x1210);
136332e9fc1aSHaojian Zhuang mmio_write_32((0xf7120000 + 0x204 + port * 0x10), 0x11111111);
136432e9fc1aSHaojian Zhuang mmio_write_32((0xf7120000 + 0x208 + port * 0x10), 0x11111111);
136532e9fc1aSHaojian Zhuang mmio_write_32((0xf7120000 + 0x400 + 0 * 0x10), 0x001d0007);
136632e9fc1aSHaojian Zhuang
136732e9fc1aSHaojian Zhuang for (port = 3; port <= 4; port++) {
136832e9fc1aSHaojian Zhuang mmio_write_32((0xf7120000 + 0x200 + port * 0x10), 0x1210);
136932e9fc1aSHaojian Zhuang mmio_write_32((0xf7120000 + 0x204 + port * 0x10), 0x77777777);
137032e9fc1aSHaojian Zhuang mmio_write_32((0xf7120000 + 0x208 + port * 0x10), 0x77777777);
137132e9fc1aSHaojian Zhuang }
137232e9fc1aSHaojian Zhuang
137332e9fc1aSHaojian Zhuang port = 1;
137432e9fc1aSHaojian Zhuang mmio_write_32((0xf7120000 + 0x200 + port * 0x10), 0x30000);
137532e9fc1aSHaojian Zhuang mmio_write_32((0xf7120000 + 0x204 + port * 0x10), 0x1234567);
137632e9fc1aSHaojian Zhuang mmio_write_32((0xf7120000 + 0x208 + port * 0x10), 0x1234567);
137732e9fc1aSHaojian Zhuang
137832e9fc1aSHaojian Zhuang mmio_write_32((0xf7124000 + 0x1f0), 0);
137932e9fc1aSHaojian Zhuang mmio_write_32((0xf7124000 + 0x0bc), 0x3020100);
138032e9fc1aSHaojian Zhuang mmio_write_32((0xf7124000 + 0x0d0), 0x3020100);
138132e9fc1aSHaojian Zhuang mmio_write_32((0xf7124000 + 0x1f4), 0x01000100);
138232e9fc1aSHaojian Zhuang mmio_write_32((0xf7124000 + 0x08c + 0 * 4), 0xd0670402);
138332e9fc1aSHaojian Zhuang mmio_write_32((0xf7124000 + 0x068 + 0 * 4), 0x31);
138432e9fc1aSHaojian Zhuang mmio_write_32((0xf7124000 + 0x000), 0x7);
138532e9fc1aSHaojian Zhuang
138632e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7124000 + 0x09c));
138732e9fc1aSHaojian Zhuang data &= ~0xff0000;
138832e9fc1aSHaojian Zhuang data |= 0x400000;
138932e9fc1aSHaojian Zhuang mmio_write_32((0xf7124000 + 0x09c), data);
139032e9fc1aSHaojian Zhuang data = mmio_read_32((0xf7124000 + 0x0ac));
139132e9fc1aSHaojian Zhuang data &= ~0xff0000;
139232e9fc1aSHaojian Zhuang data |= 0x400000;
139332e9fc1aSHaojian Zhuang mmio_write_32((0xf7124000 + 0x0ac), data);
139432e9fc1aSHaojian Zhuang port = 2;
139532e9fc1aSHaojian Zhuang mmio_write_32((0xf7120000 + 0x200 + port * 0x10), 0x30000);
139632e9fc1aSHaojian Zhuang mmio_write_32((0xf7120000 + 0x204 + port * 0x10), 0x1234567);
139732e9fc1aSHaojian Zhuang mmio_write_32((0xf7120000 + 0x208 + port * 0x10), 0x1234567);
139832e9fc1aSHaojian Zhuang
139932e9fc1aSHaojian Zhuang
140032e9fc1aSHaojian Zhuang mmio_write_32((0xf7124000 + 0x09c), 0xff7fff);
140132e9fc1aSHaojian Zhuang mmio_write_32((0xf7124000 + 0x0a0), 0xff);
140232e9fc1aSHaojian Zhuang mmio_write_32((0xf7124000 + 0x0ac), 0xff7fff);
140332e9fc1aSHaojian Zhuang mmio_write_32((0xf7124000 + 0x0b0), 0xff);
140432e9fc1aSHaojian Zhuang mmio_write_32((0xf7124000 + 0x0bc), 0x3020100);
140532e9fc1aSHaojian Zhuang mmio_write_32((0xf7124000 + 0x0d0), 0x3020100);
140632e9fc1aSHaojian Zhuang }
140732e9fc1aSHaojian Zhuang
hikey_ddr_init(unsigned int ddr_freq)1408483dce7eSHaojian Zhuang void hikey_ddr_init(unsigned int ddr_freq)
140932e9fc1aSHaojian Zhuang {
141032e9fc1aSHaojian Zhuang uint32_t data;
141132e9fc1aSHaojian Zhuang
1412483dce7eSHaojian Zhuang assert((ddr_freq == DDR_FREQ_150M) || (ddr_freq == DDR_FREQ_266M) ||
1413483dce7eSHaojian Zhuang (ddr_freq == DDR_FREQ_400M) || (ddr_freq == DDR_FREQ_533M) ||
1414483dce7eSHaojian Zhuang (ddr_freq == DDR_FREQ_800M));
141532e9fc1aSHaojian Zhuang init_pll();
141632e9fc1aSHaojian Zhuang init_freq();
141732e9fc1aSHaojian Zhuang
1418483dce7eSHaojian Zhuang init_ddr(ddr_freq);
141932e9fc1aSHaojian Zhuang
1420483dce7eSHaojian Zhuang ddrc_common_init(ddr_freq);
142132e9fc1aSHaojian Zhuang dienum_det_and_rowcol_cfg();
142232e9fc1aSHaojian Zhuang detect_ddr_chip_info();
142332e9fc1aSHaojian Zhuang
1424483dce7eSHaojian Zhuang if ((ddr_freq == DDR_FREQ_400M) || (ddr_freq == DDR_FREQ_800M)) {
142532e9fc1aSHaojian Zhuang data = mmio_read_32(0xf7032000 + 0x010);
142632e9fc1aSHaojian Zhuang data &= ~0x1;
142732e9fc1aSHaojian Zhuang mmio_write_32(0xf7032000 + 0x010, data);
1428483dce7eSHaojian Zhuang } else if ((ddr_freq == DDR_FREQ_266M) || (ddr_freq == DDR_FREQ_533M)) {
1429483dce7eSHaojian Zhuang data = mmio_read_32(0xf7032000 + 0x030);
1430483dce7eSHaojian Zhuang data &= ~0x1;
1431483dce7eSHaojian Zhuang mmio_write_32(0xf7032000 + 0x030, data);
1432483dce7eSHaojian Zhuang } else {
143332e9fc1aSHaojian Zhuang data = mmio_read_32(0xf7032000 + 0x010);
1434483dce7eSHaojian Zhuang data &= ~0x1;
1435483dce7eSHaojian Zhuang mmio_write_32(0xf7032000 + 0x010, data);
1436483dce7eSHaojian Zhuang data = mmio_read_32(0xf7032000 + 0x030);
1437483dce7eSHaojian Zhuang data &= ~0x1;
1438483dce7eSHaojian Zhuang mmio_write_32(0xf7032000 + 0x030, data);
1439483dce7eSHaojian Zhuang }
1440483dce7eSHaojian Zhuang dsb();
1441483dce7eSHaojian Zhuang isb();
144232e9fc1aSHaojian Zhuang
144332e9fc1aSHaojian Zhuang /*
144432e9fc1aSHaojian Zhuang * Test memory access. Do not use address 0x0 because the compiler
144532e9fc1aSHaojian Zhuang * may assume it is not a valid address and generate incorrect code
144632e9fc1aSHaojian Zhuang * (GCC 4.9.1 without -fno-delete-null-pointer-checks for instance).
144732e9fc1aSHaojian Zhuang */
144832e9fc1aSHaojian Zhuang mmio_write_32(0x4, 0xa5a55a5a);
144932e9fc1aSHaojian Zhuang INFO("ddr test value:0x%x\n", mmio_read_32(0x4));
145032e9fc1aSHaojian Zhuang init_ddrc_qos();
145132e9fc1aSHaojian Zhuang }
1452