1 /* 2 * Based on corenet_ds ddr code 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <i2c.h> 9 #include <hwconfig.h> 10 #include <asm/mmu.h> 11 #include <fsl_ddr_sdram.h> 12 #include <fsl_ddr_dimm_params.h> 13 #include <asm/fsl_law.h> 14 15 DECLARE_GLOBAL_DATA_PTR; 16 17 18 struct board_specific_parameters { 19 u32 n_ranks; 20 u32 datarate_mhz_high; 21 u32 clk_adjust; 22 u32 wrlvl_start; 23 u32 cpo; 24 u32 write_data_delay; 25 u32 force_2t; 26 }; 27 28 /* 29 * This table contains all valid speeds we want to override with board 30 * specific parameters. datarate_mhz_high values need to be in ascending order 31 * for each n_ranks group. 32 */ 33 static const struct board_specific_parameters udimm0[] = { 34 /* 35 * memory controller 0 36 * num| hi| clk| wrlvl | cpo |wrdata|2T 37 * ranks| mhz|adjst| start | |delay | 38 */ 39 {4, 850, 4, 6, 0xff, 2, 0}, 40 {4, 950, 5, 7, 0xff, 2, 0}, 41 {4, 1050, 5, 8, 0xff, 2, 0}, 42 {4, 1250, 5, 10, 0xff, 2, 0}, 43 {4, 1350, 5, 11, 0xff, 2, 0}, 44 {4, 1666, 5, 12, 0xff, 2, 0}, 45 {2, 850, 5, 6, 0xff, 2, 0}, 46 {2, 1050, 5, 7, 0xff, 2, 0}, 47 {2, 1250, 4, 6, 0xff, 2, 0}, 48 {2, 1350, 5, 7, 0xff, 2, 0}, 49 {2, 1666, 5, 8, 0xff, 2, 0}, 50 {1, 1250, 4, 6, 0xff, 2, 0}, 51 {1, 1335, 4, 7, 0xff, 2, 0}, 52 {1, 1666, 4, 8, 0xff, 2, 0}, 53 {} 54 }; 55 56 /* 57 * The two slots have slightly different timing. The center values are good 58 * for both slots. We use identical speed tables for them. In future use, if 59 * DIMMs have fewer center values that require two separated tables, copy the 60 * udimm0 table to udimm1 and make changes to clk_adjust and wrlvl_start. 61 */ 62 static const struct board_specific_parameters *udimms[] = { 63 udimm0, 64 udimm0, 65 }; 66 67 static const struct board_specific_parameters rdimm0[] = { 68 /* 69 * memory controller 0 70 * num| hi| clk| wrlvl | cpo |wrdata|2T 71 * ranks| mhz|adjst| start | |delay | 72 */ 73 {4, 850, 4, 6, 0xff, 2, 0}, 74 {4, 950, 5, 7, 0xff, 2, 0}, 75 {4, 1050, 5, 8, 0xff, 2, 0}, 76 {4, 1250, 5, 10, 0xff, 2, 0}, 77 {4, 1350, 5, 11, 0xff, 2, 0}, 78 {4, 1666, 5, 12, 0xff, 2, 0}, 79 {2, 850, 4, 6, 0xff, 2, 0}, 80 {2, 1050, 4, 7, 0xff, 2, 0}, 81 {2, 1666, 4, 8, 0xff, 2, 0}, 82 {1, 850, 4, 5, 0xff, 2, 0}, 83 {1, 950, 4, 7, 0xff, 2, 0}, 84 {1, 1666, 4, 8, 0xff, 2, 0}, 85 {} 86 }; 87 88 /* 89 * The two slots have slightly different timing. See comments above. 90 */ 91 static const struct board_specific_parameters *rdimms[] = { 92 rdimm0, 93 rdimm0, 94 }; 95 96 void fsl_ddr_board_options(memctl_options_t *popts, 97 dimm_params_t *pdimm, 98 unsigned int ctrl_num) 99 { 100 const struct board_specific_parameters *pbsp, *pbsp_highest = NULL; 101 ulong ddr_freq; 102 103 if (ctrl_num > 1) { 104 printf("Wrong parameter for controller number %d", ctrl_num); 105 return; 106 } 107 if (!pdimm->n_ranks) 108 return; 109 110 if (popts->registered_dimm_en) 111 pbsp = rdimms[ctrl_num]; 112 else 113 pbsp = udimms[ctrl_num]; 114 115 116 /* Get clk_adjust, cpo, write_data_delay,2T, according to the board ddr 117 * freqency and n_banks specified in board_specific_parameters table. 118 */ 119 ddr_freq = get_ddr_freq(0) / 1000000; 120 while (pbsp->datarate_mhz_high) { 121 if (pbsp->n_ranks == pdimm->n_ranks) { 122 if (ddr_freq <= pbsp->datarate_mhz_high) { 123 popts->cpo_override = pbsp->cpo; 124 popts->write_data_delay = 125 pbsp->write_data_delay; 126 popts->clk_adjust = pbsp->clk_adjust; 127 popts->wrlvl_start = pbsp->wrlvl_start; 128 popts->twot_en = pbsp->force_2t; 129 goto found; 130 } 131 pbsp_highest = pbsp; 132 } 133 pbsp++; 134 } 135 136 if (pbsp_highest) { 137 printf("Error: board specific timing not found for data rate %lu MT/s!\nTrying to use the highest speed (%u) parameters\n", 138 ddr_freq, pbsp_highest->datarate_mhz_high); 139 popts->cpo_override = pbsp_highest->cpo; 140 popts->write_data_delay = pbsp_highest->write_data_delay; 141 popts->clk_adjust = pbsp_highest->clk_adjust; 142 popts->wrlvl_start = pbsp_highest->wrlvl_start; 143 popts->twot_en = pbsp_highest->force_2t; 144 } else { 145 panic("DIMM is not supported by this board"); 146 } 147 found: 148 /* 149 * Factors to consider for half-strength driver enable: 150 * - number of DIMMs installed 151 */ 152 popts->half_strength_driver_enable = 0; 153 /* 154 * Write leveling override 155 */ 156 popts->wrlvl_override = 1; 157 popts->wrlvl_sample = 0xf; 158 159 /* 160 * Rtt and Rtt_WR override 161 */ 162 popts->rtt_override = 0; 163 164 /* Enable ZQ calibration */ 165 popts->zq_en = 1; 166 167 /* DHC_EN =1, ODT = 60 Ohm */ 168 popts->ddr_cdr1 = DDR_CDR1_DHC_EN; 169 } 170 171 int dram_init(void) 172 { 173 phys_size_t dram_size; 174 175 puts("Initializing...."); 176 177 if (!fsl_use_spd()) 178 panic("Cyrus only supports using SPD for DRAM\n"); 179 180 puts("using SPD\n"); 181 dram_size = fsl_ddr_sdram(); 182 183 dram_size = setup_ddr_tlbs(dram_size / 0x100000); 184 dram_size *= 0x100000; 185 186 debug(" DDR: "); 187 gd->ram_size = dram_size; 188 189 return 0; 190 } 191