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> 9*09d40e0eSAntonio Nino Diaz 10*09d40e0eSAntonio Nino Diaz #include <arch_helpers.h> 11*09d40e0eSAntonio Nino Diaz #include <common/debug.h> 12*09d40e0eSAntonio Nino Diaz #include <drivers/arm/sp804_delay_timer.h> 13*09d40e0eSAntonio Nino Diaz #include <lib/mmio.h> 14*09d40e0eSAntonio 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 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 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)); 14132e9fc1aSHaojian Zhuang data &= ~(0xffffff << 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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