static int validate_cci_map(const int *map) { unsigned int valid_cci_map = 0; int slave_if_id; int i; /* Validate the map */ for (i = 0; i <= g_max_master_id; i++) { slave_if_id = map[i]; if (slave_if_id < 0) continue; if (slave_if_id >= CCI_SLAVE_INTERFACE_COUNT) { tf_printf("Slave interface ID is invalid\n"); return 0; } if (valid_cci_map & (1 << slave_if_id)) { tf_printf("Multiple masters are assigned same" " slave interface ID\n"); return 0; } valid_cci_map |= 1 << slave_if_id; } if (!valid_cci_map) { tf_printf("No master is assigned a valid slave interface\n"); return 0; } return 1; }
static int detect_ddr_chip_info(void) { unsigned int data, mr5, mr6, mr7; mmio_write_32((0xf7128000 + 0x210), 0x57); mmio_write_32((0xf7128000 + 0x218), 0x10000); mmio_write_32((0xf7128000 + 0x00c), 0x1); do { data = mmio_read_32((0xf7128000 + 0x00c)); } while (data & 1); data = mmio_read_32((0xf7128000 + 0x4a8)); mr5 = data & 0xff; switch (mr5) { case 1: tf_printf("INFO: " "Samsung DDR\n"); break; case 6: tf_printf("INFO: " "Hynix DDR\n"); break; case 3: tf_printf("INFO: " "Elpida DDR\n"); break; default: tf_printf("INFO: " "DDR from other vendors\n"); break; } mmio_write_32((0xf7128000 + 0x210), 0x67); mmio_write_32((0xf7128000 + 0x218), 0x10000); mmio_write_32((0xf7128000 + 0x00c), 0x1); do { data = mmio_read_32((0xf7128000 + 0x00c)); } while (data & 1); data = mmio_read_32((0xf7128000 + 0x4a8)); mr6 = data & 0xff; mmio_write_32((0xf7128000 + 0x210), 0x77); mmio_write_32((0xf7128000 + 0x218), 0x10000); mmio_write_32((0xf7128000 + 0x00c), 0x1); do { data = mmio_read_32((0xf7128000 + 0x00c)); } while (data & 1); data = mmio_read_32((0xf7128000 + 0x4a8)); mr7 = data & 0xff; data = mr5 + (mr6 << 8) + (mr7 << 16); return data; }
/* * This is a basic implementation. This could be improved. */ void __assert (const char *function, const char *file, unsigned int line, const char *assertion) { tf_printf("ASSERT: %s <%d> : %s\n", function, line, assertion); console_flush(); plat_panic_handler(); }
/* * This function can be used to dump `ts` value for given `tid`. * Assumption is that the console is already initialized. */ void __pmf_dump_timestamp(unsigned int tid, unsigned long long ts) { tf_printf("PMF:cpu %u tid %u ts %llu\n", plat_my_core_pos(), tid, ts); }
int lpddr3_freq_init(int ddr800) { unsigned int data; if (ddr800) { set_ddrc_800mhz(); tf_printf("INFO: " "%s, set ddrc 800mhz\n", __func__); } else { set_ddrc_533mhz(); tf_printf("INFO: " "%s, set ddrc 533mhz\n", __func__); } data = cat_533mhz_800mhz(); if (data) tf_printf("NOTICE: " "fail to set eye diagram\n"); mmio_write_32((0xf712c000 + 0x004), 0xf1); if (ddr800) mmio_write_32((0xf7128000 + 0x050), 0x100023); else mmio_write_32((0xf7128000 + 0x050), 0x100123); mmio_write_32((0xf7128000 + 0x060), 0x133); mmio_write_32((0xf7128000 + 0x064), 0x133); mmio_write_32((0xf7128000 + 0x200), 0xa1000); if (ddr800) { mmio_write_32((0xf7128000 + 0x100), 0x755a9d12); mmio_write_32((0xf7128000 + 0x104), 0x1753b055); mmio_write_32((0xf7128000 + 0x108), 0x7401505f); mmio_write_32((0xf7128000 + 0x10c), 0x578ca244); mmio_write_32((0xf7128000 + 0x110), 0x10700000); mmio_write_32((0xf7128000 + 0x114), 0x13141306); } else { mmio_write_32((0xf7128000 + 0x100), 0xb77b6718); mmio_write_32((0xf7128000 + 0x104), 0x1e82a071); mmio_write_32((0xf7128000 + 0x108), 0x9501c07e); mmio_write_32((0xf7128000 + 0x10c), 0xaf50c255); mmio_write_32((0xf7128000 + 0x110), 0x10b00000); mmio_write_32((0xf7128000 + 0x114), 0x13181908); } mmio_write_32((0xf7128000 + 0x118), 0x44); do { data = mmio_read_32((0xf712c000 + 0x004)); } while (data & 1); data = mmio_read_32((0xf712c000 + 0x008)); if (data & 0x7fe) { tf_printf("NOTICE: " "fail to init ddr3 rank0\n"); return -14; } tf_printf("INFO: " "init ddr3 rank0\n"); ddrx_rdet(); ddrx_wdet(); data = mmio_read_32((0xf712c000 + 0x048)); data |= 1; mmio_write_32((0xf712c000 + 0x048), data); mmio_write_32((0xf712c000 + 0x004), 0x21); do { data = mmio_read_32((0xf712c000 + 0x004)); } while (data & 1); data = mmio_read_32((0xf712c000 + 0x008)); if (data & 0x7fe) tf_printf("NOTICE: " "ddr3 rank1 init failure\n"); else tf_printf("INFO: " "ddr3 rank1 init pass\n"); data = mmio_read_32((0xf712c000 + 0x048)); data &= ~0xf; mmio_write_32((0xf712c000 + 0x048), data); return 0; }
static void set_ddrc_533mhz(void) { unsigned int data; mmio_write_32((0xf7032000 + 0x580), 0x3); mmio_write_32((0xf7032000 + 0x5a8), 0x11111); data = mmio_read_32((0xf7032000 + 0x104)); data |= 0x100; mmio_write_32((0xf7032000 + 0x104), data); mmio_write_32((0xf7030000 + 0x050), 0x30); mmio_write_32((0xf7030000 + 0x240), 0x5ffff); mmio_write_32((0xf7030000 + 0x344), 0xf5ff); mmio_write_32((0xf712c000 + 0x00c), 0x400); mmio_write_32((0xf712c000 + 0x018), 0x7); mmio_write_32((0xf712c000 + 0x090), 0x6400000); mmio_write_32((0xf712c000 + 0x258), 0x640); mmio_write_32((0xf712c000 + 0x2d8), 0x640); mmio_write_32((0xf712c000 + 0x358), 0x640); mmio_write_32((0xf712c000 + 0x3d8), 0x640); mmio_write_32((0xf712c000 + 0x018), 0x0); mmio_write_32((0xf712c000 + 0x0b0), 0xf00000f); mmio_write_32((0xf712c000 + 0x0b4), 0xf); mmio_write_32((0xf712c000 + 0x088), 0x3fff801); mmio_write_32((0xf712c000 + 0x070), 0x8940000); data = mmio_read_32((0xf712c000 + 0x078)); data |= 4; mmio_write_32((0xf712c000 + 0x078), data); mmio_write_32((0xf712c000 + 0x01c), 0x8000080); data = mmio_read_32((0xf712c000 + 0x020)); data &= 0xfffffffe; mmio_write_32((0xf712c000 + 0x020), data); mmio_write_32((0xf712c000 + 0x1d4), 0xc0000); mmio_write_32((0xf712c000 + 0x010), 0x500000f); mmio_write_32((0xf712c000 + 0x014), 0x10); data = mmio_read_32((0xf712c000 + 0x1e4)); data &= 0xffffff00; mmio_write_32((0xf712c000 + 0x1e4), data); mmio_write_32((0xf712c000 + 0x030), 0x9dd87855); mmio_write_32((0xf712c000 + 0x034), 0xa7138bb); mmio_write_32((0xf712c000 + 0x038), 0x20091477); mmio_write_32((0xf712c000 + 0x03c), 0x84534e16); mmio_write_32((0xf712c000 + 0x040), 0x3008817); mmio_write_32((0xf712c000 + 0x064), 0x106c3); mmio_write_32((0xf712c000 + 0x068), 0xff0a0000); data = mmio_read_32((0xf712c000 + 0x070)); data &= 0xffff0000; data |= 0x305; mmio_write_32((0xf712c000 + 0x070), data); data = mmio_read_32((0xf712c000 + 0x048)); data |= 0x40000000; mmio_write_32((0xf712c000 + 0x048), data); data = mmio_read_32((0xf712c000 + 0x020)); data &= ~0x10; mmio_write_32((0xf712c000 + 0x020), data); data = mmio_read_32((0xf712c000 + 0x080)); data &= ~0x2000; mmio_write_32((0xf712c000 + 0x080), data); mmio_write_32((0xf712c000 + 0x270), 0x3); mmio_write_32((0xf712c000 + 0x2f0), 0x3); mmio_write_32((0xf712c000 + 0x370), 0x3); mmio_write_32((0xf712c000 + 0x3f0), 0x3); mmio_write_32((0xf712c000 + 0x048), 0xd0420900); mmio_write_32((0xf7128000 + 0x040), 0x0); mmio_write_32((0xf712c000 + 0x004), 0x140f); do { data = mmio_read_32((0xf712c000 + 0x004)); } while (data & 1); data = mmio_read_32((0xf712c000 + 0x008)); if (data & 0x7fe) { tf_printf("NOTICE: " "failed to init lpddr3 rank0 dram phy\n"); return; } tf_printf("NOTICE: " "succeed to init lpddr3 rank0 dram phy\n"); }
static void ddrx_wdet(void) { unsigned int data, wdet, zero_bdl, dq[4]; int i; data = mmio_read_32((0xf712c000 + 0x0d0)); data &= ~0xf; data |= 0xf; mmio_write_32((0xf712c000 + 0x0d0), data); data = mmio_read_32((0xf712c000 + 0x070)); data |= 0x80000; mmio_write_32((0xf712c000 + 0x070), data); data = mmio_read_32((0xf712c000 + 0x070)); data &= ~0x80000; mmio_write_32((0xf712c000 + 0x070), data); mmio_write_32((0xf712c000 + 0x004), 0x8000); mmio_write_32((0xf712c000 + 0x004), 0); data = mmio_read_32((0xf712c000 + 0x0d0)); data &= ~0xf000; data |= 0x8000; mmio_write_32((0xf712c000 + 0x0d0), data); mmio_write_32((0xf712c000 + 0x004), 0x201); do { data = mmio_read_32((0xf712c000 + 0x004)); } while (data & 1); data = mmio_read_32((0xf712c000 + 0x008)); if (data & 0x200) tf_printf("INFO: " "wdet lbs fail\n"); dq[0] = mmio_read_32((0xf712c000 + 0x234)) & 0x1f00; dq[1] = mmio_read_32((0xf712c000 + 0x2b4)) & 0x1f00; dq[2] = mmio_read_32((0xf712c000 + 0x334)) & 0x1f00; dq[3] = mmio_read_32((0xf712c000 + 0x3b4)) & 0x1f00; do { mmio_write_32((0xf712c000 + 0x234), dq[0]); mmio_write_32((0xf712c000 + 0x2b4), dq[1]); mmio_write_32((0xf712c000 + 0x334), dq[2]); mmio_write_32((0xf712c000 + 0x3b4), dq[3]); data = mmio_read_32((0xf712c000 + 0x070)); data |= 0x80000; mmio_write_32((0xf712c000 + 0x070), data); data = mmio_read_32((0xf712c000 + 0x070)); data &= ~0x80000; mmio_write_32((0xf712c000 + 0x070), data); mmio_write_32((0xf712c000 + 0x004), 0x8000); mmio_write_32((0xf712c000 + 0x004), 0); data = mmio_read_32((0xf712c000 + 0x0d0)); data &= ~0xf000; data |= 0x4000; mmio_write_32((0xf712c000 + 0x0d0), data); mmio_write_32((0xf712c000 + 0x004), 0x201); do { data = mmio_read_32((0xf712c000 + 0x004)); } while (data & 1); data = mmio_read_32((0xf712c000 + 0x008)); wdet = data & 0x200; if (wdet) { tf_printf("INFO: " "wdet ds fail\n"); mmio_write_32((0xf712c000 + 0x008), 0x200); } mdelay(10); for (i = 0; i < 4; i++) { data = mmio_read_32((0xf712c000 + 0x210 + i * 0x80)); if ((!(data & 0x1f)) || (!(data & 0x1f00)) || (!(data & 0x1f0000)) || (!(data & 0x1f000000))) zero_bdl = 1; data = mmio_read_32((0xf712c000 + 0x214 + i * 0x80)); if ((!(data & 0x1f)) || (!(data & 0x1f00)) || (!(data & 0x1f0000)) || (!(data & 0x1f000000))) zero_bdl = 1; data = mmio_read_32((0xf712c000 + 0x218 + i * 0x80)); if (!(data & 0x1f)) zero_bdl = 1; if (zero_bdl) { if (i == 0) dq[0] = dq[0] - 0x100; if (i == 1) dq[1] = dq[1] - 0x100; if (i == 2) dq[2] = dq[2] - 0x100; if (i == 3) dq[3] = dq[3] - 0x100; } } } while (wdet); data = mmio_read_32((0xf712c000 + 0x0d0)); data &= ~0xf000; data |= 0x3000; mmio_write_32((0xf712c000 + 0x0d0), data); mmio_write_32((0xf712c000 + 0x004), 0x201); do { data = mmio_read_32((0xf712c000 + 0x004)); } while (data & 1); data = mmio_read_32((0xf712c000 + 0x008)); if (data & 0x200) tf_printf("INFO: " "wdet rbs av fail\n"); }
static void ddrx_rdet(void) { unsigned int data, rdet, bdl[4]; data = mmio_read_32((0xf712c000 + 0x0d0)); data &= 0xf800ffff; data |= 0x8f0000; mmio_write_32((0xf712c000 + 0x0d0), data); data = mmio_read_32((0xf712c000 + 0x0dc)); data &= 0xfffffff0; data |= 0xf; mmio_write_32((0xf712c000 + 0x0dc), data); data = mmio_read_32((0xf712c000 + 0x070)); data |= 0x80000; mmio_write_32((0xf712c000 + 0x070), data); data = mmio_read_32((0xf712c000 + 0x070)); data &= 0xfff7ffff; mmio_write_32((0xf712c000 + 0x070), data); mmio_write_32((0xf712c000 + 0x004), 0x8000); mmio_write_32((0xf712c000 + 0x004), 0); data = mmio_read_32((0xf712c000 + 0x0d0)); data &= ~0xf0000000; data |= 0x80000000; mmio_write_32((0xf712c000 + 0x0d0), data); mmio_write_32((0xf712c000 + 0x004), 0x101); do { data = mmio_read_32((0xf712c000 + 0x004)); } while (!(data & 1)); data = mmio_read_32((0xf712c000 + 0x008)); if (data & 0x100) tf_printf("WARN: " "rdet lbs fail\n"); bdl[0] = mmio_read_32((0xf712c000 + 0x22c)) & 0x7f; bdl[1] = mmio_read_32((0xf712c000 + 0x2ac)) & 0x7f; bdl[2] = mmio_read_32((0xf712c000 + 0x32c)) & 0x7f; bdl[3] = mmio_read_32((0xf712c000 + 0x3ac)) & 0x7f; do { data = mmio_read_32((0xf712c000 + 0x22c)); data &= ~0x7f; data |= bdl[0]; mmio_write_32((0xf712c000 + 0x22c), data); data = mmio_read_32((0xf712c000 + 0x2ac)); data &= ~0x7f; data |= bdl[1]; mmio_write_32((0xf712c000 + 0x2ac), data); data = mmio_read_32((0xf712c000 + 0x32c)); data &= ~0x7f; data |= bdl[2]; mmio_write_32((0xf712c000 + 0x32c), data); data = mmio_read_32((0xf712c000 + 0x3ac)); data &= ~0x7f; data |= bdl[3]; mmio_write_32((0xf712c000 + 0x3ac), data); data = mmio_read_32((0xf712c000 + 0x070)); data |= 0x80000; mmio_write_32((0xf712c000 + 0x070), data); data = mmio_read_32((0xf712c000 + 0x070)); data &= 0xfff7ffff; mmio_write_32((0xf712c000 + 0x070), data); mmio_write_32((0xf712c000 + 0x004), 0x8000); mmio_write_32((0xf712c000 + 0x004), 0); data = mmio_read_32((0xf712c000 + 0x0d0)); data &= ~0xf0000000; data |= 0x40000000; mmio_write_32((0xf712c000 + 0x0d0), data); mmio_write_32((0xf712c000 + 0x004), 0x101); do { data = mmio_read_32((0xf712c000 + 0x004)); } while (data & 1); data = mmio_read_32((0xf712c000 + 0x008)); rdet = data & 0x100; if (rdet) { tf_printf("INFO: " "rdet ds fail\n"); mmio_write_32((0xf712c000 + 0x008), 0x100); } bdl[0]++; bdl[1]++; bdl[2]++; bdl[3]++; } while (rdet); data = mmio_read_32((0xf712c000 + 0x0d0)); data &= ~0xf0000000; data |= 0x30000000; mmio_write_32((0xf712c000 + 0x0d0), data); mmio_write_32((0xf712c000 + 0x004), 0x101); do { data = mmio_read_32((0xf712c000 + 0x004)); } while (data & 1); data = mmio_read_32((0xf712c000 + 0x008)); if (data & 0x100) tf_printf("INFO: " "rdet rbs av fail\n"); }
int cat_533mhz_800mhz(void) { unsigned int data, i; unsigned int bdl[5]; data = mmio_read_32((0xf712c000 + 0x1c8)); data &= 0xfffff0f0; data |= 0x100f0f; mmio_write_32((0xf712c000 + 0x1c8), data); for (i = 0; i < 0x20; i++) { mmio_write_32((0xf712c000 + 0x1d4), 0xc0000); data = (i << 0x10) + i; mmio_write_32((0xf712c000 + 0x140), data); mmio_write_32((0xf712c000 + 0x144), data); mmio_write_32((0xf712c000 + 0x148), data); mmio_write_32((0xf712c000 + 0x14c), data); mmio_write_32((0xf712c000 + 0x150), data); data = mmio_read_32((0xf712c000 + 0x070)); data |= 0x80000; mmio_write_32((0xf712c000 + 0x070), data); data = mmio_read_32((0xf712c000 + 0x070)); data &= 0xfff7ffff; mmio_write_32((0xf712c000 + 0x070), data); mmio_write_32((0xf712c000 + 0x004), 0x8000); mmio_write_32((0xf712c000 + 0x004), 0x0); mmio_write_32((0xf712c000 + 0x004), 0x801); do { data = mmio_read_32((0xf712c000 + 0x004)); } while (data & 1); data = mmio_read_32((0xf712c000 + 0x008)); if (!(data & 0x400)) { mdelay(10); return 0; } tf_printf("WARN: " "lpddr3 cat fail\n"); data = mmio_read_32((0xf712c000 + 0x1d4)); if ((data & 0x1f00) && ((data & 0x1f) == 0)) { bdl[0] = mmio_read_32((0xf712c000 + 0x140)); bdl[1] = mmio_read_32((0xf712c000 + 0x144)); bdl[2] = mmio_read_32((0xf712c000 + 0x148)); bdl[3] = mmio_read_32((0xf712c000 + 0x14c)); bdl[4] = mmio_read_32((0xf712c000 + 0x150)); if ((!(bdl[0] & 0x1f001f)) || (!(bdl[1] & 0x1f001f)) || (!(bdl[2] & 0x1f001f)) || (!(bdl[3] & 0x1f001f)) || (!(bdl[4] & 0x1f001f))) { tf_printf("WARN: " "lpddr3 cat deskew error\n"); if (i == 0x1f) { tf_printf("WARN: " "addrnbdl is max\n"); return -22; } mmio_write_32((0xf712c000 + 0x008), 0x400); } else { tf_printf("WARN: " "lpddr3 cat other error1\n"); return -22; } } else { tf_printf("WARN: " "lpddr3 cat other error2\n"); return -22; } } return -22; }
/* * This is a basic implementation. This could be improved. */ void __assert (const char *function, const char *file, unsigned int line, const char *assertion) { tf_printf("ASSERT: %s <%d> : %s\n", function, line, assertion); while(1); }