15614e71bSYork Sun /* 234e026f9SYork Sun * Copyright 2008-2014 Freescale Semiconductor, Inc. 35614e71bSYork Sun * 45b8031ccSTom Rini * SPDX-License-Identifier: GPL-2.0 55614e71bSYork Sun */ 65614e71bSYork Sun 75614e71bSYork Sun /* 85614e71bSYork Sun * Generic driver for Freescale DDR/DDR2/DDR3 memory controller. 95614e71bSYork Sun * Based on code from spd_sdram.c 105614e71bSYork Sun * Author: James Yang [at freescale.com] 115614e71bSYork Sun */ 125614e71bSYork Sun 135614e71bSYork Sun #include <common.h> 145614e71bSYork Sun #include <i2c.h> 155614e71bSYork Sun #include <fsl_ddr_sdram.h> 165614e71bSYork Sun #include <fsl_ddr.h> 175614e71bSYork Sun 186b9e309aSYork Sun /* 196b9e309aSYork Sun * CONFIG_SYS_FSL_DDR_SDRAM_BASE_PHY is the physical address from the view 206b9e309aSYork Sun * of DDR controllers. It is the same as CONFIG_SYS_DDR_SDRAM_BASE for 216b9e309aSYork Sun * all Power SoCs. But it could be different for ARM SoCs. For example, 226b9e309aSYork Sun * fsl_lsch3 has a mapping mechanism to map DDR memory to ranges (in order) of 236b9e309aSYork Sun * 0x00_8000_0000 ~ 0x00_ffff_ffff 246b9e309aSYork Sun * 0x80_8000_0000 ~ 0xff_ffff_ffff 256b9e309aSYork Sun */ 266b9e309aSYork Sun #ifndef CONFIG_SYS_FSL_DDR_SDRAM_BASE_PHY 276b9e309aSYork Sun #define CONFIG_SYS_FSL_DDR_SDRAM_BASE_PHY CONFIG_SYS_DDR_SDRAM_BASE 286b9e309aSYork Sun #endif 296b9e309aSYork Sun 309ac4ffbdSYork Sun #ifdef CONFIG_PPC 319ac4ffbdSYork Sun #include <asm/fsl_law.h> 329ac4ffbdSYork Sun 335614e71bSYork Sun void fsl_ddr_set_lawbar( 345614e71bSYork Sun const common_timing_params_t *memctl_common_params, 355614e71bSYork Sun unsigned int memctl_interleaved, 365614e71bSYork Sun unsigned int ctrl_num); 379ac4ffbdSYork Sun #endif 385614e71bSYork Sun 399ac4ffbdSYork Sun void fsl_ddr_set_intl3r(const unsigned int granule_size); 405614e71bSYork Sun #if defined(SPD_EEPROM_ADDRESS) || \ 415614e71bSYork Sun defined(SPD_EEPROM_ADDRESS1) || defined(SPD_EEPROM_ADDRESS2) || \ 425614e71bSYork Sun defined(SPD_EEPROM_ADDRESS3) || defined(SPD_EEPROM_ADDRESS4) 435614e71bSYork Sun #if (CONFIG_NUM_DDR_CONTROLLERS == 1) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1) 445614e71bSYork Sun u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { 455614e71bSYork Sun [0][0] = SPD_EEPROM_ADDRESS, 465614e71bSYork Sun }; 475614e71bSYork Sun #elif (CONFIG_NUM_DDR_CONTROLLERS == 1) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2) 485614e71bSYork Sun u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { 495614e71bSYork Sun [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ 505614e71bSYork Sun [0][1] = SPD_EEPROM_ADDRESS2, /* controller 1 */ 515614e71bSYork Sun }; 525614e71bSYork Sun #elif (CONFIG_NUM_DDR_CONTROLLERS == 2) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1) 535614e71bSYork Sun u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { 545614e71bSYork Sun [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ 555614e71bSYork Sun [1][0] = SPD_EEPROM_ADDRESS2, /* controller 2 */ 565614e71bSYork Sun }; 575614e71bSYork Sun #elif (CONFIG_NUM_DDR_CONTROLLERS == 2) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2) 585614e71bSYork Sun u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { 595614e71bSYork Sun [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ 605614e71bSYork Sun [0][1] = SPD_EEPROM_ADDRESS2, /* controller 1 */ 615614e71bSYork Sun [1][0] = SPD_EEPROM_ADDRESS3, /* controller 2 */ 625614e71bSYork Sun [1][1] = SPD_EEPROM_ADDRESS4, /* controller 2 */ 635614e71bSYork Sun }; 645614e71bSYork Sun #elif (CONFIG_NUM_DDR_CONTROLLERS == 3) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1) 655614e71bSYork Sun u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { 665614e71bSYork Sun [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ 675614e71bSYork Sun [1][0] = SPD_EEPROM_ADDRESS2, /* controller 2 */ 685614e71bSYork Sun [2][0] = SPD_EEPROM_ADDRESS3, /* controller 3 */ 695614e71bSYork Sun }; 705614e71bSYork Sun #elif (CONFIG_NUM_DDR_CONTROLLERS == 3) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2) 715614e71bSYork Sun u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { 725614e71bSYork Sun [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ 735614e71bSYork Sun [0][1] = SPD_EEPROM_ADDRESS2, /* controller 1 */ 745614e71bSYork Sun [1][0] = SPD_EEPROM_ADDRESS3, /* controller 2 */ 755614e71bSYork Sun [1][1] = SPD_EEPROM_ADDRESS4, /* controller 2 */ 765614e71bSYork Sun [2][0] = SPD_EEPROM_ADDRESS5, /* controller 3 */ 775614e71bSYork Sun [2][1] = SPD_EEPROM_ADDRESS6, /* controller 3 */ 785614e71bSYork Sun }; 795614e71bSYork Sun 805614e71bSYork Sun #endif 815614e71bSYork Sun 8234e026f9SYork Sun #define SPD_SPA0_ADDRESS 0x36 8334e026f9SYork Sun #define SPD_SPA1_ADDRESS 0x37 8434e026f9SYork Sun 855614e71bSYork Sun static void __get_spd(generic_spd_eeprom_t *spd, u8 i2c_address) 865614e71bSYork Sun { 875614e71bSYork Sun int ret; 8834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 8934e026f9SYork Sun uint8_t dummy = 0; 9034e026f9SYork Sun #endif 915614e71bSYork Sun 925614e71bSYork Sun i2c_set_bus_num(CONFIG_SYS_SPD_BUS_NUM); 935614e71bSYork Sun 9434e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 9534e026f9SYork Sun /* 9634e026f9SYork Sun * DDR4 SPD has 384 to 512 bytes 9734e026f9SYork Sun * To access the lower 256 bytes, we need to set EE page address to 0 9834e026f9SYork Sun * To access the upper 256 bytes, we need to set EE page address to 1 9934e026f9SYork Sun * See Jedec standar No. 21-C for detail 10034e026f9SYork Sun */ 10134e026f9SYork Sun i2c_write(SPD_SPA0_ADDRESS, 0, 1, &dummy, 1); 10234e026f9SYork Sun ret = i2c_read(i2c_address, 0, 1, (uchar *)spd, 256); 10334e026f9SYork Sun if (!ret) { 10434e026f9SYork Sun i2c_write(SPD_SPA1_ADDRESS, 0, 1, &dummy, 1); 10534e026f9SYork Sun ret = i2c_read(i2c_address, 0, 1, 10634e026f9SYork Sun (uchar *)((ulong)spd + 256), 107b4141195SMasahiro Yamada min(256, 108b4141195SMasahiro Yamada (int)sizeof(generic_spd_eeprom_t) - 256)); 10934e026f9SYork Sun } 11034e026f9SYork Sun #else 1115614e71bSYork Sun ret = i2c_read(i2c_address, 0, 1, (uchar *)spd, 1125614e71bSYork Sun sizeof(generic_spd_eeprom_t)); 11334e026f9SYork Sun #endif 1145614e71bSYork Sun 1155614e71bSYork Sun if (ret) { 1165614e71bSYork Sun if (i2c_address == 1175614e71bSYork Sun #ifdef SPD_EEPROM_ADDRESS 1185614e71bSYork Sun SPD_EEPROM_ADDRESS 1195614e71bSYork Sun #elif defined(SPD_EEPROM_ADDRESS1) 1205614e71bSYork Sun SPD_EEPROM_ADDRESS1 1215614e71bSYork Sun #endif 1225614e71bSYork Sun ) { 1235614e71bSYork Sun printf("DDR: failed to read SPD from address %u\n", 1245614e71bSYork Sun i2c_address); 1255614e71bSYork Sun } else { 1265614e71bSYork Sun debug("DDR: failed to read SPD from address %u\n", 1275614e71bSYork Sun i2c_address); 1285614e71bSYork Sun } 1295614e71bSYork Sun memset(spd, 0, sizeof(generic_spd_eeprom_t)); 1305614e71bSYork Sun } 1315614e71bSYork Sun } 1325614e71bSYork Sun 1335614e71bSYork Sun __attribute__((weak, alias("__get_spd"))) 1345614e71bSYork Sun void get_spd(generic_spd_eeprom_t *spd, u8 i2c_address); 1355614e71bSYork Sun 136b92557cdSYork Sun /* This function allows boards to update SPD address */ 137b92557cdSYork Sun __weak void update_spd_address(unsigned int ctrl_num, 138b92557cdSYork Sun unsigned int slot, 139b92557cdSYork Sun unsigned int *addr) 140b92557cdSYork Sun { 141b92557cdSYork Sun } 142b92557cdSYork Sun 1435614e71bSYork Sun void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd, 1441d71efbbSYork Sun unsigned int ctrl_num, unsigned int dimm_slots_per_ctrl) 1455614e71bSYork Sun { 1465614e71bSYork Sun unsigned int i; 1475614e71bSYork Sun unsigned int i2c_address = 0; 1485614e71bSYork Sun 1495614e71bSYork Sun if (ctrl_num >= CONFIG_NUM_DDR_CONTROLLERS) { 1505614e71bSYork Sun printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num); 1515614e71bSYork Sun return; 1525614e71bSYork Sun } 1535614e71bSYork Sun 1541d71efbbSYork Sun for (i = 0; i < dimm_slots_per_ctrl; i++) { 1555614e71bSYork Sun i2c_address = spd_i2c_addr[ctrl_num][i]; 156b92557cdSYork Sun update_spd_address(ctrl_num, i, &i2c_address); 1575614e71bSYork Sun get_spd(&(ctrl_dimms_spd[i]), i2c_address); 1585614e71bSYork Sun } 1595614e71bSYork Sun } 1605614e71bSYork Sun #else 1615614e71bSYork Sun void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd, 1621d71efbbSYork Sun unsigned int ctrl_num, unsigned int dimm_slots_per_ctrl) 1635614e71bSYork Sun { 1645614e71bSYork Sun } 1655614e71bSYork Sun #endif /* SPD_EEPROM_ADDRESSx */ 1665614e71bSYork Sun 1675614e71bSYork Sun /* 1685614e71bSYork Sun * ASSUMPTIONS: 1695614e71bSYork Sun * - Same number of CONFIG_DIMM_SLOTS_PER_CTLR on each controller 1705614e71bSYork Sun * - Same memory data bus width on all controllers 1715614e71bSYork Sun * 1725614e71bSYork Sun * NOTES: 1735614e71bSYork Sun * 1745614e71bSYork Sun * The memory controller and associated documentation use confusing 1755614e71bSYork Sun * terminology when referring to the orgranization of DRAM. 1765614e71bSYork Sun * 1775614e71bSYork Sun * Here is a terminology translation table: 1785614e71bSYork Sun * 1795614e71bSYork Sun * memory controller/documention |industry |this code |signals 1805614e71bSYork Sun * -------------------------------|-----------|-----------|----------------- 1815614e71bSYork Sun * physical bank/bank |rank |rank |chip select (CS) 1825614e71bSYork Sun * logical bank/sub-bank |bank |bank |bank address (BA) 1835614e71bSYork Sun * page/row |row |page |row address 1845614e71bSYork Sun * ??? |column |column |column address 1855614e71bSYork Sun * 1865614e71bSYork Sun * The naming confusion is further exacerbated by the descriptions of the 1875614e71bSYork Sun * memory controller interleaving feature, where accesses are interleaved 1885614e71bSYork Sun * _BETWEEN_ two seperate memory controllers. This is configured only in 1895614e71bSYork Sun * CS0_CONFIG[INTLV_CTL] of each memory controller. 1905614e71bSYork Sun * 1915614e71bSYork Sun * memory controller documentation | number of chip selects 1925614e71bSYork Sun * | per memory controller supported 1935614e71bSYork Sun * --------------------------------|----------------------------------------- 1945614e71bSYork Sun * cache line interleaving | 1 (CS0 only) 1955614e71bSYork Sun * page interleaving | 1 (CS0 only) 1965614e71bSYork Sun * bank interleaving | 1 (CS0 only) 1975614e71bSYork Sun * superbank interleraving | depends on bank (chip select) 1985614e71bSYork Sun * | interleraving [rank interleaving] 1995614e71bSYork Sun * | mode used on every memory controller 2005614e71bSYork Sun * 2015614e71bSYork Sun * Even further confusing is the existence of the interleaving feature 2025614e71bSYork Sun * _WITHIN_ each memory controller. The feature is referred to in 2035614e71bSYork Sun * documentation as chip select interleaving or bank interleaving, 2045614e71bSYork Sun * although it is configured in the DDR_SDRAM_CFG field. 2055614e71bSYork Sun * 2065614e71bSYork Sun * Name of field | documentation name | this code 2075614e71bSYork Sun * -----------------------------|-----------------------|------------------ 2085614e71bSYork Sun * DDR_SDRAM_CFG[BA_INTLV_CTL] | Bank (chip select) | rank interleaving 2095614e71bSYork Sun * | interleaving 2105614e71bSYork Sun */ 2115614e71bSYork Sun 2125614e71bSYork Sun const char *step_string_tbl[] = { 2135614e71bSYork Sun "STEP_GET_SPD", 2145614e71bSYork Sun "STEP_COMPUTE_DIMM_PARMS", 2155614e71bSYork Sun "STEP_COMPUTE_COMMON_PARMS", 2165614e71bSYork Sun "STEP_GATHER_OPTS", 2175614e71bSYork Sun "STEP_ASSIGN_ADDRESSES", 2185614e71bSYork Sun "STEP_COMPUTE_REGS", 2195614e71bSYork Sun "STEP_PROGRAM_REGS", 2205614e71bSYork Sun "STEP_ALL" 2215614e71bSYork Sun }; 2225614e71bSYork Sun 2235614e71bSYork Sun const char * step_to_string(unsigned int step) { 2245614e71bSYork Sun 2255614e71bSYork Sun unsigned int s = __ilog2(step); 2265614e71bSYork Sun 2275614e71bSYork Sun if ((1 << s) != step) 2285614e71bSYork Sun return step_string_tbl[7]; 2295614e71bSYork Sun 230349689b8SYork Sun if (s >= ARRAY_SIZE(step_string_tbl)) { 231349689b8SYork Sun printf("Error for the step in %s\n", __func__); 232349689b8SYork Sun s = 0; 233349689b8SYork Sun } 234349689b8SYork Sun 2355614e71bSYork Sun return step_string_tbl[s]; 2365614e71bSYork Sun } 2375614e71bSYork Sun 2385614e71bSYork Sun static unsigned long long __step_assign_addresses(fsl_ddr_info_t *pinfo, 2395614e71bSYork Sun unsigned int dbw_cap_adj[]) 2405614e71bSYork Sun { 2411d71efbbSYork Sun unsigned int i, j; 2425614e71bSYork Sun unsigned long long total_mem, current_mem_base, total_ctlr_mem; 2435614e71bSYork Sun unsigned long long rank_density, ctlr_density = 0; 2441d71efbbSYork Sun unsigned int first_ctrl = pinfo->first_ctrl; 2451d71efbbSYork Sun unsigned int last_ctrl = first_ctrl + pinfo->num_ctrls - 1; 2465614e71bSYork Sun 2475614e71bSYork Sun /* 2485614e71bSYork Sun * If a reduced data width is requested, but the SPD 2495614e71bSYork Sun * specifies a physically wider device, adjust the 2505614e71bSYork Sun * computed dimm capacities accordingly before 2515614e71bSYork Sun * assigning addresses. 2525614e71bSYork Sun */ 2531d71efbbSYork Sun for (i = first_ctrl; i <= last_ctrl; i++) { 2545614e71bSYork Sun unsigned int found = 0; 2555614e71bSYork Sun 2565614e71bSYork Sun switch (pinfo->memctl_opts[i].data_bus_width) { 2575614e71bSYork Sun case 2: 2585614e71bSYork Sun /* 16-bit */ 2595614e71bSYork Sun for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { 2605614e71bSYork Sun unsigned int dw; 2615614e71bSYork Sun if (!pinfo->dimm_params[i][j].n_ranks) 2625614e71bSYork Sun continue; 2635614e71bSYork Sun dw = pinfo->dimm_params[i][j].primary_sdram_width; 2645614e71bSYork Sun if ((dw == 72 || dw == 64)) { 2655614e71bSYork Sun dbw_cap_adj[i] = 2; 2665614e71bSYork Sun break; 2675614e71bSYork Sun } else if ((dw == 40 || dw == 32)) { 2685614e71bSYork Sun dbw_cap_adj[i] = 1; 2695614e71bSYork Sun break; 2705614e71bSYork Sun } 2715614e71bSYork Sun } 2725614e71bSYork Sun break; 2735614e71bSYork Sun 2745614e71bSYork Sun case 1: 2755614e71bSYork Sun /* 32-bit */ 2765614e71bSYork Sun for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { 2775614e71bSYork Sun unsigned int dw; 2785614e71bSYork Sun dw = pinfo->dimm_params[i][j].data_width; 2795614e71bSYork Sun if (pinfo->dimm_params[i][j].n_ranks 2805614e71bSYork Sun && (dw == 72 || dw == 64)) { 2815614e71bSYork Sun /* 2825614e71bSYork Sun * FIXME: can't really do it 2835614e71bSYork Sun * like this because this just 2845614e71bSYork Sun * further reduces the memory 2855614e71bSYork Sun */ 2865614e71bSYork Sun found = 1; 2875614e71bSYork Sun break; 2885614e71bSYork Sun } 2895614e71bSYork Sun } 2905614e71bSYork Sun if (found) { 2915614e71bSYork Sun dbw_cap_adj[i] = 1; 2925614e71bSYork Sun } 2935614e71bSYork Sun break; 2945614e71bSYork Sun 2955614e71bSYork Sun case 0: 2965614e71bSYork Sun /* 64-bit */ 2975614e71bSYork Sun break; 2985614e71bSYork Sun 2995614e71bSYork Sun default: 3005614e71bSYork Sun printf("unexpected data bus width " 3015614e71bSYork Sun "specified controller %u\n", i); 3025614e71bSYork Sun return 1; 3035614e71bSYork Sun } 3045614e71bSYork Sun debug("dbw_cap_adj[%d]=%d\n", i, dbw_cap_adj[i]); 3055614e71bSYork Sun } 3065614e71bSYork Sun 3071d71efbbSYork Sun current_mem_base = pinfo->mem_base; 3085614e71bSYork Sun total_mem = 0; 3091d71efbbSYork Sun if (pinfo->memctl_opts[first_ctrl].memctl_interleaving) { 3101d71efbbSYork Sun rank_density = pinfo->dimm_params[first_ctrl][0].rank_density >> 3111d71efbbSYork Sun dbw_cap_adj[first_ctrl]; 3121d71efbbSYork Sun switch (pinfo->memctl_opts[first_ctrl].ba_intlv_ctl & 3135614e71bSYork Sun FSL_DDR_CS0_CS1_CS2_CS3) { 3145614e71bSYork Sun case FSL_DDR_CS0_CS1_CS2_CS3: 3155614e71bSYork Sun ctlr_density = 4 * rank_density; 3165614e71bSYork Sun break; 3175614e71bSYork Sun case FSL_DDR_CS0_CS1: 3185614e71bSYork Sun case FSL_DDR_CS0_CS1_AND_CS2_CS3: 3195614e71bSYork Sun ctlr_density = 2 * rank_density; 3205614e71bSYork Sun break; 3215614e71bSYork Sun case FSL_DDR_CS2_CS3: 3225614e71bSYork Sun default: 3235614e71bSYork Sun ctlr_density = rank_density; 3245614e71bSYork Sun break; 3255614e71bSYork Sun } 3265614e71bSYork Sun debug("rank density is 0x%llx, ctlr density is 0x%llx\n", 3275614e71bSYork Sun rank_density, ctlr_density); 3281d71efbbSYork Sun for (i = first_ctrl; i <= last_ctrl; i++) { 3295614e71bSYork Sun if (pinfo->memctl_opts[i].memctl_interleaving) { 3305614e71bSYork Sun switch (pinfo->memctl_opts[i].memctl_interleaving_mode) { 3316b1e1254SYork Sun case FSL_DDR_256B_INTERLEAVING: 3325614e71bSYork Sun case FSL_DDR_CACHE_LINE_INTERLEAVING: 3335614e71bSYork Sun case FSL_DDR_PAGE_INTERLEAVING: 3345614e71bSYork Sun case FSL_DDR_BANK_INTERLEAVING: 3355614e71bSYork Sun case FSL_DDR_SUPERBANK_INTERLEAVING: 3365614e71bSYork Sun total_ctlr_mem = 2 * ctlr_density; 3375614e71bSYork Sun break; 3385614e71bSYork Sun case FSL_DDR_3WAY_1KB_INTERLEAVING: 3395614e71bSYork Sun case FSL_DDR_3WAY_4KB_INTERLEAVING: 3405614e71bSYork Sun case FSL_DDR_3WAY_8KB_INTERLEAVING: 3415614e71bSYork Sun total_ctlr_mem = 3 * ctlr_density; 3425614e71bSYork Sun break; 3435614e71bSYork Sun case FSL_DDR_4WAY_1KB_INTERLEAVING: 3445614e71bSYork Sun case FSL_DDR_4WAY_4KB_INTERLEAVING: 3455614e71bSYork Sun case FSL_DDR_4WAY_8KB_INTERLEAVING: 3465614e71bSYork Sun total_ctlr_mem = 4 * ctlr_density; 3475614e71bSYork Sun break; 3485614e71bSYork Sun default: 3495614e71bSYork Sun panic("Unknown interleaving mode"); 3505614e71bSYork Sun } 3515614e71bSYork Sun pinfo->common_timing_params[i].base_address = 3525614e71bSYork Sun current_mem_base; 3535614e71bSYork Sun pinfo->common_timing_params[i].total_mem = 3545614e71bSYork Sun total_ctlr_mem; 3555614e71bSYork Sun total_mem = current_mem_base + total_ctlr_mem; 3565614e71bSYork Sun debug("ctrl %d base 0x%llx\n", i, current_mem_base); 3575614e71bSYork Sun debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem); 3585614e71bSYork Sun } else { 3595614e71bSYork Sun /* when 3rd controller not interleaved */ 3605614e71bSYork Sun current_mem_base = total_mem; 3615614e71bSYork Sun total_ctlr_mem = 0; 3625614e71bSYork Sun pinfo->common_timing_params[i].base_address = 3635614e71bSYork Sun current_mem_base; 3645614e71bSYork Sun for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { 3655614e71bSYork Sun unsigned long long cap = 3665614e71bSYork Sun pinfo->dimm_params[i][j].capacity >> dbw_cap_adj[i]; 3675614e71bSYork Sun pinfo->dimm_params[i][j].base_address = 3685614e71bSYork Sun current_mem_base; 3695614e71bSYork Sun debug("ctrl %d dimm %d base 0x%llx\n", i, j, current_mem_base); 3705614e71bSYork Sun current_mem_base += cap; 3715614e71bSYork Sun total_ctlr_mem += cap; 3725614e71bSYork Sun } 3735614e71bSYork Sun debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem); 3745614e71bSYork Sun pinfo->common_timing_params[i].total_mem = 3755614e71bSYork Sun total_ctlr_mem; 3765614e71bSYork Sun total_mem += total_ctlr_mem; 3775614e71bSYork Sun } 3785614e71bSYork Sun } 3795614e71bSYork Sun } else { 3805614e71bSYork Sun /* 3815614e71bSYork Sun * Simple linear assignment if memory 3825614e71bSYork Sun * controllers are not interleaved. 3835614e71bSYork Sun */ 3841d71efbbSYork Sun for (i = first_ctrl; i <= last_ctrl; i++) { 3855614e71bSYork Sun total_ctlr_mem = 0; 3865614e71bSYork Sun pinfo->common_timing_params[i].base_address = 3875614e71bSYork Sun current_mem_base; 3885614e71bSYork Sun for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { 3895614e71bSYork Sun /* Compute DIMM base addresses. */ 3905614e71bSYork Sun unsigned long long cap = 3915614e71bSYork Sun pinfo->dimm_params[i][j].capacity >> dbw_cap_adj[i]; 3925614e71bSYork Sun pinfo->dimm_params[i][j].base_address = 3935614e71bSYork Sun current_mem_base; 3945614e71bSYork Sun debug("ctrl %d dimm %d base 0x%llx\n", i, j, current_mem_base); 3955614e71bSYork Sun current_mem_base += cap; 3965614e71bSYork Sun total_ctlr_mem += cap; 3975614e71bSYork Sun } 3985614e71bSYork Sun debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem); 3995614e71bSYork Sun pinfo->common_timing_params[i].total_mem = 4005614e71bSYork Sun total_ctlr_mem; 4015614e71bSYork Sun total_mem += total_ctlr_mem; 4025614e71bSYork Sun } 4035614e71bSYork Sun } 4045614e71bSYork Sun debug("Total mem by %s is 0x%llx\n", __func__, total_mem); 4055614e71bSYork Sun 4065614e71bSYork Sun return total_mem; 4075614e71bSYork Sun } 4085614e71bSYork Sun 4095614e71bSYork Sun /* Use weak function to allow board file to override the address assignment */ 4105614e71bSYork Sun __attribute__((weak, alias("__step_assign_addresses"))) 4115614e71bSYork Sun unsigned long long step_assign_addresses(fsl_ddr_info_t *pinfo, 4125614e71bSYork Sun unsigned int dbw_cap_adj[]); 4135614e71bSYork Sun 4145614e71bSYork Sun unsigned long long 4155614e71bSYork Sun fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, 4165614e71bSYork Sun unsigned int size_only) 4175614e71bSYork Sun { 4185614e71bSYork Sun unsigned int i, j; 4195614e71bSYork Sun unsigned long long total_mem = 0; 4201d71efbbSYork Sun int assert_reset = 0; 4211d71efbbSYork Sun unsigned int first_ctrl = pinfo->first_ctrl; 4221d71efbbSYork Sun unsigned int last_ctrl = first_ctrl + pinfo->num_ctrls - 1; 4231d71efbbSYork Sun __maybe_unused int retval; 4241d71efbbSYork Sun __maybe_unused bool goodspd = false; 4251d71efbbSYork Sun __maybe_unused int dimm_slots_per_ctrl = pinfo->dimm_slots_per_ctrl; 4265614e71bSYork Sun 4275614e71bSYork Sun fsl_ddr_cfg_regs_t *ddr_reg = pinfo->fsl_ddr_config_reg; 4285614e71bSYork Sun common_timing_params_t *timing_params = pinfo->common_timing_params; 4291d71efbbSYork Sun if (pinfo->board_need_mem_reset) 4301d71efbbSYork Sun assert_reset = pinfo->board_need_mem_reset(); 4315614e71bSYork Sun 4325614e71bSYork Sun /* data bus width capacity adjust shift amount */ 4335614e71bSYork Sun unsigned int dbw_capacity_adjust[CONFIG_NUM_DDR_CONTROLLERS]; 4345614e71bSYork Sun 4351d71efbbSYork Sun for (i = first_ctrl; i <= last_ctrl; i++) 4365614e71bSYork Sun dbw_capacity_adjust[i] = 0; 4375614e71bSYork Sun 4385614e71bSYork Sun debug("starting at step %u (%s)\n", 4395614e71bSYork Sun start_step, step_to_string(start_step)); 4405614e71bSYork Sun 4415614e71bSYork Sun switch (start_step) { 4425614e71bSYork Sun case STEP_GET_SPD: 4435614e71bSYork Sun #if defined(CONFIG_DDR_SPD) || defined(CONFIG_SPD_EEPROM) 4445614e71bSYork Sun /* STEP 1: Gather all DIMM SPD data */ 4451d71efbbSYork Sun for (i = first_ctrl; i <= last_ctrl; i++) { 4461d71efbbSYork Sun fsl_ddr_get_spd(pinfo->spd_installed_dimms[i], i, 4471d71efbbSYork Sun dimm_slots_per_ctrl); 4485614e71bSYork Sun } 4495614e71bSYork Sun 4505614e71bSYork Sun case STEP_COMPUTE_DIMM_PARMS: 4515614e71bSYork Sun /* STEP 2: Compute DIMM parameters from SPD data */ 4525614e71bSYork Sun 4531d71efbbSYork Sun for (i = first_ctrl; i <= last_ctrl; i++) { 4545614e71bSYork Sun for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { 4555614e71bSYork Sun generic_spd_eeprom_t *spd = 4565614e71bSYork Sun &(pinfo->spd_installed_dimms[i][j]); 4575614e71bSYork Sun dimm_params_t *pdimm = 4585614e71bSYork Sun &(pinfo->dimm_params[i][j]); 45903e664d8SYork Sun retval = compute_dimm_parameters( 46003e664d8SYork Sun i, spd, pdimm, j); 4615614e71bSYork Sun #ifdef CONFIG_SYS_DDR_RAW_TIMING 46266869f95SYork Sun if (!j && retval) { 4635614e71bSYork Sun printf("SPD error on controller %d! " 4645614e71bSYork Sun "Trying fallback to raw timing " 4655614e71bSYork Sun "calculation\n", i); 4661d71efbbSYork Sun retval = fsl_ddr_get_dimm_params(pdimm, 4671d71efbbSYork Sun i, j); 4685614e71bSYork Sun } 4695614e71bSYork Sun #else 4705614e71bSYork Sun if (retval == 2) { 4715614e71bSYork Sun printf("Error: compute_dimm_parameters" 4725614e71bSYork Sun " non-zero returned FATAL value " 4735614e71bSYork Sun "for memctl=%u dimm=%u\n", i, j); 4745614e71bSYork Sun return 0; 4755614e71bSYork Sun } 4765614e71bSYork Sun #endif 4775614e71bSYork Sun if (retval) { 4785614e71bSYork Sun debug("Warning: compute_dimm_parameters" 4795614e71bSYork Sun " non-zero return value for memctl=%u " 4805614e71bSYork Sun "dimm=%u\n", i, j); 4811d71efbbSYork Sun } else { 4821d71efbbSYork Sun goodspd = true; 4835614e71bSYork Sun } 4845614e71bSYork Sun } 4855614e71bSYork Sun } 4861d71efbbSYork Sun if (!goodspd) { 4871d71efbbSYork Sun /* 4881d71efbbSYork Sun * No valid SPD found 4891d71efbbSYork Sun * Throw an error if this is for main memory, i.e. 4901d71efbbSYork Sun * first_ctrl == 0. Otherwise, siliently return 0 4911d71efbbSYork Sun * as the memory size. 4921d71efbbSYork Sun */ 4931d71efbbSYork Sun if (first_ctrl == 0) 4941d71efbbSYork Sun printf("Error: No valid SPD detected.\n"); 4955614e71bSYork Sun 4961d71efbbSYork Sun return 0; 4971d71efbbSYork Sun } 4985614e71bSYork Sun #elif defined(CONFIG_SYS_DDR_RAW_TIMING) 4995614e71bSYork Sun case STEP_COMPUTE_DIMM_PARMS: 5001d71efbbSYork Sun for (i = first_ctrl; i <= last_ctrl; i++) { 5015614e71bSYork Sun for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { 5025614e71bSYork Sun dimm_params_t *pdimm = 5035614e71bSYork Sun &(pinfo->dimm_params[i][j]); 5045614e71bSYork Sun fsl_ddr_get_dimm_params(pdimm, i, j); 5055614e71bSYork Sun } 5065614e71bSYork Sun } 5075614e71bSYork Sun debug("Filling dimm parameters from board specific file\n"); 5085614e71bSYork Sun #endif 5095614e71bSYork Sun case STEP_COMPUTE_COMMON_PARMS: 5105614e71bSYork Sun /* 5115614e71bSYork Sun * STEP 3: Compute a common set of timing parameters 5125614e71bSYork Sun * suitable for all of the DIMMs on each memory controller 5135614e71bSYork Sun */ 5141d71efbbSYork Sun for (i = first_ctrl; i <= last_ctrl; i++) { 5155614e71bSYork Sun debug("Computing lowest common DIMM" 5165614e71bSYork Sun " parameters for memctl=%u\n", i); 51703e664d8SYork Sun compute_lowest_common_dimm_parameters 51803e664d8SYork Sun (i, 5195614e71bSYork Sun pinfo->dimm_params[i], 5205614e71bSYork Sun &timing_params[i], 5215614e71bSYork Sun CONFIG_DIMM_SLOTS_PER_CTLR); 5225614e71bSYork Sun } 5235614e71bSYork Sun 5245614e71bSYork Sun case STEP_GATHER_OPTS: 5255614e71bSYork Sun /* STEP 4: Gather configuration requirements from user */ 5261d71efbbSYork Sun for (i = first_ctrl; i <= last_ctrl; i++) { 5275614e71bSYork Sun debug("Reloading memory controller " 5285614e71bSYork Sun "configuration options for memctl=%u\n", i); 5295614e71bSYork Sun /* 5305614e71bSYork Sun * This "reloads" the memory controller options 5315614e71bSYork Sun * to defaults. If the user "edits" an option, 5325614e71bSYork Sun * next_step points to the step after this, 5335614e71bSYork Sun * which is currently STEP_ASSIGN_ADDRESSES. 5345614e71bSYork Sun */ 5355614e71bSYork Sun populate_memctl_options( 53656848428SYork Sun &timing_params[i], 5375614e71bSYork Sun &pinfo->memctl_opts[i], 5385614e71bSYork Sun pinfo->dimm_params[i], i); 5395614e71bSYork Sun /* 5405614e71bSYork Sun * For RDIMMs, JEDEC spec requires clocks to be stable 5415614e71bSYork Sun * before reset signal is deasserted. For the boards 5425614e71bSYork Sun * using fixed parameters, this function should be 5435614e71bSYork Sun * be called from board init file. 5445614e71bSYork Sun */ 5455614e71bSYork Sun if (timing_params[i].all_dimms_registered) 5465614e71bSYork Sun assert_reset = 1; 5475614e71bSYork Sun } 5481d71efbbSYork Sun if (assert_reset && !size_only) { 5491d71efbbSYork Sun if (pinfo->board_mem_reset) { 5505614e71bSYork Sun debug("Asserting mem reset\n"); 5511d71efbbSYork Sun pinfo->board_mem_reset(); 5521d71efbbSYork Sun } else { 5531d71efbbSYork Sun debug("Asserting mem reset missing\n"); 5541d71efbbSYork Sun } 5555614e71bSYork Sun } 5565614e71bSYork Sun 5575614e71bSYork Sun case STEP_ASSIGN_ADDRESSES: 5585614e71bSYork Sun /* STEP 5: Assign addresses to chip selects */ 5595614e71bSYork Sun check_interleaving_options(pinfo); 5605614e71bSYork Sun total_mem = step_assign_addresses(pinfo, dbw_capacity_adjust); 561349689b8SYork Sun debug("Total mem %llu assigned\n", total_mem); 5625614e71bSYork Sun 5635614e71bSYork Sun case STEP_COMPUTE_REGS: 5645614e71bSYork Sun /* STEP 6: compute controller register values */ 5655614e71bSYork Sun debug("FSL Memory ctrl register computation\n"); 5661d71efbbSYork Sun for (i = first_ctrl; i <= last_ctrl; i++) { 5675614e71bSYork Sun if (timing_params[i].ndimms_present == 0) { 5685614e71bSYork Sun memset(&ddr_reg[i], 0, 5695614e71bSYork Sun sizeof(fsl_ddr_cfg_regs_t)); 5705614e71bSYork Sun continue; 5715614e71bSYork Sun } 5725614e71bSYork Sun 57303e664d8SYork Sun compute_fsl_memctl_config_regs 57403e664d8SYork Sun (i, 5755614e71bSYork Sun &pinfo->memctl_opts[i], 5765614e71bSYork Sun &ddr_reg[i], &timing_params[i], 5775614e71bSYork Sun pinfo->dimm_params[i], 5785614e71bSYork Sun dbw_capacity_adjust[i], 5795614e71bSYork Sun size_only); 5805614e71bSYork Sun } 5815614e71bSYork Sun 5825614e71bSYork Sun default: 5835614e71bSYork Sun break; 5845614e71bSYork Sun } 5855614e71bSYork Sun 5865614e71bSYork Sun { 5875614e71bSYork Sun /* 5885614e71bSYork Sun * Compute the amount of memory available just by 5895614e71bSYork Sun * looking for the highest valid CSn_BNDS value. 5905614e71bSYork Sun * This allows us to also experiment with using 5915614e71bSYork Sun * only CS0 when using dual-rank DIMMs. 5925614e71bSYork Sun */ 5935614e71bSYork Sun unsigned int max_end = 0; 5945614e71bSYork Sun 5951d71efbbSYork Sun for (i = first_ctrl; i <= last_ctrl; i++) { 5965614e71bSYork Sun for (j = 0; j < CONFIG_CHIP_SELECTS_PER_CTRL; j++) { 5975614e71bSYork Sun fsl_ddr_cfg_regs_t *reg = &ddr_reg[i]; 5985614e71bSYork Sun if (reg->cs[j].config & 0x80000000) { 5995614e71bSYork Sun unsigned int end; 6005614e71bSYork Sun /* 6015614e71bSYork Sun * 0xfffffff is a special value we put 6025614e71bSYork Sun * for unused bnds 6035614e71bSYork Sun */ 6045614e71bSYork Sun if (reg->cs[j].bnds == 0xffffffff) 6055614e71bSYork Sun continue; 6065614e71bSYork Sun end = reg->cs[j].bnds & 0xffff; 6075614e71bSYork Sun if (end > max_end) { 6085614e71bSYork Sun max_end = end; 6095614e71bSYork Sun } 6105614e71bSYork Sun } 6115614e71bSYork Sun } 6125614e71bSYork Sun } 6135614e71bSYork Sun 61400ec3fd2SYork Sun total_mem = 1 + (((unsigned long long)max_end << 24ULL) | 6151d71efbbSYork Sun 0xFFFFFFULL) - pinfo->mem_base; 6165614e71bSYork Sun } 6175614e71bSYork Sun 6185614e71bSYork Sun return total_mem; 6195614e71bSYork Sun } 6205614e71bSYork Sun 6211d71efbbSYork Sun phys_size_t __fsl_ddr_sdram(fsl_ddr_info_t *pinfo) 6225614e71bSYork Sun { 6231d71efbbSYork Sun unsigned int i, first_ctrl, last_ctrl; 6249ac4ffbdSYork Sun #ifdef CONFIG_PPC 6255614e71bSYork Sun unsigned int law_memctl = LAW_TRGT_IF_DDR_1; 6269ac4ffbdSYork Sun #endif 6275614e71bSYork Sun unsigned long long total_memory; 6281d71efbbSYork Sun int deassert_reset = 0; 6295614e71bSYork Sun 6301d71efbbSYork Sun first_ctrl = pinfo->first_ctrl; 6311d71efbbSYork Sun last_ctrl = first_ctrl + pinfo->num_ctrls - 1; 6325614e71bSYork Sun 6335614e71bSYork Sun /* Compute it once normally. */ 6345614e71bSYork Sun #ifdef CONFIG_FSL_DDR_INTERACTIVE 6355614e71bSYork Sun if (tstc() && (getc() == 'd')) { /* we got a key press of 'd' */ 6361d71efbbSYork Sun total_memory = fsl_ddr_interactive(pinfo, 0); 6375614e71bSYork Sun } else if (fsl_ddr_interactive_env_var_exists()) { 6381d71efbbSYork Sun total_memory = fsl_ddr_interactive(pinfo, 1); 6395614e71bSYork Sun } else 6405614e71bSYork Sun #endif 6411d71efbbSYork Sun total_memory = fsl_ddr_compute(pinfo, STEP_GET_SPD, 0); 6425614e71bSYork Sun 6435614e71bSYork Sun /* setup 3-way interleaving before enabling DDRC */ 6441d71efbbSYork Sun switch (pinfo->memctl_opts[first_ctrl].memctl_interleaving_mode) { 6455614e71bSYork Sun case FSL_DDR_3WAY_1KB_INTERLEAVING: 6465614e71bSYork Sun case FSL_DDR_3WAY_4KB_INTERLEAVING: 6475614e71bSYork Sun case FSL_DDR_3WAY_8KB_INTERLEAVING: 6485614e71bSYork Sun fsl_ddr_set_intl3r( 6491d71efbbSYork Sun pinfo->memctl_opts[first_ctrl]. 6501d71efbbSYork Sun memctl_interleaving_mode); 6515614e71bSYork Sun break; 6525614e71bSYork Sun default: 6535614e71bSYork Sun break; 6545614e71bSYork Sun } 6555614e71bSYork Sun 6565614e71bSYork Sun /* 6575614e71bSYork Sun * Program configuration registers. 6585614e71bSYork Sun * JEDEC specs requires clocks to be stable before deasserting reset 6595614e71bSYork Sun * for RDIMMs. Clocks start after chip select is enabled and clock 6605614e71bSYork Sun * control register is set. During step 1, all controllers have their 6615614e71bSYork Sun * registers set but not enabled. Step 2 proceeds after deasserting 6625614e71bSYork Sun * reset through board FPGA or GPIO. 6635614e71bSYork Sun * For non-registered DIMMs, initialization can go through but it is 6645614e71bSYork Sun * also OK to follow the same flow. 6655614e71bSYork Sun */ 6661d71efbbSYork Sun if (pinfo->board_need_mem_reset) 6671d71efbbSYork Sun deassert_reset = pinfo->board_need_mem_reset(); 6681d71efbbSYork Sun for (i = first_ctrl; i <= last_ctrl; i++) { 6691d71efbbSYork Sun if (pinfo->common_timing_params[i].all_dimms_registered) 6705614e71bSYork Sun deassert_reset = 1; 6715614e71bSYork Sun } 6721d71efbbSYork Sun for (i = first_ctrl; i <= last_ctrl; i++) { 6735614e71bSYork Sun debug("Programming controller %u\n", i); 6741d71efbbSYork Sun if (pinfo->common_timing_params[i].ndimms_present == 0) { 6755614e71bSYork Sun debug("No dimms present on controller %u; " 6765614e71bSYork Sun "skipping programming\n", i); 6775614e71bSYork Sun continue; 6785614e71bSYork Sun } 6795614e71bSYork Sun /* 6805614e71bSYork Sun * The following call with step = 1 returns before enabling 6815614e71bSYork Sun * the controller. It has to finish with step = 2 later. 6825614e71bSYork Sun */ 6831d71efbbSYork Sun fsl_ddr_set_memctl_regs(&(pinfo->fsl_ddr_config_reg[i]), i, 6845614e71bSYork Sun deassert_reset ? 1 : 0); 6855614e71bSYork Sun } 6865614e71bSYork Sun if (deassert_reset) { 6875614e71bSYork Sun /* Use board FPGA or GPIO to deassert reset signal */ 6881d71efbbSYork Sun if (pinfo->board_mem_de_reset) { 6895614e71bSYork Sun debug("Deasserting mem reset\n"); 6901d71efbbSYork Sun pinfo->board_mem_de_reset(); 6911d71efbbSYork Sun } else { 6921d71efbbSYork Sun debug("Deasserting mem reset missing\n"); 6931d71efbbSYork Sun } 6941d71efbbSYork Sun for (i = first_ctrl; i <= last_ctrl; i++) { 6955614e71bSYork Sun /* Call with step = 2 to continue initialization */ 6961d71efbbSYork Sun fsl_ddr_set_memctl_regs(&(pinfo->fsl_ddr_config_reg[i]), 6975614e71bSYork Sun i, 2); 6985614e71bSYork Sun } 6995614e71bSYork Sun } 7005614e71bSYork Sun 701e32d59a2SYork Sun #ifdef CONFIG_FSL_DDR_SYNC_REFRESH 702e32d59a2SYork Sun fsl_ddr_sync_memctl_refresh(first_ctrl, last_ctrl); 703e32d59a2SYork Sun #endif 704e32d59a2SYork Sun 7059ac4ffbdSYork Sun #ifdef CONFIG_PPC 7065614e71bSYork Sun /* program LAWs */ 7071d71efbbSYork Sun for (i = first_ctrl; i <= last_ctrl; i++) { 7081d71efbbSYork Sun if (pinfo->memctl_opts[i].memctl_interleaving) { 7091d71efbbSYork Sun switch (pinfo->memctl_opts[i]. 7101d71efbbSYork Sun memctl_interleaving_mode) { 7115614e71bSYork Sun case FSL_DDR_CACHE_LINE_INTERLEAVING: 7125614e71bSYork Sun case FSL_DDR_PAGE_INTERLEAVING: 7135614e71bSYork Sun case FSL_DDR_BANK_INTERLEAVING: 7145614e71bSYork Sun case FSL_DDR_SUPERBANK_INTERLEAVING: 7151d71efbbSYork Sun if (i % 2) 7161d71efbbSYork Sun break; 7175614e71bSYork Sun if (i == 0) { 7185614e71bSYork Sun law_memctl = LAW_TRGT_IF_DDR_INTRLV; 7191d71efbbSYork Sun fsl_ddr_set_lawbar( 7201d71efbbSYork Sun &pinfo->common_timing_params[i], 7215614e71bSYork Sun law_memctl, i); 7225614e71bSYork Sun } 7231d71efbbSYork Sun #if CONFIG_NUM_DDR_CONTROLLERS > 3 7241d71efbbSYork Sun else if (i == 2) { 7251d71efbbSYork Sun law_memctl = LAW_TRGT_IF_DDR_INTLV_34; 7261d71efbbSYork Sun fsl_ddr_set_lawbar( 7271d71efbbSYork Sun &pinfo->common_timing_params[i], 7281d71efbbSYork Sun law_memctl, i); 7291d71efbbSYork Sun } 7301d71efbbSYork Sun #endif 7315614e71bSYork Sun break; 7325614e71bSYork Sun case FSL_DDR_3WAY_1KB_INTERLEAVING: 7335614e71bSYork Sun case FSL_DDR_3WAY_4KB_INTERLEAVING: 7345614e71bSYork Sun case FSL_DDR_3WAY_8KB_INTERLEAVING: 7355614e71bSYork Sun law_memctl = LAW_TRGT_IF_DDR_INTLV_123; 7365614e71bSYork Sun if (i == 0) { 7371d71efbbSYork Sun fsl_ddr_set_lawbar( 7381d71efbbSYork Sun &pinfo->common_timing_params[i], 7395614e71bSYork Sun law_memctl, i); 7405614e71bSYork Sun } 7415614e71bSYork Sun break; 7425614e71bSYork Sun case FSL_DDR_4WAY_1KB_INTERLEAVING: 7435614e71bSYork Sun case FSL_DDR_4WAY_4KB_INTERLEAVING: 7445614e71bSYork Sun case FSL_DDR_4WAY_8KB_INTERLEAVING: 7455614e71bSYork Sun law_memctl = LAW_TRGT_IF_DDR_INTLV_1234; 7465614e71bSYork Sun if (i == 0) 7471d71efbbSYork Sun fsl_ddr_set_lawbar( 7481d71efbbSYork Sun &pinfo->common_timing_params[i], 7495614e71bSYork Sun law_memctl, i); 7505614e71bSYork Sun /* place holder for future 4-way interleaving */ 7515614e71bSYork Sun break; 7525614e71bSYork Sun default: 7535614e71bSYork Sun break; 7545614e71bSYork Sun } 7555614e71bSYork Sun } else { 7565614e71bSYork Sun switch (i) { 7575614e71bSYork Sun case 0: 7585614e71bSYork Sun law_memctl = LAW_TRGT_IF_DDR_1; 7595614e71bSYork Sun break; 7605614e71bSYork Sun case 1: 7615614e71bSYork Sun law_memctl = LAW_TRGT_IF_DDR_2; 7625614e71bSYork Sun break; 7635614e71bSYork Sun case 2: 7645614e71bSYork Sun law_memctl = LAW_TRGT_IF_DDR_3; 7655614e71bSYork Sun break; 7665614e71bSYork Sun case 3: 7675614e71bSYork Sun law_memctl = LAW_TRGT_IF_DDR_4; 7685614e71bSYork Sun break; 7695614e71bSYork Sun default: 7705614e71bSYork Sun break; 7715614e71bSYork Sun } 7721d71efbbSYork Sun fsl_ddr_set_lawbar(&pinfo->common_timing_params[i], 7735614e71bSYork Sun law_memctl, i); 7745614e71bSYork Sun } 7755614e71bSYork Sun } 7769ac4ffbdSYork Sun #endif 7775614e71bSYork Sun 7785614e71bSYork Sun debug("total_memory by %s = %llu\n", __func__, total_memory); 7795614e71bSYork Sun 7805614e71bSYork Sun #if !defined(CONFIG_PHYS_64BIT) 7815614e71bSYork Sun /* Check for 4G or more. Bad. */ 7821d71efbbSYork Sun if ((first_ctrl == 0) && (total_memory >= (1ull << 32))) { 7835614e71bSYork Sun puts("Detected "); 7845614e71bSYork Sun print_size(total_memory, " of memory\n"); 7855614e71bSYork Sun printf(" This U-Boot only supports < 4G of DDR\n"); 7865614e71bSYork Sun printf(" You could rebuild it with CONFIG_PHYS_64BIT\n"); 7875614e71bSYork Sun printf(" "); /* re-align to match init_func_ram print */ 7885614e71bSYork Sun total_memory = CONFIG_MAX_MEM_MAPPED; 7895614e71bSYork Sun } 7905614e71bSYork Sun #endif 7915614e71bSYork Sun 7925614e71bSYork Sun return total_memory; 7935614e71bSYork Sun } 7945614e71bSYork Sun 7955614e71bSYork Sun /* 7961d71efbbSYork Sun * fsl_ddr_sdram(void) -- this is the main function to be 7971d71efbbSYork Sun * called by initdram() in the board file. 7981d71efbbSYork Sun * 7991d71efbbSYork Sun * It returns amount of memory configured in bytes. 8001d71efbbSYork Sun */ 8011d71efbbSYork Sun phys_size_t fsl_ddr_sdram(void) 8021d71efbbSYork Sun { 8031d71efbbSYork Sun fsl_ddr_info_t info; 8041d71efbbSYork Sun 8051d71efbbSYork Sun /* Reset info structure. */ 8061d71efbbSYork Sun memset(&info, 0, sizeof(fsl_ddr_info_t)); 8071d71efbbSYork Sun info.mem_base = CONFIG_SYS_FSL_DDR_SDRAM_BASE_PHY; 8081d71efbbSYork Sun info.first_ctrl = 0; 8091d71efbbSYork Sun info.num_ctrls = CONFIG_SYS_FSL_DDR_MAIN_NUM_CTRLS; 8101d71efbbSYork Sun info.dimm_slots_per_ctrl = CONFIG_DIMM_SLOTS_PER_CTLR; 8111d71efbbSYork Sun info.board_need_mem_reset = board_need_mem_reset; 8121d71efbbSYork Sun info.board_mem_reset = board_assert_mem_reset; 8131d71efbbSYork Sun info.board_mem_de_reset = board_deassert_mem_reset; 81461bd2f75SYork Sun remove_unused_controllers(&info); 8151d71efbbSYork Sun 8161d71efbbSYork Sun return __fsl_ddr_sdram(&info); 8171d71efbbSYork Sun } 8181d71efbbSYork Sun 8191d71efbbSYork Sun #ifdef CONFIG_SYS_FSL_OTHER_DDR_NUM_CTRLS 8201d71efbbSYork Sun phys_size_t fsl_other_ddr_sdram(unsigned long long base, 8211d71efbbSYork Sun unsigned int first_ctrl, 8221d71efbbSYork Sun unsigned int num_ctrls, 8231d71efbbSYork Sun unsigned int dimm_slots_per_ctrl, 8241d71efbbSYork Sun int (*board_need_reset)(void), 8251d71efbbSYork Sun void (*board_reset)(void), 8261d71efbbSYork Sun void (*board_de_reset)(void)) 8271d71efbbSYork Sun { 8281d71efbbSYork Sun fsl_ddr_info_t info; 8291d71efbbSYork Sun 8301d71efbbSYork Sun /* Reset info structure. */ 8311d71efbbSYork Sun memset(&info, 0, sizeof(fsl_ddr_info_t)); 8321d71efbbSYork Sun info.mem_base = base; 8331d71efbbSYork Sun info.first_ctrl = first_ctrl; 8341d71efbbSYork Sun info.num_ctrls = num_ctrls; 8351d71efbbSYork Sun info.dimm_slots_per_ctrl = dimm_slots_per_ctrl; 8361d71efbbSYork Sun info.board_need_mem_reset = board_need_reset; 8371d71efbbSYork Sun info.board_mem_reset = board_reset; 8381d71efbbSYork Sun info.board_mem_de_reset = board_de_reset; 8391d71efbbSYork Sun 8401d71efbbSYork Sun return __fsl_ddr_sdram(&info); 8411d71efbbSYork Sun } 8421d71efbbSYork Sun #endif 8431d71efbbSYork Sun 8441d71efbbSYork Sun /* 8451d71efbbSYork Sun * fsl_ddr_sdram_size(first_ctrl, last_intlv) - This function only returns the 8461d71efbbSYork Sun * size of the total memory without setting ddr control registers. 8475614e71bSYork Sun */ 8485614e71bSYork Sun phys_size_t 8495614e71bSYork Sun fsl_ddr_sdram_size(void) 8505614e71bSYork Sun { 8515614e71bSYork Sun fsl_ddr_info_t info; 8525614e71bSYork Sun unsigned long long total_memory = 0; 8535614e71bSYork Sun 8545614e71bSYork Sun memset(&info, 0 , sizeof(fsl_ddr_info_t)); 8551d71efbbSYork Sun info.mem_base = CONFIG_SYS_FSL_DDR_SDRAM_BASE_PHY; 8561d71efbbSYork Sun info.first_ctrl = 0; 8571d71efbbSYork Sun info.num_ctrls = CONFIG_SYS_FSL_DDR_MAIN_NUM_CTRLS; 8581d71efbbSYork Sun info.dimm_slots_per_ctrl = CONFIG_DIMM_SLOTS_PER_CTLR; 8591d71efbbSYork Sun info.board_need_mem_reset = NULL; 860*81dfdee0SEd Swarthout remove_unused_controllers(&info); 8615614e71bSYork Sun 8625614e71bSYork Sun /* Compute it once normally. */ 8635614e71bSYork Sun total_memory = fsl_ddr_compute(&info, STEP_GET_SPD, 1); 8645614e71bSYork Sun 8655614e71bSYork Sun return total_memory; 8665614e71bSYork Sun } 867