1 /* 2 * Copyright 2018-2022 NXP 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <errno.h> 9 #include <string.h> 10 11 #include <common/debug.h> 12 #include <ddr.h> 13 #include <lib/utils.h> 14 15 #include <errata.h> 16 #include <platform_def.h> 17 18 #ifdef CONFIG_STATIC_DDR 19 const struct ddr_cfg_regs static_2100 = { 20 .cs[0].config = U(0x80040322), 21 .cs[0].bnds = U(0x1FF), 22 .cs[1].config = U(0x80000322), 23 .cs[1].bnds = U(0x1FF), 24 .sdram_cfg[0] = U(0xE5004000), 25 .sdram_cfg[1] = U(0x401151), 26 .timing_cfg[0] = U(0xD1770018), 27 .timing_cfg[1] = U(0xF2FC9245), 28 .timing_cfg[2] = U(0x594197), 29 .timing_cfg[3] = U(0x2101100), 30 .timing_cfg[4] = U(0x220002), 31 .timing_cfg[5] = U(0x5401400), 32 .timing_cfg[7] = U(0x26600000), 33 .timing_cfg[8] = U(0x5446A00), 34 .dq_map[0] = U(0x32C57554), 35 .dq_map[1] = U(0xD4BB0BD4), 36 .dq_map[2] = U(0x2EC2F554), 37 .dq_map[3] = U(0xD95D4001), 38 .sdram_mode[0] = U(0x3010631), 39 .sdram_mode[1] = U(0x100200), 40 .sdram_mode[9] = U(0x8400000), 41 .sdram_mode[8] = U(0x500), 42 .sdram_mode[2] = U(0x10631), 43 .sdram_mode[3] = U(0x100200), 44 .sdram_mode[10] = U(0x400), 45 .sdram_mode[11] = U(0x8400000), 46 .sdram_mode[4] = U(0x10631), 47 .sdram_mode[5] = U(0x100200), 48 .sdram_mode[12] = U(0x400), 49 .sdram_mode[13] = U(0x8400000), 50 .sdram_mode[6] = U(0x10631), 51 .sdram_mode[7] = U(0x100200), 52 .sdram_mode[14] = U(0x400), 53 .sdram_mode[15] = U(0x8400000), 54 .interval = U(0x1FFE07FF), 55 .zq_cntl = U(0x8A090705), 56 .clk_cntl = U(0x2000000), 57 .cdr[0] = U(0x80040000), 58 .cdr[1] = U(0xC1), 59 .wrlvl_cntl[0] = U(0x86750609), 60 .wrlvl_cntl[1] = U(0xA0B0C0D), 61 .wrlvl_cntl[2] = U(0xF10110E), 62 }; 63 64 const struct ddr_cfg_regs static_1800 = { 65 .cs[0].config = U(0x80040322), 66 .cs[0].bnds = U(0x1FF), 67 .cs[1].config = U(0x80000322), 68 .cs[1].bnds = U(0x1FF), 69 .sdram_cfg[0] = U(0xE5004000), 70 .sdram_cfg[1] = U(0x401151), 71 .timing_cfg[0] = U(0x91660018), 72 .timing_cfg[1] = U(0xDDD82045), 73 .timing_cfg[2] = U(0x512153), 74 .timing_cfg[3] = U(0x10E1100), 75 .timing_cfg[4] = U(0x220002), 76 .timing_cfg[5] = U(0x4401400), 77 .timing_cfg[7] = U(0x14400000), 78 .timing_cfg[8] = U(0x3335900), 79 .dq_map[0] = U(0x32C57554), 80 .dq_map[1] = U(0xD4BB0BD4), 81 .dq_map[2] = U(0x2EC2F554), 82 .dq_map[3] = U(0xD95D4001), 83 .sdram_mode[0] = U(0x3010421), 84 .sdram_mode[1] = U(0x80200), 85 .sdram_mode[9] = U(0x4400000), 86 .sdram_mode[8] = U(0x500), 87 .sdram_mode[2] = U(0x10421), 88 .sdram_mode[3] = U(0x80200), 89 .sdram_mode[10] = U(0x400), 90 .sdram_mode[11] = U(0x4400000), 91 .sdram_mode[4] = U(0x10421), 92 .sdram_mode[5] = U(0x80200), 93 .sdram_mode[12] = U(0x400), 94 .sdram_mode[13] = U(0x4400000), 95 .sdram_mode[6] = U(0x10421), 96 .sdram_mode[7] = U(0x80200), 97 .sdram_mode[14] = U(0x400), 98 .sdram_mode[15] = U(0x4400000), 99 .interval = U(0x1B6C06DB), 100 .zq_cntl = U(0x8A090705), 101 .clk_cntl = U(0x2000000), 102 .cdr[0] = U(0x80040000), 103 .cdr[1] = U(0xC1), 104 .wrlvl_cntl[0] = U(0x86750607), 105 .wrlvl_cntl[1] = U(0x8090A0B), 106 .wrlvl_cntl[2] = U(0xD0E0F0C), 107 }; 108 109 const struct ddr_cfg_regs static_1600 = { 110 .cs[0].config = U(0x80040322), 111 .cs[0].bnds = U(0x1FF), 112 .cs[1].config = U(0x80000322), 113 .cs[1].bnds = U(0x1FF), 114 .sdram_cfg[0] = U(0xE5004000), 115 .sdram_cfg[1] = U(0x401151), 116 .sdram_cfg[2] = U(0x0), 117 .timing_cfg[0] = U(0x91550018), 118 .timing_cfg[1] = U(0xBAB48E44), 119 .timing_cfg[2] = U(0x490111), 120 .timing_cfg[3] = U(0x10C1000), 121 .timing_cfg[4] = U(0x220002), 122 .timing_cfg[5] = U(0x3401400), 123 .timing_cfg[6] = U(0x0), 124 .timing_cfg[7] = U(0x13300000), 125 .timing_cfg[8] = U(0x1224800), 126 .timing_cfg[9] = U(0x0), 127 .dq_map[0] = U(0x32C57554), 128 .dq_map[1] = U(0xD4BB0BD4), 129 .dq_map[2] = U(0x2EC2F554), 130 .dq_map[3] = U(0xD95D4001), 131 .sdram_mode[0] = U(0x3010211), 132 .sdram_mode[1] = U(0x0), 133 .sdram_mode[9] = U(0x400000), 134 .sdram_mode[8] = U(0x500), 135 .sdram_mode[2] = U(0x10211), 136 .sdram_mode[3] = U(0x0), 137 .sdram_mode[10] = U(0x400), 138 .sdram_mode[11] = U(0x400000), 139 .sdram_mode[4] = U(0x10211), 140 .sdram_mode[5] = U(0x0), 141 .sdram_mode[12] = U(0x400), 142 .sdram_mode[13] = U(0x400000), 143 .sdram_mode[6] = U(0x10211), 144 .sdram_mode[7] = U(0x0), 145 .sdram_mode[14] = U(0x400), 146 .sdram_mode[15] = U(0x400000), 147 .interval = U(0x18600618), 148 .zq_cntl = U(0x8A090705), 149 .ddr_sr_cntr = U(0x0), 150 .clk_cntl = U(0x2000000), 151 .cdr[0] = U(0x80040000), 152 .cdr[1] = U(0xC1), 153 .wrlvl_cntl[0] = U(0x86750607), 154 .wrlvl_cntl[1] = U(0x8090A0B), 155 .wrlvl_cntl[2] = U(0xD0E0F0C), 156 }; 157 158 struct static_table { 159 unsigned long rate; 160 const struct ddr_cfg_regs *regs; 161 }; 162 163 const struct static_table table[] = { 164 {1600, &static_1600}, 165 {1800, &static_1800}, 166 {2100, &static_2100}, 167 }; 168 169 long long board_static_ddr(struct ddr_info *priv) 170 { 171 const unsigned long clk = priv->clk / 1000000; 172 long long size = 0; 173 int i; 174 175 for (i = 0; i < ARRAY_SIZE(table); i++) { 176 if (table[i].rate >= clk) { 177 break; 178 } 179 } 180 if (i < ARRAY_SIZE(table)) { 181 VERBOSE("Found static setting for rate %ld\n", table[i].rate); 182 memcpy(&priv->ddr_reg, table[i].regs, 183 sizeof(struct ddr_cfg_regs)); 184 size = 0x200000000UL; 185 } else { 186 ERROR("Not static settings for rate %ld\n", clk); 187 } 188 189 return size; 190 } 191 #else /* ifndef CONFIG_STATIC_DDR */ 192 static const struct rc_timing rce[] = { 193 {U(1600), U(8), U(7)}, 194 {U(1867), U(8), U(7)}, 195 {U(2134), U(8), U(9)}, 196 {} 197 }; 198 199 static const struct board_timing udimm[] = { 200 {U(0x04), rce, U(0x01020304), U(0x06070805)}, 201 {U(0x1f), rce, U(0x01020304), U(0x06070805)}, 202 }; 203 204 int ddr_board_options(struct ddr_info *priv) 205 { 206 int ret; 207 struct memctl_opt *popts = &priv->opt; 208 209 if (popts->rdimm) { 210 debug("RDIMM parameters not set.\n"); 211 return -EINVAL; 212 } 213 214 ret = cal_board_params(priv, udimm, ARRAY_SIZE(udimm)); 215 if (ret != 0) { 216 return ret; 217 } 218 219 popts->wrlvl_override = U(1); 220 popts->wrlvl_sample = U(0x0); /* 32 clocks */ 221 popts->cpo_sample = U(0x61); 222 popts->ddr_cdr1 = DDR_CDR1_DHC_EN | 223 DDR_CDR1_ODT(DDR_CDR_ODT_80ohm); 224 popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm) | 225 DDR_CDR2_VREF_TRAIN_EN | 226 DDR_CDR2_VREF_RANGE_2; 227 popts->bstopre = U(0); 228 229 return 0; 230 } 231 #endif /* ifdef CONFIG_STATIC_DDR */ 232 233 long long init_ddr(void) 234 { 235 int spd_addr[] = {NXP_SPD_EEPROM0}; 236 struct ddr_info info; 237 struct sysinfo sys; 238 long long dram_size; 239 240 zeromem(&sys, sizeof(sys)); 241 if (get_clocks(&sys)) { 242 ERROR("System clocks are not set\n"); 243 assert(0); 244 } 245 debug("platform clock %lu\n", sys.freq_platform); 246 debug("DDR PLL1 %lu\n", sys.freq_ddr_pll0); 247 debug("DDR PLL2 %lu\n", sys.freq_ddr_pll1); 248 249 zeromem(&info, sizeof(struct ddr_info)); 250 info.num_ctlrs = U(1); 251 info.dimm_on_ctlr = U(1); 252 info.clk = get_ddr_freq(&sys, 0); 253 info.spd_addr = spd_addr; 254 info.ddr[0] = (void *)NXP_DDR_ADDR; 255 256 dram_size = dram_init(&info); 257 258 if (dram_size < 0) { 259 ERROR("DDR init failed.\n"); 260 } 261 262 #ifdef ERRATA_SOC_A008850 263 erratum_a008850_post(); 264 #endif 265 266 return dram_size; 267 } 268