1
2
3
4
5
6
7
8
9
10
11#include <common.h>
12#include <fsl_ddr_sdram.h>
13
14#include <fsl_ddr.h>
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52static unsigned long long
53compute_ranksize(const ddr3_spd_eeprom_t *spd)
54{
55 unsigned long long bsize;
56
57 int nbit_sdram_cap_bsize = 0;
58 int nbit_primary_bus_width = 0;
59 int nbit_sdram_width = 0;
60
61 if ((spd->density_banks & 0xf) < 7)
62 nbit_sdram_cap_bsize = (spd->density_banks & 0xf) + 28;
63 if ((spd->bus_width & 0x7) < 4)
64 nbit_primary_bus_width = (spd->bus_width & 0x7) + 3;
65 if ((spd->organization & 0x7) < 4)
66 nbit_sdram_width = (spd->organization & 0x7) + 2;
67
68 bsize = 1ULL << (nbit_sdram_cap_bsize - 3
69 + nbit_primary_bus_width - nbit_sdram_width);
70
71 debug("DDR: DDR III rank density = 0x%16llx\n", bsize);
72
73 return bsize;
74}
75
76
77
78
79
80
81
82
83unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
84 const ddr3_spd_eeprom_t *spd,
85 dimm_params_t *pdimm,
86 unsigned int dimm_number)
87{
88 unsigned int retval;
89 unsigned int mtb_ps;
90 int ftb_10th_ps;
91 int i;
92
93 if (spd->mem_type) {
94 if (spd->mem_type != SPD_MEMTYPE_DDR3) {
95 printf("DIMM %u: is not a DDR3 SPD.\n", dimm_number);
96 return 1;
97 }
98 } else {
99 memset(pdimm, 0, sizeof(dimm_params_t));
100 return 1;
101 }
102
103 retval = ddr3_spd_check(spd);
104 if (retval) {
105 printf("DIMM %u: failed checksum\n", dimm_number);
106 return 2;
107 }
108
109
110
111
112
113
114 memset(pdimm->mpart, 0, sizeof(pdimm->mpart));
115 if ((spd->info_size_crc & 0xF) > 1)
116 memcpy(pdimm->mpart, spd->mpart, sizeof(pdimm->mpart) - 1);
117
118
119 pdimm->n_ranks = ((spd->organization >> 3) & 0x7) + 1;
120 pdimm->rank_density = compute_ranksize(spd);
121 pdimm->capacity = pdimm->n_ranks * pdimm->rank_density;
122 pdimm->primary_sdram_width = 1 << (3 + (spd->bus_width & 0x7));
123 if ((spd->bus_width >> 3) & 0x3)
124 pdimm->ec_sdram_width = 8;
125 else
126 pdimm->ec_sdram_width = 0;
127 pdimm->data_width = pdimm->primary_sdram_width
128 + pdimm->ec_sdram_width;
129 pdimm->device_width = 1 << ((spd->organization & 0x7) + 2);
130
131
132 pdimm->mirrored_dimm = 0;
133 pdimm->registered_dimm = 0;
134 switch (spd->module_type & DDR3_SPD_MODULETYPE_MASK) {
135 case DDR3_SPD_MODULETYPE_RDIMM:
136 case DDR3_SPD_MODULETYPE_MINI_RDIMM:
137 case DDR3_SPD_MODULETYPE_72B_SO_RDIMM:
138
139 pdimm->registered_dimm = 1;
140 for (i = 0; i < 16; i += 2) {
141 u8 rcw = spd->mod_section.registered.rcw[i/2];
142 pdimm->rcw[i] = (rcw >> 0) & 0x0F;
143 pdimm->rcw[i+1] = (rcw >> 4) & 0x0F;
144 }
145 break;
146
147 case DDR3_SPD_MODULETYPE_UDIMM:
148 case DDR3_SPD_MODULETYPE_SO_DIMM:
149 case DDR3_SPD_MODULETYPE_MICRO_DIMM:
150 case DDR3_SPD_MODULETYPE_MINI_UDIMM:
151 case DDR3_SPD_MODULETYPE_MINI_CDIMM:
152 case DDR3_SPD_MODULETYPE_72B_SO_UDIMM:
153 case DDR3_SPD_MODULETYPE_72B_SO_CDIMM:
154 case DDR3_SPD_MODULETYPE_LRDIMM:
155 case DDR3_SPD_MODULETYPE_16B_SO_DIMM:
156 case DDR3_SPD_MODULETYPE_32B_SO_DIMM:
157
158 if (spd->mod_section.unbuffered.addr_mapping & 0x1)
159 pdimm->mirrored_dimm = 1;
160 break;
161
162 default:
163 printf("unknown module_type 0x%02X\n", spd->module_type);
164 return 1;
165 }
166
167
168 pdimm->n_row_addr = ((spd->addressing >> 3) & 0x7) + 12;
169 pdimm->n_col_addr = (spd->addressing & 0x7) + 9;
170 pdimm->n_banks_per_sdram_device = 8 << ((spd->density_banks >> 4) & 0x7);
171
172
173
174
175
176
177 if (pdimm->ec_sdram_width)
178 pdimm->edc_config = 0x02;
179 else
180 pdimm->edc_config = 0x00;
181
182
183
184
185
186
187 pdimm->burst_lengths_bitmask = 0x0c;
188
189
190
191
192
193
194 mtb_ps = (spd->mtb_dividend * 1000) /spd->mtb_divisor;
195 pdimm->mtb_ps = mtb_ps;
196
197
198
199
200
201
202 ftb_10th_ps =
203 ((spd->ftb_div & 0xf0) >> 4) * 10 / (spd->ftb_div & 0x0f);
204 pdimm->ftb_10th_ps = ftb_10th_ps;
205
206
207
208
209
210
211
212
213 pdimm->tckmin_x_ps = spd->tck_min * mtb_ps +
214 (spd->fine_tck_min * ftb_10th_ps) / 10;
215
216
217
218
219
220
221
222 pdimm->caslat_x = ((spd->caslat_msb << 8) | spd->caslat_lsb) << 4;
223
224
225
226
227
228
229
230
231
232 pdimm->taa_ps = spd->taa_min * mtb_ps +
233 (spd->fine_taa_min * ftb_10th_ps) / 10;
234
235
236
237
238
239
240 pdimm->twr_ps = spd->twr_min * mtb_ps;
241
242
243
244
245
246
247
248
249
250 pdimm->trcd_ps = spd->trcd_min * mtb_ps +
251 (spd->fine_trcd_min * ftb_10th_ps) / 10;
252
253
254
255
256
257
258
259 pdimm->trrd_ps = spd->trrd_min * mtb_ps;
260
261
262
263
264
265
266
267
268
269 pdimm->trp_ps = spd->trp_min * mtb_ps +
270 (spd->fine_trp_min * ftb_10th_ps) / 10;
271
272
273
274
275
276
277
278
279 pdimm->tras_ps = (((spd->tras_trc_ext & 0xf) << 8) | spd->tras_min_lsb)
280 * mtb_ps;
281
282
283
284
285
286
287
288
289 pdimm->trc_ps = (((spd->tras_trc_ext & 0xf0) << 4) | spd->trc_min_lsb)
290 * mtb_ps + (spd->fine_trc_min * ftb_10th_ps) / 10;
291
292
293
294
295
296
297
298 pdimm->trfc_ps = ((spd->trfc_min_msb << 8) | spd->trfc_min_lsb)
299 * mtb_ps;
300
301
302
303
304
305 pdimm->twtr_ps = spd->twtr_min * mtb_ps;
306
307
308
309
310
311
312 pdimm->trtp_ps = spd->trtp_min * mtb_ps;
313
314
315
316
317
318
319 pdimm->refresh_rate_ps = 7800000;
320 if ((spd->therm_ref_opt & 0x1) && !(spd->therm_ref_opt & 0x2)) {
321 pdimm->refresh_rate_ps = 3900000;
322 pdimm->extended_op_srt = 1;
323 }
324
325
326
327
328
329
330
331
332
333 pdimm->tfaw_ps = (((spd->tfaw_msb & 0xf) << 8) | spd->tfaw_min)
334 * mtb_ps;
335
336 return 0;
337}
338