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