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 3219601dd9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 3319601dd9SYork Sun /* Quad rank is not verified yet due availability. 3419601dd9SYork Sun * Replacing 20 OHM with 34 OHM since DDR4 doesn't have 20 OHM option 3519601dd9SYork Sun */ 3619601dd9SYork Sun static const struct dynamic_odt single_Q[4] = { 3719601dd9SYork Sun { /* cs0 */ 3819601dd9SYork Sun FSL_DDR_ODT_NEVER, 3919601dd9SYork Sun FSL_DDR_ODT_CS_AND_OTHER_DIMM, 4019601dd9SYork Sun DDR4_RTT_34_OHM, /* unverified */ 4119601dd9SYork Sun DDR4_RTT_120_OHM 4219601dd9SYork Sun }, 4319601dd9SYork Sun { /* cs1 */ 4419601dd9SYork Sun FSL_DDR_ODT_NEVER, 4519601dd9SYork Sun FSL_DDR_ODT_NEVER, 4619601dd9SYork Sun DDR4_RTT_OFF, 4719601dd9SYork Sun DDR4_RTT_120_OHM 4819601dd9SYork Sun }, 4919601dd9SYork Sun { /* cs2 */ 5019601dd9SYork Sun FSL_DDR_ODT_NEVER, 5119601dd9SYork Sun FSL_DDR_ODT_CS_AND_OTHER_DIMM, 5219601dd9SYork Sun DDR4_RTT_34_OHM, 5319601dd9SYork Sun DDR4_RTT_120_OHM 5419601dd9SYork Sun }, 5519601dd9SYork Sun { /* cs3 */ 5619601dd9SYork Sun FSL_DDR_ODT_NEVER, 5719601dd9SYork Sun FSL_DDR_ODT_NEVER, /* tied high */ 5819601dd9SYork Sun DDR4_RTT_OFF, 5919601dd9SYork Sun DDR4_RTT_120_OHM 6019601dd9SYork Sun } 6119601dd9SYork Sun }; 6219601dd9SYork Sun 6319601dd9SYork Sun static const struct dynamic_odt single_D[4] = { 6419601dd9SYork Sun { /* cs0 */ 6519601dd9SYork Sun FSL_DDR_ODT_NEVER, 6619601dd9SYork Sun FSL_DDR_ODT_ALL, 6719601dd9SYork Sun DDR4_RTT_40_OHM, 6819601dd9SYork Sun DDR4_RTT_OFF 6919601dd9SYork Sun }, 7019601dd9SYork Sun { /* cs1 */ 7119601dd9SYork Sun FSL_DDR_ODT_NEVER, 7219601dd9SYork Sun FSL_DDR_ODT_NEVER, 7319601dd9SYork Sun DDR4_RTT_OFF, 7419601dd9SYork Sun DDR4_RTT_OFF 7519601dd9SYork Sun }, 7619601dd9SYork Sun {0, 0, 0, 0}, 7719601dd9SYork Sun {0, 0, 0, 0} 7819601dd9SYork Sun }; 7919601dd9SYork Sun 8019601dd9SYork Sun static const struct dynamic_odt single_S[4] = { 8119601dd9SYork Sun { /* cs0 */ 8219601dd9SYork Sun FSL_DDR_ODT_NEVER, 8319601dd9SYork Sun FSL_DDR_ODT_ALL, 8419601dd9SYork Sun DDR4_RTT_40_OHM, 8519601dd9SYork Sun DDR4_RTT_OFF 8619601dd9SYork Sun }, 8719601dd9SYork Sun {0, 0, 0, 0}, 8819601dd9SYork Sun {0, 0, 0, 0}, 8919601dd9SYork Sun {0, 0, 0, 0}, 9019601dd9SYork Sun }; 9119601dd9SYork Sun 9219601dd9SYork Sun static const struct dynamic_odt dual_DD[4] = { 9319601dd9SYork Sun { /* cs0 */ 9419601dd9SYork Sun FSL_DDR_ODT_NEVER, 9519601dd9SYork Sun FSL_DDR_ODT_SAME_DIMM, 9619601dd9SYork Sun DDR4_RTT_120_OHM, 9719601dd9SYork Sun DDR4_RTT_OFF 9819601dd9SYork Sun }, 9919601dd9SYork Sun { /* cs1 */ 10019601dd9SYork Sun FSL_DDR_ODT_OTHER_DIMM, 10119601dd9SYork Sun FSL_DDR_ODT_OTHER_DIMM, 10219601dd9SYork Sun DDR4_RTT_34_OHM, 10319601dd9SYork Sun DDR4_RTT_OFF 10419601dd9SYork Sun }, 10519601dd9SYork Sun { /* cs2 */ 10619601dd9SYork Sun FSL_DDR_ODT_NEVER, 10719601dd9SYork Sun FSL_DDR_ODT_SAME_DIMM, 10819601dd9SYork Sun DDR4_RTT_120_OHM, 10919601dd9SYork Sun DDR4_RTT_OFF 11019601dd9SYork Sun }, 11119601dd9SYork Sun { /* cs3 */ 11219601dd9SYork Sun FSL_DDR_ODT_OTHER_DIMM, 11319601dd9SYork Sun FSL_DDR_ODT_OTHER_DIMM, 11419601dd9SYork Sun DDR4_RTT_34_OHM, 11519601dd9SYork Sun DDR4_RTT_OFF 11619601dd9SYork Sun } 11719601dd9SYork Sun }; 11819601dd9SYork Sun 11919601dd9SYork Sun static const struct dynamic_odt dual_DS[4] = { 12019601dd9SYork Sun { /* cs0 */ 12119601dd9SYork Sun FSL_DDR_ODT_NEVER, 12219601dd9SYork Sun FSL_DDR_ODT_SAME_DIMM, 12319601dd9SYork Sun DDR4_RTT_120_OHM, 12419601dd9SYork Sun DDR4_RTT_OFF 12519601dd9SYork Sun }, 12619601dd9SYork Sun { /* cs1 */ 12719601dd9SYork Sun FSL_DDR_ODT_OTHER_DIMM, 12819601dd9SYork Sun FSL_DDR_ODT_OTHER_DIMM, 12919601dd9SYork Sun DDR4_RTT_34_OHM, 13019601dd9SYork Sun DDR4_RTT_OFF 13119601dd9SYork Sun }, 13219601dd9SYork Sun { /* cs2 */ 13319601dd9SYork Sun FSL_DDR_ODT_OTHER_DIMM, 13419601dd9SYork Sun FSL_DDR_ODT_ALL, 13519601dd9SYork Sun DDR4_RTT_34_OHM, 13619601dd9SYork Sun DDR4_RTT_120_OHM 13719601dd9SYork Sun }, 13819601dd9SYork Sun {0, 0, 0, 0} 13919601dd9SYork Sun }; 14019601dd9SYork Sun static const struct dynamic_odt dual_SD[4] = { 14119601dd9SYork Sun { /* cs0 */ 14219601dd9SYork Sun FSL_DDR_ODT_OTHER_DIMM, 14319601dd9SYork Sun FSL_DDR_ODT_ALL, 14419601dd9SYork Sun DDR4_RTT_34_OHM, 14519601dd9SYork Sun DDR4_RTT_120_OHM 14619601dd9SYork Sun }, 14719601dd9SYork Sun {0, 0, 0, 0}, 14819601dd9SYork Sun { /* cs2 */ 14919601dd9SYork Sun FSL_DDR_ODT_NEVER, 15019601dd9SYork Sun FSL_DDR_ODT_SAME_DIMM, 15119601dd9SYork Sun DDR4_RTT_120_OHM, 15219601dd9SYork Sun DDR4_RTT_OFF 15319601dd9SYork Sun }, 15419601dd9SYork Sun { /* cs3 */ 15519601dd9SYork Sun FSL_DDR_ODT_OTHER_DIMM, 15619601dd9SYork Sun FSL_DDR_ODT_OTHER_DIMM, 15719601dd9SYork Sun DDR4_RTT_34_OHM, 15819601dd9SYork Sun DDR4_RTT_OFF 15919601dd9SYork Sun } 16019601dd9SYork Sun }; 16119601dd9SYork Sun 16219601dd9SYork Sun static const struct dynamic_odt dual_SS[4] = { 16319601dd9SYork Sun { /* cs0 */ 16419601dd9SYork Sun FSL_DDR_ODT_OTHER_DIMM, 16519601dd9SYork Sun FSL_DDR_ODT_ALL, 16619601dd9SYork Sun DDR4_RTT_34_OHM, 16719601dd9SYork Sun DDR4_RTT_120_OHM 16819601dd9SYork Sun }, 16919601dd9SYork Sun {0, 0, 0, 0}, 17019601dd9SYork Sun { /* cs2 */ 17119601dd9SYork Sun FSL_DDR_ODT_OTHER_DIMM, 17219601dd9SYork Sun FSL_DDR_ODT_ALL, 17319601dd9SYork Sun DDR4_RTT_34_OHM, 17419601dd9SYork Sun DDR4_RTT_120_OHM 17519601dd9SYork Sun }, 17619601dd9SYork Sun {0, 0, 0, 0} 17719601dd9SYork Sun }; 17819601dd9SYork Sun 17919601dd9SYork Sun static const struct dynamic_odt dual_D0[4] = { 18019601dd9SYork Sun { /* cs0 */ 18119601dd9SYork Sun FSL_DDR_ODT_NEVER, 18219601dd9SYork Sun FSL_DDR_ODT_SAME_DIMM, 18319601dd9SYork Sun DDR4_RTT_40_OHM, 18419601dd9SYork Sun DDR4_RTT_OFF 18519601dd9SYork Sun }, 18619601dd9SYork Sun { /* cs1 */ 18719601dd9SYork Sun FSL_DDR_ODT_NEVER, 18819601dd9SYork Sun FSL_DDR_ODT_NEVER, 18919601dd9SYork Sun DDR4_RTT_OFF, 19019601dd9SYork Sun DDR4_RTT_OFF 19119601dd9SYork Sun }, 19219601dd9SYork Sun {0, 0, 0, 0}, 19319601dd9SYork Sun {0, 0, 0, 0} 19419601dd9SYork Sun }; 19519601dd9SYork Sun 19619601dd9SYork Sun static const struct dynamic_odt dual_0D[4] = { 19719601dd9SYork Sun {0, 0, 0, 0}, 19819601dd9SYork Sun {0, 0, 0, 0}, 19919601dd9SYork Sun { /* cs2 */ 20019601dd9SYork Sun FSL_DDR_ODT_NEVER, 20119601dd9SYork Sun FSL_DDR_ODT_SAME_DIMM, 20219601dd9SYork Sun DDR4_RTT_40_OHM, 20319601dd9SYork Sun DDR4_RTT_OFF 20419601dd9SYork Sun }, 20519601dd9SYork Sun { /* cs3 */ 20619601dd9SYork Sun FSL_DDR_ODT_NEVER, 20719601dd9SYork Sun FSL_DDR_ODT_NEVER, 20819601dd9SYork Sun DDR4_RTT_OFF, 20919601dd9SYork Sun DDR4_RTT_OFF 21019601dd9SYork Sun } 21119601dd9SYork Sun }; 21219601dd9SYork Sun 21319601dd9SYork Sun static const struct dynamic_odt dual_S0[4] = { 21419601dd9SYork Sun { /* cs0 */ 21519601dd9SYork Sun FSL_DDR_ODT_NEVER, 21619601dd9SYork Sun FSL_DDR_ODT_CS, 21719601dd9SYork Sun DDR4_RTT_40_OHM, 21819601dd9SYork Sun DDR4_RTT_OFF 21919601dd9SYork Sun }, 22019601dd9SYork Sun {0, 0, 0, 0}, 22119601dd9SYork Sun {0, 0, 0, 0}, 22219601dd9SYork Sun {0, 0, 0, 0} 22319601dd9SYork Sun 22419601dd9SYork Sun }; 22519601dd9SYork Sun 22619601dd9SYork Sun static const struct dynamic_odt dual_0S[4] = { 22719601dd9SYork Sun {0, 0, 0, 0}, 22819601dd9SYork Sun {0, 0, 0, 0}, 22919601dd9SYork Sun { /* cs2 */ 23019601dd9SYork Sun FSL_DDR_ODT_NEVER, 23119601dd9SYork Sun FSL_DDR_ODT_CS, 23219601dd9SYork Sun DDR4_RTT_40_OHM, 23319601dd9SYork Sun DDR4_RTT_OFF 23419601dd9SYork Sun }, 23519601dd9SYork Sun {0, 0, 0, 0} 23619601dd9SYork Sun 23719601dd9SYork Sun }; 23819601dd9SYork Sun 23919601dd9SYork Sun static const struct dynamic_odt odt_unknown[4] = { 24019601dd9SYork Sun { /* cs0 */ 24119601dd9SYork Sun FSL_DDR_ODT_NEVER, 24219601dd9SYork Sun FSL_DDR_ODT_CS, 24319601dd9SYork Sun DDR4_RTT_120_OHM, 24419601dd9SYork Sun DDR4_RTT_OFF 24519601dd9SYork Sun }, 24619601dd9SYork Sun { /* cs1 */ 24719601dd9SYork Sun FSL_DDR_ODT_NEVER, 24819601dd9SYork Sun FSL_DDR_ODT_CS, 24919601dd9SYork Sun DDR4_RTT_120_OHM, 25019601dd9SYork Sun DDR4_RTT_OFF 25119601dd9SYork Sun }, 25219601dd9SYork Sun { /* cs2 */ 25319601dd9SYork Sun FSL_DDR_ODT_NEVER, 25419601dd9SYork Sun FSL_DDR_ODT_CS, 25519601dd9SYork Sun DDR4_RTT_120_OHM, 25619601dd9SYork Sun DDR4_RTT_OFF 25719601dd9SYork Sun }, 25819601dd9SYork Sun { /* cs3 */ 25919601dd9SYork Sun FSL_DDR_ODT_NEVER, 26019601dd9SYork Sun FSL_DDR_ODT_CS, 26119601dd9SYork Sun DDR4_RTT_120_OHM, 26219601dd9SYork Sun DDR4_RTT_OFF 26319601dd9SYork Sun } 26419601dd9SYork Sun }; 26519601dd9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 2665614e71bSYork Sun static const struct dynamic_odt single_Q[4] = { 2675614e71bSYork Sun { /* cs0 */ 2685614e71bSYork Sun FSL_DDR_ODT_NEVER, 2695614e71bSYork Sun FSL_DDR_ODT_CS_AND_OTHER_DIMM, 2705614e71bSYork Sun DDR3_RTT_20_OHM, 2715614e71bSYork Sun DDR3_RTT_120_OHM 2725614e71bSYork Sun }, 2735614e71bSYork Sun { /* cs1 */ 2745614e71bSYork Sun FSL_DDR_ODT_NEVER, 2755614e71bSYork Sun FSL_DDR_ODT_NEVER, /* tied high */ 2765614e71bSYork Sun DDR3_RTT_OFF, 2775614e71bSYork Sun DDR3_RTT_120_OHM 2785614e71bSYork Sun }, 2795614e71bSYork Sun { /* cs2 */ 2805614e71bSYork Sun FSL_DDR_ODT_NEVER, 2815614e71bSYork Sun FSL_DDR_ODT_CS_AND_OTHER_DIMM, 2825614e71bSYork Sun DDR3_RTT_20_OHM, 2835614e71bSYork Sun DDR3_RTT_120_OHM 2845614e71bSYork Sun }, 2855614e71bSYork Sun { /* cs3 */ 2865614e71bSYork Sun FSL_DDR_ODT_NEVER, 2875614e71bSYork Sun FSL_DDR_ODT_NEVER, /* tied high */ 2885614e71bSYork Sun DDR3_RTT_OFF, 2895614e71bSYork Sun DDR3_RTT_120_OHM 2905614e71bSYork Sun } 2915614e71bSYork Sun }; 2925614e71bSYork Sun 2935614e71bSYork Sun static const struct dynamic_odt single_D[4] = { 2945614e71bSYork Sun { /* cs0 */ 2955614e71bSYork Sun FSL_DDR_ODT_NEVER, 2965614e71bSYork Sun FSL_DDR_ODT_ALL, 2975614e71bSYork Sun DDR3_RTT_40_OHM, 2985614e71bSYork Sun DDR3_RTT_OFF 2995614e71bSYork Sun }, 3005614e71bSYork Sun { /* cs1 */ 3015614e71bSYork Sun FSL_DDR_ODT_NEVER, 3025614e71bSYork Sun FSL_DDR_ODT_NEVER, 3035614e71bSYork Sun DDR3_RTT_OFF, 3045614e71bSYork Sun DDR3_RTT_OFF 3055614e71bSYork Sun }, 3065614e71bSYork Sun {0, 0, 0, 0}, 3075614e71bSYork Sun {0, 0, 0, 0} 3085614e71bSYork Sun }; 3095614e71bSYork Sun 3105614e71bSYork Sun static const struct dynamic_odt single_S[4] = { 3115614e71bSYork Sun { /* cs0 */ 3125614e71bSYork Sun FSL_DDR_ODT_NEVER, 3135614e71bSYork Sun FSL_DDR_ODT_ALL, 3145614e71bSYork Sun DDR3_RTT_40_OHM, 3155614e71bSYork Sun DDR3_RTT_OFF 3165614e71bSYork Sun }, 3175614e71bSYork Sun {0, 0, 0, 0}, 3185614e71bSYork Sun {0, 0, 0, 0}, 3195614e71bSYork Sun {0, 0, 0, 0}, 3205614e71bSYork Sun }; 3215614e71bSYork Sun 3225614e71bSYork Sun static const struct dynamic_odt dual_DD[4] = { 3235614e71bSYork Sun { /* cs0 */ 3245614e71bSYork Sun FSL_DDR_ODT_NEVER, 3255614e71bSYork Sun FSL_DDR_ODT_SAME_DIMM, 3265614e71bSYork Sun DDR3_RTT_120_OHM, 3275614e71bSYork Sun DDR3_RTT_OFF 3285614e71bSYork Sun }, 3295614e71bSYork Sun { /* cs1 */ 3305614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3315614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3325614e71bSYork Sun DDR3_RTT_30_OHM, 3335614e71bSYork Sun DDR3_RTT_OFF 3345614e71bSYork Sun }, 3355614e71bSYork Sun { /* cs2 */ 3365614e71bSYork Sun FSL_DDR_ODT_NEVER, 3375614e71bSYork Sun FSL_DDR_ODT_SAME_DIMM, 3385614e71bSYork Sun DDR3_RTT_120_OHM, 3395614e71bSYork Sun DDR3_RTT_OFF 3405614e71bSYork Sun }, 3415614e71bSYork Sun { /* cs3 */ 3425614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3435614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3445614e71bSYork Sun DDR3_RTT_30_OHM, 3455614e71bSYork Sun DDR3_RTT_OFF 3465614e71bSYork Sun } 3475614e71bSYork Sun }; 3485614e71bSYork Sun 3495614e71bSYork Sun static const struct dynamic_odt dual_DS[4] = { 3505614e71bSYork Sun { /* cs0 */ 3515614e71bSYork Sun FSL_DDR_ODT_NEVER, 3525614e71bSYork Sun FSL_DDR_ODT_SAME_DIMM, 3535614e71bSYork Sun DDR3_RTT_120_OHM, 3545614e71bSYork Sun DDR3_RTT_OFF 3555614e71bSYork Sun }, 3565614e71bSYork Sun { /* cs1 */ 3575614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3585614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3595614e71bSYork Sun DDR3_RTT_30_OHM, 3605614e71bSYork Sun DDR3_RTT_OFF 3615614e71bSYork Sun }, 3625614e71bSYork Sun { /* cs2 */ 3635614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3645614e71bSYork Sun FSL_DDR_ODT_ALL, 3655614e71bSYork Sun DDR3_RTT_20_OHM, 3665614e71bSYork Sun DDR3_RTT_120_OHM 3675614e71bSYork Sun }, 3685614e71bSYork Sun {0, 0, 0, 0} 3695614e71bSYork Sun }; 3705614e71bSYork Sun static const struct dynamic_odt dual_SD[4] = { 3715614e71bSYork Sun { /* cs0 */ 3725614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3735614e71bSYork Sun FSL_DDR_ODT_ALL, 3745614e71bSYork Sun DDR3_RTT_20_OHM, 3755614e71bSYork Sun DDR3_RTT_120_OHM 3765614e71bSYork Sun }, 3775614e71bSYork Sun {0, 0, 0, 0}, 3785614e71bSYork Sun { /* cs2 */ 3795614e71bSYork Sun FSL_DDR_ODT_NEVER, 3805614e71bSYork Sun FSL_DDR_ODT_SAME_DIMM, 3815614e71bSYork Sun DDR3_RTT_120_OHM, 3825614e71bSYork Sun DDR3_RTT_OFF 3835614e71bSYork Sun }, 3845614e71bSYork Sun { /* cs3 */ 3855614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3865614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3875614e71bSYork Sun DDR3_RTT_20_OHM, 3885614e71bSYork Sun DDR3_RTT_OFF 3895614e71bSYork Sun } 3905614e71bSYork Sun }; 3915614e71bSYork Sun 3925614e71bSYork Sun static const struct dynamic_odt dual_SS[4] = { 3935614e71bSYork Sun { /* cs0 */ 3945614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 3955614e71bSYork Sun FSL_DDR_ODT_ALL, 3965614e71bSYork Sun DDR3_RTT_30_OHM, 3975614e71bSYork Sun DDR3_RTT_120_OHM 3985614e71bSYork Sun }, 3995614e71bSYork Sun {0, 0, 0, 0}, 4005614e71bSYork Sun { /* cs2 */ 4015614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 4025614e71bSYork Sun FSL_DDR_ODT_ALL, 4035614e71bSYork Sun DDR3_RTT_30_OHM, 4045614e71bSYork Sun DDR3_RTT_120_OHM 4055614e71bSYork Sun }, 4065614e71bSYork Sun {0, 0, 0, 0} 4075614e71bSYork Sun }; 4085614e71bSYork Sun 4095614e71bSYork Sun static const struct dynamic_odt dual_D0[4] = { 4105614e71bSYork Sun { /* cs0 */ 4115614e71bSYork Sun FSL_DDR_ODT_NEVER, 4125614e71bSYork Sun FSL_DDR_ODT_SAME_DIMM, 4135614e71bSYork Sun DDR3_RTT_40_OHM, 4145614e71bSYork Sun DDR3_RTT_OFF 4155614e71bSYork Sun }, 4165614e71bSYork Sun { /* cs1 */ 4175614e71bSYork Sun FSL_DDR_ODT_NEVER, 4185614e71bSYork Sun FSL_DDR_ODT_NEVER, 4195614e71bSYork Sun DDR3_RTT_OFF, 4205614e71bSYork Sun DDR3_RTT_OFF 4215614e71bSYork Sun }, 4225614e71bSYork Sun {0, 0, 0, 0}, 4235614e71bSYork Sun {0, 0, 0, 0} 4245614e71bSYork Sun }; 4255614e71bSYork Sun 4265614e71bSYork Sun static const struct dynamic_odt dual_0D[4] = { 4275614e71bSYork Sun {0, 0, 0, 0}, 4285614e71bSYork Sun {0, 0, 0, 0}, 4295614e71bSYork Sun { /* cs2 */ 4305614e71bSYork Sun FSL_DDR_ODT_NEVER, 4315614e71bSYork Sun FSL_DDR_ODT_SAME_DIMM, 4325614e71bSYork Sun DDR3_RTT_40_OHM, 4335614e71bSYork Sun DDR3_RTT_OFF 4345614e71bSYork Sun }, 4355614e71bSYork Sun { /* cs3 */ 4365614e71bSYork Sun FSL_DDR_ODT_NEVER, 4375614e71bSYork Sun FSL_DDR_ODT_NEVER, 4385614e71bSYork Sun DDR3_RTT_OFF, 4395614e71bSYork Sun DDR3_RTT_OFF 4405614e71bSYork Sun } 4415614e71bSYork Sun }; 4425614e71bSYork Sun 4435614e71bSYork Sun static const struct dynamic_odt dual_S0[4] = { 4445614e71bSYork Sun { /* cs0 */ 4455614e71bSYork Sun FSL_DDR_ODT_NEVER, 4465614e71bSYork Sun FSL_DDR_ODT_CS, 4475614e71bSYork Sun DDR3_RTT_40_OHM, 4485614e71bSYork Sun DDR3_RTT_OFF 4495614e71bSYork Sun }, 4505614e71bSYork Sun {0, 0, 0, 0}, 4515614e71bSYork Sun {0, 0, 0, 0}, 4525614e71bSYork Sun {0, 0, 0, 0} 4535614e71bSYork Sun 4545614e71bSYork Sun }; 4555614e71bSYork Sun 4565614e71bSYork Sun static const struct dynamic_odt dual_0S[4] = { 4575614e71bSYork Sun {0, 0, 0, 0}, 4585614e71bSYork Sun {0, 0, 0, 0}, 4595614e71bSYork Sun { /* cs2 */ 4605614e71bSYork Sun FSL_DDR_ODT_NEVER, 4615614e71bSYork Sun FSL_DDR_ODT_CS, 4625614e71bSYork Sun DDR3_RTT_40_OHM, 4635614e71bSYork Sun DDR3_RTT_OFF 4645614e71bSYork Sun }, 4655614e71bSYork Sun {0, 0, 0, 0} 4665614e71bSYork Sun 4675614e71bSYork Sun }; 4685614e71bSYork Sun 4695614e71bSYork Sun static const struct dynamic_odt odt_unknown[4] = { 4705614e71bSYork Sun { /* cs0 */ 4715614e71bSYork Sun FSL_DDR_ODT_NEVER, 4725614e71bSYork Sun FSL_DDR_ODT_CS, 4735614e71bSYork Sun DDR3_RTT_120_OHM, 4745614e71bSYork Sun DDR3_RTT_OFF 4755614e71bSYork Sun }, 4765614e71bSYork Sun { /* cs1 */ 4775614e71bSYork Sun FSL_DDR_ODT_NEVER, 4785614e71bSYork Sun FSL_DDR_ODT_CS, 4795614e71bSYork Sun DDR3_RTT_120_OHM, 4805614e71bSYork Sun DDR3_RTT_OFF 4815614e71bSYork Sun }, 4825614e71bSYork Sun { /* cs2 */ 4835614e71bSYork Sun FSL_DDR_ODT_NEVER, 4845614e71bSYork Sun FSL_DDR_ODT_CS, 4855614e71bSYork Sun DDR3_RTT_120_OHM, 4865614e71bSYork Sun DDR3_RTT_OFF 4875614e71bSYork Sun }, 4885614e71bSYork Sun { /* cs3 */ 4895614e71bSYork Sun FSL_DDR_ODT_NEVER, 4905614e71bSYork Sun FSL_DDR_ODT_CS, 4915614e71bSYork Sun DDR3_RTT_120_OHM, 4925614e71bSYork Sun DDR3_RTT_OFF 4935614e71bSYork Sun } 4945614e71bSYork Sun }; 49519601dd9SYork Sun #else /* CONFIG_SYS_FSL_DDR3 */ 4965614e71bSYork Sun static const struct dynamic_odt single_Q[4] = { 4975614e71bSYork Sun {0, 0, 0, 0}, 4985614e71bSYork Sun {0, 0, 0, 0}, 4995614e71bSYork Sun {0, 0, 0, 0}, 5005614e71bSYork Sun {0, 0, 0, 0} 5015614e71bSYork Sun }; 5025614e71bSYork Sun 5035614e71bSYork Sun static const struct dynamic_odt single_D[4] = { 5045614e71bSYork Sun { /* cs0 */ 5055614e71bSYork Sun FSL_DDR_ODT_NEVER, 5065614e71bSYork Sun FSL_DDR_ODT_ALL, 5075614e71bSYork Sun DDR2_RTT_150_OHM, 5085614e71bSYork Sun DDR2_RTT_OFF 5095614e71bSYork Sun }, 5105614e71bSYork Sun { /* cs1 */ 5115614e71bSYork Sun FSL_DDR_ODT_NEVER, 5125614e71bSYork Sun FSL_DDR_ODT_NEVER, 5135614e71bSYork Sun DDR2_RTT_OFF, 5145614e71bSYork Sun DDR2_RTT_OFF 5155614e71bSYork Sun }, 5165614e71bSYork Sun {0, 0, 0, 0}, 5175614e71bSYork Sun {0, 0, 0, 0} 5185614e71bSYork Sun }; 5195614e71bSYork Sun 5205614e71bSYork Sun static const struct dynamic_odt single_S[4] = { 5215614e71bSYork Sun { /* cs0 */ 5225614e71bSYork Sun FSL_DDR_ODT_NEVER, 5235614e71bSYork Sun FSL_DDR_ODT_ALL, 5245614e71bSYork Sun DDR2_RTT_150_OHM, 5255614e71bSYork Sun DDR2_RTT_OFF 5265614e71bSYork Sun }, 5275614e71bSYork Sun {0, 0, 0, 0}, 5285614e71bSYork Sun {0, 0, 0, 0}, 5295614e71bSYork Sun {0, 0, 0, 0}, 5305614e71bSYork Sun }; 5315614e71bSYork Sun 5325614e71bSYork Sun static const struct dynamic_odt dual_DD[4] = { 5335614e71bSYork Sun { /* cs0 */ 5345614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 5355614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 5365614e71bSYork Sun DDR2_RTT_75_OHM, 5375614e71bSYork Sun DDR2_RTT_OFF 5385614e71bSYork Sun }, 5395614e71bSYork Sun { /* cs1 */ 5405614e71bSYork Sun FSL_DDR_ODT_NEVER, 5415614e71bSYork Sun FSL_DDR_ODT_NEVER, 5425614e71bSYork Sun DDR2_RTT_OFF, 5435614e71bSYork Sun DDR2_RTT_OFF 5445614e71bSYork Sun }, 5455614e71bSYork Sun { /* cs2 */ 5465614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 5475614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 5485614e71bSYork Sun DDR2_RTT_75_OHM, 5495614e71bSYork Sun DDR2_RTT_OFF 5505614e71bSYork Sun }, 5515614e71bSYork Sun { /* cs3 */ 5525614e71bSYork Sun FSL_DDR_ODT_NEVER, 5535614e71bSYork Sun FSL_DDR_ODT_NEVER, 5545614e71bSYork Sun DDR2_RTT_OFF, 5555614e71bSYork Sun DDR2_RTT_OFF 5565614e71bSYork Sun } 5575614e71bSYork Sun }; 5585614e71bSYork Sun 5595614e71bSYork Sun static const struct dynamic_odt dual_DS[4] = { 5605614e71bSYork Sun { /* cs0 */ 5615614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 5625614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 5635614e71bSYork Sun DDR2_RTT_75_OHM, 5645614e71bSYork Sun DDR2_RTT_OFF 5655614e71bSYork Sun }, 5665614e71bSYork Sun { /* cs1 */ 5675614e71bSYork Sun FSL_DDR_ODT_NEVER, 5685614e71bSYork Sun FSL_DDR_ODT_NEVER, 5695614e71bSYork Sun DDR2_RTT_OFF, 5705614e71bSYork Sun DDR2_RTT_OFF 5715614e71bSYork Sun }, 5725614e71bSYork Sun { /* cs2 */ 5735614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 5745614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 5755614e71bSYork Sun DDR2_RTT_75_OHM, 5765614e71bSYork Sun DDR2_RTT_OFF 5775614e71bSYork Sun }, 5785614e71bSYork Sun {0, 0, 0, 0} 5795614e71bSYork Sun }; 5805614e71bSYork Sun 5815614e71bSYork Sun static const struct dynamic_odt dual_SD[4] = { 5825614e71bSYork Sun { /* cs0 */ 5835614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 5845614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 5855614e71bSYork Sun DDR2_RTT_75_OHM, 5865614e71bSYork Sun DDR2_RTT_OFF 5875614e71bSYork Sun }, 5885614e71bSYork Sun {0, 0, 0, 0}, 5895614e71bSYork Sun { /* cs2 */ 5905614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 5915614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 5925614e71bSYork Sun DDR2_RTT_75_OHM, 5935614e71bSYork Sun DDR2_RTT_OFF 5945614e71bSYork Sun }, 5955614e71bSYork Sun { /* cs3 */ 5965614e71bSYork Sun FSL_DDR_ODT_NEVER, 5975614e71bSYork Sun FSL_DDR_ODT_NEVER, 5985614e71bSYork Sun DDR2_RTT_OFF, 5995614e71bSYork Sun DDR2_RTT_OFF 6005614e71bSYork Sun } 6015614e71bSYork Sun }; 6025614e71bSYork Sun 6035614e71bSYork Sun static const struct dynamic_odt dual_SS[4] = { 6045614e71bSYork Sun { /* cs0 */ 6055614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 6065614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 6075614e71bSYork Sun DDR2_RTT_75_OHM, 6085614e71bSYork Sun DDR2_RTT_OFF 6095614e71bSYork Sun }, 6105614e71bSYork Sun {0, 0, 0, 0}, 6115614e71bSYork Sun { /* cs2 */ 6125614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 6135614e71bSYork Sun FSL_DDR_ODT_OTHER_DIMM, 6145614e71bSYork Sun DDR2_RTT_75_OHM, 6155614e71bSYork Sun DDR2_RTT_OFF 6165614e71bSYork Sun }, 6175614e71bSYork Sun {0, 0, 0, 0} 6185614e71bSYork Sun }; 6195614e71bSYork Sun 6205614e71bSYork Sun static const struct dynamic_odt dual_D0[4] = { 6215614e71bSYork Sun { /* cs0 */ 6225614e71bSYork Sun FSL_DDR_ODT_NEVER, 6235614e71bSYork Sun FSL_DDR_ODT_ALL, 6245614e71bSYork Sun DDR2_RTT_150_OHM, 6255614e71bSYork Sun DDR2_RTT_OFF 6265614e71bSYork Sun }, 6275614e71bSYork Sun { /* cs1 */ 6285614e71bSYork Sun FSL_DDR_ODT_NEVER, 6295614e71bSYork Sun FSL_DDR_ODT_NEVER, 6305614e71bSYork Sun DDR2_RTT_OFF, 6315614e71bSYork Sun DDR2_RTT_OFF 6325614e71bSYork Sun }, 6335614e71bSYork Sun {0, 0, 0, 0}, 6345614e71bSYork Sun {0, 0, 0, 0} 6355614e71bSYork Sun }; 6365614e71bSYork Sun 6375614e71bSYork Sun static const struct dynamic_odt dual_0D[4] = { 6385614e71bSYork Sun {0, 0, 0, 0}, 6395614e71bSYork Sun {0, 0, 0, 0}, 6405614e71bSYork Sun { /* cs2 */ 6415614e71bSYork Sun FSL_DDR_ODT_NEVER, 6425614e71bSYork Sun FSL_DDR_ODT_ALL, 6435614e71bSYork Sun DDR2_RTT_150_OHM, 6445614e71bSYork Sun DDR2_RTT_OFF 6455614e71bSYork Sun }, 6465614e71bSYork Sun { /* cs3 */ 6475614e71bSYork Sun FSL_DDR_ODT_NEVER, 6485614e71bSYork Sun FSL_DDR_ODT_NEVER, 6495614e71bSYork Sun DDR2_RTT_OFF, 6505614e71bSYork Sun DDR2_RTT_OFF 6515614e71bSYork Sun } 6525614e71bSYork Sun }; 6535614e71bSYork Sun 6545614e71bSYork Sun static const struct dynamic_odt dual_S0[4] = { 6555614e71bSYork Sun { /* cs0 */ 6565614e71bSYork Sun FSL_DDR_ODT_NEVER, 6575614e71bSYork Sun FSL_DDR_ODT_CS, 6585614e71bSYork Sun DDR2_RTT_150_OHM, 6595614e71bSYork Sun DDR2_RTT_OFF 6605614e71bSYork Sun }, 6615614e71bSYork Sun {0, 0, 0, 0}, 6625614e71bSYork Sun {0, 0, 0, 0}, 6635614e71bSYork Sun {0, 0, 0, 0} 6645614e71bSYork Sun 6655614e71bSYork Sun }; 6665614e71bSYork Sun 6675614e71bSYork Sun static const struct dynamic_odt dual_0S[4] = { 6685614e71bSYork Sun {0, 0, 0, 0}, 6695614e71bSYork Sun {0, 0, 0, 0}, 6705614e71bSYork Sun { /* cs2 */ 6715614e71bSYork Sun FSL_DDR_ODT_NEVER, 6725614e71bSYork Sun FSL_DDR_ODT_CS, 6735614e71bSYork Sun DDR2_RTT_150_OHM, 6745614e71bSYork Sun DDR2_RTT_OFF 6755614e71bSYork Sun }, 6765614e71bSYork Sun {0, 0, 0, 0} 6775614e71bSYork Sun 6785614e71bSYork Sun }; 6795614e71bSYork Sun 6805614e71bSYork Sun static const struct dynamic_odt odt_unknown[4] = { 6815614e71bSYork Sun { /* cs0 */ 6825614e71bSYork Sun FSL_DDR_ODT_NEVER, 6835614e71bSYork Sun FSL_DDR_ODT_CS, 6845614e71bSYork Sun DDR2_RTT_75_OHM, 6855614e71bSYork Sun DDR2_RTT_OFF 6865614e71bSYork Sun }, 6875614e71bSYork Sun { /* cs1 */ 6885614e71bSYork Sun FSL_DDR_ODT_NEVER, 6895614e71bSYork Sun FSL_DDR_ODT_NEVER, 6905614e71bSYork Sun DDR2_RTT_OFF, 6915614e71bSYork Sun DDR2_RTT_OFF 6925614e71bSYork Sun }, 6935614e71bSYork Sun { /* cs2 */ 6945614e71bSYork Sun FSL_DDR_ODT_NEVER, 6955614e71bSYork Sun FSL_DDR_ODT_CS, 6965614e71bSYork Sun DDR2_RTT_75_OHM, 6975614e71bSYork Sun DDR2_RTT_OFF 6985614e71bSYork Sun }, 6995614e71bSYork Sun { /* cs3 */ 7005614e71bSYork Sun FSL_DDR_ODT_NEVER, 7015614e71bSYork Sun FSL_DDR_ODT_NEVER, 7025614e71bSYork Sun DDR2_RTT_OFF, 7035614e71bSYork Sun DDR2_RTT_OFF 7045614e71bSYork Sun } 7055614e71bSYork Sun }; 7065614e71bSYork Sun #endif 7075614e71bSYork Sun 7085614e71bSYork Sun /* 7095614e71bSYork Sun * Automatically seleect bank interleaving mode based on DIMMs 7105614e71bSYork Sun * in this order: cs0_cs1_cs2_cs3, cs0_cs1, null. 7115614e71bSYork Sun * This function only deal with one or two slots per controller. 7125614e71bSYork Sun */ 7135614e71bSYork Sun static inline unsigned int auto_bank_intlv(dimm_params_t *pdimm) 7145614e71bSYork Sun { 7155614e71bSYork Sun #if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) 7165614e71bSYork Sun if (pdimm[0].n_ranks == 4) 7175614e71bSYork Sun return FSL_DDR_CS0_CS1_CS2_CS3; 7185614e71bSYork Sun else if (pdimm[0].n_ranks == 2) 7195614e71bSYork Sun return FSL_DDR_CS0_CS1; 7205614e71bSYork Sun #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) 7215614e71bSYork Sun #ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE 7225614e71bSYork Sun if (pdimm[0].n_ranks == 4) 7235614e71bSYork Sun return FSL_DDR_CS0_CS1_CS2_CS3; 7245614e71bSYork Sun #endif 7255614e71bSYork Sun if (pdimm[0].n_ranks == 2) { 7265614e71bSYork Sun if (pdimm[1].n_ranks == 2) 7275614e71bSYork Sun return FSL_DDR_CS0_CS1_CS2_CS3; 7285614e71bSYork Sun else 7295614e71bSYork Sun return FSL_DDR_CS0_CS1; 7305614e71bSYork Sun } 7315614e71bSYork Sun #endif 7325614e71bSYork Sun return 0; 7335614e71bSYork Sun } 7345614e71bSYork Sun 73556848428SYork Sun unsigned int populate_memctl_options(const common_timing_params_t *common_dimm, 7365614e71bSYork Sun memctl_options_t *popts, 7375614e71bSYork Sun dimm_params_t *pdimm, 7385614e71bSYork Sun unsigned int ctrl_num) 7395614e71bSYork Sun { 7405614e71bSYork Sun unsigned int i; 7415614e71bSYork Sun char buffer[HWCONFIG_BUFFER_SIZE]; 7425614e71bSYork Sun char *buf = NULL; 74334e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || \ 74434e026f9SYork Sun defined(CONFIG_SYS_FSL_DDR2) || \ 74534e026f9SYork Sun defined(CONFIG_SYS_FSL_DDR4) 7465614e71bSYork Sun const struct dynamic_odt *pdodt = odt_unknown; 7475614e71bSYork Sun #endif 7485614e71bSYork Sun ulong ddr_freq; 7495614e71bSYork Sun 7505614e71bSYork Sun /* 7515614e71bSYork Sun * Extract hwconfig from environment since we have not properly setup 7525614e71bSYork Sun * the environment but need it for ddr config params 7535614e71bSYork Sun */ 7545614e71bSYork Sun if (getenv_f("hwconfig", buffer, sizeof(buffer)) > 0) 7555614e71bSYork Sun buf = buffer; 7565614e71bSYork Sun 75734e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || \ 75834e026f9SYork Sun defined(CONFIG_SYS_FSL_DDR2) || \ 75934e026f9SYork Sun defined(CONFIG_SYS_FSL_DDR4) 7605614e71bSYork Sun /* Chip select options. */ 761349689b8SYork Sun #if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) 7625614e71bSYork Sun switch (pdimm[0].n_ranks) { 7635614e71bSYork Sun case 1: 7645614e71bSYork Sun pdodt = single_S; 7655614e71bSYork Sun break; 7665614e71bSYork Sun case 2: 7675614e71bSYork Sun pdodt = single_D; 7685614e71bSYork Sun break; 7695614e71bSYork Sun case 4: 7705614e71bSYork Sun pdodt = single_Q; 7715614e71bSYork Sun break; 7725614e71bSYork Sun } 773349689b8SYork Sun #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) 7745614e71bSYork Sun switch (pdimm[0].n_ranks) { 7755614e71bSYork Sun #ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE 7765614e71bSYork Sun case 4: 7775614e71bSYork Sun pdodt = single_Q; 7785614e71bSYork Sun if (pdimm[1].n_ranks) 779349689b8SYork Sun printf("Error: Quad- and Dual-rank DIMMs cannot be used together\n"); 7805614e71bSYork Sun break; 7815614e71bSYork Sun #endif 7825614e71bSYork Sun case 2: 7835614e71bSYork Sun switch (pdimm[1].n_ranks) { 7845614e71bSYork Sun case 2: 7855614e71bSYork Sun pdodt = dual_DD; 7865614e71bSYork Sun break; 7875614e71bSYork Sun case 1: 7885614e71bSYork Sun pdodt = dual_DS; 7895614e71bSYork Sun break; 7905614e71bSYork Sun case 0: 7915614e71bSYork Sun pdodt = dual_D0; 7925614e71bSYork Sun break; 7935614e71bSYork Sun } 7945614e71bSYork Sun break; 7955614e71bSYork Sun case 1: 7965614e71bSYork Sun switch (pdimm[1].n_ranks) { 7975614e71bSYork Sun case 2: 7985614e71bSYork Sun pdodt = dual_SD; 7995614e71bSYork Sun break; 8005614e71bSYork Sun case 1: 8015614e71bSYork Sun pdodt = dual_SS; 8025614e71bSYork Sun break; 8035614e71bSYork Sun case 0: 8045614e71bSYork Sun pdodt = dual_S0; 8055614e71bSYork Sun break; 8065614e71bSYork Sun } 8075614e71bSYork Sun break; 8085614e71bSYork Sun case 0: 8095614e71bSYork Sun switch (pdimm[1].n_ranks) { 8105614e71bSYork Sun case 2: 8115614e71bSYork Sun pdodt = dual_0D; 8125614e71bSYork Sun break; 8135614e71bSYork Sun case 1: 8145614e71bSYork Sun pdodt = dual_0S; 8155614e71bSYork Sun break; 8165614e71bSYork Sun } 8175614e71bSYork Sun break; 8185614e71bSYork Sun } 819349689b8SYork Sun #endif /* CONFIG_DIMM_SLOTS_PER_CTLR */ 820349689b8SYork Sun #endif /* CONFIG_SYS_FSL_DDR2, 3, 4 */ 8215614e71bSYork Sun 8225614e71bSYork Sun /* Pick chip-select local options. */ 8235614e71bSYork Sun for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 82434e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || \ 82534e026f9SYork Sun defined(CONFIG_SYS_FSL_DDR2) || \ 82634e026f9SYork Sun defined(CONFIG_SYS_FSL_DDR4) 8275614e71bSYork Sun popts->cs_local_opts[i].odt_rd_cfg = pdodt[i].odt_rd_cfg; 8285614e71bSYork Sun popts->cs_local_opts[i].odt_wr_cfg = pdodt[i].odt_wr_cfg; 8295614e71bSYork Sun popts->cs_local_opts[i].odt_rtt_norm = pdodt[i].odt_rtt_norm; 8305614e71bSYork Sun popts->cs_local_opts[i].odt_rtt_wr = pdodt[i].odt_rtt_wr; 8315614e71bSYork Sun #else 8325614e71bSYork Sun popts->cs_local_opts[i].odt_rd_cfg = FSL_DDR_ODT_NEVER; 8335614e71bSYork Sun popts->cs_local_opts[i].odt_wr_cfg = FSL_DDR_ODT_CS; 8345614e71bSYork Sun #endif 8355614e71bSYork Sun popts->cs_local_opts[i].auto_precharge = 0; 8365614e71bSYork Sun } 8375614e71bSYork Sun 8385614e71bSYork Sun /* Pick interleaving mode. */ 8395614e71bSYork Sun 8405614e71bSYork Sun /* 8415614e71bSYork Sun * 0 = no interleaving 8425614e71bSYork Sun * 1 = interleaving between 2 controllers 8435614e71bSYork Sun */ 8445614e71bSYork Sun popts->memctl_interleaving = 0; 8455614e71bSYork Sun 8465614e71bSYork Sun /* 8475614e71bSYork Sun * 0 = cacheline 8485614e71bSYork Sun * 1 = page 8495614e71bSYork Sun * 2 = (logical) bank 8505614e71bSYork Sun * 3 = superbank (only if CS interleaving is enabled) 8515614e71bSYork Sun */ 8525614e71bSYork Sun popts->memctl_interleaving_mode = 0; 8535614e71bSYork Sun 8545614e71bSYork Sun /* 8555614e71bSYork Sun * 0: cacheline: bit 30 of the 36-bit physical addr selects the memctl 8565614e71bSYork Sun * 1: page: bit to the left of the column bits selects the memctl 8575614e71bSYork Sun * 2: bank: bit to the left of the bank bits selects the memctl 8585614e71bSYork Sun * 3: superbank: bit to the left of the chip select selects the memctl 8595614e71bSYork Sun * 8605614e71bSYork Sun * NOTE: ba_intlv (rank interleaving) is independent of memory 8615614e71bSYork Sun * controller interleaving; it is only within a memory controller. 8625614e71bSYork Sun * Must use superbank interleaving if rank interleaving is used and 8635614e71bSYork Sun * memory controller interleaving is enabled. 8645614e71bSYork Sun */ 8655614e71bSYork Sun 8665614e71bSYork Sun /* 8675614e71bSYork Sun * 0 = no 8685614e71bSYork Sun * 0x40 = CS0,CS1 8695614e71bSYork Sun * 0x20 = CS2,CS3 8705614e71bSYork Sun * 0x60 = CS0,CS1 + CS2,CS3 8715614e71bSYork Sun * 0x04 = CS0,CS1,CS2,CS3 8725614e71bSYork Sun */ 8735614e71bSYork Sun popts->ba_intlv_ctl = 0; 8745614e71bSYork Sun 8755614e71bSYork Sun /* Memory Organization Parameters */ 87656848428SYork Sun popts->registered_dimm_en = common_dimm->all_dimms_registered; 8775614e71bSYork Sun 8785614e71bSYork Sun /* Operational Mode Paramters */ 8795614e71bSYork Sun 8805614e71bSYork Sun /* Pick ECC modes */ 8815614e71bSYork Sun popts->ecc_mode = 0; /* 0 = disabled, 1 = enabled */ 8825614e71bSYork Sun #ifdef CONFIG_DDR_ECC 8835614e71bSYork Sun if (hwconfig_sub_f("fsl_ddr", "ecc", buf)) { 8845614e71bSYork Sun if (hwconfig_subarg_cmp_f("fsl_ddr", "ecc", "on", buf)) 8855614e71bSYork Sun popts->ecc_mode = 1; 8865614e71bSYork Sun } else 8875614e71bSYork Sun popts->ecc_mode = 1; 8885614e71bSYork Sun #endif 889b06f6f2fSYork Sun /* 1 = use memory controler to init data */ 890b06f6f2fSYork Sun popts->ecc_init_using_memctl = popts->ecc_mode ? 1 : 0; 8915614e71bSYork Sun 8925614e71bSYork Sun /* 8935614e71bSYork Sun * Choose DQS config 8945614e71bSYork Sun * 0 for DDR1 8955614e71bSYork Sun * 1 for DDR2 8965614e71bSYork Sun */ 8975614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) 8985614e71bSYork Sun popts->dqs_config = 0; 8995614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2) || defined(CONFIG_SYS_FSL_DDR3) 9005614e71bSYork Sun popts->dqs_config = 1; 9015614e71bSYork Sun #endif 9025614e71bSYork Sun 9035614e71bSYork Sun /* Choose self-refresh during sleep. */ 9045614e71bSYork Sun popts->self_refresh_in_sleep = 1; 9055614e71bSYork Sun 9065614e71bSYork Sun /* Choose dynamic power management mode. */ 9075614e71bSYork Sun popts->dynamic_power = 0; 9085614e71bSYork Sun 9095614e71bSYork Sun /* 9105614e71bSYork Sun * check first dimm for primary sdram width 9115614e71bSYork Sun * presuming all dimms are similar 9125614e71bSYork Sun * 0 = 64-bit, 1 = 32-bit, 2 = 16-bit 9135614e71bSYork Sun */ 9145614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2) 9155614e71bSYork Sun if (pdimm[0].n_ranks != 0) { 9165614e71bSYork Sun if ((pdimm[0].data_width >= 64) && \ 9175614e71bSYork Sun (pdimm[0].data_width <= 72)) 9185614e71bSYork Sun popts->data_bus_width = 0; 919*0e0de24bSxypron.glpk@gmx.de else if ((pdimm[0].data_width >= 32) && \ 9205614e71bSYork Sun (pdimm[0].data_width <= 40)) 9215614e71bSYork Sun popts->data_bus_width = 1; 9225614e71bSYork Sun else { 9235614e71bSYork Sun panic("Error: data width %u is invalid!\n", 9245614e71bSYork Sun pdimm[0].data_width); 9255614e71bSYork Sun } 9265614e71bSYork Sun } 9275614e71bSYork Sun #else 9285614e71bSYork Sun if (pdimm[0].n_ranks != 0) { 9295614e71bSYork Sun if (pdimm[0].primary_sdram_width == 64) 9305614e71bSYork Sun popts->data_bus_width = 0; 9315614e71bSYork Sun else if (pdimm[0].primary_sdram_width == 32) 9325614e71bSYork Sun popts->data_bus_width = 1; 9335614e71bSYork Sun else if (pdimm[0].primary_sdram_width == 16) 9345614e71bSYork Sun popts->data_bus_width = 2; 9355614e71bSYork Sun else { 9365614e71bSYork Sun panic("Error: primary sdram width %u is invalid!\n", 9375614e71bSYork Sun pdimm[0].primary_sdram_width); 9385614e71bSYork Sun } 9395614e71bSYork Sun } 9405614e71bSYork Sun #endif 9415614e71bSYork Sun 9425614e71bSYork Sun popts->x4_en = (pdimm[0].device_width == 4) ? 1 : 0; 9435614e71bSYork Sun 9445614e71bSYork Sun /* Choose burst length. */ 94534e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 9465614e71bSYork Sun #if defined(CONFIG_E500MC) 9475614e71bSYork Sun popts->otf_burst_chop_en = 0; /* on-the-fly burst chop disable */ 9485614e71bSYork Sun popts->burst_length = DDR_BL8; /* Fixed 8-beat burst len */ 9495614e71bSYork Sun #else 9505614e71bSYork Sun if ((popts->data_bus_width == 1) || (popts->data_bus_width == 2)) { 9515614e71bSYork Sun /* 32-bit or 16-bit bus */ 9525614e71bSYork Sun popts->otf_burst_chop_en = 0; 9535614e71bSYork Sun popts->burst_length = DDR_BL8; 9545614e71bSYork Sun } else { 9555614e71bSYork Sun popts->otf_burst_chop_en = 1; /* on-the-fly burst chop */ 9565614e71bSYork Sun popts->burst_length = DDR_OTF; /* on-the-fly BC4 and BL8 */ 9575614e71bSYork Sun } 9585614e71bSYork Sun #endif 9595614e71bSYork Sun #else 9605614e71bSYork Sun popts->burst_length = DDR_BL4; /* has to be 4 for DDR2 */ 9615614e71bSYork Sun #endif 9625614e71bSYork Sun 9635614e71bSYork Sun /* Choose ddr controller address mirror mode */ 96434e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 9656b95be22SYork Sun for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) { 9666b95be22SYork Sun if (pdimm[i].n_ranks) { 9676b95be22SYork Sun popts->mirrored_dimm = pdimm[i].mirrored_dimm; 9686b95be22SYork Sun break; 9696b95be22SYork Sun } 9706b95be22SYork Sun } 9715614e71bSYork Sun #endif 9725614e71bSYork Sun 9735614e71bSYork Sun /* Global Timing Parameters. */ 97403e664d8SYork Sun debug("mclk_ps = %u ps\n", get_memory_clk_period_ps(ctrl_num)); 9755614e71bSYork Sun 9765614e71bSYork Sun /* Pick a caslat override. */ 9775614e71bSYork Sun popts->cas_latency_override = 0; 9785614e71bSYork Sun popts->cas_latency_override_value = 3; 9795614e71bSYork Sun if (popts->cas_latency_override) { 9805614e71bSYork Sun debug("using caslat override value = %u\n", 9815614e71bSYork Sun popts->cas_latency_override_value); 9825614e71bSYork Sun } 9835614e71bSYork Sun 9845614e71bSYork Sun /* Decide whether to use the computed derated latency */ 9855614e71bSYork Sun popts->use_derated_caslat = 0; 9865614e71bSYork Sun 9875614e71bSYork Sun /* Choose an additive latency. */ 9885614e71bSYork Sun popts->additive_latency_override = 0; 9895614e71bSYork Sun popts->additive_latency_override_value = 3; 9905614e71bSYork Sun if (popts->additive_latency_override) { 9915614e71bSYork Sun debug("using additive latency override value = %u\n", 9925614e71bSYork Sun popts->additive_latency_override_value); 9935614e71bSYork Sun } 9945614e71bSYork Sun 9955614e71bSYork Sun /* 9965614e71bSYork Sun * 2T_EN setting 9975614e71bSYork Sun * 9985614e71bSYork Sun * Factors to consider for 2T_EN: 9995614e71bSYork Sun * - number of DIMMs installed 10005614e71bSYork Sun * - number of components, number of active ranks 10015614e71bSYork Sun * - how much time you want to spend playing around 10025614e71bSYork Sun */ 10035614e71bSYork Sun popts->twot_en = 0; 10045614e71bSYork Sun popts->threet_en = 0; 10055614e71bSYork Sun 1006eb118807SShengzhou Liu /* for RDIMM and DDR4 UDIMM/discrete memory, address parity enable */ 1007eb118807SShengzhou Liu if (popts->registered_dimm_en) 1008eb118807SShengzhou Liu popts->ap_en = 1; /* 0 = disable, 1 = enable */ 1009eb118807SShengzhou Liu else 1010eb118807SShengzhou Liu popts->ap_en = 0; /* disabled for DDR4 UDIMM/discrete default */ 1011eb118807SShengzhou Liu 1012eb118807SShengzhou Liu if (hwconfig_sub_f("fsl_ddr", "parity", buf)) { 1013eb118807SShengzhou Liu if (hwconfig_subarg_cmp_f("fsl_ddr", "parity", "on", buf)) { 1014eb118807SShengzhou Liu if (popts->registered_dimm_en || 1015eb118807SShengzhou Liu (CONFIG_FSL_SDRAM_TYPE == SDRAM_TYPE_DDR4)) 10165614e71bSYork Sun popts->ap_en = 1; 1017eb118807SShengzhou Liu } 1018eb118807SShengzhou Liu } 10195614e71bSYork Sun 10205614e71bSYork Sun /* 10215614e71bSYork Sun * BSTTOPRE precharge interval 10225614e71bSYork Sun * 10235614e71bSYork Sun * Set this to 0 for global auto precharge 102434e026f9SYork Sun * The value of 0x100 has been used for DDR1, DDR2, DDR3. 102534e026f9SYork Sun * It is not wrong. Any value should be OK. The performance depends on 102656848428SYork Sun * applications. There is no one good value for all. One way to set 102756848428SYork Sun * is to use 1/4 of refint value. 10285614e71bSYork Sun */ 102956848428SYork Sun popts->bstopre = picos_to_mclk(ctrl_num, common_dimm->refresh_rate_ps) 103056848428SYork Sun >> 2; 10315614e71bSYork Sun 10325614e71bSYork Sun /* 10335614e71bSYork Sun * Window for four activates -- tFAW 10345614e71bSYork Sun * 10355614e71bSYork Sun * FIXME: UM: applies only to DDR2/DDR3 with eight logical banks only 10365614e71bSYork Sun * FIXME: varies depending upon number of column addresses or data 10375614e71bSYork Sun * FIXME: width, was considering looking at pdimm->primary_sdram_width 10385614e71bSYork Sun */ 10395614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) 104003e664d8SYork Sun popts->tfaw_window_four_activates_ps = mclk_to_picos(ctrl_num, 1); 10415614e71bSYork Sun 10425614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2) 10435614e71bSYork Sun /* 10445614e71bSYork Sun * x4/x8; some datasheets have 35000 10455614e71bSYork Sun * x16 wide columns only? Use 50000? 10465614e71bSYork Sun */ 10475614e71bSYork Sun popts->tfaw_window_four_activates_ps = 37500; 10485614e71bSYork Sun 104934e026f9SYork Sun #else 10505614e71bSYork Sun popts->tfaw_window_four_activates_ps = pdimm[0].tfaw_ps; 10515614e71bSYork Sun #endif 10525614e71bSYork Sun popts->zq_en = 0; 10535614e71bSYork Sun popts->wrlvl_en = 0; 105434e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) 10555614e71bSYork Sun /* 10565614e71bSYork Sun * due to ddr3 dimm is fly-by topology 10575614e71bSYork Sun * we suggest to enable write leveling to 10585614e71bSYork Sun * meet the tQDSS under different loading. 10595614e71bSYork Sun */ 10605614e71bSYork Sun popts->wrlvl_en = 1; 10615614e71bSYork Sun popts->zq_en = 1; 10625614e71bSYork Sun popts->wrlvl_override = 0; 10635614e71bSYork Sun #endif 10645614e71bSYork Sun 10655614e71bSYork Sun /* 10665614e71bSYork Sun * Check interleaving configuration from environment. 10675614e71bSYork Sun * Please refer to doc/README.fsl-ddr for the detail. 10685614e71bSYork Sun * 10695614e71bSYork Sun * If memory controller interleaving is enabled, then the data 10705614e71bSYork Sun * bus widths must be programmed identically for all memory controllers. 10715614e71bSYork Sun * 10726b1e1254SYork Sun * Attempt to set all controllers to the same chip select 10735614e71bSYork Sun * interleaving mode. It will do a best effort to get the 10745614e71bSYork Sun * requested ranks interleaved together such that the result 10755614e71bSYork Sun * should be a subset of the requested configuration. 10766b1e1254SYork Sun * 10776b1e1254SYork Sun * if CONFIG_SYS_FSL_DDR_INTLV_256B is defined, mandatory interleaving 10786b1e1254SYork Sun * with 256 Byte is enabled. 10795614e71bSYork Sun */ 108051370d56SYork Sun #if (CONFIG_SYS_NUM_DDR_CTLRS > 1) 10815614e71bSYork Sun if (!hwconfig_sub_f("fsl_ddr", "ctlr_intlv", buf)) 10826b1e1254SYork Sun #ifdef CONFIG_SYS_FSL_DDR_INTLV_256B 10836b1e1254SYork Sun ; 10846b1e1254SYork Sun #else 10855614e71bSYork Sun goto done; 10866b1e1254SYork Sun #endif 10875614e71bSYork Sun if (pdimm[0].n_ranks == 0) { 10885614e71bSYork Sun printf("There is no rank on CS0 for controller %d.\n", ctrl_num); 10895614e71bSYork Sun popts->memctl_interleaving = 0; 10905614e71bSYork Sun goto done; 10915614e71bSYork Sun } 10925614e71bSYork Sun popts->memctl_interleaving = 1; 10936b1e1254SYork Sun #ifdef CONFIG_SYS_FSL_DDR_INTLV_256B 10946b1e1254SYork Sun popts->memctl_interleaving_mode = FSL_DDR_256B_INTERLEAVING; 10956b1e1254SYork Sun popts->memctl_interleaving = 1; 10966b1e1254SYork Sun debug("256 Byte interleaving\n"); 1097349689b8SYork Sun #else 10985614e71bSYork Sun /* 10995614e71bSYork Sun * test null first. if CONFIG_HWCONFIG is not defined 11005614e71bSYork Sun * hwconfig_arg_cmp returns non-zero 11015614e71bSYork Sun */ 11025614e71bSYork Sun if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv", 11035614e71bSYork Sun "null", buf)) { 11045614e71bSYork Sun popts->memctl_interleaving = 0; 11055614e71bSYork Sun debug("memory controller interleaving disabled.\n"); 11065614e71bSYork Sun } else if (hwconfig_subarg_cmp_f("fsl_ddr", 11075614e71bSYork Sun "ctlr_intlv", 11085614e71bSYork Sun "cacheline", buf)) { 11095614e71bSYork Sun popts->memctl_interleaving_mode = 111051370d56SYork Sun ((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ? 11115614e71bSYork Sun 0 : FSL_DDR_CACHE_LINE_INTERLEAVING; 11125614e71bSYork Sun popts->memctl_interleaving = 111351370d56SYork Sun ((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ? 11145614e71bSYork Sun 0 : 1; 11155614e71bSYork Sun } else if (hwconfig_subarg_cmp_f("fsl_ddr", 11165614e71bSYork Sun "ctlr_intlv", 11175614e71bSYork Sun "page", buf)) { 11185614e71bSYork Sun popts->memctl_interleaving_mode = 111951370d56SYork Sun ((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ? 11205614e71bSYork Sun 0 : FSL_DDR_PAGE_INTERLEAVING; 11215614e71bSYork Sun popts->memctl_interleaving = 112251370d56SYork Sun ((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ? 11235614e71bSYork Sun 0 : 1; 11245614e71bSYork Sun } else if (hwconfig_subarg_cmp_f("fsl_ddr", 11255614e71bSYork Sun "ctlr_intlv", 11265614e71bSYork Sun "bank", buf)) { 11275614e71bSYork Sun popts->memctl_interleaving_mode = 112851370d56SYork Sun ((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ? 11295614e71bSYork Sun 0 : FSL_DDR_BANK_INTERLEAVING; 11305614e71bSYork Sun popts->memctl_interleaving = 113151370d56SYork Sun ((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ? 11325614e71bSYork Sun 0 : 1; 11335614e71bSYork Sun } else if (hwconfig_subarg_cmp_f("fsl_ddr", 11345614e71bSYork Sun "ctlr_intlv", 11355614e71bSYork Sun "superbank", buf)) { 11365614e71bSYork Sun popts->memctl_interleaving_mode = 113751370d56SYork Sun ((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ? 11385614e71bSYork Sun 0 : FSL_DDR_SUPERBANK_INTERLEAVING; 11395614e71bSYork Sun popts->memctl_interleaving = 114051370d56SYork Sun ((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ? 11415614e71bSYork Sun 0 : 1; 114251370d56SYork Sun #if (CONFIG_SYS_NUM_DDR_CTLRS == 3) 11435614e71bSYork Sun } else if (hwconfig_subarg_cmp_f("fsl_ddr", 11445614e71bSYork Sun "ctlr_intlv", 11455614e71bSYork Sun "3way_1KB", buf)) { 11465614e71bSYork Sun popts->memctl_interleaving_mode = 11475614e71bSYork Sun FSL_DDR_3WAY_1KB_INTERLEAVING; 11485614e71bSYork Sun } else if (hwconfig_subarg_cmp_f("fsl_ddr", 11495614e71bSYork Sun "ctlr_intlv", 11505614e71bSYork Sun "3way_4KB", buf)) { 11515614e71bSYork Sun popts->memctl_interleaving_mode = 11525614e71bSYork Sun FSL_DDR_3WAY_4KB_INTERLEAVING; 11535614e71bSYork Sun } else if (hwconfig_subarg_cmp_f("fsl_ddr", 11545614e71bSYork Sun "ctlr_intlv", 11555614e71bSYork Sun "3way_8KB", buf)) { 11565614e71bSYork Sun popts->memctl_interleaving_mode = 11575614e71bSYork Sun FSL_DDR_3WAY_8KB_INTERLEAVING; 115851370d56SYork Sun #elif (CONFIG_SYS_NUM_DDR_CTLRS == 4) 11595614e71bSYork Sun } else if (hwconfig_subarg_cmp_f("fsl_ddr", 11605614e71bSYork Sun "ctlr_intlv", 11615614e71bSYork Sun "4way_1KB", buf)) { 11625614e71bSYork Sun popts->memctl_interleaving_mode = 11635614e71bSYork Sun FSL_DDR_4WAY_1KB_INTERLEAVING; 11645614e71bSYork Sun } else if (hwconfig_subarg_cmp_f("fsl_ddr", 11655614e71bSYork Sun "ctlr_intlv", 11665614e71bSYork Sun "4way_4KB", buf)) { 11675614e71bSYork Sun popts->memctl_interleaving_mode = 11685614e71bSYork Sun FSL_DDR_4WAY_4KB_INTERLEAVING; 11695614e71bSYork Sun } else if (hwconfig_subarg_cmp_f("fsl_ddr", 11705614e71bSYork Sun "ctlr_intlv", 11715614e71bSYork Sun "4way_8KB", buf)) { 11725614e71bSYork Sun popts->memctl_interleaving_mode = 11735614e71bSYork Sun FSL_DDR_4WAY_8KB_INTERLEAVING; 11745614e71bSYork Sun #endif 11755614e71bSYork Sun } else { 11765614e71bSYork Sun popts->memctl_interleaving = 0; 11775614e71bSYork Sun printf("hwconfig has unrecognized parameter for ctlr_intlv.\n"); 11785614e71bSYork Sun } 1179349689b8SYork Sun #endif /* CONFIG_SYS_FSL_DDR_INTLV_256B */ 11805614e71bSYork Sun done: 118151370d56SYork Sun #endif /* CONFIG_SYS_NUM_DDR_CTLRS > 1 */ 11825614e71bSYork Sun if ((hwconfig_sub_f("fsl_ddr", "bank_intlv", buf)) && 11835614e71bSYork Sun (CONFIG_CHIP_SELECTS_PER_CTRL > 1)) { 11845614e71bSYork Sun /* test null first. if CONFIG_HWCONFIG is not defined, 11855614e71bSYork Sun * hwconfig_subarg_cmp_f returns non-zero */ 11865614e71bSYork Sun if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv", 11875614e71bSYork Sun "null", buf)) 11885614e71bSYork Sun debug("bank interleaving disabled.\n"); 11895614e71bSYork Sun else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv", 11905614e71bSYork Sun "cs0_cs1", buf)) 11915614e71bSYork Sun popts->ba_intlv_ctl = FSL_DDR_CS0_CS1; 11925614e71bSYork Sun else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv", 11935614e71bSYork Sun "cs2_cs3", buf)) 11945614e71bSYork Sun popts->ba_intlv_ctl = FSL_DDR_CS2_CS3; 11955614e71bSYork Sun else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv", 11965614e71bSYork Sun "cs0_cs1_and_cs2_cs3", buf)) 11975614e71bSYork Sun popts->ba_intlv_ctl = FSL_DDR_CS0_CS1_AND_CS2_CS3; 11985614e71bSYork Sun else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv", 11995614e71bSYork Sun "cs0_cs1_cs2_cs3", buf)) 12005614e71bSYork Sun popts->ba_intlv_ctl = FSL_DDR_CS0_CS1_CS2_CS3; 12015614e71bSYork Sun else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv", 12025614e71bSYork Sun "auto", buf)) 12035614e71bSYork Sun popts->ba_intlv_ctl = auto_bank_intlv(pdimm); 12045614e71bSYork Sun else 12055614e71bSYork Sun printf("hwconfig has unrecognized parameter for bank_intlv.\n"); 12065614e71bSYork Sun switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) { 12075614e71bSYork Sun case FSL_DDR_CS0_CS1_CS2_CS3: 12085614e71bSYork Sun #if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) 12095614e71bSYork Sun if (pdimm[0].n_ranks < 4) { 12105614e71bSYork Sun popts->ba_intlv_ctl = 0; 12115614e71bSYork Sun printf("Not enough bank(chip-select) for " 12125614e71bSYork Sun "CS0+CS1+CS2+CS3 on controller %d, " 12135614e71bSYork Sun "interleaving disabled!\n", ctrl_num); 12145614e71bSYork Sun } 12155614e71bSYork Sun #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) 12165614e71bSYork Sun #ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE 12175614e71bSYork Sun if (pdimm[0].n_ranks == 4) 12185614e71bSYork Sun break; 12195614e71bSYork Sun #endif 12205614e71bSYork Sun if ((pdimm[0].n_ranks < 2) && (pdimm[1].n_ranks < 2)) { 12215614e71bSYork Sun popts->ba_intlv_ctl = 0; 12225614e71bSYork Sun printf("Not enough bank(chip-select) for " 12235614e71bSYork Sun "CS0+CS1+CS2+CS3 on controller %d, " 12245614e71bSYork Sun "interleaving disabled!\n", ctrl_num); 12255614e71bSYork Sun } 12265614e71bSYork Sun if (pdimm[0].capacity != pdimm[1].capacity) { 12275614e71bSYork Sun popts->ba_intlv_ctl = 0; 12285614e71bSYork Sun printf("Not identical DIMM size for " 12295614e71bSYork Sun "CS0+CS1+CS2+CS3 on controller %d, " 12305614e71bSYork Sun "interleaving disabled!\n", ctrl_num); 12315614e71bSYork Sun } 12325614e71bSYork Sun #endif 12335614e71bSYork Sun break; 12345614e71bSYork Sun case FSL_DDR_CS0_CS1: 12355614e71bSYork Sun if (pdimm[0].n_ranks < 2) { 12365614e71bSYork Sun popts->ba_intlv_ctl = 0; 12375614e71bSYork Sun printf("Not enough bank(chip-select) for " 12385614e71bSYork Sun "CS0+CS1 on controller %d, " 12395614e71bSYork Sun "interleaving disabled!\n", ctrl_num); 12405614e71bSYork Sun } 12415614e71bSYork Sun break; 12425614e71bSYork Sun case FSL_DDR_CS2_CS3: 12435614e71bSYork Sun #if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) 12445614e71bSYork Sun if (pdimm[0].n_ranks < 4) { 12455614e71bSYork Sun popts->ba_intlv_ctl = 0; 12465614e71bSYork Sun printf("Not enough bank(chip-select) for CS2+CS3 " 12475614e71bSYork Sun "on controller %d, interleaving disabled!\n", ctrl_num); 12485614e71bSYork Sun } 12495614e71bSYork Sun #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) 12505614e71bSYork Sun if (pdimm[1].n_ranks < 2) { 12515614e71bSYork Sun popts->ba_intlv_ctl = 0; 12525614e71bSYork Sun printf("Not enough bank(chip-select) for CS2+CS3 " 12535614e71bSYork Sun "on controller %d, interleaving disabled!\n", ctrl_num); 12545614e71bSYork Sun } 12555614e71bSYork Sun #endif 12565614e71bSYork Sun break; 12575614e71bSYork Sun case FSL_DDR_CS0_CS1_AND_CS2_CS3: 12585614e71bSYork Sun #if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) 12595614e71bSYork Sun if (pdimm[0].n_ranks < 4) { 12605614e71bSYork Sun popts->ba_intlv_ctl = 0; 12615614e71bSYork Sun printf("Not enough bank(CS) for CS0+CS1 and " 12625614e71bSYork Sun "CS2+CS3 on controller %d, " 12635614e71bSYork Sun "interleaving disabled!\n", ctrl_num); 12645614e71bSYork Sun } 12655614e71bSYork Sun #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) 12665614e71bSYork Sun if ((pdimm[0].n_ranks < 2) || (pdimm[1].n_ranks < 2)) { 12675614e71bSYork Sun popts->ba_intlv_ctl = 0; 12685614e71bSYork Sun printf("Not enough bank(CS) for CS0+CS1 and " 12695614e71bSYork Sun "CS2+CS3 on controller %d, " 12705614e71bSYork Sun "interleaving disabled!\n", ctrl_num); 12715614e71bSYork Sun } 12725614e71bSYork Sun #endif 12735614e71bSYork Sun break; 12745614e71bSYork Sun default: 12755614e71bSYork Sun popts->ba_intlv_ctl = 0; 12765614e71bSYork Sun break; 12775614e71bSYork Sun } 12785614e71bSYork Sun } 12795614e71bSYork Sun 12805614e71bSYork Sun if (hwconfig_sub_f("fsl_ddr", "addr_hash", buf)) { 12815614e71bSYork Sun if (hwconfig_subarg_cmp_f("fsl_ddr", "addr_hash", "null", buf)) 12825614e71bSYork Sun popts->addr_hash = 0; 12835614e71bSYork Sun else if (hwconfig_subarg_cmp_f("fsl_ddr", "addr_hash", 12845614e71bSYork Sun "true", buf)) 12855614e71bSYork Sun popts->addr_hash = 1; 12865614e71bSYork Sun } 12875614e71bSYork Sun 12885614e71bSYork Sun if (pdimm[0].n_ranks == 4) 12895614e71bSYork Sun popts->quad_rank_present = 1; 12905614e71bSYork Sun 129103e664d8SYork Sun ddr_freq = get_ddr_freq(ctrl_num) / 1000000; 12925614e71bSYork Sun if (popts->registered_dimm_en) { 12935614e71bSYork Sun popts->rcw_override = 1; 12945614e71bSYork Sun popts->rcw_1 = 0x000a5a00; 12955614e71bSYork Sun if (ddr_freq <= 800) 12965614e71bSYork Sun popts->rcw_2 = 0x00000000; 12975614e71bSYork Sun else if (ddr_freq <= 1066) 12985614e71bSYork Sun popts->rcw_2 = 0x00100000; 12995614e71bSYork Sun else if (ddr_freq <= 1333) 13005614e71bSYork Sun popts->rcw_2 = 0x00200000; 13015614e71bSYork Sun else 13025614e71bSYork Sun popts->rcw_2 = 0x00300000; 13035614e71bSYork Sun } 13045614e71bSYork Sun 13055614e71bSYork Sun fsl_ddr_board_options(popts, pdimm, ctrl_num); 13065614e71bSYork Sun 13075614e71bSYork Sun return 0; 13085614e71bSYork Sun } 13095614e71bSYork Sun 13105614e71bSYork Sun void check_interleaving_options(fsl_ddr_info_t *pinfo) 13115614e71bSYork Sun { 13125614e71bSYork Sun int i, j, k, check_n_ranks, intlv_invalid = 0; 13135614e71bSYork Sun unsigned int check_intlv, check_n_row_addr, check_n_col_addr; 13145614e71bSYork Sun unsigned long long check_rank_density; 13155614e71bSYork Sun struct dimm_params_s *dimm; 13161d71efbbSYork Sun int first_ctrl = pinfo->first_ctrl; 13171d71efbbSYork Sun int last_ctrl = first_ctrl + pinfo->num_ctrls - 1; 13181d71efbbSYork Sun 13195614e71bSYork Sun /* 13205614e71bSYork Sun * Check if all controllers are configured for memory 13215614e71bSYork Sun * controller interleaving. Identical dimms are recommended. At least 13225614e71bSYork Sun * the size, row and col address should be checked. 13235614e71bSYork Sun */ 13245614e71bSYork Sun j = 0; 13251d71efbbSYork Sun check_n_ranks = pinfo->dimm_params[first_ctrl][0].n_ranks; 13261d71efbbSYork Sun check_rank_density = pinfo->dimm_params[first_ctrl][0].rank_density; 13271d71efbbSYork Sun check_n_row_addr = pinfo->dimm_params[first_ctrl][0].n_row_addr; 13281d71efbbSYork Sun check_n_col_addr = pinfo->dimm_params[first_ctrl][0].n_col_addr; 13291d71efbbSYork Sun check_intlv = pinfo->memctl_opts[first_ctrl].memctl_interleaving_mode; 13301d71efbbSYork Sun for (i = first_ctrl; i <= last_ctrl; i++) { 13315614e71bSYork Sun dimm = &pinfo->dimm_params[i][0]; 13325614e71bSYork Sun if (!pinfo->memctl_opts[i].memctl_interleaving) { 13335614e71bSYork Sun continue; 13345614e71bSYork Sun } else if (((check_rank_density != dimm->rank_density) || 13355614e71bSYork Sun (check_n_ranks != dimm->n_ranks) || 13365614e71bSYork Sun (check_n_row_addr != dimm->n_row_addr) || 13375614e71bSYork Sun (check_n_col_addr != dimm->n_col_addr) || 13385614e71bSYork Sun (check_intlv != 13395614e71bSYork Sun pinfo->memctl_opts[i].memctl_interleaving_mode))){ 13405614e71bSYork Sun intlv_invalid = 1; 13415614e71bSYork Sun break; 13425614e71bSYork Sun } else { 13435614e71bSYork Sun j++; 13445614e71bSYork Sun } 13455614e71bSYork Sun 13465614e71bSYork Sun } 13475614e71bSYork Sun if (intlv_invalid) { 13481d71efbbSYork Sun for (i = first_ctrl; i <= last_ctrl; i++) 13495614e71bSYork Sun pinfo->memctl_opts[i].memctl_interleaving = 0; 13505614e71bSYork Sun printf("Not all DIMMs are identical. " 13515614e71bSYork Sun "Memory controller interleaving disabled.\n"); 13525614e71bSYork Sun } else { 13535614e71bSYork Sun switch (check_intlv) { 13546b1e1254SYork Sun case FSL_DDR_256B_INTERLEAVING: 13555614e71bSYork Sun case FSL_DDR_CACHE_LINE_INTERLEAVING: 13565614e71bSYork Sun case FSL_DDR_PAGE_INTERLEAVING: 13575614e71bSYork Sun case FSL_DDR_BANK_INTERLEAVING: 13585614e71bSYork Sun case FSL_DDR_SUPERBANK_INTERLEAVING: 135951370d56SYork Sun #if (3 == CONFIG_SYS_NUM_DDR_CTLRS) 13605614e71bSYork Sun k = 2; 1361349689b8SYork Sun #else 136251370d56SYork Sun k = CONFIG_SYS_NUM_DDR_CTLRS; 1363349689b8SYork Sun #endif 13645614e71bSYork Sun break; 13655614e71bSYork Sun case FSL_DDR_3WAY_1KB_INTERLEAVING: 13665614e71bSYork Sun case FSL_DDR_3WAY_4KB_INTERLEAVING: 13675614e71bSYork Sun case FSL_DDR_3WAY_8KB_INTERLEAVING: 13685614e71bSYork Sun case FSL_DDR_4WAY_1KB_INTERLEAVING: 13695614e71bSYork Sun case FSL_DDR_4WAY_4KB_INTERLEAVING: 13705614e71bSYork Sun case FSL_DDR_4WAY_8KB_INTERLEAVING: 13715614e71bSYork Sun default: 137251370d56SYork Sun k = CONFIG_SYS_NUM_DDR_CTLRS; 13735614e71bSYork Sun break; 13745614e71bSYork Sun } 13755614e71bSYork Sun debug("%d of %d controllers are interleaving.\n", j, k); 13765614e71bSYork Sun if (j && (j != k)) { 13771d71efbbSYork Sun for (i = first_ctrl; i <= last_ctrl; i++) 13785614e71bSYork Sun pinfo->memctl_opts[i].memctl_interleaving = 0; 13791d71efbbSYork Sun if ((last_ctrl - first_ctrl) > 1) 13801d71efbbSYork Sun puts("Not all controllers have compatible interleaving mode. All disabled.\n"); 13815614e71bSYork Sun } 13825614e71bSYork Sun } 13835614e71bSYork Sun debug("Checking interleaving options completed\n"); 13845614e71bSYork Sun } 13855614e71bSYork Sun 13865614e71bSYork Sun int fsl_use_spd(void) 13875614e71bSYork Sun { 13885614e71bSYork Sun int use_spd = 0; 13895614e71bSYork Sun 13905614e71bSYork Sun #ifdef CONFIG_DDR_SPD 13915614e71bSYork Sun char buffer[HWCONFIG_BUFFER_SIZE]; 13925614e71bSYork Sun char *buf = NULL; 13935614e71bSYork Sun 13945614e71bSYork Sun /* 13955614e71bSYork Sun * Extract hwconfig from environment since we have not properly setup 13965614e71bSYork Sun * the environment but need it for ddr config params 13975614e71bSYork Sun */ 13985614e71bSYork Sun if (getenv_f("hwconfig", buffer, sizeof(buffer)) > 0) 13995614e71bSYork Sun buf = buffer; 14005614e71bSYork Sun 14015614e71bSYork Sun /* if hwconfig is not enabled, or "sdram" is not defined, use spd */ 14025614e71bSYork Sun if (hwconfig_sub_f("fsl_ddr", "sdram", buf)) { 14035614e71bSYork Sun if (hwconfig_subarg_cmp_f("fsl_ddr", "sdram", "spd", buf)) 14045614e71bSYork Sun use_spd = 1; 14055614e71bSYork Sun else if (hwconfig_subarg_cmp_f("fsl_ddr", "sdram", 14065614e71bSYork Sun "fixed", buf)) 14075614e71bSYork Sun use_spd = 0; 14085614e71bSYork Sun else 14095614e71bSYork Sun use_spd = 1; 14105614e71bSYork Sun } else 14115614e71bSYork Sun use_spd = 1; 14125614e71bSYork Sun #endif 14135614e71bSYork Sun 14145614e71bSYork Sun return use_spd; 14155614e71bSYork Sun } 1416