AMD DDR2 and DDR3 MCT function InitPhyCompensation() compliant with AGESA code.
[coreboot.git] / src / northbridge / amd / amdmct / mct_ddr3 / mct_d.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2010 Advanced Micro Devices, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
18  */
19
20 /* Description: Main memory controller system configuration for DDR 3 */
21
22 /* KNOWN ISSUES - ERRATA
23  *
24  * Trtp is not calculated correctly when the controller is in 64-bit mode, it
25  * is 1 busclock off.   No fix planned.  The controller is not ordinarily in
26  * 64-bit mode.
27  *
28  * 32 Byte burst not supported. No fix planned. The controller is not
29  * ordinarily in 64-bit mode.
30  *
31  * Trc precision does not use extra Jedec defined fractional component.
32  * InsteadTrc (course) is rounded up to nearest 1 ns.
33  *
34  * Mini and Micro DIMM not supported. Only RDIMM, UDIMM, SO-DIMM defined types
35  * supported.
36  */
37
38 static u8 ReconfigureDIMMspare_D(struct MCTStatStruc *pMCTstat,
39                                         struct DCTStatStruc *pDCTstatA);
40 static void DQSTiming_D(struct MCTStatStruc *pMCTstat,
41                                 struct DCTStatStruc *pDCTstatA);
42 static void LoadDQSSigTmgRegs_D(struct MCTStatStruc *pMCTstat,
43                                         struct DCTStatStruc *pDCTstatA);
44 static void HTMemMapInit_D(struct MCTStatStruc *pMCTstat,
45                                 struct DCTStatStruc *pDCTstatA);
46 static void MCTMemClr_D(struct MCTStatStruc *pMCTstat,
47                                 struct DCTStatStruc *pDCTstatA);
48 static void DCTMemClr_Init_D(struct MCTStatStruc *pMCTstat,
49                                 struct DCTStatStruc *pDCTstat);
50 static void DCTMemClr_Sync_D(struct MCTStatStruc *pMCTstat,
51                                 struct DCTStatStruc *pDCTstat);
52 static void MCTMemClrSync_D(struct MCTStatStruc *pMCTstat,
53                                 struct DCTStatStruc *pDCTstatA);
54 static u8 NodePresent_D(u8 Node);
55 static void SyncDCTsReady_D(struct MCTStatStruc *pMCTstat,
56                                 struct DCTStatStruc *pDCTstatA);
57 static void StartupDCT_D(struct MCTStatStruc *pMCTstat,
58                                 struct DCTStatStruc *pDCTstat, u8 dct);
59 static void ClearDCT_D(struct MCTStatStruc *pMCTstat,
60                         struct DCTStatStruc *pDCTstat, u8 dct);
61 static u8 AutoCycTiming_D(struct MCTStatStruc *pMCTstat,
62                                 struct DCTStatStruc *pDCTstat, u8 dct);
63 static void GetPresetmaxF_D(struct MCTStatStruc *pMCTstat,
64                                 struct DCTStatStruc *pDCTstat);
65 static void SPDGetTCL_D(struct MCTStatStruc *pMCTstat,
66                         struct DCTStatStruc *pDCTstat, u8 dct);
67 static u8 AutoConfig_D(struct MCTStatStruc *pMCTstat,
68                                 struct DCTStatStruc *pDCTstat, u8 dct);
69 static u8 PlatformSpec_D(struct MCTStatStruc *pMCTstat,
70                                 struct DCTStatStruc *pDCTstat, u8 dct);
71 static void SPDSetBanks_D(struct MCTStatStruc *pMCTstat,
72                                 struct DCTStatStruc *pDCTstat, u8 dct);
73 static void StitchMemory_D(struct MCTStatStruc *pMCTstat,
74                                 struct DCTStatStruc *pDCTstat, u8 dct);
75 static u16 Get_Fk_D(u8 k);
76 static u8 Get_DIMMAddress_D(struct DCTStatStruc *pDCTstat, u8 i);
77 static void mct_initDCT(struct MCTStatStruc *pMCTstat,
78                                 struct DCTStatStruc *pDCTstat);
79 static void mct_DramInit(struct MCTStatStruc *pMCTstat,
80                                 struct DCTStatStruc *pDCTstat, u8 dct);
81 static u8 mct_PlatformSpec(struct MCTStatStruc *pMCTstat,
82                                         struct DCTStatStruc *pDCTstat, u8 dct);
83 static void mct_SyncDCTsReady(struct DCTStatStruc *pDCTstat);
84 static void Get_Trdrd(struct MCTStatStruc *pMCTstat,
85                         struct DCTStatStruc *pDCTstat, u8 dct);
86 static void mct_AfterGetCLT(struct MCTStatStruc *pMCTstat,
87                                 struct DCTStatStruc *pDCTstat, u8 dct);
88 static u8 mct_SPDCalcWidth(struct MCTStatStruc *pMCTstat,\
89                                         struct DCTStatStruc *pDCTstat, u8 dct);
90 static void mct_AfterStitchMemory(struct MCTStatStruc *pMCTstat,
91                                         struct DCTStatStruc *pDCTstat, u8 dct);
92 static u8 mct_DIMMPresence(struct MCTStatStruc *pMCTstat,
93                                         struct DCTStatStruc *pDCTstat, u8 dct);
94 static void Set_OtherTiming(struct MCTStatStruc *pMCTstat,
95                                 struct DCTStatStruc *pDCTstat, u8 dct);
96 static void Get_Twrwr(struct MCTStatStruc *pMCTstat,
97                         struct DCTStatStruc *pDCTstat, u8 dct);
98 static void Get_Twrrd(struct MCTStatStruc *pMCTstat,
99                         struct DCTStatStruc *pDCTstat, u8 dct);
100 static void Get_TrwtTO(struct MCTStatStruc *pMCTstat,
101                         struct DCTStatStruc *pDCTstat, u8 dct);
102 static void Get_TrwtWB(struct MCTStatStruc *pMCTstat,
103                         struct DCTStatStruc *pDCTstat);
104 static void Get_DqsRcvEnGross_Diff(struct DCTStatStruc *pDCTstat,
105                                         u32 dev, u32 index_reg);
106 static void Get_WrDatGross_Diff(struct DCTStatStruc *pDCTstat, u8 dct,
107                                         u32 dev, u32 index_reg);
108 static u16 Get_DqsRcvEnGross_MaxMin(struct DCTStatStruc *pDCTstat,
109                                 u32 dev, u32 index_reg, u32 index);
110 static void mct_FinalMCT_D(struct MCTStatStruc *pMCTstat,
111                                 struct DCTStatStruc *pDCTstat);
112 static u16 Get_WrDatGross_MaxMin(struct DCTStatStruc *pDCTstat, u8 dct,
113                                 u32 dev, u32 index_reg, u32 index);
114 static void mct_InitialMCT_D(struct MCTStatStruc *pMCTstat,
115                                 struct DCTStatStruc *pDCTstat);
116 static void mct_init(struct MCTStatStruc *pMCTstat,
117                         struct DCTStatStruc *pDCTstat);
118 static void clear_legacy_Mode(struct MCTStatStruc *pMCTstat,
119                                 struct DCTStatStruc *pDCTstat);
120 static void mct_HTMemMapExt(struct MCTStatStruc *pMCTstat,
121                                 struct DCTStatStruc *pDCTstatA);
122 static void SetCSTriState(struct MCTStatStruc *pMCTstat,
123                                 struct DCTStatStruc *pDCTstat, u8 dct);
124 static void SetCKETriState(struct MCTStatStruc *pMCTstat,
125                                 struct DCTStatStruc *pDCTstat, u8 dct);
126 static void SetODTTriState(struct MCTStatStruc *pMCTstat,
127                                 struct DCTStatStruc *pDCTstat, u8 dct);
128 static void InitPhyCompensation(struct MCTStatStruc *pMCTstat,
129                                         struct DCTStatStruc *pDCTstat, u8 dct);
130 static u32 mct_NodePresent_D(void);
131 static void mct_OtherTiming(struct MCTStatStruc *pMCTstat,
132                                 struct DCTStatStruc *pDCTstatA);
133 static void mct_ResetDataStruct_D(struct MCTStatStruc *pMCTstat,
134                                         struct DCTStatStruc *pDCTstatA);
135 static void mct_EarlyArbEn_D(struct MCTStatStruc *pMCTstat,
136                                         struct DCTStatStruc *pDCTstat);
137 static void mct_BeforeDramInit_Prod_D(struct MCTStatStruc *pMCTstat,
138                                         struct DCTStatStruc *pDCTstat);
139 void mct_ClrClToNB_D(struct MCTStatStruc *pMCTstat,
140                         struct DCTStatStruc *pDCTstat);
141 static u8 CheckNBCOFEarlyArbEn(struct MCTStatStruc *pMCTstat,
142                                         struct DCTStatStruc *pDCTstat);
143 void mct_ClrWbEnhWsbDis_D(struct MCTStatStruc *pMCTstat,
144                                         struct DCTStatStruc *pDCTstat);
145 static void mct_BeforeDQSTrain_D(struct MCTStatStruc *pMCTstat,
146                                         struct DCTStatStruc *pDCTstatA);
147 static void AfterDramInit_D(struct DCTStatStruc *pDCTstat, u8 dct);
148 static void mct_ResetDLL_D(struct MCTStatStruc *pMCTstat,
149                                         struct DCTStatStruc *pDCTstat, u8 dct);
150 static void ProgDramMRSReg_D(struct MCTStatStruc *pMCTstat,
151                                         struct DCTStatStruc *pDCTstat, u8 dct);
152 static void mct_DramInit_Sw_D(struct MCTStatStruc *pMCTstat,
153                                         struct DCTStatStruc *pDCTstat, u8 dct);
154 static u32 mct_DisDllShutdownSR(struct MCTStatStruc *pMCTstat,
155                                 struct DCTStatStruc *pDCTstat, u32 DramConfigLo, u8 dct);
156
157 static u32 mct_DramTermDyn_RDimm(struct MCTStatStruc *pMCTstat,
158                                         struct DCTStatStruc *pDCTstat, u8 dimm);
159 static u32 mct_SetDramConfigMisc2(struct DCTStatStruc *pDCTstat, u8 dct, u32 misc2);
160 static void mct_BeforeDQSTrainSamp(struct DCTStatStruc *pDCTstat);
161 static void mct_WriteLevelization_HW(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA);
162 static u8 Get_Latency_Diff(struct MCTStatStruc *pMCTstat,
163                                         struct DCTStatStruc *pDCTstat, u8 dct);
164 static void SyncSetting(struct DCTStatStruc *pDCTstat);
165 static u8 crcCheck(u8 smbaddr);
166
167 /*See mctAutoInitMCT header for index relationships to CL and T*/
168 static const u16 Table_F_k[]    = {00,200,266,333,400,533 };
169 static const u8 Tab_BankAddr[]  = {0x3F,0x01,0x09,0x3F,0x3F,0x11,0x0A,0x19,0x12,0x1A,0x21,0x22,0x23};
170 static const u8 Table_DQSRcvEn_Offset[] = {0x00,0x01,0x10,0x11,0x2};
171
172 /****************************************************************************
173    Describe how platform maps MemClk pins to logical DIMMs. The MemClk pins
174    are identified based on BKDG definition of Fn2x88[MemClkDis] bitmap.
175    AGESA will base on this value to disable unused MemClk to save power.
176
177    If MEMCLK_MAPPING or MEMCLK_MAPPING contains all zeroes, AGESA will use
178    default MemClkDis setting based on package type.
179
180    Example:
181    BKDG definition of Fn2x88[MemClkDis] bitmap for AM3 package is like below:
182         Bit AM3/S1g3 pin name
183         0   M[B,A]_CLK_H/L[0]
184         1   M[B,A]_CLK_H/L[1]
185         2   M[B,A]_CLK_H/L[2]
186         3   M[B,A]_CLK_H/L[3]
187         4   M[B,A]_CLK_H/L[4]
188         5   M[B,A]_CLK_H/L[5]
189         6   M[B,A]_CLK_H/L[6]
190         7   M[B,A]_CLK_H/L[7]
191
192    And platform has the following routing:
193         CS0   M[B,A]_CLK_H/L[4]
194         CS1   M[B,A]_CLK_H/L[2]
195         CS2   M[B,A]_CLK_H/L[3]
196         CS3   M[B,A]_CLK_H/L[5]
197
198    Then:
199                         ;    CS0        CS1        CS2        CS3        CS4        CS5        CS6        CS7
200    MEMCLK_MAPPING  EQU    00010000b, 00000100b, 00001000b, 00100000b, 00000000b, 00000000b, 00000000b, 00000000b
201 */
202
203 /* Note: If you are not sure about the pin mappings at initial stage, we dont have to disable MemClk.
204  * Set entries in the tables all 0xFF. */
205 static const u8 Tab_L1CLKDis[]  = {0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04};
206 static const u8 Tab_AM3CLKDis[] = {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00};
207 static const u8 Tab_S1CLKDis[]  = {0xA2, 0xA2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
208 static const u8 Tab_ManualCLKDis[]= {0x10, 0x04, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00};
209
210 static const u8 Table_Comp_Rise_Slew_20x[] = {7, 3, 2, 2, 0xFF};
211 static const u8 Table_Comp_Rise_Slew_15x[] = {7, 7, 3, 2, 0xFF};
212 static const u8 Table_Comp_Fall_Slew_20x[] = {7, 5, 3, 2, 0xFF};
213 static const u8 Table_Comp_Fall_Slew_15x[] = {7, 7, 5, 3, 0xFF};
214
215 static void mctAutoInitMCT_D(struct MCTStatStruc *pMCTstat,
216                         struct DCTStatStruc *pDCTstatA)
217 {
218         /*
219          * Memory may be mapped contiguously all the way up to 4GB (depending on setup
220          * options).  It is the responsibility of PCI subsystem to create an uncacheable
221          * IO region below 4GB and to adjust TOP_MEM downward prior to any IO mapping or
222          * accesses.  It is the same responsibility of the CPU sub-system prior to
223          * accessing LAPIC.
224          *
225          * Slot Number is an external convention, and is determined by OEM with accompanying
226          * silk screening.  OEM may choose to use Slot number convention which is consistent
227          * with DIMM number conventions.  All AMD engineering platforms do.
228          *
229          * Build Requirements:
230          * 1. MCT_SEG0_START and MCT_SEG0_END macros to begin and end the code segment,
231          *    defined in mcti.inc.
232          *
233          * Run-Time Requirements:
234          * 1. Complete Hypertransport Bus Configuration
235          * 2. SMBus Controller Initialized
236          * 1. BSP in Big Real Mode
237          * 2. Stack at SS:SP, located somewhere between A000:0000 and F000:FFFF
238          * 3. Checksummed or Valid NVRAM bits
239          * 4. MCG_CTL=-1, MC4_CTL_EN=0 for all CPUs
240          * 5. MCi_STS from shutdown/warm reset recorded (if desired) prior to entry
241          * 6. All var MTRRs reset to zero
242          * 7. State of NB_CFG.DisDatMsk set properly on all CPUs
243          * 8. All CPUs at 2Ghz Speed (unless DQS training is not installed).
244          * 9. All cHT links at max Speed/Width (unless DQS training is not installed).
245          *
246          *
247          * Global relationship between index values and item values:
248          *
249          * pDCTstat.CASL pDCTstat.Speed
250          * j CL(j)       k   F(k)
251          * --------------------------
252          * 0 2.0         -   -
253          * 1 3.0         1   200 Mhz
254          * 2 4.0         2   266 Mhz
255          * 3 5.0         3   333 Mhz
256          * 4 6.0         4   400 Mhz
257          * 5 7.0         5   533 Mhz
258          * 6 8.0         6   667 Mhz
259          * 7 9.0         7   800 Mhz
260          */
261         u8 Node, NodesWmem;
262         u32 node_sys_base;
263
264 restartinit:
265         mctInitMemGPIOs_A_D();          /* Set any required GPIOs*/
266         NodesWmem = 0;
267         node_sys_base = 0;
268         for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
269                 struct DCTStatStruc *pDCTstat;
270                 pDCTstat = pDCTstatA + Node;
271                 pDCTstat->Node_ID = Node;
272                 pDCTstat->dev_host = PA_HOST(Node);
273                 pDCTstat->dev_map = PA_MAP(Node);
274                 pDCTstat->dev_dct = PA_DCT(Node);
275                 pDCTstat->dev_nbmisc = PA_NBMISC(Node);
276                 pDCTstat->NodeSysBase = node_sys_base;
277
278                 mct_init(pMCTstat, pDCTstat);
279                 mctNodeIDDebugPort_D();
280                 pDCTstat->NodePresent = NodePresent_D(Node);
281                 if (pDCTstat->NodePresent) {            /* See if Node is there*/
282                         clear_legacy_Mode(pMCTstat, pDCTstat);
283                         pDCTstat->LogicalCPUID = mctGetLogicalCPUID_D(Node);
284
285                         mct_InitialMCT_D(pMCTstat, pDCTstat);
286
287                         mctSMBhub_Init(Node);           /* Switch SMBUS crossbar to proper node*/
288
289                         mct_initDCT(pMCTstat, pDCTstat);
290                         if (pDCTstat->ErrCode == SC_FatalErr) {
291                                 goto fatalexit;         /* any fatal errors?*/
292                         } else if (pDCTstat->ErrCode < SC_StopError) {
293                                 NodesWmem++;
294                         }
295                 }       /* if Node present */
296                 node_sys_base = pDCTstat->NodeSysBase;
297                 node_sys_base += (pDCTstat->NodeSysLimit + 2) & ~0x0F;
298         }
299         if (NodesWmem == 0) {
300                 printk(BIOS_DEBUG, "No Nodes?!\n");
301                 goto fatalexit;
302         }
303
304         printk(BIOS_DEBUG, "mctAutoInitMCT_D: SyncDCTsReady_D\n");
305         SyncDCTsReady_D(pMCTstat, pDCTstatA);   /* Make sure DCTs are ready for accesses.*/
306
307         printk(BIOS_DEBUG, "mctAutoInitMCT_D: HTMemMapInit_D\n");
308         HTMemMapInit_D(pMCTstat, pDCTstatA);    /* Map local memory into system address space.*/
309         mctHookAfterHTMap();
310
311         printk(BIOS_DEBUG, "mctAutoInitMCT_D: CPUMemTyping_D\n");
312         CPUMemTyping_D(pMCTstat, pDCTstatA);    /* Map dram into WB/UC CPU cacheability */
313         mctHookAfterCPU();                      /* Setup external northbridge(s) */
314
315         printk(BIOS_DEBUG, "mctAutoInitMCT_D: DQSTiming_D\n");
316         DQSTiming_D(pMCTstat, pDCTstatA);       /* Get Receiver Enable and DQS signal timing*/
317
318         printk(BIOS_DEBUG, "mctAutoInitMCT_D: UMAMemTyping_D\n");
319         UMAMemTyping_D(pMCTstat, pDCTstatA);    /* Fix up for UMA sizing */
320
321         printk(BIOS_DEBUG, "mctAutoInitMCT_D: :OtherTiming\n");
322         mct_OtherTiming(pMCTstat, pDCTstatA);
323
324         if (ReconfigureDIMMspare_D(pMCTstat, pDCTstatA)) { /* RESET# if 1st pass of DIMM spare enabled*/
325                 goto restartinit;
326         }
327
328         InterleaveNodes_D(pMCTstat, pDCTstatA);
329         InterleaveChannels_D(pMCTstat, pDCTstatA);
330
331         printk(BIOS_DEBUG, "mctAutoInitMCT_D: ECCInit_D\n");
332         if (ECCInit_D(pMCTstat, pDCTstatA)) {           /* Setup ECC control and ECC check-bits*/
333                 printk(BIOS_DEBUG, "mctAutoInitMCT_D: MCTMemClr_D\n");
334                 MCTMemClr_D(pMCTstat,pDCTstatA);
335         }
336
337         mct_FinalMCT_D(pMCTstat, (pDCTstatA + 0) );     /* Node 0 */
338         printk(BIOS_DEBUG, "All Done\n");
339         return;
340
341 fatalexit:
342         die("mct_d: fatalexit");
343 }
344
345 static u8 ReconfigureDIMMspare_D(struct MCTStatStruc *pMCTstat,
346                                         struct DCTStatStruc *pDCTstatA)
347 {
348         u8 ret;
349
350         if (mctGet_NVbits(NV_CS_SpareCTL)) {
351                 if (MCT_DIMM_SPARE_NO_WARM) {
352                         /* Do no warm-reset DIMM spare */
353                         if (pMCTstat->GStatus & (1 << GSB_EnDIMMSpareNW)) {
354                                 LoadDQSSigTmgRegs_D(pMCTstat, pDCTstatA);
355                                 ret = 0;
356                         } else {
357                                 mct_ResetDataStruct_D(pMCTstat, pDCTstatA);
358                                 pMCTstat->GStatus |= 1 << GSB_EnDIMMSpareNW;
359                                 ret = 1;
360                         }
361                 } else {
362                         /* Do warm-reset DIMM spare */
363                         if (mctGet_NVbits(NV_DQSTrainCTL))
364                                 mctWarmReset_D();
365                         ret = 0;
366                 }
367         } else {
368                 ret = 0;
369         }
370
371         return ret;
372 }
373
374 static void DQSTiming_D(struct MCTStatStruc *pMCTstat,
375                                 struct DCTStatStruc *pDCTstatA)
376 {
377         u8 nv_DQSTrainCTL;
378
379         if (pMCTstat->GStatus & (1 << GSB_EnDIMMSpareNW)) {
380                 return;
381         }
382
383         nv_DQSTrainCTL = mctGet_NVbits(NV_DQSTrainCTL);
384         /* FIXME: BOZO- DQS training every time*/
385         nv_DQSTrainCTL = 1;
386
387         mct_BeforeDQSTrain_D(pMCTstat, pDCTstatA);
388         phyAssistedMemFnceTraining(pMCTstat, pDCTstatA);
389
390         if (nv_DQSTrainCTL) {
391                 mctHookBeforeAnyTraining(pMCTstat, pDCTstatA);
392                 /* TODO: should be in mctHookBeforeAnyTraining */
393                 _WRMSR(0x26C, 0x04040404, 0x04040404);
394                 _WRMSR(0x26D, 0x04040404, 0x04040404);
395                 _WRMSR(0x26E, 0x04040404, 0x04040404);
396                 _WRMSR(0x26F, 0x04040404, 0x04040404);
397                 mct_WriteLevelization_HW(pMCTstat, pDCTstatA);
398
399                 TrainReceiverEn_D(pMCTstat, pDCTstatA, FirstPass);
400
401                 mct_TrainDQSPos_D(pMCTstat, pDCTstatA);
402
403                 /* Second Pass never used for Barcelona! */
404                 /* TrainReceiverEn_D(pMCTstat, pDCTstatA, SecondPass); */
405
406                 mctSetEccDQSRcvrEn_D(pMCTstat, pDCTstatA);
407
408                 /* FIXME - currently uses calculated value      TrainMaxReadLatency_D(pMCTstat, pDCTstatA); */
409                 mctHookAfterAnyTraining();
410                 mctSaveDQSSigTmg_D();
411
412                 MCTMemClr_D(pMCTstat, pDCTstatA);
413         } else {
414                 mctGetDQSSigTmg_D();    /* get values into data structure */
415                 LoadDQSSigTmgRegs_D(pMCTstat, pDCTstatA);       /* load values into registers.*/
416                 /* mctDoWarmResetMemClr_D(); */
417                 MCTMemClr_D(pMCTstat, pDCTstatA);
418         }
419 }
420
421 static void LoadDQSSigTmgRegs_D(struct MCTStatStruc *pMCTstat,
422                                         struct DCTStatStruc *pDCTstatA)
423 {
424         u8 Node, Receiver, Channel, Dir, DIMM;
425         u32 dev;
426         u32 index_reg;
427         u32 reg;
428         u32 index;
429         u32 val;
430         u8 ByteLane;
431         u8 txdqs;
432
433         for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
434                 struct DCTStatStruc *pDCTstat;
435                 pDCTstat = pDCTstatA + Node;
436
437                 if (pDCTstat->DCTSysLimit) {
438                         dev = pDCTstat->dev_dct;
439                         for (Channel = 0;Channel < 2; Channel++) {
440                                 /* there are four receiver pairs,
441                                    loosely associated with chipselects.*/
442                                 index_reg = 0x98 + Channel * 0x100;
443                                 for (Receiver = 0; Receiver < 8; Receiver += 2) {
444                                         /* Set Receiver Enable Values */
445                                         mct_SetRcvrEnDly_D(pDCTstat,
446                                                 0, /* RcvrEnDly */
447                                                 1, /* FinalValue, From stack */
448                                                 Channel,
449                                                 Receiver,
450                                                 dev, index_reg,
451                                                 (Receiver >> 1) * 3 + 0x10, /* Addl_Index */
452                                                 2); /* Pass Second Pass ? */
453                                         /* Restore Write levelization training data */
454                                         for (ByteLane = 0; ByteLane < 9; ByteLane ++) {
455                                                 txdqs = pDCTstat->CH_D_B_TxDqs[Channel][Receiver >> 1][ByteLane];
456                                                 index = Table_DQSRcvEn_Offset[ByteLane >> 1];
457                                                 index += (Receiver >> 1) * 3 + 0x10 + 0x20; /* Addl_Index */
458                                                 val = Get_NB32_index_wait(dev, 0x98 + 0x100*Channel, index);
459                                                 if (ByteLane & 1) { /* odd byte lane */
460                                                         val &= ~(0xFF << 16);
461                                                         val |= txdqs << 16;
462                                                 } else {
463                                                         val &= ~0xFF;
464                                                         val |= txdqs;
465                                                 }
466                                                 Set_NB32_index_wait(dev, 0x98 + 0x100*Channel, index, val);
467                                         }
468                                 }
469                         }
470                         for (Channel = 0; Channel<2; Channel++) {
471                                 SetEccDQSRcvrEn_D(pDCTstat, Channel);
472                         }
473
474                         for (Channel = 0; Channel < 2; Channel++) {
475                                 u8 *p;
476                                 index_reg = 0x98 + Channel * 0x100;
477
478                                 /* NOTE:
479                                  * when 400, 533, 667, it will support dimm0/1/2/3,
480                                  * and set conf for dimm0, hw will copy to dimm1/2/3
481                                  * set for dimm1, hw will copy to dimm3
482                                  * Rev A/B only support DIMM0/1 when 800Mhz and above
483                                  *   + 0x100 to next dimm
484                                  * Rev C support DIMM0/1/2/3 when 800Mhz and above
485                                  *   + 0x100 to next dimm
486                                 */
487                                 for (DIMM = 0; DIMM < 4; DIMM++) {
488                                         if (DIMM == 0) {
489                                                 index = 0;      /* CHA Write Data Timing Low */
490                                         } else {
491                                                 if (pDCTstat->Speed >= 4) {
492                                                         index = 0x100 * DIMM;
493                                                 } else {
494                                                         break;
495                                                 }
496                                         }
497                                         for (Dir = 0; Dir < 2; Dir++) {/* RD/WR */
498                                                 p = pDCTstat->CH_D_DIR_B_DQS[Channel][DIMM][Dir];
499                                                 val = stream_to_int(p); /* CHA Read Data Timing High */
500                                                 Set_NB32_index_wait(dev, index_reg, index+1, val);
501                                                 val = stream_to_int(p+4); /* CHA Write Data Timing High */
502                                                 Set_NB32_index_wait(dev, index_reg, index+2, val);
503                                                 val = *(p+8); /* CHA Write ECC Timing */
504                                                 Set_NB32_index_wait(dev, index_reg, index+3, val);
505                                                 index += 4;
506                                         }
507                                 }
508                         }
509
510                         for (Channel = 0; Channel<2; Channel++) {
511                                 reg = 0x78 + Channel * 0x100;
512                                 val = Get_NB32(dev, reg);
513                                 val &= ~(0x3ff<<22);
514                                 val |= ((u32) pDCTstat->CH_MaxRdLat[Channel] << 22);
515                                 val &= ~(1<<DqsRcvEnTrain);
516                                 Set_NB32(dev, reg, val);        /* program MaxRdLatency to correspond with current delay*/
517                         }
518                 }
519         }
520 }
521
522 static void HTMemMapInit_D(struct MCTStatStruc *pMCTstat,
523                                 struct DCTStatStruc *pDCTstatA)
524 {
525         u8 Node;
526         u32 NextBase, BottomIO;
527         u8 _MemHoleRemap, DramHoleBase, DramHoleOffset;
528         u32 HoleSize, DramSelBaseAddr;
529
530         u32 val;
531         u32 base;
532         u32 limit;
533         u32 dev, devx;
534         struct DCTStatStruc *pDCTstat;
535
536         _MemHoleRemap = mctGet_NVbits(NV_MemHole);
537
538         if (pMCTstat->HoleBase == 0) {
539                 DramHoleBase = mctGet_NVbits(NV_BottomIO);
540         } else {
541                 DramHoleBase = pMCTstat->HoleBase >> (24-8);
542         }
543
544         BottomIO = DramHoleBase << (24-8);
545
546         NextBase = 0;
547         pDCTstat = pDCTstatA + 0;
548         dev = pDCTstat->dev_map;
549
550         for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
551                 pDCTstat = pDCTstatA + Node;
552                 devx = pDCTstat->dev_map;
553                 DramSelBaseAddr = 0;
554                 pDCTstat = pDCTstatA + Node; /* ??? */
555                 if (!pDCTstat->GangedMode) {
556                         DramSelBaseAddr = pDCTstat->NodeSysLimit - pDCTstat->DCTSysLimit;
557                         /*In unganged mode, we must add DCT0 and DCT1 to DCTSysLimit */
558                         val = pDCTstat->NodeSysLimit;
559                         if ((val & 0xFF) == 0xFE) {
560                                 DramSelBaseAddr++;
561                                 val++;
562                         }
563                         pDCTstat->DCTSysLimit = val;
564                 }
565
566                 base  = pDCTstat->DCTSysBase;
567                 limit = pDCTstat->DCTSysLimit;
568                 if (limit > base) {
569                         base  += NextBase;
570                         limit += NextBase;
571                         DramSelBaseAddr += NextBase;
572                         printk(BIOS_DEBUG, " Node: %02x  base: %02x  limit: %02x  BottomIO: %02x\n", Node, base, limit, BottomIO);
573
574                         if (_MemHoleRemap) {
575                                 if ((base < BottomIO) && (limit >= BottomIO)) {
576                                         /* HW Dram Remap */
577                                         pDCTstat->Status |= 1 << SB_HWHole;
578                                         pMCTstat->GStatus |= 1 << GSB_HWHole;
579                                         pDCTstat->DCTSysBase = base;
580                                         pDCTstat->DCTSysLimit = limit;
581                                         pDCTstat->DCTHoleBase = BottomIO;
582                                         pMCTstat->HoleBase = BottomIO;
583                                         HoleSize = _4GB_RJ8 - BottomIO; /* HoleSize[39:8] */
584                                         if ((DramSelBaseAddr > 0) && (DramSelBaseAddr < BottomIO))
585                                                 base = DramSelBaseAddr;
586                                         val = ((base + HoleSize) >> (24-8)) & 0xFF;
587                                         DramHoleOffset = val;
588                                         val <<= 8; /* shl 16, rol 24 */
589                                         val |= DramHoleBase << 24;
590                                         val |= 1  << DramHoleValid;
591                                         Set_NB32(devx, 0xF0, val); /* Dram Hole Address Reg */
592                                         pDCTstat->DCTSysLimit += HoleSize;
593                                         base = pDCTstat->DCTSysBase;
594                                         limit = pDCTstat->DCTSysLimit;
595                                 } else if (base == BottomIO) {
596                                         /* SW Node Hoist */
597                                         pMCTstat->GStatus |= 1<<GSB_SpIntRemapHole;
598                                         pDCTstat->Status |= 1<<SB_SWNodeHole;
599                                         pMCTstat->GStatus |= 1<<GSB_SoftHole;
600                                         pMCTstat->HoleBase = base;
601                                         limit -= base;
602                                         base = _4GB_RJ8;
603                                         limit += base;
604                                         pDCTstat->DCTSysBase = base;
605                                         pDCTstat->DCTSysLimit = limit;
606                                 } else {
607                                         /* No Remapping.  Normal Contiguous mapping */
608                                         pDCTstat->DCTSysBase = base;
609                                         pDCTstat->DCTSysLimit = limit;
610                                 }
611                         } else {
612                                 /*No Remapping.  Normal Contiguous mapping*/
613                                 pDCTstat->DCTSysBase = base;
614                                 pDCTstat->DCTSysLimit = limit;
615                         }
616                         base |= 3;              /* set WE,RE fields*/
617                         pMCTstat->SysLimit = limit;
618                 }
619                 Set_NB32(dev, 0x40 + (Node << 3), base); /* [Node] + Dram Base 0 */
620
621                 val = limit & 0xFFFF0000;
622                 val |= Node;
623                 Set_NB32(dev, 0x44 + (Node << 3), val); /* set DstNode */
624
625                 printk(BIOS_DEBUG, " Node: %02x  base: %02x  limit: %02x \n", Node, base, limit);
626                 limit = pDCTstat->DCTSysLimit;
627                 if (limit) {
628                         NextBase = (limit & 0xFFFF0000) + 0x10000;
629                 }
630         }
631
632         /* Copy dram map from Node 0 to Node 1-7 */
633         for (Node = 1; Node < MAX_NODES_SUPPORTED; Node++) {
634                 u32 reg;
635                 pDCTstat = pDCTstatA + Node;
636                 devx = pDCTstat->dev_map;
637
638                 if (pDCTstat->NodePresent) {
639                         reg = 0x40;             /*Dram Base 0*/
640                         do {
641                                 val = Get_NB32(dev, reg);
642                                 Set_NB32(devx, reg, val);
643                                 reg += 4;
644                         } while ( reg < 0x80);
645                 } else {
646                         break;                  /* stop at first absent Node */
647                 }
648         }
649
650         /*Copy dram map to F1x120/124*/
651         mct_HTMemMapExt(pMCTstat, pDCTstatA);
652 }
653
654 static void MCTMemClr_D(struct MCTStatStruc *pMCTstat,
655                                 struct DCTStatStruc *pDCTstatA)
656 {
657
658         /* Initiates a memory clear operation for all node. The mem clr
659          * is done in paralel. After the memclr is complete, all processors
660          * status are checked to ensure that memclr has completed.
661          */
662         u8 Node;
663         struct DCTStatStruc *pDCTstat;
664
665         if (!mctGet_NVbits(NV_DQSTrainCTL)){
666                 /* FIXME: callback to wrapper: mctDoWarmResetMemClr_D */
667         } else {        /* NV_DQSTrainCTL == 1 */
668                 for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
669                         pDCTstat = pDCTstatA + Node;
670
671                         if (pDCTstat->NodePresent) {
672                                 DCTMemClr_Init_D(pMCTstat, pDCTstat);
673                         }
674                 }
675                 for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
676                         pDCTstat = pDCTstatA + Node;
677
678                         if (pDCTstat->NodePresent) {
679                                 DCTMemClr_Sync_D(pMCTstat, pDCTstat);
680                         }
681                 }
682         }
683 }
684
685 static void DCTMemClr_Init_D(struct MCTStatStruc *pMCTstat,
686                                 struct DCTStatStruc *pDCTstat)
687 {
688         u32 val;
689         u32 dev;
690         u32 reg;
691
692         /* Initiates a memory clear operation on one node */
693         if (pDCTstat->DCTSysLimit) {
694                 dev = pDCTstat->dev_dct;
695                 reg = 0x110;
696
697                 do {
698                         val = Get_NB32(dev, reg);
699                 } while (val & (1 << MemClrBusy));
700
701                 val |= (1 << MemClrInit);
702                 Set_NB32(dev, reg, val);
703         }
704 }
705
706 static void MCTMemClrSync_D(struct MCTStatStruc *pMCTstat,
707                                 struct DCTStatStruc *pDCTstatA)
708 {
709         /* Ensures that memory clear has completed on all node.*/
710         u8 Node;
711         struct DCTStatStruc *pDCTstat;
712
713         if (!mctGet_NVbits(NV_DQSTrainCTL)){
714                 /* callback to wrapper: mctDoWarmResetMemClr_D */
715         } else {        /* NV_DQSTrainCTL == 1 */
716                 for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
717                         pDCTstat = pDCTstatA + Node;
718
719                         if (pDCTstat->NodePresent) {
720                                 DCTMemClr_Sync_D(pMCTstat, pDCTstat);
721                         }
722                 }
723         }
724 }
725
726 static void DCTMemClr_Sync_D(struct MCTStatStruc *pMCTstat,
727                                 struct DCTStatStruc *pDCTstat)
728 {
729         u32 val;
730         u32 dev = pDCTstat->dev_dct;
731         u32 reg;
732
733         /* Ensure that a memory clear operation has completed on one node */
734         if (pDCTstat->DCTSysLimit){
735                 reg = 0x110;
736
737                 do {
738                         val = Get_NB32(dev, reg);
739                 } while (val & (1 << MemClrBusy));
740
741                 do {
742                         val = Get_NB32(dev, reg);
743                 } while (!(val & (1 << Dr_MemClrStatus)));
744         }
745
746         val = 0x0FE40FC0;               /* BKDG recommended */
747         val |= MCCH_FlushWrOnStpGnt;    /* Set for S3 */
748         Set_NB32(dev, 0x11C, val);
749 }
750
751 static u8 NodePresent_D(u8 Node)
752 {
753         /*
754          * Determine if a single Hammer Node exists within the network.
755          */
756         u32 dev;
757         u32 val;
758         u32 dword;
759         u8 ret = 0;
760
761         dev = PA_HOST(Node);            /*test device/vendor id at host bridge  */
762         val = Get_NB32(dev, 0);
763         dword = mct_NodePresent_D();    /* FIXME: BOZO -11001022h rev for F */
764         if (val == dword) {             /* AMD Hammer Family CPU HT Configuration */
765                 if (oemNodePresent_D(Node, &ret))
766                         goto finish;
767                 /* Node ID register */
768                 val = Get_NB32(dev, 0x60);
769                 val &= 0x07;
770                 dword = Node;
771                 if (val  == dword)      /* current nodeID = requested nodeID ? */
772                         ret = 1;
773         }
774 finish:
775         return ret;
776 }
777
778 static void DCTInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct)
779 {
780         /*
781          * Initialize DRAM on single Athlon 64/Opteron Node.
782          */
783         u8 stopDCTflag;
784         u32 val;
785
786         ClearDCT_D(pMCTstat, pDCTstat, dct);
787         stopDCTflag = 1;                /*preload flag with 'disable' */
788         /* enable DDR3 support */
789         val = Get_NB32(pDCTstat->dev_dct, 0x94 + dct * 0x100);
790         val |= 1 << Ddr3Mode;
791         Set_NB32(pDCTstat->dev_dct, 0x94 + dct * 0x100, val);
792         if (mct_DIMMPresence(pMCTstat, pDCTstat, dct) < SC_StopError) {
793                 printk(BIOS_DEBUG, "\t\tDCTInit_D: mct_DIMMPresence Done\n");
794                 if (mct_SPDCalcWidth(pMCTstat, pDCTstat, dct) < SC_StopError) {
795                         printk(BIOS_DEBUG, "\t\tDCTInit_D: mct_SPDCalcWidth Done\n");
796                         if (AutoCycTiming_D(pMCTstat, pDCTstat, dct) < SC_StopError) {
797                                 printk(BIOS_DEBUG, "\t\tDCTInit_D: AutoCycTiming_D Done\n");
798                                 if (AutoConfig_D(pMCTstat, pDCTstat, dct) < SC_StopError) {
799                                         printk(BIOS_DEBUG, "\t\tDCTInit_D: AutoConfig_D Done\n");
800                                         if (PlatformSpec_D(pMCTstat, pDCTstat, dct) < SC_StopError) {
801                                                 printk(BIOS_DEBUG, "\t\tDCTInit_D: PlatformSpec_D Done\n");
802                                                 stopDCTflag = 0;
803                                                 if (!(pMCTstat->GStatus & (1 << GSB_EnDIMMSpareNW))) {
804                                                         printk(BIOS_DEBUG, "\t\tDCTInit_D: StartupDCT_D\n");
805                                                         StartupDCT_D(pMCTstat, pDCTstat, dct);   /*yeaahhh! */
806                                                 }
807                                         }
808                                 }
809                         }
810                 }
811         }
812
813         if (stopDCTflag) {
814                 u32 reg_off = dct * 0x100;
815                 val = 1<<DisDramInterface;
816                 Set_NB32(pDCTstat->dev_dct, reg_off+0x94, val);
817                 /*To maximize power savings when DisDramInterface=1b,
818                   all of the MemClkDis bits should also be set.*/
819                 val = 0xFF000000;
820                 Set_NB32(pDCTstat->dev_dct, reg_off+0x88, val);
821         } else {
822                 /* mct_EnDllShutdownSR */
823         }
824 }
825
826 static void SyncDCTsReady_D(struct MCTStatStruc *pMCTstat,
827                                 struct DCTStatStruc *pDCTstatA)
828 {
829         /* Wait (and block further access to dram) for all DCTs to be ready,
830          * by polling all InitDram bits and waiting for possible memory clear
831          * operations to be complete.  Read MemClkFreqVal bit to see if
832          * the DIMMs are present in this node.
833          */
834         u8 Node;
835         u32 val;
836
837         for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
838                 struct DCTStatStruc *pDCTstat;
839                 pDCTstat = pDCTstatA + Node;
840                 mct_SyncDCTsReady(pDCTstat);
841         }
842         /* v6.1.3 */
843         /* re-enable phy compensation engine when dram init is completed on all nodes. */
844         for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
845                 struct DCTStatStruc *pDCTstat;
846                 pDCTstat = pDCTstatA + Node;
847                 if (pDCTstat->NodePresent) {
848                         if (pDCTstat->DIMMValidDCT[0] > 0 || pDCTstat->DIMMValidDCT[1] > 0) {
849                                 /* re-enable phy compensation engine when dram init on both DCTs is completed. */
850                                 val = Get_NB32_index_wait(pDCTstat->dev_dct, 0x98, 0x8);
851                                 val &= ~(1 << DisAutoComp);
852                                 Set_NB32_index_wait(pDCTstat->dev_dct, 0x98, 0x8, val);
853                         }
854                 }
855         }
856         /* wait 750us before any memory access can be made. */
857         mct_Wait(15000);
858 }
859
860 static void StartupDCT_D(struct MCTStatStruc *pMCTstat,
861                                 struct DCTStatStruc *pDCTstat, u8 dct)
862 {
863         /* Read MemClkFreqVal bit to see if the DIMMs are present in this node.
864          * If the DIMMs are present then set the DRAM Enable bit for this node.
865          *
866          * Setting dram init starts up the DCT state machine, initializes the
867          * dram devices with MRS commands, and kicks off any
868          * HW memory clear process that the chip is capable of. The sooner
869          * that dram init is set for all nodes, the faster the memory system
870          * initialization can complete. Thus, the init loop is unrolled into
871          * two loops so as to start the processeses for non BSP nodes sooner.
872          * This procedure will not wait for the process to finish.
873          * Synchronization is handled elsewhere.
874          */
875         u32 val;
876         u32 dev;
877         u32 reg_off = dct * 0x100;
878
879         dev = pDCTstat->dev_dct;
880         val = Get_NB32(dev, 0x94 + reg_off);
881         if (val & (1<<MemClkFreqVal)) {
882                 mctHookBeforeDramInit();        /* generalized Hook */
883                 if (!(pMCTstat->GStatus & (1 << GSB_EnDIMMSpareNW)))
884                     mct_DramInit(pMCTstat, pDCTstat, dct);
885                 AfterDramInit_D(pDCTstat, dct);
886                 mctHookAfterDramInit();         /* generalized Hook*/
887         }
888 }
889
890 static void ClearDCT_D(struct MCTStatStruc *pMCTstat,
891                         struct DCTStatStruc *pDCTstat, u8 dct)
892 {
893         u32 reg_end;
894         u32 dev = pDCTstat->dev_dct;
895         u32 reg = 0x40 + 0x100 * dct;
896         u32 val = 0;
897
898         if (pMCTstat->GStatus & (1 << GSB_EnDIMMSpareNW)) {
899                 reg_end = 0x78 + 0x100 * dct;
900         } else {
901                 reg_end = 0xA4 + 0x100 * dct;
902         }
903
904         while(reg < reg_end) {
905                 Set_NB32(dev, reg, val);
906                 reg += 4;
907         }
908
909         val = 0;
910         dev = pDCTstat->dev_map;
911         reg = 0xF0;
912         Set_NB32(dev, reg, val);
913 }
914
915 static void SPD2ndTiming(struct MCTStatStruc *pMCTstat,
916                         struct DCTStatStruc *pDCTstat, u8 dct)
917 {
918         u8 i;
919         u16 Twr, Trtp;
920         u16 Trp, Trrd, Trcd, Tras, Trc;
921         u8 Trfc[4];
922         u16 Tfaw;
923         u32 DramTimingLo, DramTimingHi;
924         u8 tCK16x;
925         u16 Twtr;
926         u8 LDIMM;
927         u8 MTB16x;
928         u8 byte;
929         u32 dword;
930         u32 dev;
931         u32 reg_off;
932         u32 val;
933         u16 smbaddr;
934
935         /* Gather all DIMM mini-max values for cycle timing data */
936         Trp = 0;
937         Trrd = 0;
938         Trcd = 0;
939         Trtp = 0;
940         Tras = 0;
941         Trc = 0;
942         Twr = 0;
943         Twtr = 0;
944         for (i=0; i < 4; i++)
945                 Trfc[i] = 0;
946         Tfaw = 0;
947
948         for ( i = 0; i< MAX_DIMMS_SUPPORTED; i++) {
949                 LDIMM = i >> 1;
950                 if (pDCTstat->DIMMValid & (1 << i)) {
951                         smbaddr = Get_DIMMAddress_D(pDCTstat, (dct + i));
952
953                         val = mctRead_SPD(smbaddr, SPD_MTBDivisor); /* MTB=Dividend/Divisor */
954                         MTB16x = ((mctRead_SPD(smbaddr, SPD_MTBDividend) & 0xFF)<<4);
955                         MTB16x /= val; /* transfer to MTB*16 */
956
957                         byte = mctRead_SPD(smbaddr, SPD_tRPmin);
958                         val = byte * MTB16x;
959                         if (Trp < val)
960                                 Trp = val;
961
962                         byte = mctRead_SPD(smbaddr, SPD_tRRDmin);
963                         val = byte * MTB16x;
964                         if (Trrd < val)
965                                 Trrd = val;
966
967                         byte = mctRead_SPD(smbaddr, SPD_tRCDmin);
968                         val = byte * MTB16x;
969                         if (Trcd < val)
970                                 Trcd = val;
971
972                         byte = mctRead_SPD(smbaddr, SPD_tRTPmin);
973                         val = byte * MTB16x;
974                         if (Trtp < val)
975                                 Trtp = val;
976
977                         byte = mctRead_SPD(smbaddr, SPD_tWRmin);
978                         val = byte * MTB16x;
979                         if (Twr < val)
980                                 Twr = val;
981
982                         byte = mctRead_SPD(smbaddr, SPD_tWTRmin);
983                         val = byte * MTB16x;
984                         if (Twtr < val)
985                                 Twtr = val;
986
987                         val = mctRead_SPD(smbaddr, SPD_Upper_tRAS_tRC) & 0xFF;
988                         val >>= 4;
989                         val <<= 8;
990                         val |= mctRead_SPD(smbaddr, SPD_tRCmin) & 0xFF;
991                         val *= MTB16x;
992                         if (Trc < val)
993                                 Trc = val;
994
995                         byte = mctRead_SPD(smbaddr, SPD_Density) & 0xF;
996                         if (Trfc[LDIMM] < byte)
997                                 Trfc[LDIMM] = byte;
998
999                         val = mctRead_SPD(smbaddr, SPD_Upper_tRAS_tRC) & 0xF;
1000                         val <<= 8;
1001                         val |= (mctRead_SPD(smbaddr, SPD_tRASmin) & 0xFF);
1002                         val *= MTB16x;
1003                         if (Tras < val)
1004                                 Tras = val;
1005
1006                         val = mctRead_SPD(smbaddr, SPD_Upper_tFAW) & 0xF;
1007                         val <<= 8;
1008                         val |= mctRead_SPD(smbaddr, SPD_tFAWmin) & 0xFF;
1009                         val *= MTB16x;
1010                         if (Tfaw < val)
1011                                 Tfaw = val;
1012                 }       /* Dimm Present */
1013         }
1014
1015         /* Convert  DRAM CycleTiming values and store into DCT structure */
1016         byte = pDCTstat->DIMMAutoSpeed;
1017         if (byte == 7)
1018                 tCK16x = 20;
1019         else if (byte == 6)
1020                 tCK16x = 24;
1021         else if (byte == 5)
1022                 tCK16x = 30;
1023         else
1024                 tCK16x = 40;
1025
1026         /* Notes:
1027          1. All secondary time values given in SPDs are in binary with units of ns.
1028          2. Some time values are scaled by 16, in order to have least count of 0.25 ns
1029             (more accuracy).  JEDEC SPD spec. shows which ones are x1 and x4.
1030          3. Internally to this SW, cycle time, tCK16x, is scaled by 16 to match time values
1031         */
1032
1033         /* Tras */
1034         pDCTstat->DIMMTras = (u16)Tras;
1035         val = Tras / tCK16x;
1036         if (Tras % tCK16x) {    /* round up number of busclocks */
1037                 val++;
1038         }
1039         if (val < Min_TrasT)
1040                 val = Min_TrasT;
1041         else if (val > Max_TrasT)
1042                 val = Max_TrasT;
1043         pDCTstat->Tras = val;
1044
1045         /* Trp */
1046         pDCTstat->DIMMTrp = Trp;
1047         val = Trp / tCK16x;
1048         if (Trp % tCK16x) {     /* round up number of busclocks */
1049                 val++;
1050         }
1051         if (val < Min_TrpT)
1052                 val = Min_TrpT;
1053         else if (val > Max_TrpT)
1054                 val = Max_TrpT;
1055         pDCTstat->Trp = val;
1056
1057         /*Trrd*/
1058         pDCTstat->DIMMTrrd = Trrd;
1059         val = Trrd / tCK16x;
1060         if (Trrd % tCK16x) {    /* round up number of busclocks */
1061                 val++;
1062         }
1063         if (val < Min_TrrdT)
1064                 val = Min_TrrdT;
1065         else if (val > Max_TrrdT)
1066                 val = Max_TrrdT;
1067         pDCTstat->Trrd = val;
1068
1069         /* Trcd */
1070         pDCTstat->DIMMTrcd = Trcd;
1071         val = Trcd / tCK16x;
1072         if (Trcd % tCK16x) {    /* round up number of busclocks */
1073                 val++;
1074         }
1075         if (val < Min_TrcdT)
1076                 val = Min_TrcdT;
1077         else if (val > Max_TrcdT)
1078                 val = Max_TrcdT;
1079         pDCTstat->Trcd = val;
1080
1081         /* Trc */
1082         pDCTstat->DIMMTrc = Trc;
1083         val = Trc / tCK16x;
1084         if (Trc % tCK16x) {     /* round up number of busclocks */
1085                 val++;
1086         }
1087         if (val < Min_TrcT)
1088                 val = Min_TrcT;
1089         else if (val > Max_TrcT)
1090                 val = Max_TrcT;
1091         pDCTstat->Trc = val;
1092
1093         /* Trtp */
1094         pDCTstat->DIMMTrtp = Trtp;
1095         val = Trtp / tCK16x;
1096         if (Trtp % tCK16x) {
1097                 val ++;
1098         }
1099         if (val < Min_TrtpT)
1100                 val = Min_TrtpT;
1101         else if (val > Max_TrtpT)
1102                 val = Max_TrtpT;
1103         pDCTstat->Trtp = val;
1104
1105         /* Twr */
1106         pDCTstat->DIMMTwr = Twr;
1107         val = Twr / tCK16x;
1108         if (Twr % tCK16x) {     /* round up number of busclocks */
1109                 val++;
1110         }
1111         if (val < Min_TwrT)
1112                 val = Min_TwrT;
1113         else if (val > Max_TwrT)
1114                 val = Max_TwrT;
1115         pDCTstat->Twr = val;
1116
1117         /* Twtr */
1118         pDCTstat->DIMMTwtr = Twtr;
1119         val = Twtr / tCK16x;
1120         if (Twtr % tCK16x) {    /* round up number of busclocks */
1121                 val++;
1122         }
1123         if (val < Min_TwtrT)
1124                 val = Min_TwtrT;
1125         else if (val > Max_TwtrT)
1126                 val = Max_TwtrT;
1127         pDCTstat->Twtr = val;
1128
1129         /* Trfc0-Trfc3 */
1130         for (i=0; i<4; i++)
1131                 pDCTstat->Trfc[i] = Trfc[i];
1132
1133         /* Tfaw */
1134         pDCTstat->DIMMTfaw = Tfaw;
1135         val = Tfaw / tCK16x;
1136         if (Tfaw % tCK16x) {    /* round up number of busclocks */
1137                 val++;
1138         }
1139         if (val < Min_TfawT)
1140                 val = Min_TfawT;
1141         else if (val > Max_TfawT)
1142                 val = Max_TfawT;
1143         pDCTstat->Tfaw = val;
1144
1145         mctAdjustAutoCycTmg_D();
1146
1147         /* Program DRAM Timing values */
1148         DramTimingLo = 0;       /* Dram Timing Low init */
1149         val = pDCTstat->CASL - 2; /* pDCTstat.CASL to reg. definition */
1150         DramTimingLo |= val;
1151
1152         val = pDCTstat->Trcd - Bias_TrcdT;
1153         DramTimingLo |= val<<4;
1154
1155         val = pDCTstat->Trp - Bias_TrpT;
1156         val = mct_AdjustSPDTimings(pMCTstat, pDCTstat, val);
1157         DramTimingLo |= val<<7;
1158
1159         val = pDCTstat->Trtp - Bias_TrtpT;
1160         DramTimingLo |= val<<10;
1161
1162         val = pDCTstat->Tras - Bias_TrasT;
1163         DramTimingLo |= val<<12;
1164
1165         val = pDCTstat->Trc - Bias_TrcT;
1166         DramTimingLo |= val<<16;
1167
1168         val = pDCTstat->Trrd - Bias_TrrdT;
1169         DramTimingLo |= val<<22;
1170
1171         DramTimingHi = 0;       /* Dram Timing High init */
1172         val = pDCTstat->Twtr - Bias_TwtrT;
1173         DramTimingHi |= val<<8;
1174
1175         val = 2;
1176         DramTimingHi |= val<<16;
1177
1178         val = 0;
1179         for (i=4;i>0;i--) {
1180                 val <<= 3;
1181                 val |= Trfc[i-1];
1182         }
1183         DramTimingHi |= val << 20;
1184
1185         dev = pDCTstat->dev_dct;
1186         reg_off = 0x100 * dct;
1187         /* Twr */
1188         val = pDCTstat->Twr;
1189         if (val == 10)
1190                 val = 9;
1191         else if (val == 12)
1192                 val = 10;
1193         val = mct_AdjustSPDTimings(pMCTstat, pDCTstat, val);
1194         val -= Bias_TwrT;
1195         val <<= 4;
1196         dword = Get_NB32(dev, 0x84 + reg_off);
1197         dword &= ~0x70;
1198         dword |= val;
1199         Set_NB32(dev, 0x84 + reg_off, dword);
1200
1201         /* Tfaw */
1202         val = pDCTstat->Tfaw;
1203         val = mct_AdjustSPDTimings(pMCTstat, pDCTstat, val);
1204         val -= Bias_TfawT;
1205         val >>= 1;
1206         val <<= 28;
1207         dword = Get_NB32(dev, 0x94 + reg_off);
1208         dword &= ~0xf0000000;
1209         dword |= val;
1210         Set_NB32(dev, 0x94 + reg_off, dword);
1211
1212         /* dev = pDCTstat->dev_dct; */
1213         /* reg_off = 0x100 * dct; */
1214
1215         if (pDCTstat->Speed > 4) {
1216                 val = Get_NB32(dev, 0x88 + reg_off);
1217                 val &= 0xFF000000;
1218                 DramTimingLo |= val;
1219         }
1220         Set_NB32(dev, 0x88 + reg_off, DramTimingLo);    /*DCT Timing Low*/
1221
1222         if (pDCTstat->Speed > 4) {
1223                 DramTimingLo |= 1 << DisAutoRefresh;
1224         }
1225         DramTimingHi |= 0x000018FF;
1226         Set_NB32(dev, 0x8c + reg_off, DramTimingHi);    /*DCT Timing Hi*/
1227
1228         /* dump_pci_device(PCI_DEV(0, 0x18+pDCTstat->Node_ID, 2)); */
1229 }
1230
1231 static u8 AutoCycTiming_D(struct MCTStatStruc *pMCTstat,
1232                                 struct DCTStatStruc *pDCTstat, u8 dct)
1233 {
1234         /* Initialize  DCT Timing registers as per DIMM SPD.
1235          * For primary timing (T, CL) use best case T value.
1236          * For secondary timing params., use most aggressive settings
1237          * of slowest DIMM.
1238          *
1239          * There are three components to determining "maximum frequency":
1240          * SPD component, Bus load component, and "Preset" max frequency
1241          * component.
1242          *
1243          * The SPD component is a function of the min cycle time specified
1244          * by each DIMM, and the interaction of cycle times from all DIMMs
1245          * in conjunction with CAS latency. The SPD component only applies
1246          * when user timing mode is 'Auto'.
1247          *
1248          * The Bus load component is a limiting factor determined by electrical
1249          * characteristics on the bus as a result of varying number of device
1250          * loads. The Bus load component is specific to each platform but may
1251          * also be a function of other factors. The bus load component only
1252          * applies when user timing mode is 'Auto'.
1253          *
1254          * The Preset component is subdivided into three items and is
1255          * the minimum of the set: Silicon revision, user limit
1256          * setting when user timing mode is 'Auto' and memclock mode
1257          * is 'Limit', OEM build specification of the maximum
1258          * frequency. The Preset component is only applies when user
1259          * timing mode is 'Auto'.
1260          */
1261
1262         /* Get primary timing (CAS Latency and Cycle Time) */
1263         if (pDCTstat->Speed == 0) {
1264                 mctGet_MaxLoadFreq(pDCTstat);
1265
1266                 /* and Factor in presets (setup options, Si cap, etc.) */
1267                 GetPresetmaxF_D(pMCTstat, pDCTstat);
1268
1269                 /* Go get best T and CL as specified by DIMM mfgs. and OEM */
1270                 SPDGetTCL_D(pMCTstat, pDCTstat, dct);
1271                 /* skip callback mctForce800to1067_D */
1272                 pDCTstat->Speed = pDCTstat->DIMMAutoSpeed;
1273                 pDCTstat->CASL = pDCTstat->DIMMCASL;
1274
1275         }
1276         mct_AfterGetCLT(pMCTstat, pDCTstat, dct);
1277
1278         SPD2ndTiming(pMCTstat, pDCTstat, dct);
1279
1280         printk(BIOS_DEBUG, "AutoCycTiming: Status %x\n", pDCTstat->Status);
1281         printk(BIOS_DEBUG, "AutoCycTiming: ErrStatus %x\n", pDCTstat->ErrStatus);
1282         printk(BIOS_DEBUG, "AutoCycTiming: ErrCode %x\n", pDCTstat->ErrCode);
1283         printk(BIOS_DEBUG, "AutoCycTiming: Done\n\n");
1284
1285         mctHookAfterAutoCycTmg();
1286
1287         return pDCTstat->ErrCode;
1288 }
1289
1290 static void GetPresetmaxF_D(struct MCTStatStruc *pMCTstat,
1291                                 struct DCTStatStruc *pDCTstat)
1292 {
1293         /* Get max frequency from OEM platform definition, from any user
1294          * override (limiting) of max frequency, and from any Si Revision
1295          * Specific information.  Return the least of these three in
1296          * DCTStatStruc.PresetmaxFreq.
1297          */
1298         u16 proposedFreq;
1299         u16 word;
1300
1301         /* Get CPU Si Revision defined limit (NPT) */
1302         proposedFreq = 533;      /* Rev F0 programmable max memclock is */
1303
1304         /*Get User defined limit if  "limit" mode */
1305         if ( mctGet_NVbits(NV_MCTUSRTMGMODE) == 1) {
1306                 word = Get_Fk_D(mctGet_NVbits(NV_MemCkVal) + 1);
1307                 if (word < proposedFreq)
1308                         proposedFreq = word;
1309
1310                 /* Get Platform defined limit */
1311                 word = mctGet_NVbits(NV_MAX_MEMCLK);
1312                 if (word < proposedFreq)
1313                         proposedFreq = word;
1314
1315                 word = pDCTstat->PresetmaxFreq;
1316                 if (word > proposedFreq)
1317                         word = proposedFreq;
1318
1319                 pDCTstat->PresetmaxFreq = word;
1320         }
1321         /* Check F3xE8[DdrMaxRate] for maximum DRAM data rate support */
1322 }
1323
1324 static void SPDGetTCL_D(struct MCTStatStruc *pMCTstat,
1325                                 struct DCTStatStruc *pDCTstat, u8 dct)
1326 {
1327         /* Find the best T and CL primary timing parameter pair, per Mfg.,
1328          * for the given set of DIMMs, and store into DCTStatStruc
1329          * (.DIMMAutoSpeed and .DIMMCASL). See "Global relationship between
1330          *  index values and item values" for definition of CAS latency
1331          *  index (j) and Frequency index (k).
1332          */
1333         u8 i, CASLatLow, CASLatHigh;
1334         u16 tAAmin16x;
1335         u8 MTB16x;
1336         u16 tCKmin16x;
1337         u16 tCKproposed16x;
1338         u8 CLactual, CLdesired, CLT_Fail;
1339
1340         u8 smbaddr, byte, bytex;
1341
1342         CASLatLow = 0xFF;
1343         CASLatHigh = 0xFF;
1344         tAAmin16x = 0;
1345         tCKmin16x = 0;
1346         CLT_Fail = 0;
1347
1348         for (i = 0; i < MAX_DIMMS_SUPPORTED; i++) {
1349                 if (pDCTstat->DIMMValid & (1 << i)) {
1350                         smbaddr = Get_DIMMAddress_D(pDCTstat, (dct + i));
1351                         /* Step 1: Determine the common set of supported CAS Latency
1352                          * values for all modules on the memory channel using the CAS
1353                          * Latencies Supported in SPD bytes 14 and 15.
1354                          */
1355                         byte = mctRead_SPD(smbaddr, SPD_CASLow);
1356                         CASLatLow &= byte;
1357                         byte = mctRead_SPD(smbaddr, SPD_CASHigh);
1358                         CASLatHigh &= byte;
1359                         /* Step 2: Determine tAAmin(all) which is the largest tAAmin
1360                            value for all modules on the memory channel (SPD byte 16). */
1361                         byte = mctRead_SPD(smbaddr, SPD_MTBDivisor);
1362
1363                         MTB16x = ((mctRead_SPD(smbaddr, SPD_MTBDividend) & 0xFF)<<4);
1364                         MTB16x /= byte; /* transfer to MTB*16 */
1365
1366                         byte = mctRead_SPD(smbaddr, SPD_tAAmin);
1367                         if (tAAmin16x < byte * MTB16x)
1368                                 tAAmin16x = byte * MTB16x;
1369                         /* Step 3: Determine tCKmin(all) which is the largest tCKmin
1370                            value for all modules on the memory channel (SPD byte 12). */
1371                         byte = mctRead_SPD(smbaddr, SPD_tCKmin);
1372
1373                         if (tCKmin16x < byte * MTB16x)
1374                                 tCKmin16x = byte * MTB16x;
1375                 }
1376         }
1377         /* calculate tCKproposed16x */
1378         tCKproposed16x =  16000 / pDCTstat->PresetmaxFreq;
1379         if (tCKmin16x > tCKproposed16x)
1380                 tCKproposed16x = tCKmin16x;
1381
1382         /* mctHookTwo1333DimmOverride(); */
1383         /* For UDIMM, if there are two DDR3-1333 on the same channel,
1384            downgrade DDR speed to 1066. */
1385
1386         /* TODO: get user manual tCK16x(Freq.) and overwrite current tCKproposed16x if manual. */
1387         if (tCKproposed16x == 20)
1388                 pDCTstat->TargetFreq = 7;
1389         else if (tCKproposed16x <= 24) {
1390                 pDCTstat->TargetFreq = 6;
1391                 tCKproposed16x = 24;
1392         }
1393         else if (tCKproposed16x <= 30) {
1394                 pDCTstat->TargetFreq = 5;
1395                 tCKproposed16x = 30;
1396         }
1397         else {
1398                 pDCTstat->TargetFreq = 4;
1399                 tCKproposed16x = 40;
1400         }
1401         /* Running through this loop twice:
1402            - First time find tCL at target frequency
1403            - Second tim find tCL at 400MHz */
1404
1405         for (;;) {
1406                 CLT_Fail = 0;
1407                 /* Step 4: For a proposed tCK value (tCKproposed) between tCKmin(all) and tCKmax,
1408                    determine the desired CAS Latency. If tCKproposed is not a standard JEDEC
1409                    value (2.5, 1.875, 1.5, or 1.25 ns) then tCKproposed must be adjusted to the
1410                    next lower standard tCK value for calculating CLdesired.
1411                    CLdesired = ceiling ( tAAmin(all) / tCKproposed )
1412                    where tAAmin is defined in Byte 16. The ceiling function requires that the
1413                    quotient be rounded up always. */
1414                 CLdesired = tAAmin16x / tCKproposed16x;
1415                 if (tAAmin16x % tCKproposed16x)
1416                         CLdesired ++;
1417                 /* Step 5: Chose an actual CAS Latency (CLactual) that is greather than or equal
1418                    to CLdesired and is supported by all modules on the memory channel as
1419                    determined in step 1. If no such value exists, choose a higher tCKproposed
1420                    value and repeat steps 4 and 5 until a solution is found. */
1421                 for (i = 0, CLactual = 4; i < 15; i++, CLactual++) {
1422                         if ((CASLatHigh << 8 | CASLatLow) & (1 << i)) {
1423                                 if (CLdesired <= CLactual)
1424                                         break;
1425                         }
1426                 }
1427                 if (i == 15)
1428                         CLT_Fail = 1;
1429                 /* Step 6: Once the calculation of CLactual is completed, the BIOS must also
1430                    verify that this CAS Latency value does not exceed tAAmax, which is 20 ns
1431                    for all DDR3 speed grades, by multiplying CLactual times tCKproposed. If
1432                    not, choose a lower CL value and repeat steps 5 and 6 until a solution is found. */
1433                 if (CLactual * tCKproposed16x > 320)
1434                         CLT_Fail = 1;
1435                 /* get CL and T */
1436                 if (!CLT_Fail) {
1437                         bytex = CLactual - 2;
1438                         if (tCKproposed16x == 20)
1439                                 byte = 7;
1440                         else if (tCKproposed16x == 24)
1441                                 byte = 6;
1442                         else if (tCKproposed16x == 30)
1443                                 byte = 5;
1444                         else
1445                                 byte = 4;
1446                 } else {
1447                         /* mctHookManualCLOverride */
1448                         /* TODO: */
1449                 }
1450
1451                 if (tCKproposed16x != 40) {
1452                         if (pMCTstat->GStatus & (1 << GSB_EnDIMMSpareNW)) {
1453                                 pDCTstat->DIMMAutoSpeed = byte;
1454                                 pDCTstat->DIMMCASL = bytex;
1455                                 break;
1456                         } else {
1457                                 pDCTstat->TargetCASL = bytex;
1458                                 tCKproposed16x = 40;
1459                         }
1460                 } else {
1461                         pDCTstat->DIMMAutoSpeed = byte;
1462                         pDCTstat->DIMMCASL = bytex;
1463                         break;
1464                 }
1465         }
1466
1467         printk(BIOS_DEBUG, "SPDGetTCL_D: DIMMCASL %x\n", pDCTstat->DIMMCASL);
1468         printk(BIOS_DEBUG, "SPDGetTCL_D: DIMMAutoSpeed %x\n", pDCTstat->DIMMAutoSpeed);
1469
1470         printk(BIOS_DEBUG, "SPDGetTCL_D: Status %x\n", pDCTstat->Status);
1471         printk(BIOS_DEBUG, "SPDGetTCL_D: ErrStatus %x\n", pDCTstat->ErrStatus);
1472         printk(BIOS_DEBUG, "SPDGetTCL_D: ErrCode %x\n", pDCTstat->ErrCode);
1473         printk(BIOS_DEBUG, "SPDGetTCL_D: Done\n\n");
1474 }
1475
1476 static u8 PlatformSpec_D(struct MCTStatStruc *pMCTstat,
1477                                 struct DCTStatStruc *pDCTstat, u8 dct)
1478 {
1479         u32 dev;
1480         u32 reg;
1481         u32 val;
1482
1483         mctGet_PS_Cfg_D(pMCTstat, pDCTstat, dct);
1484
1485         if (pDCTstat->GangedMode == 1) {
1486                 mctGet_PS_Cfg_D(pMCTstat, pDCTstat, 1);
1487         }
1488
1489         if ( pDCTstat->_2Tmode == 2) {
1490                 dev = pDCTstat->dev_dct;
1491                 reg = 0x94 + 0x100 * dct; /* Dram Configuration Hi */
1492                 val = Get_NB32(dev, reg);
1493                 val |= 1 << 20;                /* 2T CMD mode */
1494                 Set_NB32(dev, reg, val);
1495         }
1496
1497         mct_PlatformSpec(pMCTstat, pDCTstat, dct);
1498         if (pDCTstat->DIMMAutoSpeed == 4)
1499                 InitPhyCompensation(pMCTstat, pDCTstat, dct);
1500         mctHookAfterPSCfg();
1501
1502         return pDCTstat->ErrCode;
1503 }
1504
1505 static u8 AutoConfig_D(struct MCTStatStruc *pMCTstat,
1506                                 struct DCTStatStruc *pDCTstat, u8 dct)
1507 {
1508         u32 DramControl, DramTimingLo, Status;
1509         u32 DramConfigLo, DramConfigHi, DramConfigMisc, DramConfigMisc2;
1510         u32 val;
1511         u32 reg_off;
1512         u32 dev;
1513         u16 word;
1514         u32 dword;
1515         u8 byte;
1516
1517         DramConfigLo = 0;
1518         DramConfigHi = 0;
1519         DramConfigMisc = 0;
1520         DramConfigMisc2 = 0;
1521
1522         /* set bank addessing and Masks, plus CS pops */
1523         SPDSetBanks_D(pMCTstat, pDCTstat, dct);
1524         if (pDCTstat->ErrCode == SC_StopError)
1525                 goto AutoConfig_exit;
1526
1527         /* map chip-selects into local address space */
1528         StitchMemory_D(pMCTstat, pDCTstat, dct);
1529         InterleaveBanks_D(pMCTstat, pDCTstat, dct);
1530
1531         /* temp image of status (for convenience). RO usage! */
1532         Status = pDCTstat->Status;
1533
1534         dev = pDCTstat->dev_dct;
1535         reg_off = 0x100 * dct;
1536
1537
1538         /* Build Dram Control Register Value */
1539         DramConfigMisc2 = Get_NB32 (dev, 0xA8 + reg_off);       /* Dram Control*/
1540         DramControl = Get_NB32 (dev, 0x78 + reg_off);           /* Dram Control*/
1541
1542         /* FIXME: Skip mct_checkForDxSupport */
1543         /* REV_CALL mct_DoRdPtrInit if not Dx */
1544         if (pDCTstat->LogicalCPUID & AMD_DR_Bx)
1545                 val = 5;
1546         else
1547                 val = 6;
1548         DramControl &= ~0xFF;
1549         DramControl |= val;     /* RdPrtInit = 6 for Cx CPU */
1550
1551         if (mctGet_NVbits(NV_CLKHZAltVidC3))
1552                 DramControl |= 1<<16; /* check */
1553
1554         DramControl |= 0x00002A00;
1555
1556         /* FIXME: Skip for Ax versions */
1557         /* callback not required - if (!mctParityControl_D()) */
1558         if (Status & (1 << SB_128bitmode))
1559                 DramConfigLo |= 1 << Width128;  /* 128-bit mode (normal) */
1560
1561         word = dct;
1562         dword = X4Dimm;
1563         while (word < 8) {
1564                 if (pDCTstat->Dimmx4Present & (1 << word))
1565                         DramConfigLo |= 1 << dword;     /* X4Dimm[3:0] */
1566                 word++;
1567                 word++;
1568                 dword++;
1569         }
1570
1571         if (!(Status & (1 << SB_Registered)))
1572                 DramConfigLo |= 1 << UnBuffDimm;        /* Unbufferd DIMMs */
1573
1574         if (mctGet_NVbits(NV_ECC_CAP))
1575                 if (Status & (1 << SB_ECCDIMMs))
1576                         if ( mctGet_NVbits(NV_ECC))
1577                                 DramConfigLo |= 1 << DimmEcEn;
1578
1579         DramConfigLo = mct_DisDllShutdownSR(pMCTstat, pDCTstat, DramConfigLo, dct);
1580
1581         /* Build Dram Config Hi Register Value */
1582         dword = pDCTstat->Speed;
1583         DramConfigHi |= dword - 1;      /* get MemClk encoding */
1584         DramConfigHi |= 1 << MemClkFreqVal;
1585
1586         if (Status & (1 << SB_Registered))
1587                 if ((pDCTstat->Dimmx4Present != 0) && (pDCTstat->Dimmx8Present != 0))
1588                         /* set only if x8 Registered DIMMs in System*/
1589                         DramConfigHi |= 1 << RDqsEn;
1590
1591         if (mctGet_NVbits(NV_CKE_CTL))
1592                 /*Chip Select control of CKE*/
1593                 DramConfigHi |= 1 << 16;
1594
1595         /* Control Bank Swizzle */
1596         if (0) /* call back not needed mctBankSwizzleControl_D()) */
1597                 DramConfigHi &= ~(1 << BankSwizzleMode);
1598         else
1599                 DramConfigHi |= 1 << BankSwizzleMode; /* recommended setting (default) */
1600
1601         /* Check for Quadrank DIMM presence */
1602         if ( pDCTstat->DimmQRPresent != 0) {
1603                 byte = mctGet_NVbits(NV_4RANKType);
1604                 if (byte == 2)
1605                         DramConfigHi |= 1 << 17;        /* S4 (4-Rank SO-DIMMs) */
1606                 else if (byte == 1)
1607                         DramConfigHi |= 1 << 18;        /* R4 (4-Rank Registered DIMMs) */
1608         }
1609
1610         if (0) /* call back not needed mctOverrideDcqBypMax_D ) */
1611                 val = mctGet_NVbits(NV_BYPMAX);
1612         else
1613                 val = 0x0f; /* recommended setting (default) */
1614         DramConfigHi |= val << 24;
1615
1616         if (pDCTstat->LogicalCPUID & (AMD_DR_Cx | AMD_DR_Bx))
1617                 DramConfigHi |= 1 << DcqArbBypassEn;
1618
1619         /* Build MemClkDis Value from Dram Timing Lo and
1620            Dram Config Misc Registers
1621          1. We will assume that MemClkDis field has been preset prior to this
1622             point.
1623          2. We will only set MemClkDis bits if a DIMM is NOT present AND if:
1624             NV_AllMemClks <>0 AND SB_DiagClks ==0 */
1625
1626         /* Dram Timing Low (owns Clock Enable bits) */
1627         DramTimingLo = Get_NB32(dev, 0x88 + reg_off);
1628         if (mctGet_NVbits(NV_AllMemClks) == 0) {
1629                 /* Special Jedec SPD diagnostic bit - "enable all clocks" */
1630                 if (!(pDCTstat->Status & (1<<SB_DiagClks))) {
1631                         const u8 *p;
1632                         const u32 *q;
1633                         p = Tab_ManualCLKDis;
1634                         q = (u32 *)p;
1635
1636                         byte = mctGet_NVbits(NV_PACK_TYPE);
1637                         if (byte == PT_L1)
1638                                 p = Tab_L1CLKDis;
1639                         else if (byte == PT_M2 || byte == PT_AS)
1640                                 p = Tab_AM3CLKDis;
1641                         else
1642                                 p = Tab_S1CLKDis;
1643
1644                         dword = 0;
1645                         byte = 0xFF;
1646                         while(dword < MAX_CS_SUPPORTED) {
1647                                 if (pDCTstat->CSPresent & (1<<dword)){
1648                                         /* re-enable clocks for the enabled CS */
1649                                         val = p[dword];
1650                                         byte &= ~val;
1651                                 }
1652                                 dword++ ;
1653                         }
1654                         DramTimingLo |= byte << 24;
1655                 }
1656         }
1657
1658         printk(BIOS_DEBUG, "AutoConfig_D: DramControl: %x\n", DramControl);
1659         printk(BIOS_DEBUG, "AutoConfig_D: DramTimingLo: %x\n", DramTimingLo);
1660         printk(BIOS_DEBUG, "AutoConfig_D: DramConfigMisc: %x\n", DramConfigMisc);
1661         printk(BIOS_DEBUG, "AutoConfig_D: DramConfigMisc2: %x\n", DramConfigMisc2);
1662         printk(BIOS_DEBUG, "AutoConfig_D: DramConfigLo: %x\n", DramConfigLo);
1663         printk(BIOS_DEBUG, "AutoConfig_D: DramConfigHi: %x\n", DramConfigHi);
1664
1665         /* Write Values to the registers */
1666         Set_NB32(dev, 0x78 + reg_off, DramControl);
1667         Set_NB32(dev, 0x88 + reg_off, DramTimingLo);
1668         Set_NB32(dev, 0xA0 + reg_off, DramConfigMisc);
1669         DramConfigMisc2 = mct_SetDramConfigMisc2(pDCTstat, dct, DramConfigMisc2);
1670         Set_NB32(dev, 0xA8 + reg_off, DramConfigMisc2);
1671         Set_NB32(dev, 0x90 + reg_off, DramConfigLo);
1672         ProgDramMRSReg_D(pMCTstat, pDCTstat, dct);
1673         dword = Get_NB32(dev, 0x94 + reg_off);
1674         DramConfigHi |= dword;
1675         mct_SetDramConfigHi_D(pDCTstat, dct, DramConfigHi);
1676         mct_EarlyArbEn_D(pMCTstat, pDCTstat);
1677         mctHookAfterAutoCfg();
1678
1679         /* dump_pci_device(PCI_DEV(0, 0x18+pDCTstat->Node_ID, 2)); */
1680
1681         printk(BIOS_DEBUG, "AutoConfig: Status %x\n", pDCTstat->Status);
1682         printk(BIOS_DEBUG, "AutoConfig: ErrStatus %x\n", pDCTstat->ErrStatus);
1683         printk(BIOS_DEBUG, "AutoConfig: ErrCode %x\n", pDCTstat->ErrCode);
1684         printk(BIOS_DEBUG, "AutoConfig: Done\n\n");
1685 AutoConfig_exit:
1686         return pDCTstat->ErrCode;
1687 }
1688
1689 static void SPDSetBanks_D(struct MCTStatStruc *pMCTstat,
1690                                 struct DCTStatStruc *pDCTstat, u8 dct)
1691 {
1692         /* Set bank addressing, program Mask values and build a chip-select
1693          * population map. This routine programs PCI 0:24N:2x80 config register
1694          * and PCI 0:24N:2x60,64,68,6C config registers (CS Mask 0-3).
1695          */
1696         u8 ChipSel, Rows, Cols, Ranks, Banks;
1697         u32 BankAddrReg, csMask;
1698
1699         u32 val;
1700         u32 reg;
1701         u32 dev;
1702         u32 reg_off;
1703         u8 byte;
1704         u16 word;
1705         u32 dword;
1706         u16 smbaddr;
1707
1708         dev = pDCTstat->dev_dct;
1709         reg_off = 0x100 * dct;
1710
1711         BankAddrReg = 0;
1712         for (ChipSel = 0; ChipSel < MAX_CS_SUPPORTED; ChipSel+=2) {
1713                 byte = ChipSel;
1714                 if ((pDCTstat->Status & (1 << SB_64MuxedMode)) && ChipSel >=4)
1715                         byte -= 3;
1716
1717                 if (pDCTstat->DIMMValid & (1<<byte)) {
1718                         smbaddr = Get_DIMMAddress_D(pDCTstat, (ChipSel + dct));
1719
1720                         byte = mctRead_SPD(smbaddr, SPD_Addressing);
1721                         Rows = (byte >> 3) & 0x7; /* Rows:0b=12-bit,... */
1722                         Cols = byte & 0x7; /* Cols:0b=9-bit,... */
1723
1724                         byte = mctRead_SPD(smbaddr, SPD_Density);
1725                         Banks = (byte >> 4) & 7; /* Banks:0b=3-bit,... */
1726
1727                         byte = mctRead_SPD(smbaddr, SPD_Organization);
1728                         Ranks = ((byte >> 3) & 7) + 1;
1729
1730                         /* Configure Bank encoding
1731                          * Use a 6-bit key into a lookup table.
1732                          * Key (index) = RRRBCC, where CC is the number of Columns minus 9,
1733                          * RRR is the number of Rows minus 12, and B is the number of banks
1734                          * minus 3.
1735                          */
1736                         byte = Cols;
1737                         if (Banks == 1)
1738                                 byte |= 4;
1739
1740                         byte |= Rows << 3;      /* RRRBCC internal encode */
1741
1742                         for (dword=0; dword < 13; dword++) {
1743                                 if (byte == Tab_BankAddr[dword])
1744                                         break;
1745                         }
1746
1747                         if (dword > 12)
1748                                 continue;
1749
1750                         /* bit no. of CS field in address mapping reg.*/
1751                         dword <<= (ChipSel<<1);
1752                         BankAddrReg |= dword;
1753
1754                         /* Mask value=(2pow(rows+cols+banks+3)-1)>>8,
1755                            or 2pow(rows+cols+banks-5)-1*/
1756                         csMask = 0;
1757
1758                         byte = Rows + Cols;             /* cl=rows+cols*/
1759                         byte += 21;                     /* row:12+col:9 */
1760                         byte -= 2;                      /* 3 banks - 5 */
1761
1762                         if (pDCTstat->Status & (1 << SB_128bitmode))
1763                                 byte++;         /* double mask size if in 128-bit mode*/
1764
1765                         csMask |= 1 << byte;
1766                         csMask--;
1767
1768                         /*set ChipSelect population indicator even bits*/
1769                         pDCTstat->CSPresent |= (1<<ChipSel);
1770                         if (Ranks >= 2)
1771                                 /*set ChipSelect population indicator odd bits*/
1772                                 pDCTstat->CSPresent |= 1 << (ChipSel + 1);
1773
1774                         reg = 0x60+(ChipSel<<1) + reg_off;      /*Dram CS Mask Register */
1775                         val = csMask;
1776                         val &= 0x1FF83FE0;      /* Mask out reserved bits.*/
1777                         Set_NB32(dev, reg, val);
1778                 } else {
1779                         if (pDCTstat->DIMMSPDCSE & (1<<ChipSel))
1780                                 pDCTstat->CSTestFail |= (1<<ChipSel);
1781                 }       /* if DIMMValid*/
1782         }       /* while ChipSel*/
1783
1784         SetCSTriState(pMCTstat, pDCTstat, dct);
1785         SetCKETriState(pMCTstat, pDCTstat, dct);
1786         SetODTTriState(pMCTstat, pDCTstat, dct);
1787
1788         if (pDCTstat->Status & (1 << SB_128bitmode)) {
1789                 SetCSTriState(pMCTstat, pDCTstat, 1); /* force dct1) */
1790                 SetCKETriState(pMCTstat, pDCTstat, 1); /* force dct1) */
1791                 SetODTTriState(pMCTstat, pDCTstat, 1); /* force dct1) */
1792         }
1793
1794         word = pDCTstat->CSPresent;
1795         mctGetCS_ExcludeMap();          /* mask out specified chip-selects */
1796         word ^= pDCTstat->CSPresent;
1797         pDCTstat->CSTestFail |= word;   /* enable ODT to disabled DIMMs */
1798         if (!pDCTstat->CSPresent)
1799                 pDCTstat->ErrCode = SC_StopError;
1800
1801         reg = 0x80 + reg_off;           /* Bank Addressing Register */
1802         Set_NB32(dev, reg, BankAddrReg);
1803
1804         pDCTstat->CSPresent_DCT[dct] = pDCTstat->CSPresent;
1805         /* dump_pci_device(PCI_DEV(0, 0x18+pDCTstat->Node_ID, 2)); */
1806
1807         printk(BIOS_DEBUG, "SPDSetBanks: CSPresent %x\n", pDCTstat->CSPresent_DCT[dct]);
1808         printk(BIOS_DEBUG, "SPDSetBanks: Status %x\n", pDCTstat->Status);
1809         printk(BIOS_DEBUG, "SPDSetBanks: ErrStatus %x\n", pDCTstat->ErrStatus);
1810         printk(BIOS_DEBUG, "SPDSetBanks: ErrCode %x\n", pDCTstat->ErrCode);
1811         printk(BIOS_DEBUG, "SPDSetBanks: Done\n\n");
1812 }
1813
1814 static void SPDCalcWidth_D(struct MCTStatStruc *pMCTstat,
1815                                 struct DCTStatStruc *pDCTstat)
1816 {
1817         /* Per SPDs, check the symmetry of DIMM pairs (DIMM on Channel A
1818          *  matching with DIMM on Channel B), the overall DIMM population,
1819          * and determine the width mode: 64-bit, 64-bit muxed, 128-bit.
1820          */
1821         u8 i;
1822         u8 smbaddr, smbaddr1;
1823         u8 byte, byte1;
1824
1825         /* Check Symmetry of Channel A and Channel B DIMMs
1826           (must be matched for 128-bit mode).*/
1827         for (i=0; i < MAX_DIMMS_SUPPORTED; i += 2) {
1828                 if ((pDCTstat->DIMMValid & (1 << i)) && (pDCTstat->DIMMValid & (1<<(i+1)))) {
1829                         smbaddr = Get_DIMMAddress_D(pDCTstat, i);
1830                         smbaddr1 = Get_DIMMAddress_D(pDCTstat, i+1);
1831
1832                         byte = mctRead_SPD(smbaddr, SPD_Addressing) & 0x7;
1833                         byte1 = mctRead_SPD(smbaddr1, SPD_Addressing) & 0x7;
1834                         if (byte != byte1) {
1835                                 pDCTstat->ErrStatus |= (1<<SB_DimmMismatchO);
1836                                 break;
1837                         }
1838
1839                         byte =   mctRead_SPD(smbaddr, SPD_Density) & 0x0f;
1840                         byte1 =  mctRead_SPD(smbaddr1, SPD_Density) & 0x0f;
1841                         if (byte != byte1) {
1842                                 pDCTstat->ErrStatus |= (1<<SB_DimmMismatchO);
1843                                 break;
1844                         }
1845
1846                         byte = mctRead_SPD(smbaddr, SPD_Organization) & 0x7;
1847                         byte1 = mctRead_SPD(smbaddr1, SPD_Organization) & 0x7;
1848                         if (byte != byte1) {
1849                                 pDCTstat->ErrStatus |= (1<<SB_DimmMismatchO);
1850                                 break;
1851                         }
1852
1853                         byte = (mctRead_SPD(smbaddr, SPD_Organization) >> 3) & 0x7;
1854                         byte1 = (mctRead_SPD(smbaddr1, SPD_Organization) >> 3) & 0x7;
1855                         if (byte != byte1) {
1856                                 pDCTstat->ErrStatus |= (1<<SB_DimmMismatchO);
1857                                 break;
1858                         }
1859
1860                         byte = mctRead_SPD(smbaddr, SPD_DMBANKS) & 7;    /* #ranks-1 */
1861                         byte1 = mctRead_SPD(smbaddr1, SPD_DMBANKS) & 7;   /* #ranks-1 */
1862                         if (byte != byte1) {
1863                                 pDCTstat->ErrStatus |= (1<<SB_DimmMismatchO);
1864                                 break;
1865                         }
1866
1867                 }
1868         }
1869
1870 }
1871
1872 static void StitchMemory_D(struct MCTStatStruc *pMCTstat,
1873                                 struct DCTStatStruc *pDCTstat, u8 dct)
1874 {
1875         /* Requires that Mask values for each bank be programmed first and that
1876          * the chip-select population indicator is correctly set.
1877          */
1878         u8 b = 0;
1879         u32 nxtcsBase, curcsBase;
1880         u8 p, q;
1881         u32 Sizeq, BiggestBank;
1882         u8 _DSpareEn;
1883
1884         u16 word;
1885         u32 dev;
1886         u32 reg;
1887         u32 reg_off;
1888         u32 val;
1889
1890         dev = pDCTstat->dev_dct;
1891         reg_off = 0x100 * dct;
1892
1893         _DSpareEn = 0;
1894
1895         /* CS Sparing 1=enabled, 0=disabled */
1896         if (mctGet_NVbits(NV_CS_SpareCTL) & 1) {
1897                 if (MCT_DIMM_SPARE_NO_WARM) {
1898                         /* Do no warm-reset DIMM spare */
1899                         if (pMCTstat->GStatus & 1 << GSB_EnDIMMSpareNW) {
1900                                 word = pDCTstat->CSPresent;
1901                                 val = bsf(word);
1902                                 word &= ~(1<<val);
1903                                 if (word)
1904                                         /* Make sure at least two chip-selects are available */
1905                                         _DSpareEn = 1;
1906                                 else
1907                                         pDCTstat->ErrStatus |= 1 << SB_SpareDis;
1908                         }
1909                 } else {
1910                         if (!mctGet_NVbits(NV_DQSTrainCTL)) { /*DQS Training 1=enabled, 0=disabled */
1911                                 word = pDCTstat->CSPresent;
1912                                 val = bsf(word);
1913                                 word &= ~(1 << val);
1914                                 if (word)
1915                                         /* Make sure at least two chip-selects are available */
1916                                         _DSpareEn = 1;
1917                                 else
1918                                         pDCTstat->ErrStatus |= 1 << SB_SpareDis;
1919                         }
1920                 }
1921         }
1922
1923         nxtcsBase = 0;          /* Next available cs base ADDR[39:8] */
1924         for (p=0; p < MAX_DIMMS_SUPPORTED; p++) {
1925                 BiggestBank = 0;
1926                 for (q = 0; q < MAX_CS_SUPPORTED; q++) { /* from DIMMS to CS */
1927                         if (pDCTstat->CSPresent & (1 << q)) {  /* bank present? */
1928                                 reg  = 0x40 + (q << 2) + reg_off;  /* Base[q] reg.*/
1929                                 val = Get_NB32(dev, reg);
1930                                 if (!(val & 3)) {       /* (CSEnable|Spare==1)bank is enabled already? */
1931                                         reg = 0x60 + (q << 1) + reg_off; /*Mask[q] reg.*/
1932                                         val = Get_NB32(dev, reg);
1933                                         val >>= 19;
1934                                         val++;
1935                                         val <<= 19;
1936                                         Sizeq = val;  /* never used */
1937                                         if (val > BiggestBank) {
1938                                                 /*Bingo! possibly Map this chip-select next! */
1939                                                 BiggestBank = val;
1940                                                 b = q;
1941                                         }
1942                                 }
1943                         }       /*if bank present */
1944                 }       /* while q */
1945                 if (BiggestBank !=0) {
1946                         curcsBase = nxtcsBase;          /* curcsBase=nxtcsBase*/
1947                         /* DRAM CS Base b Address Register offset */
1948                         reg = 0x40 + (b << 2) + reg_off;
1949                         if (_DSpareEn) {
1950                                 BiggestBank = 0;
1951                                 val = 1 << Spare;       /* Spare Enable*/
1952                         } else {
1953                                 val = curcsBase;
1954                                 val |= 1 << CSEnable;   /* Bank Enable */
1955                         }
1956                         if (((reg - 0x40) >> 2) & 1) {
1957                                 if (!(pDCTstat->Status & (1 << SB_Registered))) {
1958                                         u16  dimValid;
1959                                         dimValid = pDCTstat->DIMMValid;
1960                                         if (dct & 1)
1961                                                 dimValid <<= 1;
1962                                         if ((dimValid & pDCTstat->MirrPresU_NumRegR) != 0) {
1963                                                 val |= 1 << onDimmMirror;
1964                                         }
1965                                 }
1966                         }
1967                         Set_NB32(dev, reg, val);
1968                         if (_DSpareEn)
1969                                 _DSpareEn = 0;
1970                         else
1971                                 /* let nxtcsBase+=Size[b] */
1972                                 nxtcsBase += BiggestBank;
1973                 }
1974
1975                 /* bank present but disabled?*/
1976                 if ( pDCTstat->CSTestFail & (1 << p)) {
1977                         /* DRAM CS Base b Address Register offset */
1978                         reg = (p << 2) + 0x40 + reg_off;
1979                         val = 1 << TestFail;
1980                         Set_NB32(dev, reg, val);
1981                 }
1982         }
1983
1984         if (nxtcsBase) {
1985                 pDCTstat->DCTSysLimit = nxtcsBase - 1;
1986                 mct_AfterStitchMemory(pMCTstat, pDCTstat, dct);
1987         }
1988
1989         /* dump_pci_device(PCI_DEV(0, 0x18+pDCTstat->Node_ID, 2)); */
1990
1991         printk(BIOS_DEBUG, "StitchMemory: Status %x\n", pDCTstat->Status);
1992         printk(BIOS_DEBUG, "StitchMemory: ErrStatus %x\n", pDCTstat->ErrStatus);
1993         printk(BIOS_DEBUG, "StitchMemory: ErrCode %x\n", pDCTstat->ErrCode);
1994         printk(BIOS_DEBUG, "StitchMemory: Done\n\n");
1995 }
1996
1997 static u16 Get_Fk_D(u8 k)
1998 {
1999         return Table_F_k[k]; /* FIXME: k or k<<1 ? */
2000 }
2001
2002 static u8 DIMMPresence_D(struct MCTStatStruc *pMCTstat,
2003                                 struct DCTStatStruc *pDCTstat)
2004 {
2005         /* Check DIMMs present, verify checksum, flag SDRAM type,
2006          * build population indicator bitmaps, and preload bus loading
2007          * of DIMMs into DCTStatStruc.
2008          * MAAload=number of devices on the "A" bus.
2009          * MABload=number of devices on the "B" bus.
2010          * MAAdimms=number of DIMMs on the "A" bus slots.
2011          * MABdimms=number of DIMMs on the "B" bus slots.
2012          * DATAAload=number of ranks on the "A" bus slots.
2013          * DATABload=number of ranks on the "B" bus slots.
2014          */
2015         u16 i, j;
2016         u8 smbaddr;
2017         u8 SPDCtrl;
2018         u16 RegDIMMPresent, MaxDimms;
2019         u8 devwidth;
2020         u16 DimmSlots;
2021         u8 byte = 0, bytex;
2022
2023         /* preload data structure with addrs */
2024         mctGet_DIMMAddr(pDCTstat, pDCTstat->Node_ID);
2025
2026         DimmSlots = MaxDimms = mctGet_NVbits(NV_MAX_DIMMS);
2027
2028         SPDCtrl = mctGet_NVbits(NV_SPDCHK_RESTRT);
2029
2030         RegDIMMPresent = 0;
2031         pDCTstat->DimmQRPresent = 0;
2032
2033         for (i = 0; i < MAX_DIMMS_SUPPORTED; i++) {
2034                 if (i >= MaxDimms)
2035                         break;
2036
2037                 if ((pDCTstat->DimmQRPresent & (1 << i)) || (i < DimmSlots)) {
2038                         int status;
2039                         smbaddr = Get_DIMMAddress_D(pDCTstat, i);
2040                         status = mctRead_SPD(smbaddr, SPD_ByteUse);
2041                         if (status >= 0) { /* SPD access is ok */
2042                                 pDCTstat->DIMMPresent |= 1 << i;
2043                                 if (crcCheck(smbaddr)) { /* CRC is OK */
2044                                         byte = mctRead_SPD(smbaddr, SPD_TYPE);
2045                                         if (byte == JED_DDR3SDRAM) {
2046                                                 /*Dimm is 'Present'*/
2047                                                 pDCTstat->DIMMValid |= 1 << i;
2048                                         }
2049                                 } else {
2050                                         pDCTstat->DIMMSPDCSE = 1 << i;
2051                                         if (SPDCtrl == 0) {
2052                                                 pDCTstat->ErrStatus |= 1 << SB_DIMMChkSum;
2053                                                 pDCTstat->ErrCode = SC_StopError;
2054                                         } else {
2055                                                 /*if NV_SPDCHK_RESTRT is set to 1, ignore faulty SPD checksum*/
2056                                                 pDCTstat->ErrStatus |= 1<<SB_DIMMChkSum;
2057                                                 byte = mctRead_SPD(smbaddr, SPD_TYPE);
2058                                                 if (byte == JED_DDR3SDRAM)
2059                                                         pDCTstat->DIMMValid |= 1 << i;
2060                                         }
2061                                 }
2062                                 /* Check module type */
2063                                 byte = mctRead_SPD(smbaddr, SPD_DIMMTYPE) & 0x7;
2064                                 if (byte == JED_RDIMM || byte == JED_MiniRDIMM)
2065                                         RegDIMMPresent |= 1 << i;
2066                                 /* Check ECC capable */
2067                                 byte = mctRead_SPD(smbaddr, SPD_BusWidth);
2068                                 if (byte & JED_ECC) {
2069                                         /* DIMM is ECC capable */
2070                                         pDCTstat->DimmECCPresent |= 1 << i;
2071                                 }
2072                                 /* Check if x4 device */
2073                                 devwidth = mctRead_SPD(smbaddr, SPD_Organization) & 0x7; /* 0:x4,1:x8,2:x16 */
2074                                 if (devwidth == 0) {
2075                                         /* DIMM is made with x4 or x16 drams */
2076                                         pDCTstat->Dimmx4Present |= 1 << i;
2077                                 } else if (devwidth == 1) {
2078                                         pDCTstat->Dimmx8Present |= 1 << i;
2079                                 } else if (devwidth == 2) {
2080                                         pDCTstat->Dimmx16Present |= 1 << i;
2081                                 }
2082
2083                                 byte = (mctRead_SPD(smbaddr, SPD_Organization) >> 3);
2084                                 byte &= 7;
2085                                 if (byte == 3) { /* 4ranks */
2086                                         /* if any DIMMs are QR, we have to make two passes through DIMMs*/
2087                                         if ( pDCTstat->DimmQRPresent == 0) {
2088                                                 MaxDimms <<= 1;
2089                                         }
2090                                         if (i < DimmSlots) {
2091                                                 pDCTstat->DimmQRPresent |= (1 << i) | (1 << (i+4));
2092                                         } else {
2093                                                 pDCTstat->MAdimms[i & 1] --;
2094                                         }
2095                                         byte = 1;       /* upper two ranks of QR DIMM will be counted on another DIMM number iteration*/
2096                                 } else if (byte == 1) { /* 2ranks */
2097                                         pDCTstat->DimmDRPresent |= 1 << i;
2098                                 }
2099                                 bytex = devwidth;
2100                                 if (devwidth == 0)
2101                                         bytex = 16;
2102                                 else if (devwidth == 1)
2103                                         bytex = 8;
2104                                 else if (devwidth == 2)
2105                                         bytex = 4;
2106
2107                                 byte++;         /* al+1=rank# */
2108                                 if (byte == 2)
2109                                         bytex <<= 1;    /*double Addr bus load value for dual rank DIMMs*/
2110
2111                                 j = i & (1<<0);
2112                                 pDCTstat->DATAload[j] += byte;  /*number of ranks on DATA bus*/
2113                                 pDCTstat->MAload[j] += bytex;   /*number of devices on CMD/ADDR bus*/
2114                                 pDCTstat->MAdimms[j]++;         /*number of DIMMs on A bus */
2115
2116                                 /* check address mirror support for unbuffered dimm */
2117                                 /* check number of registers on a dimm for registered dimm */
2118                                 byte = mctRead_SPD(smbaddr, SPD_AddressMirror);
2119                                 if (RegDIMMPresent & (1 << i)) {
2120                                         if ((byte & 3) > 1)
2121                                                 pDCTstat->MirrPresU_NumRegR |= 1 << i;
2122                                 } else {
2123                                         if ((byte & 1) == 1)
2124                                                 pDCTstat->MirrPresU_NumRegR |= 1 << i;
2125                                 }
2126                                 /* Get byte62: Reference Raw Card information. We dont need it now. */
2127                                 /* byte = mctRead_SPD(smbaddr, SPD_RefRawCard); */
2128                                 /* Get Byte65/66 for register manufacture ID code */
2129                                 if ((0x97 == mctRead_SPD(smbaddr, SPD_RegManufactureID_H)) &&
2130                                     (0x80 == mctRead_SPD(smbaddr, SPD_RegManufactureID_L))) {
2131                                         if (0x16 == mctRead_SPD(smbaddr, SPD_RegManRevID))
2132                                                 pDCTstat->RegMan2Present |= 1 << i;
2133                                         else
2134                                                 pDCTstat->RegMan1Present |= 1 << i;
2135                                 }
2136                                 /* Get Control word values for RC3. We dont need it. */
2137                                 byte = mctRead_SPD(smbaddr, 70);
2138                                 pDCTstat->CtrlWrd3 |= (byte >> 4) << (i << 2); /* C3 = SPD byte 70 [7:4] */
2139                                 /* Get Control word values for RC4, and RC5 */
2140                                 byte = mctRead_SPD(smbaddr, 71);
2141                                 pDCTstat->CtrlWrd4 |= (byte & 0xFF) << (i << 2); /* RC4 = SPD byte 71 [3:0] */
2142                                 pDCTstat->CtrlWrd5 |= (byte >> 4) << (i << 2); /* RC5 = SPD byte 71 [7:4] */
2143                         }
2144                 }
2145         }
2146         printk(BIOS_DEBUG, "\t DIMMPresence: DIMMValid=%x\n", pDCTstat->DIMMValid);
2147         printk(BIOS_DEBUG, "\t DIMMPresence: DIMMPresent=%x\n", pDCTstat->DIMMPresent);
2148         printk(BIOS_DEBUG, "\t DIMMPresence: RegDIMMPresent=%x\n", RegDIMMPresent);
2149         printk(BIOS_DEBUG, "\t DIMMPresence: DimmECCPresent=%x\n", pDCTstat->DimmECCPresent);
2150         printk(BIOS_DEBUG, "\t DIMMPresence: DimmPARPresent=%x\n", pDCTstat->DimmPARPresent);
2151         printk(BIOS_DEBUG, "\t DIMMPresence: Dimmx4Present=%x\n", pDCTstat->Dimmx4Present);
2152         printk(BIOS_DEBUG, "\t DIMMPresence: Dimmx8Present=%x\n", pDCTstat->Dimmx8Present);
2153         printk(BIOS_DEBUG, "\t DIMMPresence: Dimmx16Present=%x\n", pDCTstat->Dimmx16Present);
2154         printk(BIOS_DEBUG, "\t DIMMPresence: DimmPlPresent=%x\n", pDCTstat->DimmPlPresent);
2155         printk(BIOS_DEBUG, "\t DIMMPresence: DimmDRPresent=%x\n", pDCTstat->DimmDRPresent);
2156         printk(BIOS_DEBUG, "\t DIMMPresence: DimmQRPresent=%x\n", pDCTstat->DimmQRPresent);
2157         printk(BIOS_DEBUG, "\t DIMMPresence: DATAload[0]=%x\n", pDCTstat->DATAload[0]);
2158         printk(BIOS_DEBUG, "\t DIMMPresence: MAload[0]=%x\n", pDCTstat->MAload[0]);
2159         printk(BIOS_DEBUG, "\t DIMMPresence: MAdimms[0]=%x\n", pDCTstat->MAdimms[0]);
2160         printk(BIOS_DEBUG, "\t DIMMPresence: DATAload[1]=%x\n", pDCTstat->DATAload[1]);
2161         printk(BIOS_DEBUG, "\t DIMMPresence: MAload[1]=%x\n", pDCTstat->MAload[1]);
2162         printk(BIOS_DEBUG, "\t DIMMPresence: MAdimms[1]=%x\n", pDCTstat->MAdimms[1]);
2163
2164         if (pDCTstat->DIMMValid != 0) { /* If any DIMMs are present...*/
2165                 if (RegDIMMPresent != 0) {
2166                         if ((RegDIMMPresent ^ pDCTstat->DIMMValid) !=0) {
2167                                 /* module type DIMM mismatch (reg'ed, unbuffered) */
2168                                 pDCTstat->ErrStatus |= 1<<SB_DimmMismatchM;
2169                                 pDCTstat->ErrCode = SC_StopError;
2170                         } else{
2171                                 /* all DIMMs are registered */
2172                                 pDCTstat->Status |= 1<<SB_Registered;
2173                         }
2174                 }
2175                 if (pDCTstat->DimmECCPresent != 0) {
2176                         if ((pDCTstat->DimmECCPresent ^ pDCTstat->DIMMValid )== 0) {
2177                                 /* all DIMMs are ECC capable */
2178                                 pDCTstat->Status |= 1<<SB_ECCDIMMs;
2179                         }
2180                 }
2181                 if (pDCTstat->DimmPARPresent != 0) {
2182                         if ((pDCTstat->DimmPARPresent ^ pDCTstat->DIMMValid) == 0) {
2183                                 /*all DIMMs are Parity capable */
2184                                 pDCTstat->Status |= 1<<SB_PARDIMMs;
2185                         }
2186                 }
2187         } else {
2188                 /* no DIMMs present or no DIMMs that qualified. */
2189                 pDCTstat->ErrStatus |= 1<<SB_NoDimms;
2190                 pDCTstat->ErrCode = SC_StopError;
2191         }
2192
2193         printk(BIOS_DEBUG, "\t DIMMPresence: Status %x\n", pDCTstat->Status);
2194         printk(BIOS_DEBUG, "\t DIMMPresence: ErrStatus %x\n", pDCTstat->ErrStatus);
2195         printk(BIOS_DEBUG, "\t DIMMPresence: ErrCode %x\n", pDCTstat->ErrCode);
2196         printk(BIOS_DEBUG, "\t DIMMPresence: Done\n\n");
2197
2198         mctHookAfterDIMMpre();
2199
2200         return pDCTstat->ErrCode;
2201 }
2202
2203 static u8 Get_DIMMAddress_D(struct DCTStatStruc *pDCTstat, u8 i)
2204 {
2205         u8 *p;
2206
2207         p = pDCTstat->DIMMAddr;
2208         /* mct_BeforeGetDIMMAddress(); */
2209         return p[i];
2210 }
2211
2212 static void mct_initDCT(struct MCTStatStruc *pMCTstat,
2213                                 struct DCTStatStruc *pDCTstat)
2214 {
2215         u32 val;
2216         u8 err_code;
2217
2218         /* Config. DCT0 for Ganged or unganged mode */
2219         DCTInit_D(pMCTstat, pDCTstat, 0);
2220         if (pDCTstat->ErrCode == SC_FatalErr) {
2221                 /* Do nothing goto exitDCTInit; any fatal errors? */
2222         } else {
2223                 /* Configure DCT1 if unganged and enabled*/
2224                 if (!pDCTstat->GangedMode) {
2225                         if (pDCTstat->DIMMValidDCT[1] > 0) {
2226                                 err_code = pDCTstat->ErrCode;           /* save DCT0 errors */
2227                                 pDCTstat->ErrCode = 0;
2228                                 DCTInit_D(pMCTstat, pDCTstat, 1);
2229                                 if (pDCTstat->ErrCode == 2)             /* DCT1 is not Running */
2230                                         pDCTstat->ErrCode = err_code;   /* Using DCT0 Error code to update pDCTstat.ErrCode */
2231                         } else {
2232                                 val = 1 << DisDramInterface;
2233                                 Set_NB32(pDCTstat->dev_dct, 0x100 + 0x94, val);
2234                         }
2235                 }
2236         }
2237 /* exitDCTInit: */
2238 }
2239
2240 static void mct_DramInit(struct MCTStatStruc *pMCTstat,
2241                                 struct DCTStatStruc *pDCTstat, u8 dct)
2242 {
2243         mct_BeforeDramInit_Prod_D(pMCTstat, pDCTstat);
2244         mct_DramInit_Sw_D(pMCTstat, pDCTstat, dct);
2245         /* mct_DramInit_Hw_D(pMCTstat, pDCTstat, dct); */
2246 }
2247
2248 static u8 mct_setMode(struct MCTStatStruc *pMCTstat,
2249                                 struct DCTStatStruc *pDCTstat)
2250 {
2251         u8 byte;
2252         u8 bytex;
2253         u32 val;
2254         u32 reg;
2255
2256         byte = bytex = pDCTstat->DIMMValid;
2257         bytex &= 0x55;          /* CHA DIMM pop */
2258         pDCTstat->DIMMValidDCT[0] = bytex;
2259
2260         byte &= 0xAA;           /* CHB DIMM popa */
2261         byte >>= 1;
2262         pDCTstat->DIMMValidDCT[1] = byte;
2263
2264         if (byte != bytex) {
2265                 pDCTstat->ErrStatus &= ~(1 << SB_DimmMismatchO);
2266         } else {
2267                 byte = mctGet_NVbits(NV_Unganged);
2268                 if (byte)
2269                         pDCTstat->ErrStatus |= (1 << SB_DimmMismatchO); /* Set temp. to avoid setting of ganged mode */
2270
2271                 if (!(pDCTstat->ErrStatus & (1 << SB_DimmMismatchO))) {
2272                         pDCTstat->GangedMode = 1;
2273                         /* valid 128-bit mode population. */
2274                         pDCTstat->Status |= 1 << SB_128bitmode;
2275                         reg = 0x110;
2276                         val = Get_NB32(pDCTstat->dev_dct, reg);
2277                         val |= 1 << DctGangEn;
2278                         Set_NB32(pDCTstat->dev_dct, reg, val);
2279                 }
2280                 if (byte)       /* NV_Unganged */
2281                         pDCTstat->ErrStatus &= ~(1 << SB_DimmMismatchO); /* Clear so that there is no DIMM missmatch error */
2282         }
2283         return pDCTstat->ErrCode;
2284 }
2285
2286 u32 Get_NB32(u32 dev, u32 reg)
2287 {
2288         return pci_read_config32(dev, reg);
2289 }
2290
2291 void Set_NB32(u32 dev, u32 reg, u32 val)
2292 {
2293         pci_write_config32(dev, reg, val);
2294 }
2295
2296
2297 u32 Get_NB32_index(u32 dev, u32 index_reg, u32 index)
2298 {
2299         u32 dword;
2300
2301         Set_NB32(dev, index_reg, index);
2302         dword = Get_NB32(dev, index_reg+0x4);
2303
2304         return dword;
2305 }
2306
2307 void Set_NB32_index(u32 dev, u32 index_reg, u32 index, u32 data)
2308 {
2309         Set_NB32(dev, index_reg, index);
2310         Set_NB32(dev, index_reg + 0x4, data);
2311 }
2312
2313 u32 Get_NB32_index_wait(u32 dev, u32 index_reg, u32 index)
2314 {
2315
2316         u32 dword;
2317
2318
2319         index &= ~(1 << DctAccessWrite);
2320         Set_NB32(dev, index_reg, index);
2321         do {
2322                 dword = Get_NB32(dev, index_reg);
2323         } while (!(dword & (1 << DctAccessDone)));
2324         dword = Get_NB32(dev, index_reg + 0x4);
2325
2326         return dword;
2327 }
2328
2329 void Set_NB32_index_wait(u32 dev, u32 index_reg, u32 index, u32 data)
2330 {
2331         u32 dword;
2332
2333
2334         Set_NB32(dev, index_reg + 0x4, data);
2335         index |= (1 << DctAccessWrite);
2336         Set_NB32(dev, index_reg, index);
2337         do {
2338                 dword = Get_NB32(dev, index_reg);
2339         } while (!(dword & (1 << DctAccessDone)));
2340
2341 }
2342
2343 static u8 mct_PlatformSpec(struct MCTStatStruc *pMCTstat,
2344                                         struct DCTStatStruc *pDCTstat, u8 dct)
2345 {
2346         /* Get platform specific config/timing values from the interface layer
2347          * and program them into DCT.
2348          */
2349
2350         u32 dev = pDCTstat->dev_dct;
2351         u32 index_reg;
2352         u8 i, i_start, i_end;
2353
2354         if (pDCTstat->GangedMode) {
2355                 SyncSetting(pDCTstat);
2356                 /* mct_SetupSync_D */
2357                 i_start = 0;
2358                 i_end = 2;
2359         } else {
2360                 i_start = dct;
2361                 i_end = dct + 1;
2362         }
2363         for (i=i_start; i<i_end; i++) {
2364                 index_reg = 0x98 + (i * 0x100);
2365                 Set_NB32_index_wait(dev, index_reg, 0x00, pDCTstat->CH_ODC_CTL[i]); /* Channel A Output Driver Compensation Control */
2366                 Set_NB32_index_wait(dev, index_reg, 0x04, pDCTstat->CH_ADDR_TMG[i]); /* Channel A Output Driver Compensation Control */
2367         }
2368
2369         return pDCTstat->ErrCode;
2370
2371 }
2372
2373 static void mct_SyncDCTsReady(struct DCTStatStruc *pDCTstat)
2374 {
2375         u32 dev;
2376         u32 val;
2377
2378         if (pDCTstat->NodePresent) {
2379                 dev = pDCTstat->dev_dct;
2380
2381                 if ((pDCTstat->DIMMValidDCT[0] ) || (pDCTstat->DIMMValidDCT[1])) {              /* This Node has dram */
2382                         do {
2383                                 val = Get_NB32(dev, 0x110);
2384                         } while (!(val & (1 << DramEnabled)));
2385                 }
2386         }       /* Node is present */
2387 }
2388
2389 static void mct_AfterGetCLT(struct MCTStatStruc *pMCTstat,
2390                                 struct DCTStatStruc *pDCTstat, u8 dct)
2391 {
2392         if (!pDCTstat->GangedMode) {
2393                 if (dct == 0 ) {
2394                         pDCTstat->DIMMValid = pDCTstat->DIMMValidDCT[dct];
2395                         if (pDCTstat->DIMMValidDCT[dct] == 0)
2396                                 pDCTstat->ErrCode = SC_StopError;
2397                 } else {
2398                         pDCTstat->CSPresent = 0;
2399                         pDCTstat->CSTestFail = 0;
2400                         pDCTstat->DIMMValid = pDCTstat->DIMMValidDCT[dct];
2401                         if (pDCTstat->DIMMValidDCT[dct] == 0)
2402                                 pDCTstat->ErrCode = SC_StopError;
2403                 }
2404         }
2405 }
2406
2407 static u8 mct_SPDCalcWidth(struct MCTStatStruc *pMCTstat,
2408                                         struct DCTStatStruc *pDCTstat, u8 dct)
2409 {
2410         u8 ret;
2411         u32 val;
2412
2413         if ( dct == 0) {
2414                 SPDCalcWidth_D(pMCTstat, pDCTstat);
2415                 ret = mct_setMode(pMCTstat, pDCTstat);
2416         } else {
2417                 ret = pDCTstat->ErrCode;
2418         }
2419
2420         if (pDCTstat->DIMMValidDCT[0] == 0) {
2421                 val = Get_NB32(pDCTstat->dev_dct, 0x94);
2422                 val |= 1 << DisDramInterface;
2423                 Set_NB32(pDCTstat->dev_dct, 0x94, val);
2424         }
2425         if (pDCTstat->DIMMValidDCT[1] == 0) {
2426                 val = Get_NB32(pDCTstat->dev_dct, 0x94 + 0x100);
2427                 val |= 1 << DisDramInterface;
2428                 Set_NB32(pDCTstat->dev_dct, 0x94 + 0x100, val);
2429         }
2430
2431         printk(BIOS_DEBUG, "SPDCalcWidth: Status %x\n", pDCTstat->Status);
2432         printk(BIOS_DEBUG, "SPDCalcWidth: ErrStatus %x\n", pDCTstat->ErrStatus);
2433         printk(BIOS_DEBUG, "SPDCalcWidth: ErrCode %x\n", pDCTstat->ErrCode);
2434         printk(BIOS_DEBUG, "SPDCalcWidth: Done\n");
2435         /* Disable dram interface before DRAM init */
2436
2437         return ret;
2438 }
2439
2440 static void mct_AfterStitchMemory(struct MCTStatStruc *pMCTstat,
2441                                         struct DCTStatStruc *pDCTstat, u8 dct)
2442 {
2443         u32 val;
2444         u32 dword;
2445         u32 dev;
2446         u32 reg;
2447         u8 _MemHoleRemap;
2448         u32 DramHoleBase;
2449
2450         _MemHoleRemap = mctGet_NVbits(NV_MemHole);
2451         DramHoleBase = mctGet_NVbits(NV_BottomIO);
2452         DramHoleBase <<= 8;
2453         /* Increase hole size so;[31:24]to[31:16]
2454          * it has granularity of 128MB shl eax,8
2455          * Set 'effective' bottom IOmov DramHoleBase,eax
2456          */
2457         pMCTstat->HoleBase = (DramHoleBase & 0xFFFFF800) << 8;
2458
2459         /* In unganged mode, we must add DCT0 and DCT1 to DCTSysLimit */
2460         if (!pDCTstat->GangedMode) {
2461                 dev = pDCTstat->dev_dct;
2462                 pDCTstat->NodeSysLimit += pDCTstat->DCTSysLimit;
2463                 /* if DCT0 and DCT1 both exist, set DctSelBaseAddr[47:27] to the top of DCT0 */
2464                 if (dct == 0) {
2465                         if (pDCTstat->DIMMValidDCT[1] > 0) {
2466                                 dword = pDCTstat->DCTSysLimit + 1;
2467                                 dword += pDCTstat->NodeSysBase;
2468                                 dword >>= 8; /* scale [39:8] to [47:27],and to F2x110[31:11] */
2469                                 if ((dword >= DramHoleBase) && _MemHoleRemap) {
2470                                         pMCTstat->HoleBase = (DramHoleBase & 0xFFFFF800) << 8;
2471                                         val = pMCTstat->HoleBase;
2472                                         val >>= 16;
2473                                         val = (((~val) & 0xFF) + 1);
2474                                         val <<= 8;
2475                                         dword += val;
2476                                 }
2477                                 reg = 0x110;
2478                                 val = Get_NB32(dev, reg);
2479                                 val &= 0x7F;
2480                                 val |= dword;
2481                                 val |= 3;  /* Set F2x110[DctSelHiRngEn], F2x110[DctSelHi] */
2482                                 Set_NB32(dev, reg, val);
2483
2484                                 reg = 0x114;
2485                                 val = dword;
2486                                 Set_NB32(dev, reg, val);
2487                         }
2488                 } else {
2489                         /* Program the DctSelBaseAddr value to 0
2490                            if DCT 0 is disabled */
2491                         if (pDCTstat->DIMMValidDCT[0] == 0) {
2492                                 dword = pDCTstat->NodeSysBase;
2493                                 dword >>= 8;
2494                                 if ((dword >= DramHoleBase) && _MemHoleRemap) {
2495                                         pMCTstat->HoleBase = (DramHoleBase & 0xFFFFF800) << 8;
2496                                         val = pMCTstat->HoleBase;
2497                                         val >>= 8;
2498                                         val &= ~(0xFFFF);
2499                                         val |= (((~val) & 0xFFFF) + 1);
2500                                         dword += val;
2501                                 }
2502                                 reg = 0x114;
2503                                 val = dword;
2504                                 Set_NB32(dev, reg, val);
2505
2506                                 reg = 0x110;
2507                                 val |= 3;       /* Set F2x110[DctSelHiRngEn], F2x110[DctSelHi] */
2508                                 Set_NB32(dev, reg, val);
2509                         }
2510                 }
2511         } else {
2512                 pDCTstat->NodeSysLimit += pDCTstat->DCTSysLimit;
2513         }
2514         printk(BIOS_DEBUG, "AfterStitch pDCTstat->NodeSysBase = %x\n", pDCTstat->NodeSysBase);
2515         printk(BIOS_DEBUG, "mct_AfterStitchMemory: pDCTstat->NodeSysLimit = %x\n", pDCTstat->NodeSysLimit);
2516 }
2517
2518 static u8 mct_DIMMPresence(struct MCTStatStruc *pMCTstat,
2519                                         struct DCTStatStruc *pDCTstat, u8 dct)
2520 {
2521         u8 ret;
2522
2523         if (dct == 0)
2524                 ret = DIMMPresence_D(pMCTstat, pDCTstat);
2525         else
2526                 ret = pDCTstat->ErrCode;
2527
2528         return ret;
2529 }
2530
2531 /* mct_BeforeGetDIMMAddress inline in C */
2532
2533 static void mct_OtherTiming(struct MCTStatStruc *pMCTstat,
2534                                 struct DCTStatStruc *pDCTstatA)
2535 {
2536         u8 Node;
2537
2538         for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
2539                 struct DCTStatStruc *pDCTstat;
2540                 pDCTstat = pDCTstatA + Node;
2541                 if (pDCTstat->NodePresent) {
2542                         if (pDCTstat->DIMMValidDCT[0]) {
2543                                 pDCTstat->DIMMValid = pDCTstat->DIMMValidDCT[0];
2544                                 Set_OtherTiming(pMCTstat, pDCTstat, 0);
2545                         }
2546                         if (pDCTstat->DIMMValidDCT[1] && !pDCTstat->GangedMode ) {
2547                                 pDCTstat->DIMMValid = pDCTstat->DIMMValidDCT[1];
2548                                 Set_OtherTiming(pMCTstat, pDCTstat, 1);
2549                         }
2550                 }       /* Node is present*/
2551         }       /* while Node */
2552 }
2553
2554 static void Set_OtherTiming(struct MCTStatStruc *pMCTstat,
2555                                 struct DCTStatStruc *pDCTstat, u8 dct)
2556 {
2557         u32 reg;
2558         u32 reg_off = 0x100 * dct;
2559         u32 val;
2560         u32 dword;
2561         u32 dev = pDCTstat->dev_dct;
2562
2563         Get_DqsRcvEnGross_Diff(pDCTstat, dev, 0x98 + reg_off);
2564         Get_WrDatGross_Diff(pDCTstat, dct, dev, 0x98 + reg_off);
2565         Get_Trdrd(pMCTstat, pDCTstat, dct);
2566         Get_Twrwr(pMCTstat, pDCTstat, dct);
2567         Get_Twrrd(pMCTstat, pDCTstat, dct);
2568         Get_TrwtTO(pMCTstat, pDCTstat, dct);
2569         Get_TrwtWB(pMCTstat, pDCTstat);
2570
2571         reg = 0x8C + reg_off;           /* Dram Timing Hi */
2572         val = Get_NB32(dev, reg);
2573         val &= 0xffff0300;
2574         dword = pDCTstat->TrwtTO;
2575         val |= dword << 4;
2576         dword = pDCTstat->Twrrd & 3;
2577         val |= dword << 10;
2578         dword = pDCTstat->Twrwr & 3;
2579         val |= dword << 12;
2580         dword = pDCTstat->Trdrd & 3;
2581         val |= dword << 14;
2582         dword = pDCTstat->TrwtWB;
2583         val |= dword;
2584         Set_NB32(dev, reg, val);
2585
2586         reg = 0x78 + reg_off;
2587         val = Get_NB32(dev, reg);
2588         val &= 0xFFFFC0FF;
2589         dword = pDCTstat->Twrrd >> 2;
2590         val |= dword << 8;
2591         dword = pDCTstat->Twrwr >> 2;
2592         val |= dword << 10;
2593         dword = pDCTstat->Trdrd >> 2;
2594         val |= dword << 12;
2595         Set_NB32(dev, reg, val);
2596 }
2597
2598 static void Get_Trdrd(struct MCTStatStruc *pMCTstat,
2599                         struct DCTStatStruc *pDCTstat, u8 dct)
2600 {
2601         int8_t Trdrd;
2602
2603         Trdrd = ((int8_t)(pDCTstat->DqsRcvEnGrossMax - pDCTstat->DqsRcvEnGrossMin) >> 1) + 1;
2604         if (Trdrd > 8)
2605                 Trdrd = 8;
2606         pDCTstat->Trdrd = Trdrd;
2607 }
2608
2609 static void Get_Twrwr(struct MCTStatStruc *pMCTstat,
2610                         struct DCTStatStruc *pDCTstat, u8 dct)
2611 {
2612         int8_t Twrwr = 0;
2613
2614         Twrwr = ((int8_t)(pDCTstat->WrDatGrossMax - pDCTstat->WrDatGrossMin) >> 1) + 2;
2615
2616         if (Twrwr < 2)
2617                 Twrwr = 2;
2618         else if (Twrwr > 9)
2619                 Twrwr = 9;
2620
2621         pDCTstat->Twrwr = Twrwr;
2622 }
2623
2624 static void Get_Twrrd(struct MCTStatStruc *pMCTstat,
2625                         struct DCTStatStruc *pDCTstat, u8 dct)
2626 {
2627         u8 LDplus1;
2628         int8_t Twrrd;
2629
2630         LDplus1 = Get_Latency_Diff(pMCTstat, pDCTstat, dct);
2631
2632         Twrrd = ((int8_t)(pDCTstat->WrDatGrossMax - pDCTstat->DqsRcvEnGrossMin) >> 1) + 4 - LDplus1;
2633
2634         if (Twrrd < 2)
2635                 Twrrd = 2;
2636         else if (Twrrd > 10)
2637                 Twrrd = 10;
2638         pDCTstat->Twrrd = Twrrd;
2639 }
2640
2641 static void Get_TrwtTO(struct MCTStatStruc *pMCTstat,
2642                         struct DCTStatStruc *pDCTstat, u8 dct)
2643 {
2644         u8 LDplus1;
2645         int8_t TrwtTO;
2646
2647         LDplus1 = Get_Latency_Diff(pMCTstat, pDCTstat, dct);
2648
2649         TrwtTO = ((int8_t)(pDCTstat->DqsRcvEnGrossMax - pDCTstat->WrDatGrossMin) >> 1) + LDplus1;
2650
2651         pDCTstat->TrwtTO = TrwtTO;
2652 }
2653
2654 static void Get_TrwtWB(struct MCTStatStruc *pMCTstat,
2655                         struct DCTStatStruc *pDCTstat)
2656 {
2657         /* TrwtWB ensures read-to-write data-bus turnaround.
2658            This value should be one more than the programmed TrwtTO.*/
2659         pDCTstat->TrwtWB = pDCTstat->TrwtTO;
2660 }
2661
2662 static u8 Get_Latency_Diff(struct MCTStatStruc *pMCTstat,
2663                            struct DCTStatStruc *pDCTstat, u8 dct)
2664 {
2665         u32 reg_off =  0x100 * dct;
2666         u32 dev = pDCTstat->dev_dct;
2667         u32 val1, val2;
2668
2669         val1 = Get_NB32(dev, reg_off + 0x88) & 0xF;
2670         val2 = (Get_NB32(dev, reg_off + 0x84) >> 20) & 7;
2671
2672         return val1 - val2;
2673 }
2674
2675 static void Get_DqsRcvEnGross_Diff(struct DCTStatStruc *pDCTstat,
2676                                         u32 dev, u32 index_reg)
2677 {
2678         u8 Smallest, Largest;
2679         u32 val;
2680         u8 byte, bytex;
2681
2682         /* The largest DqsRcvEnGrossDelay of any DIMM minus the
2683            DqsRcvEnGrossDelay of any other DIMM is equal to the Critical
2684            Gross Delay Difference (CGDD) */
2685         /* DqsRcvEn byte 1,0 */
2686         val = Get_DqsRcvEnGross_MaxMin(pDCTstat, dev, index_reg, 0x10);
2687         Largest = val & 0xFF;
2688         Smallest = (val >> 8) & 0xFF;
2689
2690         /* DqsRcvEn byte 3,2 */
2691         val = Get_DqsRcvEnGross_MaxMin(pDCTstat, dev, index_reg, 0x11);
2692         byte = val & 0xFF;
2693         bytex = (val >> 8) & 0xFF;
2694         if (bytex < Smallest)
2695                 Smallest = bytex;
2696         if (byte > Largest)
2697                 Largest = byte;
2698
2699         /* DqsRcvEn byte 5,4 */
2700         val = Get_DqsRcvEnGross_MaxMin(pDCTstat, dev, index_reg, 0x20);
2701         byte = val & 0xFF;
2702         bytex = (val >> 8) & 0xFF;
2703         if (bytex < Smallest)
2704                 Smallest = bytex;
2705         if (byte > Largest)
2706                 Largest = byte;
2707
2708         /* DqsRcvEn byte 7,6 */
2709         val = Get_DqsRcvEnGross_MaxMin(pDCTstat, dev, index_reg, 0x21);
2710         byte = val & 0xFF;
2711         bytex = (val >> 8) & 0xFF;
2712         if (bytex < Smallest)
2713                 Smallest = bytex;
2714         if (byte > Largest)
2715                 Largest = byte;
2716
2717         if (pDCTstat->DimmECCPresent> 0) {
2718                 /*DqsRcvEn Ecc */
2719                 val = Get_DqsRcvEnGross_MaxMin(pDCTstat, dev, index_reg, 0x12);
2720                 byte = val & 0xFF;
2721                 bytex = (val >> 8) & 0xFF;
2722                 if (bytex < Smallest)
2723                         Smallest = bytex;
2724                 if (byte > Largest)
2725                         Largest = byte;
2726         }
2727
2728         pDCTstat->DqsRcvEnGrossMax = Largest;
2729         pDCTstat->DqsRcvEnGrossMin = Smallest;
2730 }
2731
2732 static void Get_WrDatGross_Diff(struct DCTStatStruc *pDCTstat,
2733                                         u8 dct, u32 dev, u32 index_reg)
2734 {
2735         u8 Smallest, Largest;
2736         u32 val;
2737         u8 byte, bytex;
2738
2739         /* The largest WrDatGrossDlyByte of any DIMM minus the
2740           WrDatGrossDlyByte of any other DIMM is equal to CGDD */
2741         if (pDCTstat->DIMMValid & (1 << 0)) {
2742                 val = Get_WrDatGross_MaxMin(pDCTstat, dct, dev, index_reg, 0x01);       /* WrDatGrossDlyByte byte 0,1,2,3 for DIMM0 */
2743                 Largest = val & 0xFF;
2744                 Smallest = (val >> 8) & 0xFF;
2745         }
2746         if (pDCTstat->DIMMValid & (1 << 2)) {
2747                 val = Get_WrDatGross_MaxMin(pDCTstat, dct, dev, index_reg, 0x101);      /* WrDatGrossDlyByte byte 0,1,2,3 for DIMM1 */
2748                 byte = val & 0xFF;
2749                 bytex = (val >> 8) & 0xFF;
2750                 if (bytex < Smallest)
2751                         Smallest = bytex;
2752                 if (byte > Largest)
2753                         Largest = byte;
2754         }
2755
2756         /* If Cx, 2 more dimm need to be checked to find out the largest and smallest */
2757         if (pDCTstat->LogicalCPUID & AMD_DR_Cx) {
2758                 if (pDCTstat->DIMMValid & (1 << 4)) {
2759                         val = Get_WrDatGross_MaxMin(pDCTstat, dct, dev, index_reg, 0x201);      /* WrDatGrossDlyByte byte 0,1,2,3 for DIMM2 */
2760                         byte = val & 0xFF;
2761                         bytex = (val >> 8) & 0xFF;
2762                         if (bytex < Smallest)
2763                                 Smallest = bytex;
2764                         if (byte > Largest)
2765                                 Largest = byte;
2766                 }
2767                 if (pDCTstat->DIMMValid & (1 << 6)) {
2768                         val = Get_WrDatGross_MaxMin(pDCTstat, dct, dev, index_reg, 0x301);      /* WrDatGrossDlyByte byte 0,1,2,3 for DIMM2 */
2769                         byte = val & 0xFF;
2770                         bytex = (val >> 8) & 0xFF;
2771                         if (bytex < Smallest)
2772                                 Smallest = bytex;
2773                         if (byte > Largest)
2774                                 Largest = byte;
2775                 }
2776         }
2777
2778         pDCTstat->WrDatGrossMax = Largest;
2779         pDCTstat->WrDatGrossMin = Smallest;
2780 }
2781
2782 static u16 Get_DqsRcvEnGross_MaxMin(struct DCTStatStruc *pDCTstat,
2783                                         u32 dev, u32 index_reg,
2784                                         u32 index)
2785 {
2786         u8 Smallest, Largest;
2787         u8 i;
2788         u8 byte;
2789         u32 val;
2790         u16 word;
2791         u8 ecc_reg = 0;
2792
2793         Smallest = 7;
2794         Largest = 0;
2795
2796         if (index == 0x12)
2797                 ecc_reg = 1;
2798
2799         for (i=0; i < 8; i+=2) {
2800                 if ( pDCTstat->DIMMValid & (1 << i)) {
2801                         val = Get_NB32_index_wait(dev, index_reg, index);
2802                         val &= 0x00E000E0;
2803                         byte = (val >> 5) & 0xFF;
2804                         if (byte < Smallest)
2805                                 Smallest = byte;
2806                         if (byte > Largest)
2807                                 Largest = byte;
2808                         if (!(ecc_reg)) {
2809                                 byte = (val >> (16 + 5)) & 0xFF;
2810                                 if (byte < Smallest)
2811                                         Smallest = byte;
2812                                 if (byte > Largest)
2813                                         Largest = byte;
2814                         }
2815                 }
2816         index += 3;
2817         }       /* while ++i */
2818
2819         word = Smallest;
2820         word <<= 8;
2821         word |= Largest;
2822
2823         return word;
2824 }
2825
2826 static u16 Get_WrDatGross_MaxMin(struct DCTStatStruc *pDCTstat,
2827                                         u8 dct, u32 dev, u32 index_reg,
2828                                         u32 index)
2829 {
2830         u8 Smallest, Largest;
2831         u8 i, j;
2832         u32 val;
2833         u8 byte;
2834         u16 word;
2835
2836         Smallest = 3;
2837         Largest = 0;
2838         for (i=0; i < 2; i++) {
2839                 val = Get_NB32_index_wait(dev, index_reg, index);
2840                 val &= 0x60606060;
2841                 val >>= 5;
2842                 for (j=0; j < 4; j++) {
2843                         byte = val & 0xFF;
2844                         if (byte < Smallest)
2845                                 Smallest = byte;
2846                         if (byte > Largest)
2847                                 Largest = byte;
2848                         val >>= 8;
2849                 }       /* while ++j */
2850                 index++;
2851         }       /*while ++i*/
2852
2853         if (pDCTstat->DimmECCPresent > 0) {
2854                 index++;
2855                 val = Get_NB32_index_wait(dev, index_reg, index);
2856                 val &= 0x00000060;
2857                 val >>= 5;
2858                 byte = val & 0xFF;
2859                 if (byte < Smallest)
2860                         Smallest = byte;
2861                 if (byte > Largest)
2862                         Largest = byte;
2863         }
2864
2865         word = Smallest;
2866         word <<= 8;
2867         word |= Largest;
2868
2869         return word;
2870 }
2871
2872 static void mct_FinalMCT_D(struct MCTStatStruc *pMCTstat,
2873                                 struct DCTStatStruc *pDCTstat)
2874 {
2875         mct_ClrClToNB_D(pMCTstat, pDCTstat);
2876         mct_ClrWbEnhWsbDis_D(pMCTstat, pDCTstat);
2877 }
2878
2879 static void mct_InitialMCT_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat)
2880 {
2881         mct_SetClToNB_D(pMCTstat, pDCTstat);
2882         mct_SetWbEnhWsbDis_D(pMCTstat, pDCTstat);
2883 }
2884
2885 static u32 mct_NodePresent_D(void)
2886 {
2887         u32 val;
2888         val = 0x12001022;
2889         return val;
2890 }
2891
2892 static void mct_init(struct MCTStatStruc *pMCTstat,
2893                         struct DCTStatStruc *pDCTstat)
2894 {
2895         u32 lo, hi;
2896         u32 addr;
2897
2898         pDCTstat->GangedMode = 0;
2899         pDCTstat->DRPresent = 1;
2900
2901         /* enable extend PCI configuration access */
2902         addr = 0xC001001F;
2903         _RDMSR(addr, &lo, &hi);
2904         if (hi & (1 << (46-32))) {
2905                 pDCTstat->Status |= 1 << SB_ExtConfig;
2906         } else {
2907                 hi |= 1 << (46-32);
2908                 _WRMSR(addr, lo, hi);
2909         }
2910 }
2911
2912 static void clear_legacy_Mode(struct MCTStatStruc *pMCTstat,
2913                                 struct DCTStatStruc *pDCTstat)
2914 {
2915         u32 reg;
2916         u32 val;
2917         u32 dev = pDCTstat->dev_dct;
2918
2919         /* Clear Legacy BIOS Mode bit */
2920         reg = 0x94;
2921         val = Get_NB32(dev, reg);
2922         val &= ~(1<<LegacyBiosMode);
2923         Set_NB32(dev, reg, val);
2924
2925         reg = 0x94 + 0x100;
2926         val = Get_NB32(dev, reg);
2927         val &= ~(1<<LegacyBiosMode);
2928         Set_NB32(dev, reg, val);
2929 }
2930
2931 static void mct_HTMemMapExt(struct MCTStatStruc *pMCTstat,
2932                                 struct DCTStatStruc *pDCTstatA)
2933 {
2934         u8 Node;
2935         u32 Drambase, Dramlimit;
2936         u32 val;
2937         u32 reg;
2938         u32 dev;
2939         u32 devx;
2940         u32 dword;
2941         struct DCTStatStruc *pDCTstat;
2942
2943         pDCTstat = pDCTstatA + 0;
2944         dev = pDCTstat->dev_map;
2945
2946         /* Copy dram map from F1x40/44,F1x48/4c,
2947           to F1x120/124(Node0),F1x120/124(Node1),...*/
2948         for (Node=0; Node < MAX_NODES_SUPPORTED; Node++) {
2949                 pDCTstat = pDCTstatA + Node;
2950                 devx = pDCTstat->dev_map;
2951
2952                 /* get base/limit from Node0 */
2953                 reg = 0x40 + (Node << 3);               /* Node0/Dram Base 0 */
2954                 val = Get_NB32(dev, reg);
2955                 Drambase = val >> ( 16 + 3);
2956
2957                 reg = 0x44 + (Node << 3);               /* Node0/Dram Base 0 */
2958                 val = Get_NB32(dev, reg);
2959                 Dramlimit = val >> (16 + 3);
2960
2961                 /* set base/limit to F1x120/124 per Node */
2962                 if (pDCTstat->NodePresent) {
2963                         reg = 0x120;            /* F1x120,DramBase[47:27] */
2964                         val = Get_NB32(devx, reg);
2965                         val &= 0xFFE00000;
2966                         val |= Drambase;
2967                         Set_NB32(devx, reg, val);
2968
2969                         reg = 0x124;
2970                         val = Get_NB32(devx, reg);
2971                         val &= 0xFFE00000;
2972                         val |= Dramlimit;
2973                         Set_NB32(devx, reg, val);
2974
2975                         if ( pMCTstat->GStatus & ( 1 << GSB_HWHole)) {
2976                                 reg = 0xF0;
2977                                 val = Get_NB32(devx, reg);
2978                                 val |= (1 << DramMemHoistValid);
2979                                 val &= ~(0xFF << 24);
2980                                 dword = (pMCTstat->HoleBase >> (24 - 8)) & 0xFF;
2981                                 dword <<= 24;
2982                                 val |= dword;
2983                                 Set_NB32(devx, reg, val);
2984                         }
2985
2986                 }
2987         }
2988 }
2989
2990 static void SetCSTriState(struct MCTStatStruc *pMCTstat,
2991                                 struct DCTStatStruc *pDCTstat, u8 dct)
2992 {
2993         u32 val;
2994         u32 dev = pDCTstat->dev_dct;
2995         u32 index_reg = 0x98 + 0x100 * dct;
2996         u32 index;
2997         u16 word;
2998
2999         /* Tri-state unused chipselects when motherboard
3000            termination is available */
3001
3002         /* FIXME: skip for Ax */
3003
3004         word = pDCTstat->CSPresent;
3005         if (pDCTstat->Status & (1 << SB_Registered)) {
3006                 word |= (word & 0x55) << 1;
3007         }
3008         word = (~word) & 0xFF;
3009         index  = 0x0c;
3010         val = Get_NB32_index_wait(dev, index_reg, index);
3011         val |= word;
3012         Set_NB32_index_wait(dev, index_reg, index, val);
3013 }
3014
3015 static void SetCKETriState(struct MCTStatStruc *pMCTstat,
3016                                 struct DCTStatStruc *pDCTstat, u8 dct)
3017 {
3018         u32 val;
3019         u32 dev;
3020         u32 index_reg = 0x98 + 0x100 * dct;
3021         u32 index;
3022         u16 word;
3023
3024         /* Tri-state unused CKEs when motherboard termination is available */
3025
3026         /* FIXME: skip for Ax */
3027
3028         dev = pDCTstat->dev_dct;
3029         word = pDCTstat->CSPresent;
3030
3031         index  = 0x0c;
3032         val = Get_NB32_index_wait(dev, index_reg, index);
3033         if ((word & 0x55) == 0)
3034                 val |= 1 << 12;
3035
3036         if ((word & 0xAA) == 0)
3037                 val |= 1 << 13;
3038
3039         Set_NB32_index_wait(dev, index_reg, index, val);
3040 }
3041
3042 static void SetODTTriState(struct MCTStatStruc *pMCTstat,
3043                                 struct DCTStatStruc *pDCTstat, u8 dct)
3044 {
3045         u32 val;
3046         u32 dev;
3047         u32 index_reg = 0x98 + 0x100 * dct;
3048         u8 cs;
3049         u32 index;
3050         u8 odt;
3051         u8 max_dimms;
3052
3053         /* FIXME: skip for Ax */
3054
3055         dev = pDCTstat->dev_dct;
3056
3057         /* Tri-state unused ODTs when motherboard termination is available */
3058         max_dimms = (u8) mctGet_NVbits(NV_MAX_DIMMS);
3059         odt = 0x0F;     /* ODT tri-state setting */
3060
3061         if (pDCTstat->Status & (1 <<SB_Registered)) {
3062                 for (cs = 0; cs < 8; cs += 2) {
3063                         if (pDCTstat->CSPresent & (1 << cs)) {
3064                                 odt &= ~(1 << (cs / 2));
3065                                 if (mctGet_NVbits(NV_4RANKType) != 0) { /* quad-rank capable platform */
3066                                         if (pDCTstat->CSPresent & (1 << (cs + 1)))
3067                                                 odt &= ~(4 << (cs / 2));
3068                                 }
3069                         }
3070                 }
3071         } else {                /* AM3 package */
3072                 val = ~(pDCTstat->CSPresent);
3073                 odt = val & 9;  /* swap bits 1 and 2 */
3074                 if (val & (1 << 1))
3075                         odt |= 1 << 2;
3076                 if (val & (1 << 2))
3077                         odt |= 1 << 1;
3078         }
3079
3080         index  = 0x0C;
3081         val = Get_NB32_index_wait(dev, index_reg, index);
3082         val |= ((odt & 0xFF) << 8);     /* set bits 11:8 ODTTriState[3:0] */
3083         Set_NB32_index_wait(dev, index_reg, index, val);
3084
3085 }
3086
3087 static void InitPhyCompensation(struct MCTStatStruc *pMCTstat,
3088                                         struct DCTStatStruc *pDCTstat, u8 dct)
3089 {
3090         u8 i;
3091         u32 index_reg = 0x98 + 0x100 * dct;
3092         u32 dev = pDCTstat->dev_dct;
3093         u32 val;
3094         u32 valx = 0;
3095         u32 dword;
3096         const u8 *p;
3097
3098         val = Get_NB32_index_wait(dev, index_reg, 0x00);
3099         dword = 0;
3100         for (i=0; i < 6; i++) {
3101                 switch (i) {
3102                         case 0:
3103                         case 4:
3104                                 p = Table_Comp_Rise_Slew_15x;
3105                                 valx = p[(val >> 16) & 3];
3106                                 break;
3107                         case 1:
3108                         case 5:
3109                                 p = Table_Comp_Fall_Slew_15x;
3110                                 valx = p[(val >> 16) & 3];
3111                                 break;
3112                         case 2:
3113                                 p = Table_Comp_Rise_Slew_20x;
3114                                 valx = p[(val >> 8) & 3];
3115                                 break;
3116                         case 3:
3117                                 p = Table_Comp_Fall_Slew_20x;
3118                                 valx = p[(val >> 8) & 3];
3119                                 break;
3120
3121                 }
3122                 dword |= valx << (5 * i);
3123         }
3124
3125         /* Override/Exception */
3126         if (!pDCTstat->GangedMode) {
3127                 i = 0; /* use i for the dct setting required */
3128                 if (pDCTstat->MAdimms[0] < 4)
3129                         i = 1;
3130                 if (((pDCTstat->Speed == 2) || (pDCTstat->Speed == 3)) && (pDCTstat->MAdimms[i] == 4)) {
3131                         dword &= 0xF18FFF18;
3132                         index_reg = 0x98;       /* force dct = 0 */
3133                 }
3134         }
3135
3136         Set_NB32_index_wait(dev, index_reg, 0x0a, dword);
3137 }
3138
3139 static void mct_EarlyArbEn_D(struct MCTStatStruc *pMCTstat,
3140                                         struct DCTStatStruc *pDCTstat)
3141 {
3142         u32 reg;
3143         u32 val;
3144         u32 dev = pDCTstat->dev_dct;
3145
3146         /* GhEnhancement #18429 modified by askar: For low NB CLK :
3147          * Memclk ratio, the DCT may need to arbitrate early to avoid
3148          * unnecessary bubbles.
3149          * bit 19 of F2x[1,0]78 Dram  Control Register, set this bit only when
3150          * NB CLK : Memclk ratio is between 3:1 (inclusive) to 4:5 (inclusive)
3151          */
3152         reg = 0x78;
3153         val = Get_NB32(dev, reg);
3154
3155         if (pDCTstat->LogicalCPUID & (AMD_DR_Bx | AMD_DR_Cx))
3156                 val |= (1 << EarlyArbEn);
3157         else if (CheckNBCOFEarlyArbEn(pMCTstat, pDCTstat))
3158                 val |= (1 << EarlyArbEn);
3159
3160         Set_NB32(dev, reg, val);
3161 }
3162
3163 static u8 CheckNBCOFEarlyArbEn(struct MCTStatStruc *pMCTstat,
3164                                         struct DCTStatStruc *pDCTstat)
3165 {
3166         u32 reg;
3167         u32 val;
3168         u32 tmp;
3169         u32 rem;
3170         u32 dev = pDCTstat->dev_dct;
3171         u32  hi, lo;
3172         u8 NbDid = 0;
3173
3174         /* Check if NB COF >= 4*Memclk, if it is not, return a fatal error
3175          */
3176
3177         /* 3*(Fn2xD4[NBFid]+4)/(2^NbDid)/(3+Fn2x94[MemClkFreq]) */
3178         _RDMSR(0xC0010071, &lo, &hi);
3179         if (lo & (1 << 22))
3180                 NbDid |= 1;
3181
3182         reg = 0x94;
3183         val = Get_NB32(dev, reg);
3184         if (!(val & (1 << MemClkFreqVal)))
3185                 val = Get_NB32(dev, reg + 0x100);       /* get the DCT1 value */
3186
3187         val &= 0x07;
3188         val += 3;
3189         if (NbDid)
3190                 val <<= 1;
3191         tmp = val;
3192
3193         dev = pDCTstat->dev_nbmisc;
3194         reg = 0xD4;
3195         val = Get_NB32(dev, reg);
3196         val &= 0x1F;
3197         val += 3;
3198         val *= 3;
3199         val = val / tmp;
3200         rem = val % tmp;
3201         tmp >>= 1;
3202
3203         /* Yes this could be nicer but this was how the asm was.... */
3204         if (val < 3) {                          /* NClk:MemClk < 3:1 */
3205                 return 0;
3206         } else if (val > 4) {                   /* NClk:MemClk >= 5:1 */
3207                 return 0;
3208         } else if ((val == 4) && (rem > tmp)) { /* NClk:MemClk > 4.5:1 */
3209                 return 0;
3210         } else {
3211                 return 1;                       /* 3:1 <= NClk:MemClk <= 4.5:1*/
3212         }
3213 }
3214
3215 static void mct_ResetDataStruct_D(struct MCTStatStruc *pMCTstat,
3216                                         struct DCTStatStruc *pDCTstatA)
3217 {
3218         u8 Node;
3219         u32 i;
3220         struct DCTStatStruc *pDCTstat;
3221         u32 start, stop;
3222         u8 *p;
3223         u16 host_serv1, host_serv2;
3224
3225         /* Initialize Data structures by clearing all entries to 0 */
3226         p = (u8 *) pMCTstat;
3227         for (i = 0; i < sizeof(struct MCTStatStruc); i++) {
3228                 p[i] = 0;
3229         }
3230
3231         for (Node = 0; Node < 8; Node++) {
3232                 pDCTstat = pDCTstatA + Node;
3233                 host_serv1 = pDCTstat->HostBiosSrvc1;
3234                 host_serv2 = pDCTstat->HostBiosSrvc2;
3235
3236                 p = (u8 *) pDCTstat;
3237                 start = 0;
3238                 stop = ((u32) &((struct DCTStatStruc *)0)->CH_MaxRdLat[2]);
3239                 for (i = start; i < stop ; i++) {
3240                         p[i] = 0;
3241                 }
3242
3243                 start = ((u32) &((struct DCTStatStruc *)0)->CH_D_BC_RCVRDLY[2][4]);
3244                 stop = sizeof(struct DCTStatStruc);
3245                 for (i = start; i < stop; i++) {
3246                         p[i] = 0;
3247                 }
3248                 pDCTstat->HostBiosSrvc1 = host_serv1;
3249                 pDCTstat->HostBiosSrvc2 = host_serv2;
3250         }
3251 }
3252
3253 static void mct_BeforeDramInit_Prod_D(struct MCTStatStruc *pMCTstat,
3254                                         struct DCTStatStruc *pDCTstat)
3255 {
3256         u8 i;
3257         u32 reg_off, dword;
3258         u32 dev = pDCTstat->dev_dct;
3259
3260         if (pDCTstat->LogicalCPUID & AMD_DR_Dx) {
3261                 if ((pDCTstat->Speed == 3))
3262                         dword = 0x00000800;
3263                 else
3264                         dword = 0x00000000;
3265                 for (i=0; i < 2; i++) {
3266                         reg_off = 0x100 * i;
3267                         Set_NB32(dev,  0x98 + reg_off, 0x0D000030);
3268                         Set_NB32(dev,  0x9C + reg_off, dword);
3269                         Set_NB32(dev,  0x98 + reg_off, 0x4D040F30);
3270                 }
3271         }
3272 }
3273
3274 static u32 mct_DisDllShutdownSR(struct MCTStatStruc *pMCTstat,
3275                                 struct DCTStatStruc *pDCTstat, u32 DramConfigLo, u8 dct)
3276 {
3277         u32 reg_off = 0x100 * dct;
3278         u32 dev = pDCTstat->dev_dct;
3279
3280         /* Write 0000_07D0h to register F2x[1, 0]98_x4D0FE006 */
3281         if (pDCTstat->LogicalCPUID & (AMD_DA_C2 | AMD_RB_C3)) {
3282                 Set_NB32(dev,  0x9C + reg_off, 0x1c);
3283                 Set_NB32(dev,  0x98 + reg_off, 0x4D0FE006);
3284                 Set_NB32(dev,  0x9C + reg_off, 0x13d);
3285                 Set_NB32(dev,  0x98 + reg_off, 0x4D0FE007);
3286         }
3287
3288         return DramConfigLo | /* DisDllShutdownSR */ 1 << 27;
3289 }
3290
3291 void mct_SetClToNB_D(struct MCTStatStruc *pMCTstat,
3292                         struct DCTStatStruc *pDCTstat)
3293 {
3294         u32 lo, hi;
3295         u32 msr;
3296
3297         /* FIXME: Maybe check the CPUID? - not for now. */
3298         /* pDCTstat->LogicalCPUID; */
3299
3300         msr = BU_CFG2;
3301         _RDMSR(msr, &lo, &hi);
3302         lo |= 1 << ClLinesToNbDis;
3303         _WRMSR(msr, lo, hi);
3304 }
3305
3306 void mct_ClrClToNB_D(struct MCTStatStruc *pMCTstat,
3307                         struct DCTStatStruc *pDCTstat)
3308 {
3309
3310         u32 lo, hi;
3311         u32 msr;
3312
3313         /* FIXME: Maybe check the CPUID? - not for now. */
3314         /* pDCTstat->LogicalCPUID; */
3315
3316         msr = BU_CFG2;
3317         _RDMSR(msr, &lo, &hi);
3318         if (!pDCTstat->ClToNB_flag)
3319                 lo &= ~(1<<ClLinesToNbDis);
3320         _WRMSR(msr, lo, hi);
3321
3322 }
3323
3324 void mct_SetWbEnhWsbDis_D(struct MCTStatStruc *pMCTstat,
3325                                 struct DCTStatStruc *pDCTstat)
3326 {
3327         u32 lo, hi;
3328         u32 msr;
3329
3330         /* FIXME: Maybe check the CPUID? - not for now. */
3331         /* pDCTstat->LogicalCPUID; */
3332
3333         msr = BU_CFG;
3334         _RDMSR(msr, &lo, &hi);
3335         hi |= (1 << WbEnhWsbDis_D);
3336         _WRMSR(msr, lo, hi);
3337 }
3338
3339 void mct_ClrWbEnhWsbDis_D(struct MCTStatStruc *pMCTstat,
3340                                 struct DCTStatStruc *pDCTstat)
3341 {
3342         u32 lo, hi;
3343         u32 msr;
3344
3345         /* FIXME: Maybe check the CPUID? - not for now. */
3346         /* pDCTstat->LogicalCPUID; */
3347
3348         msr = BU_CFG;
3349         _RDMSR(msr, &lo, &hi);
3350         hi &= ~(1 << WbEnhWsbDis_D);
3351         _WRMSR(msr, lo, hi);
3352 }
3353
3354 static u32 mct_DramTermDyn_RDimm(struct MCTStatStruc *pMCTstat,
3355                                 struct DCTStatStruc *pDCTstat, u8 dimm)
3356 {
3357         u8 DimmsInstalled = dimm;
3358         u32 DramTermDyn = 0;
3359         u8 Speed = pDCTstat->Speed;
3360
3361         if (mctGet_NVbits(NV_MAX_DIMMS) == 4) {
3362                 if (pDCTstat->CSPresent & 0xF0) {
3363                         if (DimmsInstalled == 1)
3364                                 if (Speed == 7)
3365                                         DramTermDyn |= 1 << 10;
3366                                 else
3367                                         DramTermDyn |= 1 << 11;
3368                         else
3369                                 if (Speed == 4)
3370                                         DramTermDyn |= 1 << 11;
3371                                 else
3372                                         DramTermDyn |= 1 << 10;
3373                 } else {
3374                         if (DimmsInstalled != 1) {
3375                                 if (Speed == 7)
3376                                         DramTermDyn |= 1 << 10;
3377                                 else
3378                                         DramTermDyn |= 1 << 11;
3379                         }
3380                 }
3381         } else {
3382                 if (DimmsInstalled != 1)
3383                         DramTermDyn |= 1 << 11;
3384         }
3385         return DramTermDyn;
3386 }
3387
3388 void ProgDramMRSReg_D(struct MCTStatStruc *pMCTstat,
3389                                 struct DCTStatStruc *pDCTstat, u8 dct)
3390 {
3391         u32 DramMRS, dword;
3392         u8 byte;
3393
3394         DramMRS = 0;
3395
3396         /* Set chip select CKE control mode */
3397         if (mctGet_NVbits(NV_CKE_CTL)) {
3398                 if (pDCTstat->CSPresent == 3) {
3399                         u16 word;
3400                         word = pDCTstat->DIMMSPDCSE;
3401                         if (dct == 0)
3402                                 word &= 0b01010100;
3403                         else
3404                                 word &= 0b10101000;
3405                         if (word == 0)
3406                                 DramMRS |= 1 << 23;
3407                 }
3408         }
3409         /*
3410          DRAM MRS Register
3411          DrvImpCtrl: drive impedance control.01b(34 ohm driver; Ron34 = Rzq/7)
3412         */
3413         DramMRS |= 1 << 2;
3414         /* Dram nominal termination: */
3415         byte = pDCTstat->MAdimms[dct];
3416         if (!(pDCTstat->Status & (1 << SB_Registered))) {
3417                 DramMRS |= 1 << 7; /* 60 ohms */
3418                 if (byte & 2) {
3419                         if (pDCTstat->Speed < 6)
3420                                 DramMRS |= 1 << 8; /* 40 ohms */
3421                         else
3422                                 DramMRS |= 1 << 9; /* 30 ohms */
3423                 }
3424         }
3425         /* Dram dynamic termination: Disable(1DIMM), 120ohm(>=2DIMM) */
3426         if (!(pDCTstat->Status & (1 << SB_Registered))) {
3427                 if (byte >= 2) {
3428                         if (pDCTstat->Speed == 7)
3429                                 DramMRS |= 1 << 10;
3430                         else
3431                                 DramMRS |= 1 << 11;
3432                 }
3433         } else {
3434                 DramMRS |= mct_DramTermDyn_RDimm(pMCTstat, pDCTstat, byte);
3435         }
3436
3437         /* burst length control */
3438         if (pDCTstat->Status & (1 << SB_128bitmode))
3439                 DramMRS |= 1 << 1;
3440         /* Qoff=0, output buffers enabled */
3441         /* Tcwl */
3442         DramMRS |= (pDCTstat->Speed - 4) << 20;
3443         /* ASR=1, auto self refresh */
3444         /* SRT=0 */
3445         DramMRS |= 1 << 18;
3446
3447         dword = Get_NB32(pDCTstat->dev_dct, 0x100 * dct + 0x84);
3448         dword &= ~0x00FC2F8F;
3449         dword |= DramMRS;
3450         Set_NB32(pDCTstat->dev_dct, 0x100 * dct + 0x84, dword);
3451 }
3452
3453 void mct_SetDramConfigHi_D(struct DCTStatStruc *pDCTstat, u32 dct,
3454                                 u32 DramConfigHi)
3455 {
3456         /* Bug#15114: Comp. update interrupted by Freq. change can cause
3457          * subsequent update to be invalid during any MemClk frequency change:
3458          * Solution: From the bug report:
3459          *  1. A software-initiated frequency change should be wrapped into the
3460          *     following sequence :
3461          *      - a) Disable Compensation (F2[1, 0]9C_x08[30] )
3462          *      b) Reset the Begin Compensation bit (D3CMP->COMP_CONFIG[0]) in all the compensation engines
3463          *      c) Do frequency change
3464          *      d) Enable Compensation (F2[1, 0]9C_x08[30] )
3465          *  2. A software-initiated Disable Compensation should always be
3466          *     followed by step b) of the above steps.
3467          * Silicon Status: Fixed In Rev B0
3468          *
3469          * Errata#177: DRAM Phy Automatic Compensation Updates May Be Invalid
3470          * Solution: BIOS should disable the phy automatic compensation prior
3471          * to initiating a memory clock frequency change as follows:
3472          *  1. Disable PhyAutoComp by writing 1'b1 to F2x[1, 0]9C_x08[30]
3473          *  2. Reset the Begin Compensation bits by writing 32'h0 to
3474          *     F2x[1, 0]9C_x4D004F00
3475          *  3. Perform frequency change
3476          *  4. Enable PhyAutoComp by writing 1'b0 to F2x[1, 0]9C_08[30]
3477          *  In addition, any time software disables the automatic phy
3478          *   compensation it should reset the begin compensation bit per step 2.
3479          *   Silicon Status: Fixed in DR-B0
3480          */
3481
3482         u32 dev = pDCTstat->dev_dct;
3483         u32 index_reg = 0x98 + 0x100 * dct;
3484         u32 index;
3485
3486         u32 val;
3487
3488         index = 0x08;
3489         val = Get_NB32_index_wait(dev, index_reg, index);
3490         if (!(val & (1 << DisAutoComp)))
3491                 Set_NB32_index_wait(dev, index_reg, index, val | (1 << DisAutoComp));
3492
3493         mct_Wait(100);
3494
3495         Set_NB32(dev, 0x94 + 0x100 * dct, DramConfigHi);
3496 }
3497
3498 static void mct_BeforeDQSTrain_D(struct MCTStatStruc *pMCTstat,
3499                                         struct DCTStatStruc *pDCTstatA)
3500 {
3501         u8 Node;
3502         struct DCTStatStruc *pDCTstat;
3503
3504         /* Errata 178
3505          *
3506          * Bug#15115: Uncertainty In The Sync Chain Leads To Setup Violations
3507          *            In TX FIFO
3508          * Solution: BIOS should program DRAM Control Register[RdPtrInit] =
3509          *            5h, (F2x[1, 0]78[3:0] = 5h).
3510          * Silicon Status: Fixed In Rev B0
3511          *
3512          * Bug#15880: Determine validity of reset settings for DDR PHY timing.
3513          * Solutiuon: At least, set WrDqs fine delay to be 0 for DDR3 training.
3514          */
3515         for (Node = 0; Node < 8; Node++) {
3516                 pDCTstat = pDCTstatA + Node;
3517
3518                 if (pDCTstat->NodePresent)
3519                         mct_BeforeDQSTrainSamp(pDCTstat); /* only Bx */
3520                         mct_ResetDLL_D(pMCTstat, pDCTstat, 0);
3521                         mct_ResetDLL_D(pMCTstat, pDCTstat, 1);
3522         }
3523 }
3524
3525 static void mct_ResetDLL_D(struct MCTStatStruc *pMCTstat,
3526                                         struct DCTStatStruc *pDCTstat, u8 dct)
3527 {
3528         u8 Receiver;
3529         u32 dev = pDCTstat->dev_dct;
3530         u32 reg_off = 0x100 * dct;
3531         u32 addr;
3532         u32 lo, hi;
3533         u8 wrap32dis = 0;
3534         u8 valid = 0;
3535
3536         /* Skip reset DLL for B3 */
3537         if (pDCTstat->LogicalCPUID & AMD_DR_B3) {
3538                 return;
3539         }
3540
3541         addr = HWCR;
3542         _RDMSR(addr, &lo, &hi);
3543         if(lo & (1<<17)) {              /* save the old value */
3544                 wrap32dis = 1;
3545         }
3546         lo |= (1<<17);                  /* HWCR.wrap32dis */
3547         /* Setting wrap32dis allows 64-bit memory references in 32bit mode */
3548         _WRMSR(addr, lo, hi);
3549
3550         pDCTstat->Channel = dct;
3551         Receiver = mct_InitReceiver_D(pDCTstat, dct);
3552         /* there are four receiver pairs, loosely associated with chipselects.*/
3553         for (; Receiver < 8; Receiver += 2) {
3554                 if (mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, dct, Receiver)) {
3555                         addr = mct_GetRcvrSysAddr_D(pMCTstat, pDCTstat, dct, Receiver, &valid);
3556                         if (valid) {
3557                                 mct_Read1LTestPattern_D(pMCTstat, pDCTstat, addr);      /* cache fills */
3558
3559                                 /* Write 0000_8000h to register F2x[1,0]9C_xD080F0C */
3560                                 Set_NB32_index_wait(dev, 0x98 + reg_off, 0x4D080F0C, 0x00008000);
3561                                 mct_Wait(80); /* wait >= 300ns */
3562
3563                                 /* Write 0000_0000h to register F2x[1,0]9C_xD080F0C */
3564                                 Set_NB32_index_wait(dev, 0x98 + reg_off, 0x4D080F0C, 0x00000000);
3565                                 mct_Wait(800); /* wait >= 2us */
3566                                 break;
3567                         }
3568                 }
3569         }
3570
3571         if(!wrap32dis) {
3572                 addr = HWCR;
3573                 _RDMSR(addr, &lo, &hi);
3574                 lo &= ~(1<<17);         /* restore HWCR.wrap32dis */
3575                 _WRMSR(addr, lo, hi);
3576         }
3577 }
3578
3579 static void mct_EnableDatIntlv_D(struct MCTStatStruc *pMCTstat,
3580                                         struct DCTStatStruc *pDCTstat)
3581 {
3582         u32 dev = pDCTstat->dev_dct;
3583         u32 val;
3584
3585         /*  Enable F2x110[DctDatIntlv] */
3586         /* Call back not required mctHookBeforeDatIntlv_D() */
3587         /* FIXME Skip for Ax */
3588         if (!pDCTstat->GangedMode) {
3589                 val = Get_NB32(dev, 0x110);
3590                 val |= 1 << 5;                  /* DctDatIntlv */
3591                 Set_NB32(dev, 0x110, val);
3592
3593                 /* FIXME Skip for Cx */
3594                 dev = pDCTstat->dev_nbmisc;
3595                 val = Get_NB32(dev, 0x8C);      /* NB Configuration Hi */
3596                 val |= 1 << (36-32);            /* DisDatMask */
3597                 Set_NB32(dev, 0x8C, val);
3598         }
3599 }
3600
3601 static void SetDllSpeedUp_D(struct MCTStatStruc *pMCTstat,
3602                                 struct DCTStatStruc *pDCTstat, u8 dct)
3603 {
3604         u32 val;
3605         u32 dev = pDCTstat->dev_dct;
3606         u32 reg_off = 0x100 * dct;
3607
3608         if (pDCTstat->Speed >= 7) { /* DDR1600 and above */
3609                 /* Set bit13 PowerDown to register F2x[1, 0]98_x0D080F10 */
3610                 Set_NB32(dev, reg_off + 0x98, 0x0D080F10);
3611                 val = Get_NB32(dev, reg_off + 0x9C);
3612                 val |= 1 < 13;
3613                 Set_NB32(dev, reg_off + 0x9C, val);
3614                 Set_NB32(dev, reg_off + 0x98, 0x4D080F10);
3615
3616                 /* Set bit13 PowerDown to register F2x[1, 0]98_x0D080F11 */
3617                 Set_NB32(dev, reg_off + 0x98, 0x0D080F11);
3618                 val = Get_NB32(dev, reg_off + 0x9C);
3619                 val |= 1 < 13;
3620                 Set_NB32(dev, reg_off + 0x9C, val);
3621                 Set_NB32(dev, reg_off + 0x98, 0x4D080F11);
3622
3623                 /* Set bit13 PowerDown to register F2x[1, 0]98_x0D088F30 */
3624                 Set_NB32(dev, reg_off + 0x98, 0x0D088F30);
3625                 val = Get_NB32(dev, reg_off + 0x9C);
3626                 val |= 1 < 13;
3627                 Set_NB32(dev, reg_off + 0x9C, val);
3628                 Set_NB32(dev, reg_off + 0x98, 0x4D088F30);
3629
3630                 /* Set bit13 PowerDown to register F2x[1, 0]98_x0D08CF30 */
3631                 Set_NB32(dev, reg_off + 0x98, 0x0D08CF30);
3632                 val = Get_NB32(dev, reg_off + 0x9C);
3633                 val |= 1 < 13;
3634                 Set_NB32(dev, reg_off + 0x9C, val);
3635                 Set_NB32(dev, reg_off + 0x98, 0x4D08CF30);
3636
3637         }
3638 }
3639
3640 static void SyncSetting(struct DCTStatStruc *pDCTstat)
3641 {
3642         /* set F2x78[ChSetupSync] when F2x[1, 0]9C_x04[AddrCmdSetup, CsOdtSetup,
3643          * CkeSetup] setups for one DCT are all 0s and at least one of the setups,
3644          * F2x[1, 0]9C_x04[AddrCmdSetup, CsOdtSetup, CkeSetup], of the other
3645          * controller is 1
3646          */
3647         u32 cha, chb;
3648         u32 dev = pDCTstat->dev_dct;
3649         u32 val;
3650
3651         cha = pDCTstat->CH_ADDR_TMG[0] & 0x0202020;
3652         chb = pDCTstat->CH_ADDR_TMG[1] & 0x0202020;
3653
3654         if ((cha != chb) && ((cha == 0) || (chb == 0))) {
3655                 val = Get_NB32(dev, 0x78);
3656                 val |= 1 << ChSetupSync;
3657                 Set_NB32(dev, 0x78, val);
3658         }
3659 }
3660
3661 static void AfterDramInit_D(struct DCTStatStruc *pDCTstat, u8 dct) {
3662
3663         u32 val;
3664         u32 reg_off = 0x100 * dct;
3665         u32 dev = pDCTstat->dev_dct;
3666
3667         if (pDCTstat->LogicalCPUID & (AMD_DR_B2 | AMD_DR_B3)) {
3668                 mct_Wait(10000);        /* Wait 50 us*/
3669                 val = Get_NB32(dev, 0x110);
3670                 if (!(val & (1 << DramEnabled))) {
3671                         /* If 50 us expires while DramEnable =0 then do the following */
3672                         val = Get_NB32(dev, 0x90 + reg_off);
3673                         val &= ~(1 << Width128);                /* Program Width128 = 0 */
3674                         Set_NB32(dev, 0x90 + reg_off, val);
3675
3676                         val = Get_NB32_index_wait(dev, 0x98 + reg_off, 0x05);   /* Perform dummy CSR read to F2x09C_x05 */
3677
3678                         if (pDCTstat->GangedMode) {
3679                                 val = Get_NB32(dev, 0x90 + reg_off);
3680                                 val |= 1 << Width128;           /* Program Width128 = 0 */
3681                                 Set_NB32(dev, 0x90 + reg_off, val);
3682                         }
3683                 }
3684         }
3685 }
3686
3687 /* ==========================================================
3688  *  6-bit Bank Addressing Table
3689  *  RR=rows-13 binary
3690  *  B=Banks-2 binary
3691  *  CCC=Columns-9 binary
3692  * ==========================================================
3693  *  DCT CCCBRR  Rows    Banks   Columns 64-bit CS Size
3694  *  Encoding
3695  *  0000        000000  13      2       9       128MB
3696  *  0001        001000  13      2       10      256MB
3697  *  0010        001001  14      2       10      512MB
3698  *  0011        010000  13      2       11      512MB
3699  *  0100        001100  13      3       10      512MB
3700  *  0101        001101  14      3       10      1GB
3701  *  0110        010001  14      2       11      1GB
3702  *  0111        001110  15      3       10      2GB
3703  *  1000        010101  14      3       11      2GB
3704  *  1001        010110  15      3       11      4GB
3705  *  1010        001111  16      3       10      4GB
3706  *  1011        010111  16      3       11      8GB
3707  */
3708 u8 crcCheck(u8 smbaddr)
3709 {
3710         u8 byte_use;
3711         u8 Index;
3712         u16 CRC;
3713         u8 byte, i;
3714
3715         byte_use = mctRead_SPD(smbaddr, SPD_ByteUse);
3716         if (byte_use & 0x80)
3717                 byte_use = 117;
3718         else
3719                 byte_use = 126;
3720
3721         CRC = 0;
3722         for (Index = 0; Index < byte_use; Index ++) {
3723                 byte = mctRead_SPD(smbaddr, Index);
3724                 CRC ^= byte << 8;
3725                 for (i=0; i<8; i++) {
3726                         if (CRC & 0x8000) {
3727                                 CRC <<= 1;
3728                                 CRC ^= 0x1021;
3729                         } else
3730                                 CRC <<= 1;
3731                 }
3732         }
3733         return CRC == (mctRead_SPD(smbaddr, SPD_byte_127) << 8 | mctRead_SPD(smbaddr, SPD_byte_126));
3734 }