1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38static u8 ReconfigureDIMMspare_D(struct MCTStatStruc *pMCTstat,
39 struct DCTStatStruc *pDCTstatA);
40static void DQSTiming_D(struct MCTStatStruc *pMCTstat,
41 struct DCTStatStruc *pDCTstatA);
42static void LoadDQSSigTmgRegs_D(struct MCTStatStruc *pMCTstat,
43 struct DCTStatStruc *pDCTstatA);
44static void HTMemMapInit_D(struct MCTStatStruc *pMCTstat,
45 struct DCTStatStruc *pDCTstatA);
46static void MCTMemClr_D(struct MCTStatStruc *pMCTstat,
47 struct DCTStatStruc *pDCTstatA);
48static void DCTMemClr_Init_D(struct MCTStatStruc *pMCTstat,
49 struct DCTStatStruc *pDCTstat);
50static void DCTMemClr_Sync_D(struct MCTStatStruc *pMCTstat,
51 struct DCTStatStruc *pDCTstat);
52static void MCTMemClrSync_D(struct MCTStatStruc *pMCTstat,
53 struct DCTStatStruc *pDCTstatA);
54static u8 NodePresent_D(u8 Node);
55static void SyncDCTsReady_D(struct MCTStatStruc *pMCTstat,
56 struct DCTStatStruc *pDCTstatA);
57static void StartupDCT_D(struct MCTStatStruc *pMCTstat,
58 struct DCTStatStruc *pDCTstat, u8 dct);
59static void ClearDCT_D(struct MCTStatStruc *pMCTstat,
60 struct DCTStatStruc *pDCTstat, u8 dct);
61static u8 AutoCycTiming_D(struct MCTStatStruc *pMCTstat,
62 struct DCTStatStruc *pDCTstat, u8 dct);
63static void GetPresetmaxF_D(struct MCTStatStruc *pMCTstat,
64 struct DCTStatStruc *pDCTstat);
65static void SPDGetTCL_D(struct MCTStatStruc *pMCTstat,
66 struct DCTStatStruc *pDCTstat, u8 dct);
67static u8 AutoConfig_D(struct MCTStatStruc *pMCTstat,
68 struct DCTStatStruc *pDCTstat, u8 dct);
69static u8 PlatformSpec_D(struct MCTStatStruc *pMCTstat,
70 struct DCTStatStruc *pDCTstat, u8 dct);
71static void SPDSetBanks_D(struct MCTStatStruc *pMCTstat,
72 struct DCTStatStruc *pDCTstat, u8 dct);
73static void StitchMemory_D(struct MCTStatStruc *pMCTstat,
74 struct DCTStatStruc *pDCTstat, u8 dct);
75static u16 Get_Fk_D(u8 k);
76static u8 Get_DIMMAddress_D(struct DCTStatStruc *pDCTstat, u8 i);
77static void mct_initDCT(struct MCTStatStruc *pMCTstat,
78 struct DCTStatStruc *pDCTstat);
79static void mct_DramInit(struct MCTStatStruc *pMCTstat,
80 struct DCTStatStruc *pDCTstat, u8 dct);
81static u8 mct_PlatformSpec(struct MCTStatStruc *pMCTstat,
82 struct DCTStatStruc *pDCTstat, u8 dct);
83static u8 mct_BeforePlatformSpec(struct MCTStatStruc *pMCTstat,
84 struct DCTStatStruc *pDCTstat, u8 dct);
85static void mct_SyncDCTsReady(struct DCTStatStruc *pDCTstat);
86static void Get_Trdrd(struct MCTStatStruc *pMCTstat,
87 struct DCTStatStruc *pDCTstat, u8 dct);
88static void mct_AfterGetCLT(struct MCTStatStruc *pMCTstat,
89 struct DCTStatStruc *pDCTstat, u8 dct);
90static u8 mct_SPDCalcWidth(struct MCTStatStruc *pMCTstat,\
91 struct DCTStatStruc *pDCTstat, u8 dct);
92static void mct_AfterStitchMemory(struct MCTStatStruc *pMCTstat,
93 struct DCTStatStruc *pDCTstat, u8 dct);
94static u8 mct_DIMMPresence(struct MCTStatStruc *pMCTstat,
95 struct DCTStatStruc *pDCTstat, u8 dct);
96static void Set_OtherTiming(struct MCTStatStruc *pMCTstat,
97 struct DCTStatStruc *pDCTstat, u8 dct);
98static void Get_Twrwr(struct MCTStatStruc *pMCTstat,
99 struct DCTStatStruc *pDCTstat, u8 dct);
100static void Get_Twrrd(struct MCTStatStruc *pMCTstat,
101 struct DCTStatStruc *pDCTstat, u8 dct);
102static void Get_TrwtTO(struct MCTStatStruc *pMCTstat,
103 struct DCTStatStruc *pDCTstat, u8 dct);
104static void Get_TrwtWB(struct MCTStatStruc *pMCTstat,
105 struct DCTStatStruc *pDCTstat);
106static void Get_DqsRcvEnGross_Diff(struct DCTStatStruc *pDCTstat,
107 u32 dev, u32 index_reg);
108static void Get_WrDatGross_Diff(struct DCTStatStruc *pDCTstat, u8 dct,
109 u32 dev, u32 index_reg);
110static u16 Get_DqsRcvEnGross_MaxMin(struct DCTStatStruc *pDCTstat,
111 u32 dev, u32 index_reg, u32 index);
112static void mct_FinalMCT_D(struct MCTStatStruc *pMCTstat,
113 struct DCTStatStruc *pDCTstat);
114static u16 Get_WrDatGross_MaxMin(struct DCTStatStruc *pDCTstat, u8 dct,
115 u32 dev, u32 index_reg, u32 index);
116static void mct_InitialMCT_D(struct MCTStatStruc *pMCTstat,
117 struct DCTStatStruc *pDCTstat);
118static void mct_init(struct MCTStatStruc *pMCTstat,
119 struct DCTStatStruc *pDCTstat);
120static void clear_legacy_Mode(struct MCTStatStruc *pMCTstat,
121 struct DCTStatStruc *pDCTstat);
122static void mct_HTMemMapExt(struct MCTStatStruc *pMCTstat,
123 struct DCTStatStruc *pDCTstatA);
124static void SetCSTriState(struct MCTStatStruc *pMCTstat,
125 struct DCTStatStruc *pDCTstat, u8 dct);
126static void SetCKETriState(struct MCTStatStruc *pMCTstat,
127 struct DCTStatStruc *pDCTstat, u8 dct);
128static void SetODTTriState(struct MCTStatStruc *pMCTstat,
129 struct DCTStatStruc *pDCTstat, u8 dct);
130static void InitPhyCompensation(struct MCTStatStruc *pMCTstat,
131 struct DCTStatStruc *pDCTstat, u8 dct);
132static u32 mct_NodePresent_D(void);
133static void mct_OtherTiming(struct MCTStatStruc *pMCTstat,
134 struct DCTStatStruc *pDCTstatA);
135static void mct_ResetDataStruct_D(struct MCTStatStruc *pMCTstat,
136 struct DCTStatStruc *pDCTstatA);
137static void mct_EarlyArbEn_D(struct MCTStatStruc *pMCTstat,
138 struct DCTStatStruc *pDCTstat, u8 dct);
139static void mct_BeforeDramInit_Prod_D(struct MCTStatStruc *pMCTstat,
140 struct DCTStatStruc *pDCTstat);
141void mct_ClrClToNB_D(struct MCTStatStruc *pMCTstat,
142 struct DCTStatStruc *pDCTstat);
143static u8 CheckNBCOFEarlyArbEn(struct MCTStatStruc *pMCTstat,
144 struct DCTStatStruc *pDCTstat);
145void mct_ClrWbEnhWsbDis_D(struct MCTStatStruc *pMCTstat,
146 struct DCTStatStruc *pDCTstat);
147static void mct_BeforeDQSTrain_D(struct MCTStatStruc *pMCTstat,
148 struct DCTStatStruc *pDCTstatA);
149static void AfterDramInit_D(struct DCTStatStruc *pDCTstat, u8 dct);
150static void mct_ResetDLL_D(struct MCTStatStruc *pMCTstat,
151 struct DCTStatStruc *pDCTstat, u8 dct);
152static void ProgDramMRSReg_D(struct MCTStatStruc *pMCTstat,
153 struct DCTStatStruc *pDCTstat, u8 dct);
154static void mct_DramInit_Sw_D(struct MCTStatStruc *pMCTstat,
155 struct DCTStatStruc *pDCTstat, u8 dct);
156static u32 mct_DisDllShutdownSR(struct MCTStatStruc *pMCTstat,
157 struct DCTStatStruc *pDCTstat, u32 DramConfigLo, u8 dct);
158static void mct_EnDllShutdownSR(struct MCTStatStruc *pMCTstat,
159 struct DCTStatStruc *pDCTstat, u8 dct);
160
161static u32 mct_MR1Odt_RDimm(struct MCTStatStruc *pMCTstat,
162 struct DCTStatStruc *pDCTstat, u8 dct, u32 MrsChipSel);
163static u32 mct_DramTermDyn_RDimm(struct MCTStatStruc *pMCTstat,
164 struct DCTStatStruc *pDCTstat, u8 dimm);
165static u32 mct_SetDramConfigMisc2(struct DCTStatStruc *pDCTstat, u8 dct, u32 misc2);
166static void mct_BeforeDQSTrainSamp(struct DCTStatStruc *pDCTstat);
167static void mct_WriteLevelization_HW(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA);
168static u8 Get_Latency_Diff(struct MCTStatStruc *pMCTstat,
169 struct DCTStatStruc *pDCTstat, u8 dct);
170static void SyncSetting(struct DCTStatStruc *pDCTstat);
171static u8 crcCheck(u8 smbaddr);
172static void mct_ExtMCTConfig_Bx(struct DCTStatStruc *pDCTstat);
173static void mct_ExtMCTConfig_Cx(struct DCTStatStruc *pDCTstat);
174
175
176static const u16 Table_F_k[] = {00,200,266,333,400,533 };
177static const u8 Tab_BankAddr[] = {0x3F,0x01,0x09,0x3F,0x3F,0x11,0x0A,0x19,0x12,0x1A,0x21,0x22,0x23};
178static const u8 Table_DQSRcvEn_Offset[] = {0x00,0x01,0x10,0x11,0x2};
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213static const u8 Tab_L1CLKDis[] = {0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04};
214static const u8 Tab_AM3CLKDis[] = {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00};
215static const u8 Tab_S1CLKDis[] = {0xA2, 0xA2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
216static const u8 Tab_ManualCLKDis[]= {0x10, 0x04, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00};
217
218static const u8 Table_Comp_Rise_Slew_20x[] = {7, 3, 2, 2, 0xFF};
219static const u8 Table_Comp_Rise_Slew_15x[] = {7, 7, 3, 2, 0xFF};
220static const u8 Table_Comp_Fall_Slew_20x[] = {7, 5, 3, 2, 0xFF};
221static const u8 Table_Comp_Fall_Slew_15x[] = {7, 7, 5, 3, 0xFF};
222
223static void mctAutoInitMCT_D(struct MCTStatStruc *pMCTstat,
224 struct DCTStatStruc *pDCTstatA)
225{
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269 u8 Node, NodesWmem;
270 u32 node_sys_base;
271
272restartinit:
273 mctInitMemGPIOs_A_D();
274 NodesWmem = 0;
275 node_sys_base = 0;
276 for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
277 struct DCTStatStruc *pDCTstat;
278 pDCTstat = pDCTstatA + Node;
279 pDCTstat->Node_ID = Node;
280 pDCTstat->dev_host = PA_HOST(Node);
281 pDCTstat->dev_map = PA_MAP(Node);
282 pDCTstat->dev_dct = PA_DCT(Node);
283 pDCTstat->dev_nbmisc = PA_NBMISC(Node);
284 pDCTstat->NodeSysBase = node_sys_base;
285
286 mct_init(pMCTstat, pDCTstat);
287 mctNodeIDDebugPort_D();
288 pDCTstat->NodePresent = NodePresent_D(Node);
289 if (pDCTstat->NodePresent) {
290 clear_legacy_Mode(pMCTstat, pDCTstat);
291 pDCTstat->LogicalCPUID = mctGetLogicalCPUID_D(Node);
292
293 mct_InitialMCT_D(pMCTstat, pDCTstat);
294
295 mctSMBhub_Init(Node);
296
297 mct_initDCT(pMCTstat, pDCTstat);
298 if (pDCTstat->ErrCode == SC_FatalErr) {
299 goto fatalexit;
300 } else if (pDCTstat->ErrCode < SC_StopError) {
301 NodesWmem++;
302 }
303 }
304 node_sys_base = pDCTstat->NodeSysBase;
305 node_sys_base += (pDCTstat->NodeSysLimit + 2) & ~0x0F;
306 }
307 if (NodesWmem == 0) {
308 printk(BIOS_DEBUG, "No Nodes?!\n");
309 goto fatalexit;
310 }
311
312 printk(BIOS_DEBUG, "mctAutoInitMCT_D: SyncDCTsReady_D\n");
313 SyncDCTsReady_D(pMCTstat, pDCTstatA);
314
315 printk(BIOS_DEBUG, "mctAutoInitMCT_D: HTMemMapInit_D\n");
316 HTMemMapInit_D(pMCTstat, pDCTstatA);
317 mctHookAfterHTMap();
318
319 printk(BIOS_DEBUG, "mctAutoInitMCT_D: CPUMemTyping_D\n");
320 CPUMemTyping_D(pMCTstat, pDCTstatA);
321 mctHookAfterCPU();
322
323 printk(BIOS_DEBUG, "mctAutoInitMCT_D: DQSTiming_D\n");
324 DQSTiming_D(pMCTstat, pDCTstatA);
325
326 printk(BIOS_DEBUG, "mctAutoInitMCT_D: UMAMemTyping_D\n");
327 UMAMemTyping_D(pMCTstat, pDCTstatA);
328
329 printk(BIOS_DEBUG, "mctAutoInitMCT_D: :OtherTiming\n");
330 mct_OtherTiming(pMCTstat, pDCTstatA);
331
332 if (ReconfigureDIMMspare_D(pMCTstat, pDCTstatA)) {
333 goto restartinit;
334 }
335
336 InterleaveNodes_D(pMCTstat, pDCTstatA);
337 InterleaveChannels_D(pMCTstat, pDCTstatA);
338
339 printk(BIOS_DEBUG, "mctAutoInitMCT_D: ECCInit_D\n");
340 if (ECCInit_D(pMCTstat, pDCTstatA)) {
341 printk(BIOS_DEBUG, "mctAutoInitMCT_D: MCTMemClr_D\n");
342 MCTMemClr_D(pMCTstat,pDCTstatA);
343 }
344
345 mct_FinalMCT_D(pMCTstat, pDCTstatA);
346 printk(BIOS_DEBUG, "All Done\n");
347 return;
348
349fatalexit:
350 die("mct_d: fatalexit");
351}
352
353static u8 ReconfigureDIMMspare_D(struct MCTStatStruc *pMCTstat,
354 struct DCTStatStruc *pDCTstatA)
355{
356 u8 ret;
357
358 if (mctGet_NVbits(NV_CS_SpareCTL)) {
359 if (MCT_DIMM_SPARE_NO_WARM) {
360
361 if (pMCTstat->GStatus & (1 << GSB_EnDIMMSpareNW)) {
362 LoadDQSSigTmgRegs_D(pMCTstat, pDCTstatA);
363 ret = 0;
364 } else {
365 mct_ResetDataStruct_D(pMCTstat, pDCTstatA);
366 pMCTstat->GStatus |= 1 << GSB_EnDIMMSpareNW;
367 ret = 1;
368 }
369 } else {
370
371 if (mctGet_NVbits(NV_DQSTrainCTL))
372 mctWarmReset_D();
373 ret = 0;
374 }
375 } else {
376 ret = 0;
377 }
378
379 return ret;
380}
381
382static void DQSTiming_D(struct MCTStatStruc *pMCTstat,
383 struct DCTStatStruc *pDCTstatA)
384{
385 u8 nv_DQSTrainCTL;
386
387 if (pMCTstat->GStatus & (1 << GSB_EnDIMMSpareNW)) {
388 return;
389 }
390
391 nv_DQSTrainCTL = mctGet_NVbits(NV_DQSTrainCTL);
392
393 nv_DQSTrainCTL = 1;
394
395 mct_BeforeDQSTrain_D(pMCTstat, pDCTstatA);
396 phyAssistedMemFnceTraining(pMCTstat, pDCTstatA);
397
398 if (nv_DQSTrainCTL) {
399 mctHookBeforeAnyTraining(pMCTstat, pDCTstatA);
400
401 _WRMSR(0x26C, 0x04040404, 0x04040404);
402 _WRMSR(0x26D, 0x04040404, 0x04040404);
403 _WRMSR(0x26E, 0x04040404, 0x04040404);
404 _WRMSR(0x26F, 0x04040404, 0x04040404);
405 mct_WriteLevelization_HW(pMCTstat, pDCTstatA);
406
407 TrainReceiverEn_D(pMCTstat, pDCTstatA, FirstPass);
408
409 mct_TrainDQSPos_D(pMCTstat, pDCTstatA);
410
411
412
413
414 mctSetEccDQSRcvrEn_D(pMCTstat, pDCTstatA);
415
416
417 mctHookAfterAnyTraining();
418 mctSaveDQSSigTmg_D();
419
420 MCTMemClr_D(pMCTstat, pDCTstatA);
421 } else {
422 mctGetDQSSigTmg_D();
423 LoadDQSSigTmgRegs_D(pMCTstat, pDCTstatA);
424
425 MCTMemClr_D(pMCTstat, pDCTstatA);
426 }
427}
428
429static void LoadDQSSigTmgRegs_D(struct MCTStatStruc *pMCTstat,
430 struct DCTStatStruc *pDCTstatA)
431{
432 u8 Node, Receiver, Channel, Dir, DIMM;
433 u32 dev;
434 u32 index_reg;
435 u32 reg;
436 u32 index;
437 u32 val;
438 u8 ByteLane;
439 u8 txdqs;
440
441 for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
442 struct DCTStatStruc *pDCTstat;
443 pDCTstat = pDCTstatA + Node;
444
445 if (pDCTstat->DCTSysLimit) {
446 dev = pDCTstat->dev_dct;
447 for (Channel = 0;Channel < 2; Channel++) {
448
449
450 index_reg = 0x98 + Channel * 0x100;
451 for (Receiver = 0; Receiver < 8; Receiver += 2) {
452
453 mct_SetRcvrEnDly_D(pDCTstat,
454 0,
455 1,
456 Channel,
457 Receiver,
458 dev, index_reg,
459 (Receiver >> 1) * 3 + 0x10,
460 2);
461
462 for (ByteLane = 0; ByteLane < 9; ByteLane ++) {
463 txdqs = pDCTstat->CH_D_B_TxDqs[Channel][Receiver >> 1][ByteLane];
464 index = Table_DQSRcvEn_Offset[ByteLane >> 1];
465 index += (Receiver >> 1) * 3 + 0x10 + 0x20;
466 val = Get_NB32_index_wait(dev, 0x98 + 0x100*Channel, index);
467 if (ByteLane & 1) {
468 val &= ~(0xFF << 16);
469 val |= txdqs << 16;
470 } else {
471 val &= ~0xFF;
472 val |= txdqs;
473 }
474 Set_NB32_index_wait(dev, 0x98 + 0x100*Channel, index, val);
475 }
476 }
477 }
478 for (Channel = 0; Channel<2; Channel++) {
479 SetEccDQSRcvrEn_D(pDCTstat, Channel);
480 }
481
482 for (Channel = 0; Channel < 2; Channel++) {
483 u8 *p;
484 index_reg = 0x98 + Channel * 0x100;
485
486
487
488
489
490
491
492
493
494
495 for (DIMM = 0; DIMM < 4; DIMM++) {
496 if (DIMM == 0) {
497 index = 0;
498 } else {
499 if (pDCTstat->Speed >= 4) {
500 index = 0x100 * DIMM;
501 } else {
502 break;
503 }
504 }
505 for (Dir = 0; Dir < 2; Dir++) {
506 p = pDCTstat->CH_D_DIR_B_DQS[Channel][DIMM][Dir];
507 val = stream_to_int(p);
508 Set_NB32_index_wait(dev, index_reg, index+1, val);
509 val = stream_to_int(p+4);
510 Set_NB32_index_wait(dev, index_reg, index+2, val);
511 val = *(p+8);
512 Set_NB32_index_wait(dev, index_reg, index+3, val);
513 index += 4;
514 }
515 }
516 }
517
518 for (Channel = 0; Channel<2; Channel++) {
519 reg = 0x78 + Channel * 0x100;
520 val = Get_NB32(dev, reg);
521 val &= ~(0x3ff<<22);
522 val |= ((u32) pDCTstat->CH_MaxRdLat[Channel] << 22);
523 val &= ~(1<<DqsRcvEnTrain);
524 Set_NB32(dev, reg, val);
525 }
526 }
527 }
528}
529
530static void HTMemMapInit_D(struct MCTStatStruc *pMCTstat,
531 struct DCTStatStruc *pDCTstatA)
532{
533 u8 Node;
534 u32 NextBase, BottomIO;
535 u8 _MemHoleRemap, DramHoleBase, DramHoleOffset;
536 u32 HoleSize, DramSelBaseAddr;
537
538 u32 val;
539 u32 base;
540 u32 limit;
541 u32 dev, devx;
542 struct DCTStatStruc *pDCTstat;
543
544 _MemHoleRemap = mctGet_NVbits(NV_MemHole);
545
546 if (pMCTstat->HoleBase == 0) {
547 DramHoleBase = mctGet_NVbits(NV_BottomIO);
548 } else {
549 DramHoleBase = pMCTstat->HoleBase >> (24-8);
550 }
551
552 BottomIO = DramHoleBase << (24-8);
553
554 NextBase = 0;
555 pDCTstat = pDCTstatA + 0;
556 dev = pDCTstat->dev_map;
557
558 for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
559 pDCTstat = pDCTstatA + Node;
560 devx = pDCTstat->dev_map;
561 DramSelBaseAddr = 0;
562 pDCTstat = pDCTstatA + Node;
563 if (!pDCTstat->GangedMode) {
564 DramSelBaseAddr = pDCTstat->NodeSysLimit - pDCTstat->DCTSysLimit;
565
566 val = pDCTstat->NodeSysLimit;
567 if ((val & 0xFF) == 0xFE) {
568 DramSelBaseAddr++;
569 val++;
570 }
571 pDCTstat->DCTSysLimit = val;
572 }
573
574 base = pDCTstat->DCTSysBase;
575 limit = pDCTstat->DCTSysLimit;
576 if (limit > base) {
577 base += NextBase;
578 limit += NextBase;
579 DramSelBaseAddr += NextBase;
580 printk(BIOS_DEBUG, " Node: %02x base: %02x limit: %02x BottomIO: %02x\n", Node, base, limit, BottomIO);
581
582 if (_MemHoleRemap) {
583 if ((base < BottomIO) && (limit >= BottomIO)) {
584
585 pDCTstat->Status |= 1 << SB_HWHole;
586 pMCTstat->GStatus |= 1 << GSB_HWHole;
587 pDCTstat->DCTSysBase = base;
588 pDCTstat->DCTSysLimit = limit;
589 pDCTstat->DCTHoleBase = BottomIO;
590 pMCTstat->HoleBase = BottomIO;
591 HoleSize = _4GB_RJ8 - BottomIO;
592 if ((DramSelBaseAddr > 0) && (DramSelBaseAddr < BottomIO))
593 base = DramSelBaseAddr;
594 val = ((base + HoleSize) >> (24-8)) & 0xFF;
595 DramHoleOffset = val;
596 val <<= 8;
597 val |= DramHoleBase << 24;
598 val |= 1 << DramHoleValid;
599 Set_NB32(devx, 0xF0, val);
600 pDCTstat->DCTSysLimit += HoleSize;
601 base = pDCTstat->DCTSysBase;
602 limit = pDCTstat->DCTSysLimit;
603 } else if (base == BottomIO) {
604
605 pMCTstat->GStatus |= 1<<GSB_SpIntRemapHole;
606 pDCTstat->Status |= 1<<SB_SWNodeHole;
607 pMCTstat->GStatus |= 1<<GSB_SoftHole;
608 pMCTstat->HoleBase = base;
609 limit -= base;
610 base = _4GB_RJ8;
611 limit += base;
612 pDCTstat->DCTSysBase = base;
613 pDCTstat->DCTSysLimit = limit;
614 } else {
615
616 pDCTstat->DCTSysBase = base;
617 pDCTstat->DCTSysLimit = limit;
618 }
619 } else {
620
621 pDCTstat->DCTSysBase = base;
622 pDCTstat->DCTSysLimit = limit;
623 }
624 base |= 3;
625 pMCTstat->SysLimit = limit;
626 }
627 Set_NB32(dev, 0x40 + (Node << 3), base);
628
629 val = limit & 0xFFFF0000;
630 val |= Node;
631 Set_NB32(dev, 0x44 + (Node << 3), val);
632
633 printk(BIOS_DEBUG, " Node: %02x base: %02x limit: %02x \n", Node, base, limit);
634 limit = pDCTstat->DCTSysLimit;
635 if (limit) {
636 NextBase = (limit & 0xFFFF0000) + 0x10000;
637 }
638 }
639
640
641 for (Node = 1; Node < MAX_NODES_SUPPORTED; Node++) {
642 u32 reg;
643 pDCTstat = pDCTstatA + Node;
644 devx = pDCTstat->dev_map;
645
646 if (pDCTstat->NodePresent) {
647 reg = 0x40;
648 do {
649 val = Get_NB32(dev, reg);
650 Set_NB32(devx, reg, val);
651 reg += 4;
652 } while ( reg < 0x80);
653 } else {
654 break;
655 }
656 }
657
658
659 mct_HTMemMapExt(pMCTstat, pDCTstatA);
660}
661
662static void MCTMemClr_D(struct MCTStatStruc *pMCTstat,
663 struct DCTStatStruc *pDCTstatA)
664{
665
666
667
668
669
670 u8 Node;
671 struct DCTStatStruc *pDCTstat;
672
673 if (!mctGet_NVbits(NV_DQSTrainCTL)){
674
675 } else {
676 for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
677 pDCTstat = pDCTstatA + Node;
678
679 if (pDCTstat->NodePresent) {
680 DCTMemClr_Init_D(pMCTstat, pDCTstat);
681 }
682 }
683 for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
684 pDCTstat = pDCTstatA + Node;
685
686 if (pDCTstat->NodePresent) {
687 DCTMemClr_Sync_D(pMCTstat, pDCTstat);
688 }
689 }
690 }
691}
692
693static void DCTMemClr_Init_D(struct MCTStatStruc *pMCTstat,
694 struct DCTStatStruc *pDCTstat)
695{
696 u32 val;
697 u32 dev;
698 u32 reg;
699
700
701 if (pDCTstat->DCTSysLimit) {
702 dev = pDCTstat->dev_dct;
703 reg = 0x110;
704
705 do {
706 val = Get_NB32(dev, reg);
707 } while (val & (1 << MemClrBusy));
708
709 val |= (1 << MemClrInit);
710 Set_NB32(dev, reg, val);
711 }
712}
713
714static void MCTMemClrSync_D(struct MCTStatStruc *pMCTstat,
715 struct DCTStatStruc *pDCTstatA)
716{
717
718 u8 Node;
719 struct DCTStatStruc *pDCTstat;
720
721 if (!mctGet_NVbits(NV_DQSTrainCTL)){
722
723 } else {
724 for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
725 pDCTstat = pDCTstatA + Node;
726
727 if (pDCTstat->NodePresent) {
728 DCTMemClr_Sync_D(pMCTstat, pDCTstat);
729 }
730 }
731 }
732}
733
734static void DCTMemClr_Sync_D(struct MCTStatStruc *pMCTstat,
735 struct DCTStatStruc *pDCTstat)
736{
737 u32 val;
738 u32 dev = pDCTstat->dev_dct;
739 u32 reg;
740
741
742 if (pDCTstat->DCTSysLimit){
743 reg = 0x110;
744
745 do {
746 val = Get_NB32(dev, reg);
747 } while (val & (1 << MemClrBusy));
748
749 do {
750 val = Get_NB32(dev, reg);
751 } while (!(val & (1 << Dr_MemClrStatus)));
752 }
753
754 val = 0x0FE40FC0;
755 val |= MCCH_FlushWrOnStpGnt;
756 Set_NB32(dev, 0x11C, val);
757}
758
759static u8 NodePresent_D(u8 Node)
760{
761
762
763
764 u32 dev;
765 u32 val;
766 u32 dword;
767 u8 ret = 0;
768
769 dev = PA_HOST(Node);
770 val = Get_NB32(dev, 0);
771 dword = mct_NodePresent_D();
772 if (val == dword) {
773 if (oemNodePresent_D(Node, &ret))
774 goto finish;
775
776 val = Get_NB32(dev, 0x60);
777 val &= 0x07;
778 dword = Node;
779 if (val == dword)
780 ret = 1;
781 }
782finish:
783 return ret;
784}
785
786static void DCTInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct)
787{
788
789
790
791 u8 stopDCTflag;
792 u32 val;
793
794 ClearDCT_D(pMCTstat, pDCTstat, dct);
795 stopDCTflag = 1;
796
797 val = Get_NB32(pDCTstat->dev_dct, 0x94 + dct * 0x100);
798 val |= 1 << Ddr3Mode;
799 Set_NB32(pDCTstat->dev_dct, 0x94 + dct * 0x100, val);
800 if (mct_DIMMPresence(pMCTstat, pDCTstat, dct) < SC_StopError) {
801 printk(BIOS_DEBUG, "\t\tDCTInit_D: mct_DIMMPresence Done\n");
802 if (mct_SPDCalcWidth(pMCTstat, pDCTstat, dct) < SC_StopError) {
803 printk(BIOS_DEBUG, "\t\tDCTInit_D: mct_SPDCalcWidth Done\n");
804 if (AutoCycTiming_D(pMCTstat, pDCTstat, dct) < SC_StopError) {
805 printk(BIOS_DEBUG, "\t\tDCTInit_D: AutoCycTiming_D Done\n");
806 if (AutoConfig_D(pMCTstat, pDCTstat, dct) < SC_StopError) {
807 printk(BIOS_DEBUG, "\t\tDCTInit_D: AutoConfig_D Done\n");
808 if (PlatformSpec_D(pMCTstat, pDCTstat, dct) < SC_StopError) {
809 printk(BIOS_DEBUG, "\t\tDCTInit_D: PlatformSpec_D Done\n");
810 stopDCTflag = 0;
811 if (!(pMCTstat->GStatus & (1 << GSB_EnDIMMSpareNW))) {
812 printk(BIOS_DEBUG, "\t\tDCTInit_D: StartupDCT_D\n");
813 StartupDCT_D(pMCTstat, pDCTstat, dct);
814 }
815 }
816 }
817 }
818 }
819 }
820
821 if (stopDCTflag) {
822 u32 reg_off = dct * 0x100;
823 val = 1<<DisDramInterface;
824 Set_NB32(pDCTstat->dev_dct, reg_off+0x94, val);
825
826
827 val = 0xFF000000;
828 Set_NB32(pDCTstat->dev_dct, reg_off+0x88, val);
829 } else {
830 mct_EnDllShutdownSR(pMCTstat, pDCTstat, dct);
831 }
832}
833
834static void SyncDCTsReady_D(struct MCTStatStruc *pMCTstat,
835 struct DCTStatStruc *pDCTstatA)
836{
837
838
839
840
841
842 u8 Node;
843 u32 val;
844
845 for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
846 struct DCTStatStruc *pDCTstat;
847 pDCTstat = pDCTstatA + Node;
848 mct_SyncDCTsReady(pDCTstat);
849 }
850
851
852 for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
853 struct DCTStatStruc *pDCTstat;
854 pDCTstat = pDCTstatA + Node;
855 if (pDCTstat->NodePresent) {
856 if (pDCTstat->DIMMValidDCT[0] > 0 || pDCTstat->DIMMValidDCT[1] > 0) {
857
858 val = Get_NB32_index_wait(pDCTstat->dev_dct, 0x98, 0x8);
859 val &= ~(1 << DisAutoComp);
860 Set_NB32_index_wait(pDCTstat->dev_dct, 0x98, 0x8, val);
861 }
862 }
863 }
864
865 mct_Wait(15000);
866}
867
868static void StartupDCT_D(struct MCTStatStruc *pMCTstat,
869 struct DCTStatStruc *pDCTstat, u8 dct)
870{
871
872
873
874
875
876
877
878
879
880
881
882
883 u32 val;
884 u32 dev;
885 u32 reg_off = dct * 0x100;
886
887 dev = pDCTstat->dev_dct;
888 val = Get_NB32(dev, 0x94 + reg_off);
889 if (val & (1<<MemClkFreqVal)) {
890 mctHookBeforeDramInit();
891 if (!(pMCTstat->GStatus & (1 << GSB_EnDIMMSpareNW)))
892 mct_DramInit(pMCTstat, pDCTstat, dct);
893 AfterDramInit_D(pDCTstat, dct);
894 mctHookAfterDramInit();
895 }
896}
897
898static void ClearDCT_D(struct MCTStatStruc *pMCTstat,
899 struct DCTStatStruc *pDCTstat, u8 dct)
900{
901 u32 reg_end;
902 u32 dev = pDCTstat->dev_dct;
903 u32 reg = 0x40 + 0x100 * dct;
904 u32 val = 0;
905
906 if (pMCTstat->GStatus & (1 << GSB_EnDIMMSpareNW)) {
907 reg_end = 0x78 + 0x100 * dct;
908 } else {
909 reg_end = 0xA4 + 0x100 * dct;
910 }
911
912 while(reg < reg_end) {
913 if ((reg & 0xFF) == 0x90) {
914 if (pDCTstat->LogicalCPUID & AMD_DR_Dx) {
915 val = Get_NB32(dev, reg);
916 val |= 0x08000000;
917 }
918 }
919 Set_NB32(dev, reg, val);
920 val = 0;
921 reg += 4;
922 }
923
924 val = 0;
925 dev = pDCTstat->dev_map;
926 reg = 0xF0;
927 Set_NB32(dev, reg, val);
928}
929
930static void SPD2ndTiming(struct MCTStatStruc *pMCTstat,
931 struct DCTStatStruc *pDCTstat, u8 dct)
932{
933 u8 i;
934 u16 Twr, Trtp;
935 u16 Trp, Trrd, Trcd, Tras, Trc;
936 u8 Trfc[4];
937 u16 Tfaw;
938 u32 DramTimingLo, DramTimingHi;
939 u8 tCK16x;
940 u16 Twtr;
941 u8 LDIMM;
942 u8 MTB16x;
943 u8 byte;
944 u32 dword;
945 u32 dev;
946 u32 reg_off;
947 u32 val;
948 u16 smbaddr;
949
950
951 Trp = 0;
952 Trrd = 0;
953 Trcd = 0;
954 Trtp = 0;
955 Tras = 0;
956 Trc = 0;
957 Twr = 0;
958 Twtr = 0;
959 for (i=0; i < 4; i++)
960 Trfc[i] = 0;
961 Tfaw = 0;
962
963 for ( i = 0; i< MAX_DIMMS_SUPPORTED; i++) {
964 LDIMM = i >> 1;
965 if (pDCTstat->DIMMValid & (1 << i)) {
966 smbaddr = Get_DIMMAddress_D(pDCTstat, (dct + i));
967
968 val = mctRead_SPD(smbaddr, SPD_MTBDivisor);
969 MTB16x = ((mctRead_SPD(smbaddr, SPD_MTBDividend) & 0xFF)<<4);
970 MTB16x /= val;
971
972 byte = mctRead_SPD(smbaddr, SPD_tRPmin);
973 val = byte * MTB16x;
974 if (Trp < val)
975 Trp = val;
976
977 byte = mctRead_SPD(smbaddr, SPD_tRRDmin);
978 val = byte * MTB16x;
979 if (Trrd < val)
980 Trrd = val;
981
982 byte = mctRead_SPD(smbaddr, SPD_tRCDmin);
983 val = byte * MTB16x;
984 if (Trcd < val)
985 Trcd = val;
986
987 byte = mctRead_SPD(smbaddr, SPD_tRTPmin);
988 val = byte * MTB16x;
989 if (Trtp < val)
990 Trtp = val;
991
992 byte = mctRead_SPD(smbaddr, SPD_tWRmin);
993 val = byte * MTB16x;
994 if (Twr < val)
995 Twr = val;
996
997 byte = mctRead_SPD(smbaddr, SPD_tWTRmin);
998 val = byte * MTB16x;
999 if (Twtr < val)
1000 Twtr = val;
1001
1002 val = mctRead_SPD(smbaddr, SPD_Upper_tRAS_tRC) & 0xFF;
1003 val >>= 4;
1004 val <<= 8;
1005 val |= mctRead_SPD(smbaddr, SPD_tRCmin) & 0xFF;
1006 val *= MTB16x;
1007 if (Trc < val)
1008 Trc = val;
1009
1010 byte = mctRead_SPD(smbaddr, SPD_Density) & 0xF;
1011 if (Trfc[LDIMM] < byte)
1012 Trfc[LDIMM] = byte;
1013
1014 val = mctRead_SPD(smbaddr, SPD_Upper_tRAS_tRC) & 0xF;
1015 val <<= 8;
1016 val |= (mctRead_SPD(smbaddr, SPD_tRASmin) & 0xFF);
1017 val *= MTB16x;
1018 if (Tras < val)
1019 Tras = val;
1020
1021 val = mctRead_SPD(smbaddr, SPD_Upper_tFAW) & 0xF;
1022 val <<= 8;
1023 val |= mctRead_SPD(smbaddr, SPD_tFAWmin) & 0xFF;
1024 val *= MTB16x;
1025 if (Tfaw < val)
1026 Tfaw = val;
1027 }
1028 }
1029
1030
1031 byte = pDCTstat->DIMMAutoSpeed;
1032 if (byte == 7)
1033 tCK16x = 20;
1034 else if (byte == 6)
1035 tCK16x = 24;
1036 else if (byte == 5)
1037 tCK16x = 30;
1038 else
1039 tCK16x = 40;
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049 pDCTstat->DIMMTras = (u16)Tras;
1050 val = Tras / tCK16x;
1051 if (Tras % tCK16x) {
1052 val++;
1053 }
1054 if (val < Min_TrasT)
1055 val = Min_TrasT;
1056 else if (val > Max_TrasT)
1057 val = Max_TrasT;
1058 pDCTstat->Tras = val;
1059
1060
1061 pDCTstat->DIMMTrp = Trp;
1062 val = Trp / tCK16x;
1063 if (Trp % tCK16x) {
1064 val++;
1065 }
1066 if (val < Min_TrpT)
1067 val = Min_TrpT;
1068 else if (val > Max_TrpT)
1069 val = Max_TrpT;
1070 pDCTstat->Trp = val;
1071
1072
1073 pDCTstat->DIMMTrrd = Trrd;
1074 val = Trrd / tCK16x;
1075 if (Trrd % tCK16x) {
1076 val++;
1077 }
1078 if (val < Min_TrrdT)
1079 val = Min_TrrdT;
1080 else if (val > Max_TrrdT)
1081 val = Max_TrrdT;
1082 pDCTstat->Trrd = val;
1083
1084
1085 pDCTstat->DIMMTrcd = Trcd;
1086 val = Trcd / tCK16x;
1087 if (Trcd % tCK16x) {
1088 val++;
1089 }
1090 if (val < Min_TrcdT)
1091 val = Min_TrcdT;
1092 else if (val > Max_TrcdT)
1093 val = Max_TrcdT;
1094 pDCTstat->Trcd = val;
1095
1096
1097 pDCTstat->DIMMTrc = Trc;
1098 val = Trc / tCK16x;
1099 if (Trc % tCK16x) {
1100 val++;
1101 }
1102 if (val < Min_TrcT)
1103 val = Min_TrcT;
1104 else if (val > Max_TrcT)
1105 val = Max_TrcT;
1106 pDCTstat->Trc = val;
1107
1108
1109 pDCTstat->DIMMTrtp = Trtp;
1110 val = Trtp / tCK16x;
1111 if (Trtp % tCK16x) {
1112 val ++;
1113 }
1114 if (val < Min_TrtpT)
1115 val = Min_TrtpT;
1116 else if (val > Max_TrtpT)
1117 val = Max_TrtpT;
1118 pDCTstat->Trtp = val;
1119
1120
1121 pDCTstat->DIMMTwr = Twr;
1122 val = Twr / tCK16x;
1123 if (Twr % tCK16x) {
1124 val++;
1125 }
1126 if (val < Min_TwrT)
1127 val = Min_TwrT;
1128 else if (val > Max_TwrT)
1129 val = Max_TwrT;
1130 pDCTstat->Twr = val;
1131
1132
1133 pDCTstat->DIMMTwtr = Twtr;
1134 val = Twtr / tCK16x;
1135 if (Twtr % tCK16x) {
1136 val++;
1137 }
1138 if (val < Min_TwtrT)
1139 val = Min_TwtrT;
1140 else if (val > Max_TwtrT)
1141 val = Max_TwtrT;
1142 pDCTstat->Twtr = val;
1143
1144
1145 for (i=0; i<4; i++)
1146 pDCTstat->Trfc[i] = Trfc[i];
1147
1148
1149 pDCTstat->DIMMTfaw = Tfaw;
1150 val = Tfaw / tCK16x;
1151 if (Tfaw % tCK16x) {
1152 val++;
1153 }
1154 if (val < Min_TfawT)
1155 val = Min_TfawT;
1156 else if (val > Max_TfawT)
1157 val = Max_TfawT;
1158 pDCTstat->Tfaw = val;
1159
1160 mctAdjustAutoCycTmg_D();
1161
1162
1163 DramTimingLo = 0;
1164 val = pDCTstat->CASL - 2;
1165 DramTimingLo |= val;
1166
1167 val = pDCTstat->Trcd - Bias_TrcdT;
1168 DramTimingLo |= val<<4;
1169
1170 val = pDCTstat->Trp - Bias_TrpT;
1171 val = mct_AdjustSPDTimings(pMCTstat, pDCTstat, val);
1172 DramTimingLo |= val<<7;
1173
1174 val = pDCTstat->Trtp - Bias_TrtpT;
1175 DramTimingLo |= val<<10;
1176
1177 val = pDCTstat->Tras - Bias_TrasT;
1178 DramTimingLo |= val<<12;
1179
1180 val = pDCTstat->Trc - Bias_TrcT;
1181 DramTimingLo |= val<<16;
1182
1183 val = pDCTstat->Trrd - Bias_TrrdT;
1184 DramTimingLo |= val<<22;
1185
1186 DramTimingHi = 0;
1187 val = pDCTstat->Twtr - Bias_TwtrT;
1188 DramTimingHi |= val<<8;
1189
1190 val = 2;
1191 DramTimingHi |= val<<16;
1192
1193 val = 0;
1194 for (i=4;i>0;i--) {
1195 val <<= 3;
1196 val |= Trfc[i-1];
1197 }
1198 DramTimingHi |= val << 20;
1199
1200 dev = pDCTstat->dev_dct;
1201 reg_off = 0x100 * dct;
1202
1203 val = pDCTstat->Twr;
1204 if (val == 10)
1205 val = 9;
1206 else if (val == 12)
1207 val = 10;
1208 val = mct_AdjustSPDTimings(pMCTstat, pDCTstat, val);
1209 val -= Bias_TwrT;
1210 val <<= 4;
1211 dword = Get_NB32(dev, 0x84 + reg_off);
1212 dword &= ~0x70;
1213 dword |= val;
1214 Set_NB32(dev, 0x84 + reg_off, dword);
1215
1216
1217 val = pDCTstat->Tfaw;
1218 val = mct_AdjustSPDTimings(pMCTstat, pDCTstat, val);
1219 val -= Bias_TfawT;
1220 val >>= 1;
1221 val <<= 28;
1222 dword = Get_NB32(dev, 0x94 + reg_off);
1223 dword &= ~0xf0000000;
1224 dword |= val;
1225 Set_NB32(dev, 0x94 + reg_off, dword);
1226
1227
1228
1229
1230 if (pDCTstat->Speed > 4) {
1231 val = Get_NB32(dev, 0x88 + reg_off);
1232 val &= 0xFF000000;
1233 DramTimingLo |= val;
1234 }
1235 Set_NB32(dev, 0x88 + reg_off, DramTimingLo);
1236
1237 if (pDCTstat->Speed > 4) {
1238 DramTimingHi |= 1 << DisAutoRefresh;
1239 }
1240 DramTimingHi |= 0x000018FF;
1241 Set_NB32(dev, 0x8c + reg_off, DramTimingHi);
1242
1243
1244}
1245
1246static u8 AutoCycTiming_D(struct MCTStatStruc *pMCTstat,
1247 struct DCTStatStruc *pDCTstat, u8 dct)
1248{
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278 if (pDCTstat->Speed == 0) {
1279 mctGet_MaxLoadFreq(pDCTstat);
1280
1281
1282 GetPresetmaxF_D(pMCTstat, pDCTstat);
1283
1284
1285 SPDGetTCL_D(pMCTstat, pDCTstat, dct);
1286
1287 pDCTstat->Speed = pDCTstat->DIMMAutoSpeed;
1288 pDCTstat->CASL = pDCTstat->DIMMCASL;
1289
1290 }
1291 mct_AfterGetCLT(pMCTstat, pDCTstat, dct);
1292
1293 SPD2ndTiming(pMCTstat, pDCTstat, dct);
1294
1295 printk(BIOS_DEBUG, "AutoCycTiming: Status %x\n", pDCTstat->Status);
1296 printk(BIOS_DEBUG, "AutoCycTiming: ErrStatus %x\n", pDCTstat->ErrStatus);
1297 printk(BIOS_DEBUG, "AutoCycTiming: ErrCode %x\n", pDCTstat->ErrCode);
1298 printk(BIOS_DEBUG, "AutoCycTiming: Done\n\n");
1299
1300 mctHookAfterAutoCycTmg();
1301
1302 return pDCTstat->ErrCode;
1303}
1304
1305static void GetPresetmaxF_D(struct MCTStatStruc *pMCTstat,
1306 struct DCTStatStruc *pDCTstat)
1307{
1308
1309
1310
1311
1312
1313
1314 u16 proposedFreq;
1315 u16 word;
1316
1317
1318 proposedFreq = 800;
1319
1320
1321 if ( mctGet_NVbits(NV_MCTUSRTMGMODE) == 1) {
1322 word = Get_Fk_D(mctGet_NVbits(NV_MemCkVal) + 1);
1323 if (word < proposedFreq)
1324 proposedFreq = word;
1325
1326
1327 word = mctGet_NVbits(NV_MAX_MEMCLK);
1328 if (word < proposedFreq)
1329 proposedFreq = word;
1330
1331 word = pDCTstat->PresetmaxFreq;
1332 if (word > proposedFreq)
1333 word = proposedFreq;
1334
1335 pDCTstat->PresetmaxFreq = word;
1336 }
1337
1338}
1339
1340static void SPDGetTCL_D(struct MCTStatStruc *pMCTstat,
1341 struct DCTStatStruc *pDCTstat, u8 dct)
1342{
1343
1344
1345
1346
1347
1348
1349 u8 i, CASLatLow, CASLatHigh;
1350 u16 tAAmin16x;
1351 u8 MTB16x;
1352 u16 tCKmin16x;
1353 u16 tCKproposed16x;
1354 u8 CLactual, CLdesired, CLT_Fail;
1355
1356 u8 smbaddr, byte, bytex;
1357
1358 CASLatLow = 0xFF;
1359 CASLatHigh = 0xFF;
1360 tAAmin16x = 0;
1361 tCKmin16x = 0;
1362 CLT_Fail = 0;
1363
1364 for (i = 0; i < MAX_DIMMS_SUPPORTED; i++) {
1365 if (pDCTstat->DIMMValid & (1 << i)) {
1366 smbaddr = Get_DIMMAddress_D(pDCTstat, (dct + i));
1367
1368
1369
1370
1371 byte = mctRead_SPD(smbaddr, SPD_CASLow);
1372 CASLatLow &= byte;
1373 byte = mctRead_SPD(smbaddr, SPD_CASHigh);
1374 CASLatHigh &= byte;
1375
1376
1377 byte = mctRead_SPD(smbaddr, SPD_MTBDivisor);
1378
1379 MTB16x = ((mctRead_SPD(smbaddr, SPD_MTBDividend) & 0xFF)<<4);
1380 MTB16x /= byte;
1381
1382 byte = mctRead_SPD(smbaddr, SPD_tAAmin);
1383 if (tAAmin16x < byte * MTB16x)
1384 tAAmin16x = byte * MTB16x;
1385
1386
1387 byte = mctRead_SPD(smbaddr, SPD_tCKmin);
1388
1389 if (tCKmin16x < byte * MTB16x)
1390 tCKmin16x = byte * MTB16x;
1391 }
1392 }
1393
1394 tCKproposed16x = 16000 / pDCTstat->PresetmaxFreq;
1395 if (tCKmin16x > tCKproposed16x)
1396 tCKproposed16x = tCKmin16x;
1397
1398
1399
1400
1401
1402
1403 if (tCKproposed16x == 20)
1404 pDCTstat->TargetFreq = 7;
1405 else if (tCKproposed16x <= 24) {
1406 pDCTstat->TargetFreq = 6;
1407 tCKproposed16x = 24;
1408 }
1409 else if (tCKproposed16x <= 30) {
1410 pDCTstat->TargetFreq = 5;
1411 tCKproposed16x = 30;
1412 }
1413 else {
1414 pDCTstat->TargetFreq = 4;
1415 tCKproposed16x = 40;
1416 }
1417
1418
1419
1420
1421 for (;;) {
1422 CLT_Fail = 0;
1423
1424
1425
1426
1427
1428
1429
1430 CLdesired = tAAmin16x / tCKproposed16x;
1431 if (tAAmin16x % tCKproposed16x)
1432 CLdesired ++;
1433
1434
1435
1436
1437 for (i = 0, CLactual = 4; i < 15; i++, CLactual++) {
1438 if ((CASLatHigh << 8 | CASLatLow) & (1 << i)) {
1439 if (CLdesired <= CLactual)
1440 break;
1441 }
1442 }
1443 if (i == 15)
1444 CLT_Fail = 1;
1445
1446
1447
1448
1449 if (CLactual * tCKproposed16x > 320)
1450 CLT_Fail = 1;
1451
1452 if (!CLT_Fail) {
1453 bytex = CLactual - 2;
1454 if (tCKproposed16x == 20)
1455 byte = 7;
1456 else if (tCKproposed16x == 24)
1457 byte = 6;
1458 else if (tCKproposed16x == 30)
1459 byte = 5;
1460 else
1461 byte = 4;
1462 } else {
1463
1464
1465 }
1466
1467 if (tCKproposed16x != 40) {
1468 if (pMCTstat->GStatus & (1 << GSB_EnDIMMSpareNW)) {
1469 pDCTstat->DIMMAutoSpeed = byte;
1470 pDCTstat->DIMMCASL = bytex;
1471 break;
1472 } else {
1473 pDCTstat->TargetCASL = bytex;
1474 tCKproposed16x = 40;
1475 }
1476 } else {
1477 pDCTstat->DIMMAutoSpeed = byte;
1478 pDCTstat->DIMMCASL = bytex;
1479 break;
1480 }
1481 }
1482
1483 printk(BIOS_DEBUG, "SPDGetTCL_D: DIMMCASL %x\n", pDCTstat->DIMMCASL);
1484 printk(BIOS_DEBUG, "SPDGetTCL_D: DIMMAutoSpeed %x\n", pDCTstat->DIMMAutoSpeed);
1485
1486 printk(BIOS_DEBUG, "SPDGetTCL_D: Status %x\n", pDCTstat->Status);
1487 printk(BIOS_DEBUG, "SPDGetTCL_D: ErrStatus %x\n", pDCTstat->ErrStatus);
1488 printk(BIOS_DEBUG, "SPDGetTCL_D: ErrCode %x\n", pDCTstat->ErrCode);
1489 printk(BIOS_DEBUG, "SPDGetTCL_D: Done\n\n");
1490}
1491
1492static u8 PlatformSpec_D(struct MCTStatStruc *pMCTstat,
1493 struct DCTStatStruc *pDCTstat, u8 dct)
1494{
1495 u32 dev;
1496 u32 reg;
1497 u32 val;
1498
1499 mctGet_PS_Cfg_D(pMCTstat, pDCTstat, dct);
1500
1501 if (pDCTstat->GangedMode == 1) {
1502 mctGet_PS_Cfg_D(pMCTstat, pDCTstat, 1);
1503 mct_BeforePlatformSpec(pMCTstat, pDCTstat, 1);
1504 }
1505
1506 if ( pDCTstat->_2Tmode == 2) {
1507 dev = pDCTstat->dev_dct;
1508 reg = 0x94 + 0x100 * dct;
1509 val = Get_NB32(dev, reg);
1510 val |= 1 << 20;
1511 Set_NB32(dev, reg, val);
1512 }
1513
1514 mct_BeforePlatformSpec(pMCTstat, pDCTstat, dct);
1515 mct_PlatformSpec(pMCTstat, pDCTstat, dct);
1516 if (pDCTstat->DIMMAutoSpeed == 4)
1517 InitPhyCompensation(pMCTstat, pDCTstat, dct);
1518 mctHookAfterPSCfg();
1519
1520 return pDCTstat->ErrCode;
1521}
1522
1523static u8 AutoConfig_D(struct MCTStatStruc *pMCTstat,
1524 struct DCTStatStruc *pDCTstat, u8 dct)
1525{
1526 u32 DramControl, DramTimingLo, Status;
1527 u32 DramConfigLo, DramConfigHi, DramConfigMisc, DramConfigMisc2;
1528 u32 val;
1529 u32 reg_off;
1530 u32 dev;
1531 u16 word;
1532 u32 dword;
1533 u8 byte;
1534
1535 DramConfigLo = 0;
1536 DramConfigHi = 0;
1537 DramConfigMisc = 0;
1538 DramConfigMisc2 = 0;
1539
1540
1541 SPDSetBanks_D(pMCTstat, pDCTstat, dct);
1542 if (pDCTstat->ErrCode == SC_StopError)
1543 goto AutoConfig_exit;
1544
1545
1546 StitchMemory_D(pMCTstat, pDCTstat, dct);
1547 InterleaveBanks_D(pMCTstat, pDCTstat, dct);
1548
1549
1550 Status = pDCTstat->Status;
1551
1552 dev = pDCTstat->dev_dct;
1553 reg_off = 0x100 * dct;
1554
1555
1556
1557 DramConfigMisc2 = Get_NB32 (dev, 0xA8 + reg_off);
1558 DramControl = Get_NB32 (dev, 0x78 + reg_off);
1559
1560
1561
1562 if (pDCTstat->LogicalCPUID & AMD_DR_Bx)
1563 val = 5;
1564 else
1565 val = 6;
1566 DramControl &= ~0xFF;
1567 DramControl |= val;
1568
1569 if (mctGet_NVbits(NV_CLKHZAltVidC3))
1570 DramControl |= 1<<16;
1571
1572 DramControl |= 0x00002A00;
1573
1574
1575
1576 if (Status & (1 << SB_128bitmode))
1577 DramConfigLo |= 1 << Width128;
1578
1579 word = dct;
1580 dword = X4Dimm;
1581 while (word < 8) {
1582 if (pDCTstat->Dimmx4Present & (1 << word))
1583 DramConfigLo |= 1 << dword;
1584 word++;
1585 word++;
1586 dword++;
1587 }
1588
1589 if (!(Status & (1 << SB_Registered)))
1590 DramConfigLo |= 1 << UnBuffDimm;
1591
1592 if (mctGet_NVbits(NV_ECC_CAP))
1593 if (Status & (1 << SB_ECCDIMMs))
1594 if ( mctGet_NVbits(NV_ECC))
1595 DramConfigLo |= 1 << DimmEcEn;
1596
1597 DramConfigLo = mct_DisDllShutdownSR(pMCTstat, pDCTstat, DramConfigLo, dct);
1598
1599
1600 dword = pDCTstat->Speed;
1601 DramConfigHi |= dword - 1;
1602 DramConfigHi |= 1 << MemClkFreqVal;
1603
1604 if (Status & (1 << SB_Registered))
1605 if ((pDCTstat->Dimmx4Present != 0) && (pDCTstat->Dimmx8Present != 0))
1606
1607 DramConfigHi |= 1 << RDqsEn;
1608
1609 if (mctGet_NVbits(NV_CKE_CTL))
1610
1611 DramConfigHi |= 1 << 16;
1612
1613
1614 if (0)
1615 DramConfigHi &= ~(1 << BankSwizzleMode);
1616 else
1617 DramConfigHi |= 1 << BankSwizzleMode;
1618
1619
1620 if ( pDCTstat->DimmQRPresent != 0) {
1621 byte = mctGet_NVbits(NV_4RANKType);
1622 if (byte == 2)
1623 DramConfigHi |= 1 << 17;
1624 else if (byte == 1)
1625 DramConfigHi |= 1 << 18;
1626 }
1627
1628 if (0)
1629 val = mctGet_NVbits(NV_BYPMAX);
1630 else
1631 val = 0x0f;
1632 DramConfigHi |= val << 24;
1633
1634 if (pDCTstat->LogicalCPUID & (AMD_DR_Cx | AMD_DR_Bx))
1635 DramConfigHi |= 1 << DcqArbBypassEn;
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645 DramTimingLo = Get_NB32(dev, 0x88 + reg_off);
1646 if (mctGet_NVbits(NV_AllMemClks) == 0) {
1647
1648 if (!(pDCTstat->Status & (1<<SB_DiagClks))) {
1649 const u8 *p;
1650 const u32 *q;
1651 p = Tab_ManualCLKDis;
1652 q = (u32 *)p;
1653
1654 byte = mctGet_NVbits(NV_PACK_TYPE);
1655 if (byte == PT_L1)
1656 p = Tab_L1CLKDis;
1657 else if (byte == PT_M2 || byte == PT_AS)
1658 p = Tab_AM3CLKDis;
1659 else
1660 p = Tab_S1CLKDis;
1661
1662 dword = 0;
1663 byte = 0xFF;
1664 while(dword < MAX_CS_SUPPORTED) {
1665 if (pDCTstat->CSPresent & (1<<dword)){
1666
1667 val = p[dword];
1668 byte &= ~val;
1669 }
1670 dword++ ;
1671 }
1672 DramTimingLo |= byte << 24;
1673 }
1674 }
1675
1676 printk(BIOS_DEBUG, "AutoConfig_D: DramControl: %x\n", DramControl);
1677 printk(BIOS_DEBUG, "AutoConfig_D: DramTimingLo: %x\n", DramTimingLo);
1678 printk(BIOS_DEBUG, "AutoConfig_D: DramConfigMisc: %x\n", DramConfigMisc);
1679 printk(BIOS_DEBUG, "AutoConfig_D: DramConfigMisc2: %x\n", DramConfigMisc2);
1680 printk(BIOS_DEBUG, "AutoConfig_D: DramConfigLo: %x\n", DramConfigLo);
1681 printk(BIOS_DEBUG, "AutoConfig_D: DramConfigHi: %x\n", DramConfigHi);
1682
1683
1684 Set_NB32(dev, 0x78 + reg_off, DramControl);
1685 Set_NB32(dev, 0x88 + reg_off, DramTimingLo);
1686 Set_NB32(dev, 0xA0 + reg_off, DramConfigMisc);
1687 DramConfigMisc2 = mct_SetDramConfigMisc2(pDCTstat, dct, DramConfigMisc2);
1688 Set_NB32(dev, 0xA8 + reg_off, DramConfigMisc2);
1689 Set_NB32(dev, 0x90 + reg_off, DramConfigLo);
1690 ProgDramMRSReg_D(pMCTstat, pDCTstat, dct);
1691 dword = Get_NB32(dev, 0x94 + reg_off);
1692 DramConfigHi |= dword;
1693 mct_SetDramConfigHi_D(pDCTstat, dct, DramConfigHi);
1694 mct_EarlyArbEn_D(pMCTstat, pDCTstat, dct);
1695 mctHookAfterAutoCfg();
1696
1697
1698
1699 printk(BIOS_DEBUG, "AutoConfig: Status %x\n", pDCTstat->Status);
1700 printk(BIOS_DEBUG, "AutoConfig: ErrStatus %x\n", pDCTstat->ErrStatus);
1701 printk(BIOS_DEBUG, "AutoConfig: ErrCode %x\n", pDCTstat->ErrCode);
1702 printk(BIOS_DEBUG, "AutoConfig: Done\n\n");
1703AutoConfig_exit:
1704 return pDCTstat->ErrCode;
1705}
1706
1707static void SPDSetBanks_D(struct MCTStatStruc *pMCTstat,
1708 struct DCTStatStruc *pDCTstat, u8 dct)
1709{
1710
1711
1712
1713
1714 u8 ChipSel, Rows, Cols, Ranks, Banks;
1715 u32 BankAddrReg, csMask;
1716
1717 u32 val;
1718 u32 reg;
1719 u32 dev;
1720 u32 reg_off;
1721 u8 byte;
1722 u16 word;
1723 u32 dword;
1724 u16 smbaddr;
1725
1726 dev = pDCTstat->dev_dct;
1727 reg_off = 0x100 * dct;
1728
1729 BankAddrReg = 0;
1730 for (ChipSel = 0; ChipSel < MAX_CS_SUPPORTED; ChipSel+=2) {
1731 byte = ChipSel;
1732 if ((pDCTstat->Status & (1 << SB_64MuxedMode)) && ChipSel >=4)
1733 byte -= 3;
1734
1735 if (pDCTstat->DIMMValid & (1<<byte)) {
1736 smbaddr = Get_DIMMAddress_D(pDCTstat, (ChipSel + dct));
1737
1738 byte = mctRead_SPD(smbaddr, SPD_Addressing);
1739 Rows = (byte >> 3) & 0x7;
1740 Cols = byte & 0x7;
1741
1742 byte = mctRead_SPD(smbaddr, SPD_Density);
1743 Banks = (byte >> 4) & 7;
1744
1745 byte = mctRead_SPD(smbaddr, SPD_Organization);
1746 Ranks = ((byte >> 3) & 7) + 1;
1747
1748
1749
1750
1751
1752
1753
1754 byte = Cols;
1755 if (Banks == 1)
1756 byte |= 4;
1757
1758 byte |= Rows << 3;
1759
1760 for (dword=0; dword < 13; dword++) {
1761 if (byte == Tab_BankAddr[dword])
1762 break;
1763 }
1764
1765 if (dword > 12)
1766 continue;
1767
1768
1769 dword <<= (ChipSel<<1);
1770 BankAddrReg |= dword;
1771
1772
1773
1774 csMask = 0;
1775
1776 byte = Rows + Cols;
1777 byte += 21;
1778 byte -= 2;
1779
1780 if (pDCTstat->Status & (1 << SB_128bitmode))
1781 byte++;
1782
1783 csMask |= 1 << byte;
1784 csMask--;
1785
1786
1787 pDCTstat->CSPresent |= (1<<ChipSel);
1788 if (Ranks >= 2)
1789
1790 pDCTstat->CSPresent |= 1 << (ChipSel + 1);
1791
1792 reg = 0x60+(ChipSel<<1) + reg_off;
1793 val = csMask;
1794 val &= 0x1FF83FE0;
1795 Set_NB32(dev, reg, val);
1796 } else {
1797 if (pDCTstat->DIMMSPDCSE & (1<<ChipSel))
1798 pDCTstat->CSTestFail |= (1<<ChipSel);
1799 }
1800 }
1801
1802 SetCSTriState(pMCTstat, pDCTstat, dct);
1803 SetCKETriState(pMCTstat, pDCTstat, dct);
1804 SetODTTriState(pMCTstat, pDCTstat, dct);
1805
1806 if (pDCTstat->Status & (1 << SB_128bitmode)) {
1807 SetCSTriState(pMCTstat, pDCTstat, 1);
1808 SetCKETriState(pMCTstat, pDCTstat, 1);
1809 SetODTTriState(pMCTstat, pDCTstat, 1);
1810 }
1811
1812 word = pDCTstat->CSPresent;
1813 mctGetCS_ExcludeMap();
1814 word ^= pDCTstat->CSPresent;
1815 pDCTstat->CSTestFail |= word;
1816 if (!pDCTstat->CSPresent)
1817 pDCTstat->ErrCode = SC_StopError;
1818
1819 reg = 0x80 + reg_off;
1820 Set_NB32(dev, reg, BankAddrReg);
1821
1822 pDCTstat->CSPresent_DCT[dct] = pDCTstat->CSPresent;
1823
1824
1825 printk(BIOS_DEBUG, "SPDSetBanks: CSPresent %x\n", pDCTstat->CSPresent_DCT[dct]);
1826 printk(BIOS_DEBUG, "SPDSetBanks: Status %x\n", pDCTstat->Status);
1827 printk(BIOS_DEBUG, "SPDSetBanks: ErrStatus %x\n", pDCTstat->ErrStatus);
1828 printk(BIOS_DEBUG, "SPDSetBanks: ErrCode %x\n", pDCTstat->ErrCode);
1829 printk(BIOS_DEBUG, "SPDSetBanks: Done\n\n");
1830}
1831
1832static void SPDCalcWidth_D(struct MCTStatStruc *pMCTstat,
1833 struct DCTStatStruc *pDCTstat)
1834{
1835
1836
1837
1838
1839 u8 i;
1840 u8 smbaddr, smbaddr1;
1841 u8 byte, byte1;
1842
1843
1844
1845 for (i=0; i < MAX_DIMMS_SUPPORTED; i += 2) {
1846 if ((pDCTstat->DIMMValid & (1 << i)) && (pDCTstat->DIMMValid & (1<<(i+1)))) {
1847 smbaddr = Get_DIMMAddress_D(pDCTstat, i);
1848 smbaddr1 = Get_DIMMAddress_D(pDCTstat, i+1);
1849
1850 byte = mctRead_SPD(smbaddr, SPD_Addressing) & 0x7;
1851 byte1 = mctRead_SPD(smbaddr1, SPD_Addressing) & 0x7;
1852 if (byte != byte1) {
1853 pDCTstat->ErrStatus |= (1<<SB_DimmMismatchO);
1854 break;
1855 }
1856
1857 byte = mctRead_SPD(smbaddr, SPD_Density) & 0x0f;
1858 byte1 = mctRead_SPD(smbaddr1, SPD_Density) & 0x0f;
1859 if (byte != byte1) {
1860 pDCTstat->ErrStatus |= (1<<SB_DimmMismatchO);
1861 break;
1862 }
1863
1864 byte = mctRead_SPD(smbaddr, SPD_Organization) & 0x7;
1865 byte1 = mctRead_SPD(smbaddr1, SPD_Organization) & 0x7;
1866 if (byte != byte1) {
1867 pDCTstat->ErrStatus |= (1<<SB_DimmMismatchO);
1868 break;
1869 }
1870
1871 byte = (mctRead_SPD(smbaddr, SPD_Organization) >> 3) & 0x7;
1872 byte1 = (mctRead_SPD(smbaddr1, SPD_Organization) >> 3) & 0x7;
1873 if (byte != byte1) {
1874 pDCTstat->ErrStatus |= (1<<SB_DimmMismatchO);
1875 break;
1876 }
1877
1878 byte = mctRead_SPD(smbaddr, SPD_DMBANKS) & 7;
1879 byte1 = mctRead_SPD