15614e71bSYork Sun /* 234e026f9SYork Sun * Copyright 2008, 2010-2014 Freescale Semiconductor, Inc. 35614e71bSYork Sun * 45614e71bSYork Sun * SPDX-License-Identifier: GPL-2.0+ 55614e71bSYork Sun */ 65614e71bSYork Sun 75614e71bSYork Sun #include <common.h> 85614e71bSYork Sun #include <hwconfig.h> 95614e71bSYork Sun #include <fsl_ddr_sdram.h> 105614e71bSYork Sun 115614e71bSYork Sun #include <fsl_ddr.h> 125614e71bSYork Sun 135614e71bSYork Sun /* 145614e71bSYork Sun * Use our own stack based buffer before relocation to allow accessing longer 155614e71bSYork Sun * hwconfig strings that might be in the environment before we've relocated. 165614e71bSYork Sun * This is pretty fragile on both the use of stack and if the buffer is big 175614e71bSYork Sun * enough. However we will get a warning from getenv_f for the later. 185614e71bSYork Sun */ 195614e71bSYork Sun 205614e71bSYork Sun /* Board-specific functions defined in each board's ddr.c */ 215614e71bSYork Sun extern void fsl_ddr_board_options(memctl_options_t *popts, 225614e71bSYork Sun dimm_params_t *pdimm, 235614e71bSYork Sun unsigned int ctrl_num); 245614e71bSYork Sun 255614e71bSYork Sun struct dynamic_odt { 265614e71bSYork Sun unsigned int odt_rd_cfg; 275614e71bSYork Sun unsigned int odt_wr_cfg; 285614e71bSYork Sun unsigned int odt_rtt_norm; 295614e71bSYork Sun unsigned int odt_rtt_wr; 305614e71bSYork Sun }; 315614e71bSYork Sun 3234e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 335614e71bSYork Sun static const struct dynamic_odt single_Q[4] = { 345614e71bSYork Sun { /* cs0 */ 355614e71bSYork Sun FSL_DDR_ODT_NEVER, 365614e71bSYork Sun FSL_DDR_ODT_CS_AND_OTHER_DIMM, 375614e71bSYork Sun DDR3_RTT_20_OHM, 385614e71bSYork Sun DDR3_RTT_120_OHM 395614e71bSYork Sun }, 405614e71bSYork Sun { /* cs1 */ 415614e71bSYork Sun FSL_DDR_ODT_NEVER, 425614e71bSYork Sun FSL_DDR_ODT_NEVER, /* tied high */ 435614e71bSYork Sun DDR3_RTT_OFF, 445614e71bSYork Sun DDR3_RTT_120_OHM 455614e71bSYork Sun }, 465614e71bSYork Sun { /* cs2 */ 475614e71bSYork Sun FSL_DDR_ODT_NEVER, 485614e71bSYork Sun FSL_DDR_ODT_CS_AND_OTHER_DIMM, 495614e71bSYork Sun DDR3_RTT_20_OHM, 505614e71bSYork Sun DDR3_RTT_120_OHM 515614e71bSYork Sun }, 525614e71bSYork Sun { /* cs3 */ 535614e71bSYork Sun FSL_DDR_ODT_NEVER, 545614e71bSYork Sun FSL_DDR_ODT_NEVER, /* tied high */ 555614e71bSYork Sun DDR3_RTT_OFF, 565614e71bSYork Sun DDR3_RTT_120_OHM 575614e71bSYork Sun } 585614e71bSYork Sun }; 595614e71bSYork Sun 605614e71bSYork Sun static const struct dynamic_odt single_D[4] = { 615614e71bSYork Sun { /* cs0 */ 625614e71bSYork Sun FSL_DDR_ODT_NEVER, 635614e71bSYork Sun FSL_DDR_ODT_ALL, 645614e71bSYork Sun DDR3_RTT_40_OHM, 655614e71bSYork Sun DDR3_RTT_OFF 665614e71bSYork Sun }, 675614e71bSYork Sun { /* cs1 */ 685614e71bSYork Sun FSL_DDR_ODT_NEVER, 695614e71bSYork Sun FSL_DDR_ODT_NEVER, 705614e71bSYork Sun DDR3_RTT_OFF, 715614e71bSYork Sun DDR3_RTT_OFF 725614e71bSYork Sun }, 735614e71bSYork Sun {0, 0, 0, 0}, 745614e71bSYork Sun {0, 0, 0, 0} 755614e71bSYork Sun }; 765614e71bSYork Sun 775614e71bSYork Sun static const struct dynamic_odt single_S[4] = { 785614e71bSYork Sun { /* cs0 */ 795614e71bSYork Sun FSL_DDR_ODT_NEVER, 805614e71bSYork Sun FSL_DDR_ODT_ALL, 815614e71bSYork Sun DDR3_RTT_40_OHM, 825614e71bSYork Sun DDR3_RTT_OFF 835614e71bSYork Sun }, 845614e71bSYork Sun {0, 0, 0, 0}, 855614e71bSYork Sun {0, 0, 0, 0}, 865614e71bSYork Sun {0, 0, 0, 0}, 875614e71bSYork Sun }; 885614e71bSYork Sun 895614e71bSYork Sun static const struct dynamic_odt dual_DD[4] = { 905614e71bSYork Sun { /* cs0 */ 915614e71bSYork Sun FSL_DDR_ODT_NEVER, 925614e71bSYork Sun FSL_DDR_ODT_SAME_DIMM, 935614e71bSYork Sun DDR3_RTT_120_OHM, 945614e71bSYork Sun DDR3_RTT_OFF 955614e71bSYork Sun }, 965614e71bSYork Sun { /* cs1 */ 975614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 985614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 995614e71bSYork Sun DDR3_RTT_30_OHM, 1005614e71bSYork Sun DDR3_RTT_OFF 1015614e71bSYork Sun }, 1025614e71bSYork Sun { /* cs2 */ 1035614e71bSYork Sun FSL_DDR_ODT_NEVER, 1045614e71bSYork Sun FSL_DDR_ODT_SAME_DIMM, 1055614e71bSYork Sun DDR3_RTT_120_OHM, 1065614e71bSYork Sun DDR3_RTT_OFF 1075614e71bSYork Sun }, 1085614e71bSYork Sun { /* cs3 */ 1095614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 1105614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 1115614e71bSYork Sun DDR3_RTT_30_OHM, 1125614e71bSYork Sun DDR3_RTT_OFF 1135614e71bSYork Sun } 1145614e71bSYork Sun }; 1155614e71bSYork Sun 1165614e71bSYork Sun static const struct dynamic_odt dual_DS[4] = { 1175614e71bSYork Sun { /* cs0 */ 1185614e71bSYork Sun FSL_DDR_ODT_NEVER, 1195614e71bSYork Sun FSL_DDR_ODT_SAME_DIMM, 1205614e71bSYork Sun DDR3_RTT_120_OHM, 1215614e71bSYork Sun DDR3_RTT_OFF 1225614e71bSYork Sun }, 1235614e71bSYork Sun { /* cs1 */ 1245614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 1255614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 1265614e71bSYork Sun DDR3_RTT_30_OHM, 1275614e71bSYork Sun DDR3_RTT_OFF 1285614e71bSYork Sun }, 1295614e71bSYork Sun { /* cs2 */ 1305614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 1315614e71bSYork Sun FSL_DDR_ODT_ALL, 1325614e71bSYork Sun DDR3_RTT_20_OHM, 1335614e71bSYork Sun DDR3_RTT_120_OHM 1345614e71bSYork Sun }, 1355614e71bSYork Sun {0, 0, 0, 0} 1365614e71bSYork Sun }; 1375614e71bSYork Sun static const struct dynamic_odt dual_SD[4] = { 1385614e71bSYork Sun { /* cs0 */ 1395614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 1405614e71bSYork Sun FSL_DDR_ODT_ALL, 1415614e71bSYork Sun DDR3_RTT_20_OHM, 1425614e71bSYork Sun DDR3_RTT_120_OHM 1435614e71bSYork Sun }, 1445614e71bSYork Sun {0, 0, 0, 0}, 1455614e71bSYork Sun { /* cs2 */ 1465614e71bSYork Sun FSL_DDR_ODT_NEVER, 1475614e71bSYork Sun FSL_DDR_ODT_SAME_DIMM, 1485614e71bSYork Sun DDR3_RTT_120_OHM, 1495614e71bSYork Sun DDR3_RTT_OFF 1505614e71bSYork Sun }, 1515614e71bSYork Sun { /* cs3 */ 1525614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 1535614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 1545614e71bSYork Sun DDR3_RTT_20_OHM, 1555614e71bSYork Sun DDR3_RTT_OFF 1565614e71bSYork Sun } 1575614e71bSYork Sun }; 1585614e71bSYork Sun 1595614e71bSYork Sun static const struct dynamic_odt dual_SS[4] = { 1605614e71bSYork Sun { /* cs0 */ 1615614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 1625614e71bSYork Sun FSL_DDR_ODT_ALL, 1635614e71bSYork Sun DDR3_RTT_30_OHM, 1645614e71bSYork Sun DDR3_RTT_120_OHM 1655614e71bSYork Sun }, 1665614e71bSYork Sun {0, 0, 0, 0}, 1675614e71bSYork Sun { /* cs2 */ 1685614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 1695614e71bSYork Sun FSL_DDR_ODT_ALL, 1705614e71bSYork Sun DDR3_RTT_30_OHM, 1715614e71bSYork Sun DDR3_RTT_120_OHM 1725614e71bSYork Sun }, 1735614e71bSYork Sun {0, 0, 0, 0} 1745614e71bSYork Sun }; 1755614e71bSYork Sun 1765614e71bSYork Sun static const struct dynamic_odt dual_D0[4] = { 1775614e71bSYork Sun { /* cs0 */ 1785614e71bSYork Sun FSL_DDR_ODT_NEVER, 1795614e71bSYork Sun FSL_DDR_ODT_SAME_DIMM, 1805614e71bSYork Sun DDR3_RTT_40_OHM, 1815614e71bSYork Sun DDR3_RTT_OFF 1825614e71bSYork Sun }, 1835614e71bSYork Sun { /* cs1 */ 1845614e71bSYork Sun FSL_DDR_ODT_NEVER, 1855614e71bSYork Sun FSL_DDR_ODT_NEVER, 1865614e71bSYork Sun DDR3_RTT_OFF, 1875614e71bSYork Sun DDR3_RTT_OFF 1885614e71bSYork Sun }, 1895614e71bSYork Sun {0, 0, 0, 0}, 1905614e71bSYork Sun {0, 0, 0, 0} 1915614e71bSYork Sun }; 1925614e71bSYork Sun 1935614e71bSYork Sun static const struct dynamic_odt dual_0D[4] = { 1945614e71bSYork Sun {0, 0, 0, 0}, 1955614e71bSYork Sun {0, 0, 0, 0}, 1965614e71bSYork Sun { /* cs2 */ 1975614e71bSYork Sun FSL_DDR_ODT_NEVER, 1985614e71bSYork Sun FSL_DDR_ODT_SAME_DIMM, 1995614e71bSYork Sun DDR3_RTT_40_OHM, 2005614e71bSYork Sun DDR3_RTT_OFF 2015614e71bSYork Sun }, 2025614e71bSYork Sun { /* cs3 */ 2035614e71bSYork Sun FSL_DDR_ODT_NEVER, 2045614e71bSYork Sun FSL_DDR_ODT_NEVER, 2055614e71bSYork Sun DDR3_RTT_OFF, 2065614e71bSYork Sun DDR3_RTT_OFF 2075614e71bSYork Sun } 2085614e71bSYork Sun }; 2095614e71bSYork Sun 2105614e71bSYork Sun static const struct dynamic_odt dual_S0[4] = { 2115614e71bSYork Sun { /* cs0 */ 2125614e71bSYork Sun FSL_DDR_ODT_NEVER, 2135614e71bSYork Sun FSL_DDR_ODT_CS, 2145614e71bSYork Sun DDR3_RTT_40_OHM, 2155614e71bSYork Sun DDR3_RTT_OFF 2165614e71bSYork Sun }, 2175614e71bSYork Sun {0, 0, 0, 0}, 2185614e71bSYork Sun {0, 0, 0, 0}, 2195614e71bSYork Sun {0, 0, 0, 0} 2205614e71bSYork Sun 2215614e71bSYork Sun }; 2225614e71bSYork Sun 2235614e71bSYork Sun static const struct dynamic_odt dual_0S[4] = { 2245614e71bSYork Sun {0, 0, 0, 0}, 2255614e71bSYork Sun {0, 0, 0, 0}, 2265614e71bSYork Sun { /* cs2 */ 2275614e71bSYork Sun FSL_DDR_ODT_NEVER, 2285614e71bSYork Sun FSL_DDR_ODT_CS, 2295614e71bSYork Sun DDR3_RTT_40_OHM, 2305614e71bSYork Sun DDR3_RTT_OFF 2315614e71bSYork Sun }, 2325614e71bSYork Sun {0, 0, 0, 0} 2335614e71bSYork Sun 2345614e71bSYork Sun }; 2355614e71bSYork Sun 2365614e71bSYork Sun static const struct dynamic_odt odt_unknown[4] = { 2375614e71bSYork Sun { /* cs0 */ 2385614e71bSYork Sun FSL_DDR_ODT_NEVER, 2395614e71bSYork Sun FSL_DDR_ODT_CS, 2405614e71bSYork Sun DDR3_RTT_120_OHM, 2415614e71bSYork Sun DDR3_RTT_OFF 2425614e71bSYork Sun }, 2435614e71bSYork Sun { /* cs1 */ 2445614e71bSYork Sun FSL_DDR_ODT_NEVER, 2455614e71bSYork Sun FSL_DDR_ODT_CS, 2465614e71bSYork Sun DDR3_RTT_120_OHM, 2475614e71bSYork Sun DDR3_RTT_OFF 2485614e71bSYork Sun }, 2495614e71bSYork Sun { /* cs2 */ 2505614e71bSYork Sun FSL_DDR_ODT_NEVER, 2515614e71bSYork Sun FSL_DDR_ODT_CS, 2525614e71bSYork Sun DDR3_RTT_120_OHM, 2535614e71bSYork Sun DDR3_RTT_OFF 2545614e71bSYork Sun }, 2555614e71bSYork Sun { /* cs3 */ 2565614e71bSYork Sun FSL_DDR_ODT_NEVER, 2575614e71bSYork Sun FSL_DDR_ODT_CS, 2585614e71bSYork Sun DDR3_RTT_120_OHM, 2595614e71bSYork Sun DDR3_RTT_OFF 2605614e71bSYork Sun } 2615614e71bSYork Sun }; 26234e026f9SYork Sun #else /* CONFIG_SYS_FSL_DDR3 || CONFIG_SYS_FSL_DDR4 */ 2635614e71bSYork Sun static const struct dynamic_odt single_Q[4] = { 2645614e71bSYork Sun {0, 0, 0, 0}, 2655614e71bSYork Sun {0, 0, 0, 0}, 2665614e71bSYork Sun {0, 0, 0, 0}, 2675614e71bSYork Sun {0, 0, 0, 0} 2685614e71bSYork Sun }; 2695614e71bSYork Sun 2705614e71bSYork Sun static const struct dynamic_odt single_D[4] = { 2715614e71bSYork Sun { /* cs0 */ 2725614e71bSYork Sun FSL_DDR_ODT_NEVER, 2735614e71bSYork Sun FSL_DDR_ODT_ALL, 2745614e71bSYork Sun DDR2_RTT_150_OHM, 2755614e71bSYork Sun DDR2_RTT_OFF 2765614e71bSYork Sun }, 2775614e71bSYork Sun { /* cs1 */ 2785614e71bSYork Sun FSL_DDR_ODT_NEVER, 2795614e71bSYork Sun FSL_DDR_ODT_NEVER, 2805614e71bSYork Sun DDR2_RTT_OFF, 2815614e71bSYork Sun DDR2_RTT_OFF 2825614e71bSYork Sun }, 2835614e71bSYork Sun {0, 0, 0, 0}, 2845614e71bSYork Sun {0, 0, 0, 0} 2855614e71bSYork Sun }; 2865614e71bSYork Sun 2875614e71bSYork Sun static const struct dynamic_odt single_S[4] = { 2885614e71bSYork Sun { /* cs0 */ 2895614e71bSYork Sun FSL_DDR_ODT_NEVER, 2905614e71bSYork Sun FSL_DDR_ODT_ALL, 2915614e71bSYork Sun DDR2_RTT_150_OHM, 2925614e71bSYork Sun DDR2_RTT_OFF 2935614e71bSYork Sun }, 2945614e71bSYork Sun {0, 0, 0, 0}, 2955614e71bSYork Sun {0, 0, 0, 0}, 2965614e71bSYork Sun {0, 0, 0, 0}, 2975614e71bSYork Sun }; 2985614e71bSYork Sun 2995614e71bSYork Sun static const struct dynamic_odt dual_DD[4] = { 3005614e71bSYork Sun { /* cs0 */ 3015614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3025614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3035614e71bSYork Sun DDR2_RTT_75_OHM, 3045614e71bSYork Sun DDR2_RTT_OFF 3055614e71bSYork Sun }, 3065614e71bSYork Sun { /* cs1 */ 3075614e71bSYork Sun FSL_DDR_ODT_NEVER, 3085614e71bSYork Sun FSL_DDR_ODT_NEVER, 3095614e71bSYork Sun DDR2_RTT_OFF, 3105614e71bSYork Sun DDR2_RTT_OFF 3115614e71bSYork Sun }, 3125614e71bSYork Sun { /* cs2 */ 3135614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3145614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3155614e71bSYork Sun DDR2_RTT_75_OHM, 3165614e71bSYork Sun DDR2_RTT_OFF 3175614e71bSYork Sun }, 3185614e71bSYork Sun { /* cs3 */ 3195614e71bSYork Sun FSL_DDR_ODT_NEVER, 3205614e71bSYork Sun FSL_DDR_ODT_NEVER, 3215614e71bSYork Sun DDR2_RTT_OFF, 3225614e71bSYork Sun DDR2_RTT_OFF 3235614e71bSYork Sun } 3245614e71bSYork Sun }; 3255614e71bSYork Sun 3265614e71bSYork Sun static const struct dynamic_odt dual_DS[4] = { 3275614e71bSYork Sun { /* cs0 */ 3285614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3295614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3305614e71bSYork Sun DDR2_RTT_75_OHM, 3315614e71bSYork Sun DDR2_RTT_OFF 3325614e71bSYork Sun }, 3335614e71bSYork Sun { /* cs1 */ 3345614e71bSYork Sun FSL_DDR_ODT_NEVER, 3355614e71bSYork Sun FSL_DDR_ODT_NEVER, 3365614e71bSYork Sun DDR2_RTT_OFF, 3375614e71bSYork Sun DDR2_RTT_OFF 3385614e71bSYork Sun }, 3395614e71bSYork Sun { /* cs2 */ 3405614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3415614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3425614e71bSYork Sun DDR2_RTT_75_OHM, 3435614e71bSYork Sun DDR2_RTT_OFF 3445614e71bSYork Sun }, 3455614e71bSYork Sun {0, 0, 0, 0} 3465614e71bSYork Sun }; 3475614e71bSYork Sun 3485614e71bSYork Sun static const struct dynamic_odt dual_SD[4] = { 3495614e71bSYork Sun { /* cs0 */ 3505614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3515614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3525614e71bSYork Sun DDR2_RTT_75_OHM, 3535614e71bSYork Sun DDR2_RTT_OFF 3545614e71bSYork Sun }, 3555614e71bSYork Sun {0, 0, 0, 0}, 3565614e71bSYork Sun { /* cs2 */ 3575614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3585614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3595614e71bSYork Sun DDR2_RTT_75_OHM, 3605614e71bSYork Sun DDR2_RTT_OFF 3615614e71bSYork Sun }, 3625614e71bSYork Sun { /* cs3 */ 3635614e71bSYork Sun FSL_DDR_ODT_NEVER, 3645614e71bSYork Sun FSL_DDR_ODT_NEVER, 3655614e71bSYork Sun DDR2_RTT_OFF, 3665614e71bSYork Sun DDR2_RTT_OFF 3675614e71bSYork Sun } 3685614e71bSYork Sun }; 3695614e71bSYork Sun 3705614e71bSYork Sun static const struct dynamic_odt dual_SS[4] = { 3715614e71bSYork Sun { /* cs0 */ 3725614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3735614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3745614e71bSYork Sun DDR2_RTT_75_OHM, 3755614e71bSYork Sun DDR2_RTT_OFF 3765614e71bSYork Sun }, 3775614e71bSYork Sun {0, 0, 0, 0}, 3785614e71bSYork Sun { /* cs2 */ 3795614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3805614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3815614e71bSYork Sun DDR2_RTT_75_OHM, 3825614e71bSYork Sun DDR2_RTT_OFF 3835614e71bSYork Sun }, 3845614e71bSYork Sun {0, 0, 0, 0} 3855614e71bSYork Sun }; 3865614e71bSYork Sun 3875614e71bSYork Sun static const struct dynamic_odt dual_D0[4] = { 3885614e71bSYork Sun { /* cs0 */ 3895614e71bSYork Sun FSL_DDR_ODT_NEVER, 3905614e71bSYork Sun FSL_DDR_ODT_ALL, 3915614e71bSYork Sun DDR2_RTT_150_OHM, 3925614e71bSYork Sun DDR2_RTT_OFF 3935614e71bSYork Sun }, 3945614e71bSYork Sun { /* cs1 */ 3955614e71bSYork Sun FSL_DDR_ODT_NEVER, 3965614e71bSYork Sun FSL_DDR_ODT_NEVER, 3975614e71bSYork Sun DDR2_RTT_OFF, 3985614e71bSYork Sun DDR2_RTT_OFF 3995614e71bSYork Sun }, 4005614e71bSYork Sun {0, 0, 0, 0}, 4015614e71bSYork Sun {0, 0, 0, 0} 4025614e71bSYork Sun }; 4035614e71bSYork Sun 4045614e71bSYork Sun static const struct dynamic_odt dual_0D[4] = { 4055614e71bSYork Sun {0, 0, 0, 0}, 4065614e71bSYork Sun {0, 0, 0, 0}, 4075614e71bSYork Sun { /* cs2 */ 4085614e71bSYork Sun FSL_DDR_ODT_NEVER, 4095614e71bSYork Sun FSL_DDR_ODT_ALL, 4105614e71bSYork Sun DDR2_RTT_150_OHM, 4115614e71bSYork Sun DDR2_RTT_OFF 4125614e71bSYork Sun }, 4135614e71bSYork Sun { /* cs3 */ 4145614e71bSYork Sun FSL_DDR_ODT_NEVER, 4155614e71bSYork Sun FSL_DDR_ODT_NEVER, 4165614e71bSYork Sun DDR2_RTT_OFF, 4175614e71bSYork Sun DDR2_RTT_OFF 4185614e71bSYork Sun } 4195614e71bSYork Sun }; 4205614e71bSYork Sun 4215614e71bSYork Sun static const struct dynamic_odt dual_S0[4] = { 4225614e71bSYork Sun { /* cs0 */ 4235614e71bSYork Sun FSL_DDR_ODT_NEVER, 4245614e71bSYork Sun FSL_DDR_ODT_CS, 4255614e71bSYork Sun DDR2_RTT_150_OHM, 4265614e71bSYork Sun DDR2_RTT_OFF 4275614e71bSYork Sun }, 4285614e71bSYork Sun {0, 0, 0, 0}, 4295614e71bSYork Sun {0, 0, 0, 0}, 4305614e71bSYork Sun {0, 0, 0, 0} 4315614e71bSYork Sun 4325614e71bSYork Sun }; 4335614e71bSYork Sun 4345614e71bSYork Sun static const struct dynamic_odt dual_0S[4] = { 4355614e71bSYork Sun {0, 0, 0, 0}, 4365614e71bSYork Sun {0, 0, 0, 0}, 4375614e71bSYork Sun { /* cs2 */ 4385614e71bSYork Sun FSL_DDR_ODT_NEVER, 4395614e71bSYork Sun FSL_DDR_ODT_CS, 4405614e71bSYork Sun DDR2_RTT_150_OHM, 4415614e71bSYork Sun DDR2_RTT_OFF 4425614e71bSYork Sun }, 4435614e71bSYork Sun {0, 0, 0, 0} 4445614e71bSYork Sun 4455614e71bSYork Sun }; 4465614e71bSYork Sun 4475614e71bSYork Sun static const struct dynamic_odt odt_unknown[4] = { 4485614e71bSYork Sun { /* cs0 */ 4495614e71bSYork Sun FSL_DDR_ODT_NEVER, 4505614e71bSYork Sun FSL_DDR_ODT_CS, 4515614e71bSYork Sun DDR2_RTT_75_OHM, 4525614e71bSYork Sun DDR2_RTT_OFF 4535614e71bSYork Sun }, 4545614e71bSYork Sun { /* cs1 */ 4555614e71bSYork Sun FSL_DDR_ODT_NEVER, 4565614e71bSYork Sun FSL_DDR_ODT_NEVER, 4575614e71bSYork Sun DDR2_RTT_OFF, 4585614e71bSYork Sun DDR2_RTT_OFF 4595614e71bSYork Sun }, 4605614e71bSYork Sun { /* cs2 */ 4615614e71bSYork Sun FSL_DDR_ODT_NEVER, 4625614e71bSYork Sun FSL_DDR_ODT_CS, 4635614e71bSYork Sun DDR2_RTT_75_OHM, 4645614e71bSYork Sun DDR2_RTT_OFF 4655614e71bSYork Sun }, 4665614e71bSYork Sun { /* cs3 */ 4675614e71bSYork Sun FSL_DDR_ODT_NEVER, 4685614e71bSYork Sun FSL_DDR_ODT_NEVER, 4695614e71bSYork Sun DDR2_RTT_OFF, 4705614e71bSYork Sun DDR2_RTT_OFF 4715614e71bSYork Sun } 4725614e71bSYork Sun }; 4735614e71bSYork Sun #endif 4745614e71bSYork Sun 4755614e71bSYork Sun /* 4765614e71bSYork Sun * Automatically seleect bank interleaving mode based on DIMMs 4775614e71bSYork Sun * in this order: cs0_cs1_cs2_cs3, cs0_cs1, null. 4785614e71bSYork Sun * This function only deal with one or two slots per controller. 4795614e71bSYork Sun */ 4805614e71bSYork Sun static inline unsigned int auto_bank_intlv(dimm_params_t *pdimm) 4815614e71bSYork Sun { 4825614e71bSYork Sun #if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) 4835614e71bSYork Sun if (pdimm[0].n_ranks == 4) 4845614e71bSYork Sun return FSL_DDR_CS0_CS1_CS2_CS3; 4855614e71bSYork Sun else if (pdimm[0].n_ranks == 2) 4865614e71bSYork Sun return FSL_DDR_CS0_CS1; 4875614e71bSYork Sun #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) 4885614e71bSYork Sun #ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE 4895614e71bSYork Sun if (pdimm[0].n_ranks == 4) 4905614e71bSYork Sun return FSL_DDR_CS0_CS1_CS2_CS3; 4915614e71bSYork Sun #endif 4925614e71bSYork Sun if (pdimm[0].n_ranks == 2) { 4935614e71bSYork Sun if (pdimm[1].n_ranks == 2) 4945614e71bSYork Sun return FSL_DDR_CS0_CS1_CS2_CS3; 4955614e71bSYork Sun else 4965614e71bSYork Sun return FSL_DDR_CS0_CS1; 4975614e71bSYork Sun } 4985614e71bSYork Sun #endif 4995614e71bSYork Sun return 0; 5005614e71bSYork Sun } 5015614e71bSYork Sun 5025614e71bSYork Sun unsigned int populate_memctl_options(int all_dimms_registered, 5035614e71bSYork Sun memctl_options_t *popts, 5045614e71bSYork Sun dimm_params_t *pdimm, 5055614e71bSYork Sun unsigned int ctrl_num) 5065614e71bSYork Sun { 5075614e71bSYork Sun unsigned int i; 5085614e71bSYork Sun char buffer[HWCONFIG_BUFFER_SIZE]; 5095614e71bSYork Sun char *buf = NULL; 51034e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || \ 51134e026f9SYork Sun defined(CONFIG_SYS_FSL_DDR2) || \ 51234e026f9SYork Sun defined(CONFIG_SYS_FSL_DDR4) 5135614e71bSYork Sun const struct dynamic_odt *pdodt = odt_unknown; 5145614e71bSYork Sun #endif 5155614e71bSYork Sun ulong ddr_freq; 5165614e71bSYork Sun 5175614e71bSYork Sun /* 5185614e71bSYork Sun * Extract hwconfig from environment since we have not properly setup 5195614e71bSYork Sun * the environment but need it for ddr config params 5205614e71bSYork Sun */ 5215614e71bSYork Sun if (getenv_f("hwconfig", buffer, sizeof(buffer)) > 0) 5225614e71bSYork Sun buf = buffer; 5235614e71bSYork Sun 52434e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || \ 52534e026f9SYork Sun defined(CONFIG_SYS_FSL_DDR2) || \ 52634e026f9SYork Sun defined(CONFIG_SYS_FSL_DDR4) 5275614e71bSYork Sun /* Chip select options. */ 528*349689b8SYork Sun #if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) 5295614e71bSYork Sun switch (pdimm[0].n_ranks) { 5305614e71bSYork Sun case 1: 5315614e71bSYork Sun pdodt = single_S; 5325614e71bSYork Sun break; 5335614e71bSYork Sun case 2: 5345614e71bSYork Sun pdodt = single_D; 5355614e71bSYork Sun break; 5365614e71bSYork Sun case 4: 5375614e71bSYork Sun pdodt = single_Q; 5385614e71bSYork Sun break; 5395614e71bSYork Sun } 540*349689b8SYork Sun #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) 5415614e71bSYork Sun switch (pdimm[0].n_ranks) { 5425614e71bSYork Sun #ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE 5435614e71bSYork Sun case 4: 5445614e71bSYork Sun pdodt = single_Q; 5455614e71bSYork Sun if (pdimm[1].n_ranks) 546*349689b8SYork Sun printf("Error: Quad- and Dual-rank DIMMs cannot be used together\n"); 5475614e71bSYork Sun break; 5485614e71bSYork Sun #endif 5495614e71bSYork Sun case 2: 5505614e71bSYork Sun switch (pdimm[1].n_ranks) { 5515614e71bSYork Sun case 2: 5525614e71bSYork Sun pdodt = dual_DD; 5535614e71bSYork Sun break; 5545614e71bSYork Sun case 1: 5555614e71bSYork Sun pdodt = dual_DS; 5565614e71bSYork Sun break; 5575614e71bSYork Sun case 0: 5585614e71bSYork Sun pdodt = dual_D0; 5595614e71bSYork Sun break; 5605614e71bSYork Sun } 5615614e71bSYork Sun break; 5625614e71bSYork Sun case 1: 5635614e71bSYork Sun switch (pdimm[1].n_ranks) { 5645614e71bSYork Sun case 2: 5655614e71bSYork Sun pdodt = dual_SD; 5665614e71bSYork Sun break; 5675614e71bSYork Sun case 1: 5685614e71bSYork Sun pdodt = dual_SS; 5695614e71bSYork Sun break; 5705614e71bSYork Sun case 0: 5715614e71bSYork Sun pdodt = dual_S0; 5725614e71bSYork Sun break; 5735614e71bSYork Sun } 5745614e71bSYork Sun break; 5755614e71bSYork Sun case 0: 5765614e71bSYork Sun switch (pdimm[1].n_ranks) { 5775614e71bSYork Sun case 2: 5785614e71bSYork Sun pdodt = dual_0D; 5795614e71bSYork Sun break; 5805614e71bSYork Sun case 1: 5815614e71bSYork Sun pdodt = dual_0S; 5825614e71bSYork Sun break; 5835614e71bSYork Sun } 5845614e71bSYork Sun break; 5855614e71bSYork Sun } 586*349689b8SYork Sun #endif /* CONFIG_DIMM_SLOTS_PER_CTLR */ 587*349689b8SYork Sun #endif /* CONFIG_SYS_FSL_DDR2, 3, 4 */ 5885614e71bSYork Sun 5895614e71bSYork Sun /* Pick chip-select local options. */ 5905614e71bSYork Sun for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 59134e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || \ 59234e026f9SYork Sun defined(CONFIG_SYS_FSL_DDR2) || \ 59334e026f9SYork Sun defined(CONFIG_SYS_FSL_DDR4) 5945614e71bSYork Sun popts->cs_local_opts[i].odt_rd_cfg = pdodt[i].odt_rd_cfg; 5955614e71bSYork Sun popts->cs_local_opts[i].odt_wr_cfg = pdodt[i].odt_wr_cfg; 5965614e71bSYork Sun popts->cs_local_opts[i].odt_rtt_norm = pdodt[i].odt_rtt_norm; 5975614e71bSYork Sun popts->cs_local_opts[i].odt_rtt_wr = pdodt[i].odt_rtt_wr; 5985614e71bSYork Sun #else 5995614e71bSYork Sun popts->cs_local_opts[i].odt_rd_cfg = FSL_DDR_ODT_NEVER; 6005614e71bSYork Sun popts->cs_local_opts[i].odt_wr_cfg = FSL_DDR_ODT_CS; 6015614e71bSYork Sun #endif 6025614e71bSYork Sun popts->cs_local_opts[i].auto_precharge = 0; 6035614e71bSYork Sun } 6045614e71bSYork Sun 6055614e71bSYork Sun /* Pick interleaving mode. */ 6065614e71bSYork Sun 6075614e71bSYork Sun /* 6085614e71bSYork Sun * 0 = no interleaving 6095614e71bSYork Sun * 1 = interleaving between 2 controllers 6105614e71bSYork Sun */ 6115614e71bSYork Sun popts->memctl_interleaving = 0; 6125614e71bSYork Sun 6135614e71bSYork Sun /* 6145614e71bSYork Sun * 0 = cacheline 6155614e71bSYork Sun * 1 = page 6165614e71bSYork Sun * 2 = (logical) bank 6175614e71bSYork Sun * 3 = superbank (only if CS interleaving is enabled) 6185614e71bSYork Sun */ 6195614e71bSYork Sun popts->memctl_interleaving_mode = 0; 6205614e71bSYork Sun 6215614e71bSYork Sun /* 6225614e71bSYork Sun * 0: cacheline: bit 30 of the 36-bit physical addr selects the memctl 6235614e71bSYork Sun * 1: page: bit to the left of the column bits selects the memctl 6245614e71bSYork Sun * 2: bank: bit to the left of the bank bits selects the memctl 6255614e71bSYork Sun * 3: superbank: bit to the left of the chip select selects the memctl 6265614e71bSYork Sun * 6275614e71bSYork Sun * NOTE: ba_intlv (rank interleaving) is independent of memory 6285614e71bSYork Sun * controller interleaving; it is only within a memory controller. 6295614e71bSYork Sun * Must use superbank interleaving if rank interleaving is used and 6305614e71bSYork Sun * memory controller interleaving is enabled. 6315614e71bSYork Sun */ 6325614e71bSYork Sun 6335614e71bSYork Sun /* 6345614e71bSYork Sun * 0 = no 6355614e71bSYork Sun * 0x40 = CS0,CS1 6365614e71bSYork Sun * 0x20 = CS2,CS3 6375614e71bSYork Sun * 0x60 = CS0,CS1 + CS2,CS3 6385614e71bSYork Sun * 0x04 = CS0,CS1,CS2,CS3 6395614e71bSYork Sun */ 6405614e71bSYork Sun popts->ba_intlv_ctl = 0; 6415614e71bSYork Sun 6425614e71bSYork Sun /* Memory Organization Parameters */ 6435614e71bSYork Sun popts->registered_dimm_en = all_dimms_registered; 6445614e71bSYork Sun 6455614e71bSYork Sun /* Operational Mode Paramters */ 6465614e71bSYork Sun 6475614e71bSYork Sun /* Pick ECC modes */ 6485614e71bSYork Sun popts->ecc_mode = 0; /* 0 = disabled, 1 = enabled */ 6495614e71bSYork Sun #ifdef CONFIG_DDR_ECC 6505614e71bSYork Sun if (hwconfig_sub_f("fsl_ddr", "ecc", buf)) { 6515614e71bSYork Sun if (hwconfig_subarg_cmp_f("fsl_ddr", "ecc", "on", buf)) 6525614e71bSYork Sun popts->ecc_mode = 1; 6535614e71bSYork Sun } else 6545614e71bSYork Sun popts->ecc_mode = 1; 6555614e71bSYork Sun #endif 6565614e71bSYork Sun popts->ecc_init_using_memctl = 1; /* 0 = use DMA, 1 = use memctl */ 6575614e71bSYork Sun 6585614e71bSYork Sun /* 6595614e71bSYork Sun * Choose DQS config 6605614e71bSYork Sun * 0 for DDR1 6615614e71bSYork Sun * 1 for DDR2 6625614e71bSYork Sun */ 6635614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) 6645614e71bSYork Sun popts->dqs_config = 0; 6655614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2) || defined(CONFIG_SYS_FSL_DDR3) 6665614e71bSYork Sun popts->dqs_config = 1; 6675614e71bSYork Sun #endif 6685614e71bSYork Sun 6695614e71bSYork Sun /* Choose self-refresh during sleep. */ 6705614e71bSYork Sun popts->self_refresh_in_sleep = 1; 6715614e71bSYork Sun 6725614e71bSYork Sun /* Choose dynamic power management mode. */ 6735614e71bSYork Sun popts->dynamic_power = 0; 6745614e71bSYork Sun 6755614e71bSYork Sun /* 6765614e71bSYork Sun * check first dimm for primary sdram width 6775614e71bSYork Sun * presuming all dimms are similar 6785614e71bSYork Sun * 0 = 64-bit, 1 = 32-bit, 2 = 16-bit 6795614e71bSYork Sun */ 6805614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2) 6815614e71bSYork Sun if (pdimm[0].n_ranks != 0) { 6825614e71bSYork Sun if ((pdimm[0].data_width >= 64) && \ 6835614e71bSYork Sun (pdimm[0].data_width <= 72)) 6845614e71bSYork Sun popts->data_bus_width = 0; 6855614e71bSYork Sun else if ((pdimm[0].data_width >= 32) || \ 6865614e71bSYork Sun (pdimm[0].data_width <= 40)) 6875614e71bSYork Sun popts->data_bus_width = 1; 6885614e71bSYork Sun else { 6895614e71bSYork Sun panic("Error: data width %u is invalid!\n", 6905614e71bSYork Sun pdimm[0].data_width); 6915614e71bSYork Sun } 6925614e71bSYork Sun } 6935614e71bSYork Sun #else 6945614e71bSYork Sun if (pdimm[0].n_ranks != 0) { 6955614e71bSYork Sun if (pdimm[0].primary_sdram_width == 64) 6965614e71bSYork Sun popts->data_bus_width = 0; 6975614e71bSYork Sun else if (pdimm[0].primary_sdram_width == 32) 6985614e71bSYork Sun popts->data_bus_width = 1; 6995614e71bSYork Sun else if (pdimm[0].primary_sdram_width == 16) 7005614e71bSYork Sun popts->data_bus_width = 2; 7015614e71bSYork Sun else { 7025614e71bSYork Sun panic("Error: primary sdram width %u is invalid!\n", 7035614e71bSYork Sun pdimm[0].primary_sdram_width); 7045614e71bSYork Sun } 7055614e71bSYork Sun } 7065614e71bSYork Sun #endif 7075614e71bSYork Sun 7085614e71bSYork Sun popts->x4_en = (pdimm[0].device_width == 4) ? 1 : 0; 7095614e71bSYork Sun 7105614e71bSYork Sun /* Choose burst length. */ 71134e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 7125614e71bSYork Sun #if defined(CONFIG_E500MC) 7135614e71bSYork Sun popts->otf_burst_chop_en = 0; /* on-the-fly burst chop disable */ 7145614e71bSYork Sun popts->burst_length = DDR_BL8; /* Fixed 8-beat burst len */ 7155614e71bSYork Sun #else 7165614e71bSYork Sun if ((popts->data_bus_width == 1) || (popts->data_bus_width == 2)) { 7175614e71bSYork Sun /* 32-bit or 16-bit bus */ 7185614e71bSYork Sun popts->otf_burst_chop_en = 0; 7195614e71bSYork Sun popts->burst_length = DDR_BL8; 7205614e71bSYork Sun } else { 7215614e71bSYork Sun popts->otf_burst_chop_en = 1; /* on-the-fly burst chop */ 7225614e71bSYork Sun popts->burst_length = DDR_OTF; /* on-the-fly BC4 and BL8 */ 7235614e71bSYork Sun } 7245614e71bSYork Sun #endif 7255614e71bSYork Sun #else 7265614e71bSYork Sun popts->burst_length = DDR_BL4; /* has to be 4 for DDR2 */ 7275614e71bSYork Sun #endif 7285614e71bSYork Sun 7295614e71bSYork Sun /* Choose ddr controller address mirror mode */ 73034e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 7315614e71bSYork Sun popts->mirrored_dimm = pdimm[0].mirrored_dimm; 7325614e71bSYork Sun #endif 7335614e71bSYork Sun 7345614e71bSYork Sun /* Global Timing Parameters. */ 7355614e71bSYork Sun debug("mclk_ps = %u ps\n", get_memory_clk_period_ps()); 7365614e71bSYork Sun 7375614e71bSYork Sun /* Pick a caslat override. */ 7385614e71bSYork Sun popts->cas_latency_override = 0; 7395614e71bSYork Sun popts->cas_latency_override_value = 3; 7405614e71bSYork Sun if (popts->cas_latency_override) { 7415614e71bSYork Sun debug("using caslat override value = %u\n", 7425614e71bSYork Sun popts->cas_latency_override_value); 7435614e71bSYork Sun } 7445614e71bSYork Sun 7455614e71bSYork Sun /* Decide whether to use the computed derated latency */ 7465614e71bSYork Sun popts->use_derated_caslat = 0; 7475614e71bSYork Sun 7485614e71bSYork Sun /* Choose an additive latency. */ 7495614e71bSYork Sun popts->additive_latency_override = 0; 7505614e71bSYork Sun popts->additive_latency_override_value = 3; 7515614e71bSYork Sun if (popts->additive_latency_override) { 7525614e71bSYork Sun debug("using additive latency override value = %u\n", 7535614e71bSYork Sun popts->additive_latency_override_value); 7545614e71bSYork Sun } 7555614e71bSYork Sun 7565614e71bSYork Sun /* 7575614e71bSYork Sun * 2T_EN setting 7585614e71bSYork Sun * 7595614e71bSYork Sun * Factors to consider for 2T_EN: 7605614e71bSYork Sun * - number of DIMMs installed 7615614e71bSYork Sun * - number of components, number of active ranks 7625614e71bSYork Sun * - how much time you want to spend playing around 7635614e71bSYork Sun */ 7645614e71bSYork Sun popts->twot_en = 0; 7655614e71bSYork Sun popts->threet_en = 0; 7665614e71bSYork Sun 7675614e71bSYork Sun /* for RDIMM, address parity enable */ 7685614e71bSYork Sun popts->ap_en = 1; 7695614e71bSYork Sun 7705614e71bSYork Sun /* 7715614e71bSYork Sun * BSTTOPRE precharge interval 7725614e71bSYork Sun * 7735614e71bSYork Sun * Set this to 0 for global auto precharge 77434e026f9SYork Sun * The value of 0x100 has been used for DDR1, DDR2, DDR3. 77534e026f9SYork Sun * It is not wrong. Any value should be OK. The performance depends on 77634e026f9SYork Sun * applications. There is no one good value for all. 7775614e71bSYork Sun */ 7785614e71bSYork Sun popts->bstopre = 0x100; 7795614e71bSYork Sun 7805614e71bSYork Sun /* Minimum CKE pulse width -- tCKE(MIN) */ 7815614e71bSYork Sun popts->tcke_clock_pulse_width_ps 7825614e71bSYork Sun = mclk_to_picos(FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR); 7835614e71bSYork Sun 7845614e71bSYork Sun /* 7855614e71bSYork Sun * Window for four activates -- tFAW 7865614e71bSYork Sun * 7875614e71bSYork Sun * FIXME: UM: applies only to DDR2/DDR3 with eight logical banks only 7885614e71bSYork Sun * FIXME: varies depending upon number of column addresses or data 7895614e71bSYork Sun * FIXME: width, was considering looking at pdimm->primary_sdram_width 7905614e71bSYork Sun */ 7915614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) 7925614e71bSYork Sun popts->tfaw_window_four_activates_ps = mclk_to_picos(1); 7935614e71bSYork Sun 7945614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2) 7955614e71bSYork Sun /* 7965614e71bSYork Sun * x4/x8; some datasheets have 35000 7975614e71bSYork Sun * x16 wide columns only? Use 50000? 7985614e71bSYork Sun */ 7995614e71bSYork Sun popts->tfaw_window_four_activates_ps = 37500; 8005614e71bSYork Sun 80134e026f9SYork Sun #else 8025614e71bSYork Sun popts->tfaw_window_four_activates_ps = pdimm[0].tfaw_ps; 8035614e71bSYork Sun #endif 8045614e71bSYork Sun popts->zq_en = 0; 8055614e71bSYork Sun popts->wrlvl_en = 0; 80634e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 8075614e71bSYork Sun /* 8085614e71bSYork Sun * due to ddr3 dimm is fly-by topology 8095614e71bSYork Sun * we suggest to enable write leveling to 8105614e71bSYork Sun * meet the tQDSS under different loading. 8115614e71bSYork Sun */ 8125614e71bSYork Sun popts->wrlvl_en = 1; 8135614e71bSYork Sun popts->zq_en = 1; 8145614e71bSYork Sun popts->wrlvl_override = 0; 8155614e71bSYork Sun #endif 8165614e71bSYork Sun 8175614e71bSYork Sun /* 8185614e71bSYork Sun * Check interleaving configuration from environment. 8195614e71bSYork Sun * Please refer to doc/README.fsl-ddr for the detail. 8205614e71bSYork Sun * 8215614e71bSYork Sun * If memory controller interleaving is enabled, then the data 8225614e71bSYork Sun * bus widths must be programmed identically for all memory controllers. 8235614e71bSYork Sun * 8246b1e1254SYork Sun * Attempt to set all controllers to the same chip select 8255614e71bSYork Sun * interleaving mode. It will do a best effort to get the 8265614e71bSYork Sun * requested ranks interleaved together such that the result 8275614e71bSYork Sun * should be a subset of the requested configuration. 8286b1e1254SYork Sun * 8296b1e1254SYork Sun * if CONFIG_SYS_FSL_DDR_INTLV_256B is defined, mandatory interleaving 8306b1e1254SYork Sun * with 256 Byte is enabled. 8315614e71bSYork Sun */ 8325614e71bSYork Sun #if (CONFIG_NUM_DDR_CONTROLLERS > 1) 8335614e71bSYork Sun if (!hwconfig_sub_f("fsl_ddr", "ctlr_intlv", buf)) 8346b1e1254SYork Sun #ifdef CONFIG_SYS_FSL_DDR_INTLV_256B 8356b1e1254SYork Sun ; 8366b1e1254SYork Sun #else 8375614e71bSYork Sun goto done; 8386b1e1254SYork Sun #endif 8395614e71bSYork Sun if (pdimm[0].n_ranks == 0) { 8405614e71bSYork Sun printf("There is no rank on CS0 for controller %d.\n", ctrl_num); 8415614e71bSYork Sun popts->memctl_interleaving = 0; 8425614e71bSYork Sun goto done; 8435614e71bSYork Sun } 8445614e71bSYork Sun popts->memctl_interleaving = 1; 8456b1e1254SYork Sun #ifdef CONFIG_SYS_FSL_DDR_INTLV_256B 8466b1e1254SYork Sun popts->memctl_interleaving_mode = FSL_DDR_256B_INTERLEAVING; 8476b1e1254SYork Sun popts->memctl_interleaving = 1; 8486b1e1254SYork Sun debug("256 Byte interleaving\n"); 849*349689b8SYork Sun #else 8505614e71bSYork Sun /* 8515614e71bSYork Sun * test null first. if CONFIG_HWCONFIG is not defined 8525614e71bSYork Sun * hwconfig_arg_cmp returns non-zero 8535614e71bSYork Sun */ 8545614e71bSYork Sun if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv", 8555614e71bSYork Sun "null", buf)) { 8565614e71bSYork Sun popts->memctl_interleaving = 0; 8575614e71bSYork Sun debug("memory controller interleaving disabled.\n"); 8585614e71bSYork Sun } else if (hwconfig_subarg_cmp_f("fsl_ddr", 8595614e71bSYork Sun "ctlr_intlv", 8605614e71bSYork Sun "cacheline", buf)) { 8615614e71bSYork Sun popts->memctl_interleaving_mode = 8625614e71bSYork Sun ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? 8635614e71bSYork Sun 0 : FSL_DDR_CACHE_LINE_INTERLEAVING; 8645614e71bSYork Sun popts->memctl_interleaving = 8655614e71bSYork Sun ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? 8665614e71bSYork Sun 0 : 1; 8675614e71bSYork Sun } else if (hwconfig_subarg_cmp_f("fsl_ddr", 8685614e71bSYork Sun "ctlr_intlv", 8695614e71bSYork Sun "page", buf)) { 8705614e71bSYork Sun popts->memctl_interleaving_mode = 8715614e71bSYork Sun ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? 8725614e71bSYork Sun 0 : FSL_DDR_PAGE_INTERLEAVING; 8735614e71bSYork Sun popts->memctl_interleaving = 8745614e71bSYork Sun ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? 8755614e71bSYork Sun 0 : 1; 8765614e71bSYork Sun } else if (hwconfig_subarg_cmp_f("fsl_ddr", 8775614e71bSYork Sun "ctlr_intlv", 8785614e71bSYork Sun "bank", buf)) { 8795614e71bSYork Sun popts->memctl_interleaving_mode = 8805614e71bSYork Sun ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? 8815614e71bSYork Sun 0 : FSL_DDR_BANK_INTERLEAVING; 8825614e71bSYork Sun popts->memctl_interleaving = 8835614e71bSYork Sun ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? 8845614e71bSYork Sun 0 : 1; 8855614e71bSYork Sun } else if (hwconfig_subarg_cmp_f("fsl_ddr", 8865614e71bSYork Sun "ctlr_intlv", 8875614e71bSYork Sun "superbank", buf)) { 8885614e71bSYork Sun popts->memctl_interleaving_mode = 8895614e71bSYork Sun ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? 8905614e71bSYork Sun 0 : FSL_DDR_SUPERBANK_INTERLEAVING; 8915614e71bSYork Sun popts->memctl_interleaving = 8925614e71bSYork Sun ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? 8935614e71bSYork Sun 0 : 1; 8945614e71bSYork Sun #if (CONFIG_NUM_DDR_CONTROLLERS == 3) 8955614e71bSYork Sun } else if (hwconfig_subarg_cmp_f("fsl_ddr", 8965614e71bSYork Sun "ctlr_intlv", 8975614e71bSYork Sun "3way_1KB", buf)) { 8985614e71bSYork Sun popts->memctl_interleaving_mode = 8995614e71bSYork Sun FSL_DDR_3WAY_1KB_INTERLEAVING; 9005614e71bSYork Sun } else if (hwconfig_subarg_cmp_f("fsl_ddr", 9015614e71bSYork Sun "ctlr_intlv", 9025614e71bSYork Sun "3way_4KB", buf)) { 9035614e71bSYork Sun popts->memctl_interleaving_mode = 9045614e71bSYork Sun FSL_DDR_3WAY_4KB_INTERLEAVING; 9055614e71bSYork Sun } else if (hwconfig_subarg_cmp_f("fsl_ddr", 9065614e71bSYork Sun "ctlr_intlv", 9075614e71bSYork Sun "3way_8KB", buf)) { 9085614e71bSYork Sun popts->memctl_interleaving_mode = 9095614e71bSYork Sun FSL_DDR_3WAY_8KB_INTERLEAVING; 9105614e71bSYork Sun #elif (CONFIG_NUM_DDR_CONTROLLERS == 4) 9115614e71bSYork Sun } else if (hwconfig_subarg_cmp_f("fsl_ddr", 9125614e71bSYork Sun "ctlr_intlv", 9135614e71bSYork Sun "4way_1KB", buf)) { 9145614e71bSYork Sun popts->memctl_interleaving_mode = 9155614e71bSYork Sun FSL_DDR_4WAY_1KB_INTERLEAVING; 9165614e71bSYork Sun } else if (hwconfig_subarg_cmp_f("fsl_ddr", 9175614e71bSYork Sun "ctlr_intlv", 9185614e71bSYork Sun "4way_4KB", buf)) { 9195614e71bSYork Sun popts->memctl_interleaving_mode = 9205614e71bSYork Sun FSL_DDR_4WAY_4KB_INTERLEAVING; 9215614e71bSYork Sun } else if (hwconfig_subarg_cmp_f("fsl_ddr", 9225614e71bSYork Sun "ctlr_intlv", 9235614e71bSYork Sun "4way_8KB", buf)) { 9245614e71bSYork Sun popts->memctl_interleaving_mode = 9255614e71bSYork Sun FSL_DDR_4WAY_8KB_INTERLEAVING; 9265614e71bSYork Sun #endif 9275614e71bSYork Sun } else { 9285614e71bSYork Sun popts->memctl_interleaving = 0; 9295614e71bSYork Sun printf("hwconfig has unrecognized parameter for ctlr_intlv.\n"); 9305614e71bSYork Sun } 931*349689b8SYork Sun #endif /* CONFIG_SYS_FSL_DDR_INTLV_256B */ 9325614e71bSYork Sun done: 933*349689b8SYork Sun #endif /* CONFIG_NUM_DDR_CONTROLLERS > 1 */ 9345614e71bSYork Sun if ((hwconfig_sub_f("fsl_ddr", "bank_intlv", buf)) && 9355614e71bSYork Sun (CONFIG_CHIP_SELECTS_PER_CTRL > 1)) { 9365614e71bSYork Sun /* test null first. if CONFIG_HWCONFIG is not defined, 9375614e71bSYork Sun * hwconfig_subarg_cmp_f returns non-zero */ 9385614e71bSYork Sun if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv", 9395614e71bSYork Sun "null", buf)) 9405614e71bSYork Sun debug("bank interleaving disabled.\n"); 9415614e71bSYork Sun else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv", 9425614e71bSYork Sun "cs0_cs1", buf)) 9435614e71bSYork Sun popts->ba_intlv_ctl = FSL_DDR_CS0_CS1; 9445614e71bSYork Sun else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv", 9455614e71bSYork Sun "cs2_cs3", buf)) 9465614e71bSYork Sun popts->ba_intlv_ctl = FSL_DDR_CS2_CS3; 9475614e71bSYork Sun else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv", 9485614e71bSYork Sun "cs0_cs1_and_cs2_cs3", buf)) 9495614e71bSYork Sun popts->ba_intlv_ctl = FSL_DDR_CS0_CS1_AND_CS2_CS3; 9505614e71bSYork Sun else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv", 9515614e71bSYork Sun "cs0_cs1_cs2_cs3", buf)) 9525614e71bSYork Sun popts->ba_intlv_ctl = FSL_DDR_CS0_CS1_CS2_CS3; 9535614e71bSYork Sun else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv", 9545614e71bSYork Sun "auto", buf)) 9555614e71bSYork Sun popts->ba_intlv_ctl = auto_bank_intlv(pdimm); 9565614e71bSYork Sun else 9575614e71bSYork Sun printf("hwconfig has unrecognized parameter for bank_intlv.\n"); 9585614e71bSYork Sun switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) { 9595614e71bSYork Sun case FSL_DDR_CS0_CS1_CS2_CS3: 9605614e71bSYork Sun #if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) 9615614e71bSYork Sun if (pdimm[0].n_ranks < 4) { 9625614e71bSYork Sun popts->ba_intlv_ctl = 0; 9635614e71bSYork Sun printf("Not enough bank(chip-select) for " 9645614e71bSYork Sun "CS0+CS1+CS2+CS3 on controller %d, " 9655614e71bSYork Sun "interleaving disabled!\n", ctrl_num); 9665614e71bSYork Sun } 9675614e71bSYork Sun #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) 9685614e71bSYork Sun #ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE 9695614e71bSYork Sun if (pdimm[0].n_ranks == 4) 9705614e71bSYork Sun break; 9715614e71bSYork Sun #endif 9725614e71bSYork Sun if ((pdimm[0].n_ranks < 2) && (pdimm[1].n_ranks < 2)) { 9735614e71bSYork Sun popts->ba_intlv_ctl = 0; 9745614e71bSYork Sun printf("Not enough bank(chip-select) for " 9755614e71bSYork Sun "CS0+CS1+CS2+CS3 on controller %d, " 9765614e71bSYork Sun "interleaving disabled!\n", ctrl_num); 9775614e71bSYork Sun } 9785614e71bSYork Sun if (pdimm[0].capacity != pdimm[1].capacity) { 9795614e71bSYork Sun popts->ba_intlv_ctl = 0; 9805614e71bSYork Sun printf("Not identical DIMM size for " 9815614e71bSYork Sun "CS0+CS1+CS2+CS3 on controller %d, " 9825614e71bSYork Sun "interleaving disabled!\n", ctrl_num); 9835614e71bSYork Sun } 9845614e71bSYork Sun #endif 9855614e71bSYork Sun break; 9865614e71bSYork Sun case FSL_DDR_CS0_CS1: 9875614e71bSYork Sun if (pdimm[0].n_ranks < 2) { 9885614e71bSYork Sun popts->ba_intlv_ctl = 0; 9895614e71bSYork Sun printf("Not enough bank(chip-select) for " 9905614e71bSYork Sun "CS0+CS1 on controller %d, " 9915614e71bSYork Sun "interleaving disabled!\n", ctrl_num); 9925614e71bSYork Sun } 9935614e71bSYork Sun break; 9945614e71bSYork Sun case FSL_DDR_CS2_CS3: 9955614e71bSYork Sun #if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) 9965614e71bSYork Sun if (pdimm[0].n_ranks < 4) { 9975614e71bSYork Sun popts->ba_intlv_ctl = 0; 9985614e71bSYork Sun printf("Not enough bank(chip-select) for CS2+CS3 " 9995614e71bSYork Sun "on controller %d, interleaving disabled!\n", ctrl_num); 10005614e71bSYork Sun } 10015614e71bSYork Sun #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) 10025614e71bSYork Sun if (pdimm[1].n_ranks < 2) { 10035614e71bSYork Sun popts->ba_intlv_ctl = 0; 10045614e71bSYork Sun printf("Not enough bank(chip-select) for CS2+CS3 " 10055614e71bSYork Sun "on controller %d, interleaving disabled!\n", ctrl_num); 10065614e71bSYork Sun } 10075614e71bSYork Sun #endif 10085614e71bSYork Sun break; 10095614e71bSYork Sun case FSL_DDR_CS0_CS1_AND_CS2_CS3: 10105614e71bSYork Sun #if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) 10115614e71bSYork Sun if (pdimm[0].n_ranks < 4) { 10125614e71bSYork Sun popts->ba_intlv_ctl = 0; 10135614e71bSYork Sun printf("Not enough bank(CS) for CS0+CS1 and " 10145614e71bSYork Sun "CS2+CS3 on controller %d, " 10155614e71bSYork Sun "interleaving disabled!\n", ctrl_num); 10165614e71bSYork Sun } 10175614e71bSYork Sun #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) 10185614e71bSYork Sun if ((pdimm[0].n_ranks < 2) || (pdimm[1].n_ranks < 2)) { 10195614e71bSYork Sun popts->ba_intlv_ctl = 0; 10205614e71bSYork Sun printf("Not enough bank(CS) for CS0+CS1 and " 10215614e71bSYork Sun "CS2+CS3 on controller %d, " 10225614e71bSYork Sun "interleaving disabled!\n", ctrl_num); 10235614e71bSYork Sun } 10245614e71bSYork Sun #endif 10255614e71bSYork Sun break; 10265614e71bSYork Sun default: 10275614e71bSYork Sun popts->ba_intlv_ctl = 0; 10285614e71bSYork Sun break; 10295614e71bSYork Sun } 10305614e71bSYork Sun } 10315614e71bSYork Sun 10325614e71bSYork Sun if (hwconfig_sub_f("fsl_ddr", "addr_hash", buf)) { 10335614e71bSYork Sun if (hwconfig_subarg_cmp_f("fsl_ddr", "addr_hash", "null", buf)) 10345614e71bSYork Sun popts->addr_hash = 0; 10355614e71bSYork Sun else if (hwconfig_subarg_cmp_f("fsl_ddr", "addr_hash", 10365614e71bSYork Sun "true", buf)) 10375614e71bSYork Sun popts->addr_hash = 1; 10385614e71bSYork Sun } 10395614e71bSYork Sun 10405614e71bSYork Sun if (pdimm[0].n_ranks == 4) 10415614e71bSYork Sun popts->quad_rank_present = 1; 10425614e71bSYork Sun 10435614e71bSYork Sun ddr_freq = get_ddr_freq(0) / 1000000; 10445614e71bSYork Sun if (popts->registered_dimm_en) { 10455614e71bSYork Sun popts->rcw_override = 1; 10465614e71bSYork Sun popts->rcw_1 = 0x000a5a00; 10475614e71bSYork Sun if (ddr_freq <= 800) 10485614e71bSYork Sun popts->rcw_2 = 0x00000000; 10495614e71bSYork Sun else if (ddr_freq <= 1066) 10505614e71bSYork Sun popts->rcw_2 = 0x00100000; 10515614e71bSYork Sun else if (ddr_freq <= 1333) 10525614e71bSYork Sun popts->rcw_2 = 0x00200000; 10535614e71bSYork Sun else 10545614e71bSYork Sun popts->rcw_2 = 0x00300000; 10555614e71bSYork Sun } 10565614e71bSYork Sun 10575614e71bSYork Sun fsl_ddr_board_options(popts, pdimm, ctrl_num); 10585614e71bSYork Sun 10595614e71bSYork Sun return 0; 10605614e71bSYork Sun } 10615614e71bSYork Sun 10625614e71bSYork Sun void check_interleaving_options(fsl_ddr_info_t *pinfo) 10635614e71bSYork Sun { 10645614e71bSYork Sun int i, j, k, check_n_ranks, intlv_invalid = 0; 10655614e71bSYork Sun unsigned int check_intlv, check_n_row_addr, check_n_col_addr; 10665614e71bSYork Sun unsigned long long check_rank_density; 10675614e71bSYork Sun struct dimm_params_s *dimm; 10685614e71bSYork Sun /* 10695614e71bSYork Sun * Check if all controllers are configured for memory 10705614e71bSYork Sun * controller interleaving. Identical dimms are recommended. At least 10715614e71bSYork Sun * the size, row and col address should be checked. 10725614e71bSYork Sun */ 10735614e71bSYork Sun j = 0; 10745614e71bSYork Sun check_n_ranks = pinfo->dimm_params[0][0].n_ranks; 10755614e71bSYork Sun check_rank_density = pinfo->dimm_params[0][0].rank_density; 10765614e71bSYork Sun check_n_row_addr = pinfo->dimm_params[0][0].n_row_addr; 10775614e71bSYork Sun check_n_col_addr = pinfo->dimm_params[0][0].n_col_addr; 10785614e71bSYork Sun check_intlv = pinfo->memctl_opts[0].memctl_interleaving_mode; 10795614e71bSYork Sun for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { 10805614e71bSYork Sun dimm = &pinfo->dimm_params[i][0]; 10815614e71bSYork Sun if (!pinfo->memctl_opts[i].memctl_interleaving) { 10825614e71bSYork Sun continue; 10835614e71bSYork Sun } else if (((check_rank_density != dimm->rank_density) || 10845614e71bSYork Sun (check_n_ranks != dimm->n_ranks) || 10855614e71bSYork Sun (check_n_row_addr != dimm->n_row_addr) || 10865614e71bSYork Sun (check_n_col_addr != dimm->n_col_addr) || 10875614e71bSYork Sun (check_intlv != 10885614e71bSYork Sun pinfo->memctl_opts[i].memctl_interleaving_mode))){ 10895614e71bSYork Sun intlv_invalid = 1; 10905614e71bSYork Sun break; 10915614e71bSYork Sun } else { 10925614e71bSYork Sun j++; 10935614e71bSYork Sun } 10945614e71bSYork Sun 10955614e71bSYork Sun } 10965614e71bSYork Sun if (intlv_invalid) { 10975614e71bSYork Sun for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) 10985614e71bSYork Sun pinfo->memctl_opts[i].memctl_interleaving = 0; 10995614e71bSYork Sun printf("Not all DIMMs are identical. " 11005614e71bSYork Sun "Memory controller interleaving disabled.\n"); 11015614e71bSYork Sun } else { 11025614e71bSYork Sun switch (check_intlv) { 11036b1e1254SYork Sun case FSL_DDR_256B_INTERLEAVING: 11045614e71bSYork Sun case FSL_DDR_CACHE_LINE_INTERLEAVING: 11055614e71bSYork Sun case FSL_DDR_PAGE_INTERLEAVING: 11065614e71bSYork Sun case FSL_DDR_BANK_INTERLEAVING: 11075614e71bSYork Sun case FSL_DDR_SUPERBANK_INTERLEAVING: 1108*349689b8SYork Sun #if (3 == CONFIG_NUM_DDR_CONTROLLERS) 11095614e71bSYork Sun k = 2; 1110*349689b8SYork Sun #else 11115614e71bSYork Sun k = CONFIG_NUM_DDR_CONTROLLERS; 1112*349689b8SYork Sun #endif 11135614e71bSYork Sun break; 11145614e71bSYork Sun case FSL_DDR_3WAY_1KB_INTERLEAVING: 11155614e71bSYork Sun case FSL_DDR_3WAY_4KB_INTERLEAVING: 11165614e71bSYork Sun case FSL_DDR_3WAY_8KB_INTERLEAVING: 11175614e71bSYork Sun case FSL_DDR_4WAY_1KB_INTERLEAVING: 11185614e71bSYork Sun case FSL_DDR_4WAY_4KB_INTERLEAVING: 11195614e71bSYork Sun case FSL_DDR_4WAY_8KB_INTERLEAVING: 11205614e71bSYork Sun default: 11215614e71bSYork Sun k = CONFIG_NUM_DDR_CONTROLLERS; 11225614e71bSYork Sun break; 11235614e71bSYork Sun } 11245614e71bSYork Sun debug("%d of %d controllers are interleaving.\n", j, k); 11255614e71bSYork Sun if (j && (j != k)) { 11265614e71bSYork Sun for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) 11275614e71bSYork Sun pinfo->memctl_opts[i].memctl_interleaving = 0; 11285614e71bSYork Sun printf("Not all controllers have compatible " 11295614e71bSYork Sun "interleaving mode. All disabled.\n"); 11305614e71bSYork Sun } 11315614e71bSYork Sun } 11325614e71bSYork Sun debug("Checking interleaving options completed\n"); 11335614e71bSYork Sun } 11345614e71bSYork Sun 11355614e71bSYork Sun int fsl_use_spd(void) 11365614e71bSYork Sun { 11375614e71bSYork Sun int use_spd = 0; 11385614e71bSYork Sun 11395614e71bSYork Sun #ifdef CONFIG_DDR_SPD 11405614e71bSYork Sun char buffer[HWCONFIG_BUFFER_SIZE]; 11415614e71bSYork Sun char *buf = NULL; 11425614e71bSYork Sun 11435614e71bSYork Sun /* 11445614e71bSYork Sun * Extract hwconfig from environment since we have not properly setup 11455614e71bSYork Sun * the environment but need it for ddr config params 11465614e71bSYork Sun */ 11475614e71bSYork Sun if (getenv_f("hwconfig", buffer, sizeof(buffer)) > 0) 11485614e71bSYork Sun buf = buffer; 11495614e71bSYork Sun 11505614e71bSYork Sun /* if hwconfig is not enabled, or "sdram" is not defined, use spd */ 11515614e71bSYork Sun if (hwconfig_sub_f("fsl_ddr", "sdram", buf)) { 11525614e71bSYork Sun if (hwconfig_subarg_cmp_f("fsl_ddr", "sdram", "spd", buf)) 11535614e71bSYork Sun use_spd = 1; 11545614e71bSYork Sun else if (hwconfig_subarg_cmp_f("fsl_ddr", "sdram", 11555614e71bSYork Sun "fixed", buf)) 11565614e71bSYork Sun use_spd = 0; 11575614e71bSYork Sun else 11585614e71bSYork Sun use_spd = 1; 11595614e71bSYork Sun } else 11605614e71bSYork Sun use_spd = 1; 11615614e71bSYork Sun #endif 11625614e71bSYork Sun 11635614e71bSYork Sun return use_spd; 11645614e71bSYork Sun } 1165