1
2
3
4
5
6
7#include <common.h>
8#include <fsl_ddr_sdram.h>
9
10#include <fsl_ddr.h>
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33static unsigned long long
34compute_ranksize(unsigned int mem_type, unsigned char row_dens)
35{
36 unsigned long long bsize;
37
38
39 bsize = ((row_dens >> 5) | ((row_dens & 31) << 3));
40 bsize <<= 27ULL;
41 debug("DDR: DDR II rank density = 0x%16llx\n", bsize);
42
43 return bsize;
44}
45
46
47
48
49
50
51
52
53
54
55
56static unsigned int
57convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val)
58{
59
60 unsigned int tenths_ps[16] = {
61 0,
62 100,
63 200,
64 300,
65 400,
66 500,
67 600,
68 700,
69 800,
70 900,
71 250,
72 330,
73 660,
74 750,
75 0,
76 0
77 };
78
79 unsigned int whole_ns = (spd_val & 0xF0) >> 4;
80 unsigned int tenth_ns = spd_val & 0x0F;
81 unsigned int ps = whole_ns * 1000 + tenths_ps[tenth_ns];
82
83 return ps;
84}
85
86static unsigned int
87convert_bcd_hundredths_to_cycle_time_ps(unsigned int spd_val)
88{
89 unsigned int tenth_ns = (spd_val & 0xF0) >> 4;
90 unsigned int hundredth_ns = spd_val & 0x0F;
91 unsigned int ps = tenth_ns * 100 + hundredth_ns * 10;
92
93 return ps;
94}
95
96static unsigned int byte40_table_ps[8] = {
97 0,
98 250,
99 330,
100 500,
101 660,
102 750,
103 0,
104 0
105};
106
107static unsigned int
108compute_trfc_ps_from_spd(unsigned char trctrfc_ext, unsigned char trfc)
109{
110 unsigned int trfc_ps;
111
112 trfc_ps = (((trctrfc_ext & 0x1) * 256) + trfc) * 1000
113 + byte40_table_ps[(trctrfc_ext >> 1) & 0x7];
114
115 return trfc_ps;
116}
117
118static unsigned int
119compute_trc_ps_from_spd(unsigned char trctrfc_ext, unsigned char trc)
120{
121 unsigned int trc_ps;
122
123 trc_ps = trc * 1000 + byte40_table_ps[(trctrfc_ext >> 4) & 0x7];
124
125 return trc_ps;
126}
127
128
129
130
131
132
133static unsigned int
134determine_refresh_rate_ps(const unsigned int spd_refresh)
135{
136 unsigned int refresh_time_ps[8] = {
137 15625000,
138 3900000,
139 7800000,
140 31300000,
141 62500000,
142 125000000,
143 15625000,
144 15625000,
145 };
146
147 return refresh_time_ps[spd_refresh & 0x7];
148}
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177unsigned short ddr2_speed_bins[] = { 0, 5000, 3750, 3000, 2500, 1875 };
178
179unsigned int
180compute_derated_DDR2_CAS_latency(unsigned int mclk_ps)
181{
182 const unsigned int num_speed_bins = ARRAY_SIZE(ddr2_speed_bins);
183 unsigned int lowest_tCKmin_found = 0;
184 unsigned int lowest_tCKmin_CL = 0;
185 unsigned int i;
186
187 debug("mclk_ps = %u\n", mclk_ps);
188
189 for (i = 0; i < num_speed_bins; i++) {
190 unsigned int x = ddr2_speed_bins[i];
191 debug("i=%u, x = %u, lowest_tCKmin_found = %u\n",
192 i, x, lowest_tCKmin_found);
193 if (x && x <= mclk_ps && x >= lowest_tCKmin_found ) {
194 lowest_tCKmin_found = x;
195 lowest_tCKmin_CL = i + 2;
196 }
197 }
198
199 debug("lowest_tCKmin_CL = %u\n", lowest_tCKmin_CL);
200
201 return lowest_tCKmin_CL;
202}
203
204
205
206
207
208
209
210
211
212unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
213 const ddr2_spd_eeprom_t *spd,
214 dimm_params_t *pdimm,
215 unsigned int dimm_number)
216{
217 unsigned int retval;
218
219 if (spd->mem_type) {
220 if (spd->mem_type != SPD_MEMTYPE_DDR2) {
221 printf("DIMM %u: is not a DDR2 SPD.\n", dimm_number);
222 return 1;
223 }
224 } else {
225 memset(pdimm, 0, sizeof(dimm_params_t));
226 return 1;
227 }
228
229 retval = ddr2_spd_check(spd);
230 if (retval) {
231 printf("DIMM %u: failed checksum\n", dimm_number);
232 return 2;
233 }
234
235
236
237
238
239
240 memset(pdimm->mpart, 0, sizeof(pdimm->mpart));
241 memcpy(pdimm->mpart, spd->mpart, sizeof(pdimm->mpart) - 1);
242
243
244 pdimm->n_ranks = (spd->mod_ranks & 0x7) + 1;
245 pdimm->rank_density = compute_ranksize(spd->mem_type, spd->rank_dens);
246 pdimm->capacity = pdimm->n_ranks * pdimm->rank_density;
247 pdimm->data_width = spd->dataw;
248 pdimm->primary_sdram_width = spd->primw;
249 pdimm->ec_sdram_width = spd->ecw;
250
251
252 switch (spd->dimm_type) {
253 case DDR2_SPD_DIMMTYPE_RDIMM:
254 case DDR2_SPD_DIMMTYPE_72B_SO_RDIMM:
255 case DDR2_SPD_DIMMTYPE_MINI_RDIMM:
256
257 pdimm->registered_dimm = 1;
258 break;
259
260 case DDR2_SPD_DIMMTYPE_UDIMM:
261 case DDR2_SPD_DIMMTYPE_SO_DIMM:
262 case DDR2_SPD_DIMMTYPE_MICRO_DIMM:
263 case DDR2_SPD_DIMMTYPE_MINI_UDIMM:
264
265 pdimm->registered_dimm = 0;
266 break;
267
268 case DDR2_SPD_DIMMTYPE_72B_SO_CDIMM:
269 default:
270 printf("unknown dimm_type 0x%02X\n", spd->dimm_type);
271 return 1;
272 }
273
274
275 pdimm->n_row_addr = spd->nrow_addr;
276 pdimm->n_col_addr = spd->ncol_addr;
277 pdimm->n_banks_per_sdram_device = spd->nbanks;
278 pdimm->edc_config = spd->config;
279 pdimm->burst_lengths_bitmask = spd->burstl;
280 pdimm->row_density = spd->rank_dens;
281
282
283
284
285
286
287 pdimm->tckmin_x_ps
288 = convert_bcd_tenths_to_cycle_time_ps(spd->clk_cycle);
289 pdimm->tckmin_x_minus_1_ps
290 = convert_bcd_tenths_to_cycle_time_ps(spd->clk_cycle2);
291 pdimm->tckmin_x_minus_2_ps
292 = convert_bcd_tenths_to_cycle_time_ps(spd->clk_cycle3);
293
294 pdimm->tckmax_ps = convert_bcd_tenths_to_cycle_time_ps(spd->tckmax);
295
296
297
298
299
300
301
302
303 pdimm->caslat_x = __ilog2(spd->cas_lat);
304 pdimm->caslat_x_minus_1 = __ilog2(spd->cas_lat
305 & ~(1 << pdimm->caslat_x));
306 pdimm->caslat_x_minus_2 = __ilog2(spd->cas_lat
307 & ~(1 << pdimm->caslat_x)
308 & ~(1 << pdimm->caslat_x_minus_1));
309
310
311 pdimm->caslat_lowest_derated = compute_derated_DDR2_CAS_latency(
312 get_memory_clk_period_ps(ctrl_num));
313
314
315 pdimm->trcd_ps = spd->trcd * 250;
316 pdimm->trp_ps = spd->trp * 250;
317 pdimm->tras_ps = spd->tras * 1000;
318
319 pdimm->twr_ps = spd->twr * 250;
320 pdimm->twtr_ps = spd->twtr * 250;
321 pdimm->trfc_ps = compute_trfc_ps_from_spd(spd->trctrfc_ext, spd->trfc);
322
323 pdimm->trrd_ps = spd->trrd * 250;
324 pdimm->trc_ps = compute_trc_ps_from_spd(spd->trctrfc_ext, spd->trc);
325
326 pdimm->refresh_rate_ps = determine_refresh_rate_ps(spd->refresh);
327
328 pdimm->tis_ps = convert_bcd_hundredths_to_cycle_time_ps(spd->ca_setup);
329 pdimm->tih_ps = convert_bcd_hundredths_to_cycle_time_ps(spd->ca_hold);
330 pdimm->tds_ps
331 = convert_bcd_hundredths_to_cycle_time_ps(spd->data_setup);
332 pdimm->tdh_ps
333 = convert_bcd_hundredths_to_cycle_time_ps(spd->data_hold);
334
335 pdimm->trtp_ps = spd->trtp * 250;
336 pdimm->tdqsq_max_ps = spd->tdqsq * 10;
337 pdimm->tqhs_ps = spd->tqhs * 10;
338
339 return 0;
340}
341