zero warnings days. Down to under 600 different warnings
[coreboot.git] / src / northbridge / via / vx800 / dev_init.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2009 One Laptop per Child, Association, 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 void DRAMSetVRNum(DRAM_SYS_ATTR *DramAttr, u8 PhyRank /* physical rank */,
21                   u8 VirRank /* virtual rank */, BOOLEAN Enable);
22 void SetEndingAddr(DRAM_SYS_ATTR *DramAttr, u8 VirRank /* Ending address
23                    register number indicator (INDEX */, INT8 Value /* (value)
24                    add or subtract value to this and after banks. */);
25 void InitDDR2CHA(DRAM_SYS_ATTR *DramAttr);
26 void InitDDR2CHB(DRAM_SYS_ATTR *DramAttr);
27 void InitDDR2CHC(DRAM_SYS_ATTR *DramAttr);
28
29 CB_STATUS VerifyChc(void);
30
31 /*===================================================================
32 Function   : DRAMRegInitValue()
33 Precondition : 
34 Input      :  
35                    DramAttr:  pointer point to  DRAM_SYS_ATTR  which consist the DDR and Dimm information
36                                     in MotherBoard
37 Output     : Void
38 Purpose   : Set necessary register before DRAM initialize
39 ===================================================================*/
40
41 static const u8 DramRegTbl[][3] = {
42         /* Reg AND   OR */
43         {0x50, 0x11, 0xEE},     // DDR default MA7 for DRAM init
44         {0x51, 0x11, 0x60},     // DDR default MA3 for CHB init
45         {0x52, 0x00, 0x33},     // DDR use BA0=M17, BA1=M18,
46         {0x53, 0x00, 0x3F},     // DDR    BA2=M19
47
48         {0x54, 0x00, 0x00},     // default PR0=VR0; PR1=VR1
49         {0x55, 0x00, 0x00},     // default PR2=VR2; PR3=VR3
50         {0x56, 0x00, 0x00},     // default PR4=VR4; PR5=VR5
51         {0x57, 0x00, 0x00},     // default PR4=VR4; PR5=VR5
52
53         {0x60, 0x00, 0x00},     // disable fast turn-around
54         {0x65, 0x00, 0xD9},     // AGP timer = 0XD; Host timer = 8;
55         {0x66, 0x00, 0x88},     // DRAMC Queue Size = 4; park at the last bus
56                                 // owner,Priority promotion timer = 8
57         {0x68, 0x00, 0x0C},
58         {0x69, 0xF0, 0x04},     // set RX69[3:0]=0000b
59         {0x6A, 0x00, 0x00},     // refresh counter
60         {0x6E, 0xF8, 0x80},     // must set 6E[7], or else DDR2 probe test
61                                 // will fail
62         /*
63          * In here, we not set RX70~RX74, because we just init DRAM but no
64          * need R/W DRAM, when we check DQS input/output delay, then we need
65          * R/W DRAM.
66          */
67
68         // {0x79, 0x00, 0x8F },
69         {0x85, 0x00, 0x00},
70         // {0x90, 0x87, 0x78 },
71         // {0x91, 0x00, 0x46 }, 
72         {0x40, 0x00, 0x00},
73
74         {0, 0, 0}
75 };
76
77 void DRAMRegInitValue(DRAM_SYS_ATTR *DramAttr)
78 {
79         u8 Idx, CL, Data;
80
81         for (Idx = 0; DramRegTbl[Idx][0] != 0; Idx++) {
82                 Data = pci_read_config8(MEMCTRL, DramRegTbl[Idx][0]);
83                 Data &= DramRegTbl[Idx][1];
84                 Data |= DramRegTbl[Idx][2];
85                 pci_write_config8(MEMCTRL, DramRegTbl[Idx][0], Data);
86         }
87
88         Data = 0x80;
89         pci_write_config8(PCI_DEV(0, 0, 4), 0xa3, Data);
90
91         // Set DRAM controller mode. */
92         Data = pci_read_config8(MEMCTRL, 0x6c);
93         Data &= 0xFB;
94         if (ENABLE_CHC == 0) {
95                 Data |= 0x4;    /* Only CHA 64 bit mode */
96                 pci_write_config8(MEMCTRL, 0x6c, Data);
97         } else {
98                 Data |= 0x0;    /* CHA + CHC */
99                 pci_write_config8(MEMCTRL, 0x6c, Data);
100
101                 // Data = 0xAA;
102                 // pci_write_config8(MEMCTRL, 0xb1, Data);
103
104                 // set CHB DQSB input delay, or else will meet error which
105                 // is some byte is right but another bit is error.
106                 Data = pci_read_config8(MEMCTRL, 0xff);
107                 Data = (Data & 0x03) | 0x3D;
108                 pci_write_config8(MEMCTRL, 0xff, Data);
109
110                 // enable CHC  RXDB[7]
111                 // Data = pci_read_config8(MEMCTRL, 0xdb);
112                 // Data = (Data & 0x7F) | 0x80;
113                 // pci_write_config8(MEMCTRL, 0xdb, Data);
114
115                 // rx62[2:0], CHA and CHB CL
116                 Data = pci_read_config8(MEMCTRL, 0x62);
117                 CL = Data & 0x07;
118
119                 // If CL = 6, so I set CHB CL = 5 default.
120                 if (CL >= 4)
121                         CL = 3;
122
123                 /* Set CHC Read CL rxDC[6:7]. */
124                 Data = pci_read_config8(MEMCTRL, 0xdc);
125                 Data = (Data & 0x3F) | (CL << 6);
126                 pci_write_config8(MEMCTRL, 0xdc, Data);
127
128                 /* Set CHC write CL rxDF[6:7]. */
129                 Data = pci_read_config8(MEMCTRL, 0xdf);
130                 Data = (Data & 0x3F) | (CL << 6);
131                 pci_write_config8(MEMCTRL, 0xdf, Data);
132
133                 /* Set CHC ODT RxDC[5:0] */
134                 Data = pci_read_config8(MEMCTRL, 0xdc);
135                 Data = (Data & 0xC0) | 0x03;
136                 pci_write_config8(MEMCTRL, 0xdc, Data);
137
138                 /* Set column type RXDD[6] and enable ODT PAD RXDD[7]. */
139                 Data = pci_read_config8(MEMCTRL, 0xdd);
140                 Data |= 0x80;
141                 Idx = DramAttr->DimmInfo[2].SPDDataBuf[SPD_SDRAM_COL_ADDR];
142                 if ((Idx & 0x0F) == 10)
143                         Data |= 0x40;   /* MA9~MA0 */
144                 else
145                         Data &= 0xBF;   /* MA8~MA0 */
146                 pci_write_config8(MEMCTRL, 0xdd, Data);
147         }
148
149         // Disable Read DRAM fast ready ;Rx51[7]
150         // Disable Read Around Write    ;Rx51[6]
151
152         // Disable Consecutive Read     ;RX52[1:0]
153         // Disable Speculative Read
154 }
155
156 /*===================================================================
157 Function   : DRAMInitializeProc()
158 Precondition : 
159 Input      :  
160                    DramAttr:  pointer point to  DRAM_SYS_ATTR  which consist the DDR and Dimm information
161                                     in MotherBoard
162 Output     : Void
163 Purpose   : DRAM initialize according to the bios porting guid
164 ===================================================================*/
165
166 #define EXIST_TEST_PATTERN              0x55555555
167 #define NOT_EXIST_TEST_PATTERN          0xAAAAAAAA
168
169 BOOLEAN ChkForExistLowBank(void)
170 {
171         u32 *Address, data32;
172
173         /* Check pattern */
174         Address = (u32 *) 8;
175         *Address = EXIST_TEST_PATTERN;
176         Address = (u32 *) 4;
177         *Address = EXIST_TEST_PATTERN;
178
179         // _asm {WBINVD}   
180         WaitMicroSec(100);
181         Address = (u32 *) 8;
182         data32 = *Address;
183         if (data32 != EXIST_TEST_PATTERN)
184                 return FALSE;
185         Address = (u32 *) 4;
186         data32 = *Address;
187         if (data32 != EXIST_TEST_PATTERN)
188                 return FALSE;
189
190         /* Check not Pattern */
191         Address = (u32 *) 8;
192         *Address = NOT_EXIST_TEST_PATTERN;
193         Address = (u32 *) 4;
194         *Address = NOT_EXIST_TEST_PATTERN;
195         // _asm {WBINVD}
196         WaitMicroSec(100);
197
198         Address = (u32 *) 8;
199         data32 = *Address;
200         if (data32 != (u32) (NOT_EXIST_TEST_PATTERN))
201                 return FALSE;
202         Address = (u32 *) 4;
203         data32 = *Address;
204         if (data32 != (u32) (NOT_EXIST_TEST_PATTERN))
205                 return FALSE;
206
207         return TRUE;
208 }
209
210 void InitDDR2CHC(DRAM_SYS_ATTR *DramAttr);
211 void InitDDR2CHB(DRAM_SYS_ATTR *DramAttr);
212
213 void DRAMInitializeProc(DRAM_SYS_ATTR *DramAttr)
214 {
215         u8 shift, idx;
216         BOOLEAN Status;
217
218         shift = 1;
219         for (idx = 0; idx < MAX_RANKS; idx++) {
220                 if ((DramAttr->RankPresentMap & shift) != 0) {
221                         /*
222                          * Set VR# to physical rank indicated = PR + physical
223                          * rank enable bit.
224                          */
225                         DRAMSetVRNum(DramAttr, idx, idx, TRUE);
226                         SetEndingAddr(DramAttr, idx, 0x10); /* Assume 1G size */
227                         if (idx < 4) /* CHA init */
228                                 InitDDR2CHA(DramAttr);  // temp wjb 2007/1 only for compiling
229                         // in the function InitDDR2,the parameter is no need   
230                         Status = ChkForExistLowBank();
231                         if (Status == TRUE) {
232                                 PRINT_DEBUG_MEM(" S\r");
233                         } else {
234                                 PRINT_DEBUG_MEM(" F\r");
235                         }
236
237                         /*
238                          * Set VR# to physical rank indicated = 00h + physical
239                          * rank enable bit.
240                          */
241                         DRAMSetVRNum(DramAttr, idx, 0, FALSE);
242                         SetEndingAddr(DramAttr, idx, -16);
243                 }
244                 shift <<= 1;
245         }
246         if (ENABLE_CHC)
247                 InitDDR2CHC(DramAttr);
248
249 }
250
251 /*===================================================================
252 Function   : DRAMSetVRNUM()
253 Precondition : 
254 Input      :  
255                    DramAttr:  pointer point to  DRAM_SYS_ATTR  which consist the DDR and Dimm information
256                                     in MotherBoard
257                   PhyRank:   Physical Rank number
258                   VirRank:    Virtual Rank number
259                   Enable:      Enable/Disable Physical Rank
260 Output     : Void
261 Purpose   : Set virtual rank number for physical rank
262                  Program the specific physical rank with specific virtual rank number
263                  Program when necessary, otherwise don't touch the pr-vr-mapping registers
264 ===================================================================*/
265
266 void DRAMSetVRNum(DRAM_SYS_ATTR *DramAttr, u8 PhyRank /* physical rank */,
267                   u8 VirRank /* virtual rank */, BOOLEAN Enable)
268 {
269         u8 Data, AndData, OrData;
270
271         Data = pci_read_config8(MEMCTRL, (0x54 + (PhyRank >> 1)));
272
273         OrData = 0;
274         if (Enable)
275                 OrData |= 0x08;
276         OrData |= VirRank;
277         if ((PhyRank & 0x01) == 0x00) {
278                 AndData = 0x0F; // keep the value of odd rank on PR # is even(keep 1,3,5,7)
279                 OrData <<= 4;   // VR #, value to be set
280         } else {
281                 AndData = 0xF0; // keep the value of even rank on PR # is odd(keep 0,2,4,6)
282         }
283
284         Data &= AndData;
285         Data |= OrData;
286         pci_write_config8(MEMCTRL, (0x54 + (PhyRank >> 1)), Data);
287 }
288
289 /*===================================================================
290 Function   : SetEndingAddr()
291 Precondition : 
292 Input      :  
293                    DramAttr:  pointer point to  DRAM_SYS_ATTR  which consist the DDR and Dimm information
294                                     in MotherBoard
295                   VirRank:    Virtual Rank number
296                   Value:       (value) add or subtract value to this and after banks 
297 Output     : Void
298 Purpose   : Set ending address of virtual rank specified by VirRank 
299 ===================================================================*/
300
301 void SetEndingAddr(DRAM_SYS_ATTR *DramAttr, u8 VirRank /* ending address
302                    register number indicator (INDEX */, INT8 Value /* (value)
303                    add or subtract value to this and after banks */) {
304         u8 Data;
305
306         /* Read register,Rx40-Rx47(0,1,2,3,4,5,6,7) and set ending address. */
307         Data = pci_read_config8(MEMCTRL, 0x40 + VirRank);
308         Data = (u8) (Data + Value);
309         pci_write_config8(MEMCTRL, 0x40 + VirRank, Data);
310
311         /* Program the virank's begining address to zero. */
312         Data = 0x00;
313         pci_write_config8(MEMCTRL, 0x48 + VirRank, Data);
314 }
315
316 /*===================================================================
317 Function   : InitDDR2()
318 Precondition : 
319 Input      :  
320                    DramAttr:  pointer point to  DRAM_SYS_ATTR  which consist the DDR and Dimm information
321                                     in MotherBoard
322 Output     : Void
323 Purpose   : Initialize DDR2 by standard sequence
324 ===================================================================*/
325
326 //                               DLL:         Enable                              Reset
327 static const u32 CHA_MRS_DLL_150[2] = { 0x00020200, 0x00000800 };       // with 150 ohm (A17=1, A9=1), (A11=1)(cpu address)
328 static const u32 CHA_MRS_DLL_75[2] = { 0x00020020, 0x00000800 };        // with 75 ohm  (A17=1, A5=1), (A11=1)(cpu address)
329
330 //               CPU(DRAM)
331 // { DLL: Enable. A17(BA0)=1 and A3(MA0)=0 }
332 // { DLL: reset.  A11(MA8)=1 }
333 //
334 //                      DDR2                    CL=2    CL=3    CL=4    CL=5     CL=6(Burst type=interleave)(WR fine tune in code)
335 static const u16 CHA_DDR2_MRS_table[5] = { 0x0150, 0x01D0, 0x0250, 0x02D0, 0x350 };     // BL=4 ;Use 1X-bandwidth MA table to init DRAM
336
337 //                                                       MA11        MA10(AP)      MA9
338 #define CHA_MRS_DDR2_TWR2               (0 << 13) + (0 << 20) + (1 << 12)       // Value = 001000h
339 #define CHA_MRS_DDR2_TWR3               (0 << 13) + (1 << 20) + (0 << 12)       // Value = 100000h
340 #define CHA_MRS_DDR2_TWR4               (0 << 13) + (1 << 20) + (1 << 12)       // Value = 101000h
341 #define CHA_MRS_DDR2_TWR5               (1 << 13) + (0 << 20) + (0 << 12)       // Value = 002000h
342 #define CHA_MRS_DDR2_TWR6               (1 << 13) + (0 << 20) + (1 << 12)       // Value = 003000h
343
344 //                              DDR2             Twr=2                  Twr=3              Twr=4                  Twr=5
345 static const u32 CHA_DDR2_Twr_table[5] = {
346         CHA_MRS_DDR2_TWR2, CHA_MRS_DDR2_TWR3, CHA_MRS_DDR2_TWR4,
347         CHA_MRS_DDR2_TWR5, CHA_MRS_DDR2_TWR6
348 };
349
350 #define CHA_OCD_Exit_150ohm             0x20200 // EMRS(1), BA0=1, MA9=MA8=MA7=0,MA6=1,MA2=0 (DRAM bus address)
351 //                A17=1, A12=A11=A10=0,A9=1 ,A5=0  (CPU address)
352 #define CHA_OCD_Default_150ohm          0x21E00 // EMRS(1), BA0=1, MA9=MA8=MA7=1,MA6=1,MA2=0 (DRAM bus address)
353 //               A17=1, A12=A11=A10=1,A9=1 ,A5=0  (CPU address)
354 #define CHA_OCD_Exit_75ohm              0x20020 // EMRS(1), BA0=1, MA9=MA8=MA7=0,MA6=0,MA2=1 (DRAM bus address)
355 //              A17=1, A12=A11=A10=0,A9=0 ,A5=1  (CPU address)
356 #define CHA_OCD_Default_75ohm           0x21C20 // EMRS(1), BA0=1, MA9=MA8=MA7=1,MA6=0,MA2=1 (DRAM bus address)
357 //              A17=1, A12=A11=A10=1,A9=0 ,A5=1  (CPU address)
358
359 void InitDDR2CHA(DRAM_SYS_ATTR *DramAttr)
360 {
361         u8 Data, Reg6BVal, Idx, CL, BL, Twr, DimmNum;
362         u32 AccessAddr;
363
364         /* Step 2 */
365         /* Disable bank paging and multi page. */
366         Data = pci_read_config8(MEMCTRL, 0x69);
367         Data &= ~0x03;
368         pci_write_config8(MEMCTRL, 0x69, Data);
369
370         Reg6BVal = pci_read_config8(MEMCTRL, 0x6b);
371         Reg6BVal &= ~0x07;
372
373         /* Step 3 */
374         /* At least one NOP cycle will be issued after the 1m sec device
375          * deselect.
376          */
377         Data = Reg6BVal | 0x01;
378         pci_write_config8(MEMCTRL, 0x6b, Data);
379
380         /* Step 4 */
381         /* Read a double word from any address of the DIMM. */
382         DimmRead(0x0);
383
384         /* Step 5 */
385         /*
386          * A minimum pause of 200u sec will be provided after the NOP.
387          * - <<<    reduce BOOT UP time >>> -
388          * Loop 200us
389          */
390         for (Idx = 0; Idx < 0x10; Idx++)
391                 WaitMicroSec(100);
392
393         // Step 6.
394         // Precharge all (PALL) will be issued to the DDR.
395         Data = Reg6BVal | 0x02;
396         pci_write_config8(MEMCTRL, 0x6b, Data);
397
398         // Step7.
399         // Read a double word from any address of the DIMM
400         DimmRead(0x0);
401
402         // Step 8.
403         // MSR Eable will be issued to the DDR
404         Data = Reg6BVal | 0x03;
405         pci_write_config8(MEMCTRL, 0x6b, Data);
406
407         /* Step 9, 10.
408          *
409          * Check ODT value for EMRS(1) command according to ODTLookUp_TBL
410          * in driving_setting.c if there is one DIMM in MB's one channel,
411          * the DDR2's ODT is 150ohm if there is two DIMM in MB's one channel,
412          * the DDR2's ODT is 75 ohm.
413          */
414         DimmNum = DramAttr->DimmNumChA;
415
416         if (DimmNum == 1) { /* DDR's ODT is 150ohm */
417                 AccessAddr = (u32) CHA_MRS_DLL_150[0];
418                 DimmRead(AccessAddr); /* Issue EMRS DLL Enable. */
419                 PRINT_DEBUG_MEM("Step 9 Address ");
420                 PRINT_DEBUG_MEM_HEX32(AccessAddr);
421                 PRINT_DEBUG_MEM("\r");
422
423                 AccessAddr = (u32) CHA_MRS_DLL_150[1];
424                 DimmRead(AccessAddr); /* Issue MRS DLL Reset. */
425                 PRINT_DEBUG_MEM("Step 10 Address ");
426                 PRINT_DEBUG_MEM_HEX32(AccessAddr);
427                 PRINT_DEBUG_MEM("\r");
428         } else if (DimmNum == 2) { /* DDR's ODT is 75ohm */
429                 AccessAddr = (u32) CHA_MRS_DLL_75[0];
430                 DimmRead(AccessAddr); /* Issue EMRS DLL Enable. */
431                 AccessAddr = (u32) CHA_MRS_DLL_75[1];
432                 DimmRead(AccessAddr); /* Issue MRS DLL Reset. */
433         } else {
434                 PRINT_DEBUG_MEM("Dimm NUM ERROR:");
435                 PRINT_DEBUG_MEM_HEX8(DimmNum);
436                 PRINT_DEBUG_MEM("\r");
437         }
438
439         /* Step 11. Precharge all (PALL) will be issued to the DDR. */
440         Data = Reg6BVal | 0x02;
441         pci_write_config8(MEMCTRL, 0x6b, Data);
442
443         /* Step 12. Read a double word from any address of the DIMM. */
444         DimmRead(0x0);
445
446         /* Step 13. Execute 8 CBR refresh. */
447         Data = Reg6BVal | 0x04;
448         pci_write_config8(MEMCTRL, 0x6b, Data);
449
450         // issue 14,15 , 16
451         //reads and wait 100us between each read
452         for (Idx = 0; Idx < 8; Idx++) {
453                 DimmRead(0x0);
454                 WaitMicroSec(100);
455         }
456
457         /* Step 17. Enable MRS for MAA. */
458         Data = Reg6BVal | 0x03;
459         pci_write_config8(MEMCTRL, 0x6b, Data);
460
461         /*
462          * Step 18. The SDRAM parameters (Burst Length, CAS# Latency,
463          * Write recovery etc.)
464          */
465
466         /* Burst Length: really offset Rx6c[3] */
467         Data = pci_read_config8(MEMCTRL, 0x6c);
468         BL = (Data & 0x08) >> 3;
469
470         /* CL: really offset RX62[2:0] */
471         Data = pci_read_config8(MEMCTRL, 0x62);
472         CL = Data & 0x03;
473
474         AccessAddr = (u32) (CHA_DDR2_MRS_table[CL]);
475         if (BL)
476                 AccessAddr += 8;
477
478         /* Write recovery: really offset Rx63[7-5] */
479         Data = pci_read_config8(MEMCTRL, 0x63);
480         Twr = (Data & 0xE0) >> 5;
481
482         AccessAddr += CHA_DDR2_Twr_table[Twr];
483         // AccessAddr = 0x1012D8;
484         DimmRead(AccessAddr); /* Set MRS command. */
485         PRINT_DEBUG_MEM("Step 18 Address");
486         PRINT_DEBUG_MEM_HEX32(AccessAddr);
487         PRINT_DEBUG_MEM("\r");
488
489         /* Step 19, 20 */
490         if (DimmNum == 1) { /* DDR's ODT is 150ohm */
491                 AccessAddr = (u32) CHA_OCD_Default_150ohm;
492                 DimmRead(AccessAddr);   /* Issue EMRS OCD Default. */
493                 PRINT_DEBUG_MEM("Step 19 Address ");
494                 PRINT_DEBUG_MEM_HEX32(AccessAddr);
495                 PRINT_DEBUG_MEM("\r");
496
497                 AccessAddr = (u32) CHA_OCD_Exit_150ohm;
498                 DimmRead(AccessAddr); /* Issue EMRS OCD Calibration Mode Exit. */
499                 PRINT_DEBUG_MEM("Step 20 Address ");
500                 PRINT_DEBUG_MEM_HEX32(AccessAddr);
501                 PRINT_DEBUG_MEM("\r");
502         } else if (DimmNum == 2) { /* DDR's ODT is 75ohm */
503                 AccessAddr = (u32) CHA_OCD_Default_75ohm;
504                 DimmRead(AccessAddr); /* Issue EMRS OCD Default. */
505                 AccessAddr = (u32) CHA_OCD_Exit_75ohm;
506                 DimmRead(AccessAddr); /* Issue EMRS OCD Calibration Mode Exit. */
507         } else {
508                 PRINT_DEBUG_MEM("Dimm NUM ERROR: ");
509                 PRINT_DEBUG_MEM_HEX8(DimmNum);
510                 PRINT_DEBUG_MEM("\r");
511         }
512
513         /*
514          * Step 21. After MRS the device should be ready for full
515          * functionality within 3 clocks after Tmrd is met.
516          */
517         Data = Reg6BVal;
518         pci_write_config8(MEMCTRL, 0x6b, Data);
519
520         /* Enable bank paging and multi page. */
521         Data = pci_read_config8(MEMCTRL, 0x69);
522         Data |= 0x03;
523         pci_write_config8(MEMCTRL, 0x69, Data);
524 }
525
526 /*===================================================================
527 Function   : InitDDR2_CHB()
528 Precondition : 
529 Input      :  
530                    DramAttr:  pointer point to  DRAM_SYS_ATTR  which consist the DDR and Dimm information
531                                     in MotherBoard
532 Output     : Void
533 Purpose   : Initialize DDR2 of CHB by standard sequence
534 Reference  : 
535 ===================================================================*/
536 /*//                             DLL:         Enable                              Reset
537 static const  u32 CHB_MRS_DLL_150[2] =  { 0x00020200 | (1 << 20), 0x00000800 }; // with 150 ohm (A17=1, A9=1), (A11=1)(cpu address)
538 //u32 CHB_MRS_DLL_75[2]  =      { 0x00020020 | (1 << 20), 0x00000800 }; // with 75 ohm  (A17=1, A5=1), (A11=1)(cpu address)
539 //               CPU(DRAM)
540 // { DLL: Enable. A17(BA0)=1 and A3(MA0)=0 }
541 // { DLL: reset.  A11(MA8)=1 }
542 //
543 //                      DDR2                    CL=2    CL=3    CL=4    CL=5    (Burst type=interleave)(WR fine tune in code)
544 static const  u16 CHB_DDR2_MRS_table[4] ={ 0x0150, 0x01D0, 0x0250, 0x02D0 };    // BL=4 ;Use 1X-bandwidth MA table to init DRAM
545
546 //                                                       MA11        MA10(AP)      MA9
547 #define CHB_MRS_DDR2_TWR2               (0 << 13) + (0 << 20) + (1 << 12)       // Value = 001000h
548 #define CHB_MRS_DDR2_TWR3               (0 << 13) + (1 << 20) + (0 << 12)       // Value = 100000h
549 #define CHB_MRS_DDR2_TWR4               (0 << 13) + (1 << 20) + (1 << 12)       // Value = 101000h
550 #define CHB_MRS_DDR2_TWR5               (1 << 13) + (0 << 20) + (0 << 12)       // Value = 002000h
551 #define CHB_MRS_DDR2_TWR6               (1 << 13) + (0 << 20) + (1 << 12)       // Value = 003000h
552
553 //                              DDR2             Twr=2                  Twr=3              Twr=4                  Twr=5
554 static const u32 CHB_DDR2_Twr_table[5] = { CHB_MRS_DDR2_TWR2,   CHB_MRS_DDR2_TWR3, CHB_MRS_DDR2_TWR4, CHB_MRS_DDR2_TWR5, CHB_MRS_DDR2_TWR6 };
555
556 #define CHB_OCD_Exit_150ohm             0x20200 | (1 << 20)              // EMRS(1), BA0=1, MA9=MA8=MA7=0,MA6=1,MA2=0 (DRAM bus address)
557 //                A17=1, A12=A11=A10=0,A9=1 ,A5=0  (CPU address)
558 #define CHB_OCD_Default_150ohm  0x21E00 | (1 << 20)             // EMRS(1), BA0=1, MA9=MA8=MA7=1,MA6=1,MA2=0 (DRAM bus address)
559 //               A17=1, A12=A11=A10=1,A9=1 ,A5=0  (CPU address)
560 //#define CHB_OCD_Exit_75ohm            0x20020 | (1 << 20)           // EMRS(1), BA0=1, MA9=MA8=MA7=0,MA6=0,MA2=1 (DRAM bus address)
561 //              A17=1, A12=A11=A10=0,A9=0 ,A5=1  (CPU address)
562 //#define CHB_OCD_Default_75ohm 0x21C20 | (1 << 20)      // EMRS(1), BA0=1, MA9=MA8=MA7=1,MA6=0,MA2=1 (DRAM bus address)
563 //              A17=1, A12=A11=A10=1,A9=0 ,A5=1  (CPU address)
564 void InitDDR2CHB(
565                DRAM_SYS_ATTR          *DramAttr
566              )
567
568 {
569     u8     Data;
570     u8      Idx, CL, BL, Twr;
571     u32   AccessAddr;
572
573     Data = 0x80;
574     pci_write_config8(MEMCTRL, 0x54, Data);
575         
576     // step3.
577     //disable bank paging and multi page
578     Data=pci_read_config8(MEMCTRL, 0x69);
579     Data &= ~0x03;
580     pci_write_config8(MEMCTRL, 0x69, Data);
581
582     Data=pci_read_config8(MEMCTRL, 0xd3);
583     Data |= 0x80;
584     pci_write_config8(MEMCTRL, 0xd3, Data);
585         
586     //step 4. Initialize CHB begin
587     Data=pci_read_config8(MEMCTRL, 0xd3);
588     Data |= 0x40;
589     pci_write_config8(MEMCTRL, 0xd3, Data);
590         
591     //Step 5. NOP command enable
592     Data=pci_read_config8(MEMCTRL, 0xd7);
593     Data &= 0xC7;
594     Data  |= 0x08;
595     pci_write_config8(MEMCTRL, 0xd7, Data);
596    
597     //Step 6.  issue a nop cycle,RegD3[7]  0 -> 1
598     Data=pci_read_config8(MEMCTRL, 0xd3);
599     Data &= 0x7F;
600     pci_write_config8(MEMCTRL, 0xd3, Data);
601     Data |=  0x80;
602     pci_write_config8(MEMCTRL, 0xd3, Data);
603
604     // Step 7.
605     // A minimum pause of 200u sec will be provided after the NOP.
606     // - <<<    reduce BOOT UP time >>> -
607     // Loop 200us
608     for (Idx = 0; Idx < 0x10; Idx++)
609         WaitMicroSec(10);
610         
611     // Step 8.
612     // all banks precharge command enable
613     Data=pci_read_config8(MEMCTRL, 0xd7);
614     Data &= 0xC7;
615     Data |= 0x10;
616     pci_write_config8(MEMCTRL, 0xd7, Data);
617
618    //step 9. issue a precharge all cycle,RegD3[7]  0 -> 1
619     Data=pci_read_config8(MEMCTRL, 0xd3);
620     Data &= 0x7F;
621     pci_write_config8(MEMCTRL, 0xd3, Data);
622     Data |=  0x80;
623     pci_write_config8(MEMCTRL, 0xd3, Data);
624         
625    //step10. EMRS enable
626     Data=pci_read_config8(MEMCTRL, 0xd7);
627     Data &= 0xC7;
628     Data |= 0x18;
629     pci_write_config8(MEMCTRL, 0xd7, Data);
630
631     Data=pci_read_config8(MEMCTRL, 0xd3);
632     Data &= 0xC7;
633     Data |= 0x08;
634     pci_write_config8(MEMCTRL, 0xd3, Data);
635
636     //step11. EMRS DLL Enable and Disable DQS
637     AccessAddr = CHB_MRS_DLL_150[0] >> 3;
638     Data =(u8) (AccessAddr & 0xff);
639     pci_write_config8(MEMCTRL, 0xd9, Data);
640
641     Data = (u8)((AccessAddr & 0xff00) >> 8);
642     pci_write_config8(MEMCTRL, 0xda, Data);
643
644     Data=pci_read_config8(MEMCTRL, 0xd7);
645     Data &= 0xF9;
646     Data |= (u8)((AccessAddr & 0x30000) >> 15);
647     pci_write_config8(MEMCTRL, 0xd7, Data);
648
649     //step12.  issue EMRS cycle
650     Data=pci_read_config8(MEMCTRL, 0xd3);
651     Data &= 0x7F;
652     pci_write_config8(MEMCTRL, 0xd3, Data);
653     Data |=  0x80;
654     pci_write_config8(MEMCTRL, 0xd3, Data);
655
656     //step13. MSR enable
657     Data=pci_read_config8(MEMCTRL, 0xd7);
658     Data &= 0xC7;
659     Data |= 0x18;
660     pci_write_config8(MEMCTRL, 0xd7, Data);
661
662     Data=pci_read_config8(MEMCTRL, 0xd3);
663     Data &= 0xC7;
664     Data |= 0x00;
665     pci_write_config8(MEMCTRL, 0xd3, Data);
666
667     //step 14. MSR DLL Reset 
668     AccessAddr = CHB_MRS_DLL_150[1] >> 3;
669     Data =(u8) (AccessAddr & 0xff);
670     pci_write_config8(MEMCTRL, 0xd9, Data);
671
672     Data = (u8)((AccessAddr & 0xff00) >> 8);
673     pci_write_config8(MEMCTRL, 0xda, Data);
674
675     Data=pci_read_config8(MEMCTRL, 0xd7);
676     Data &= 0xF9;
677     Data |= (u8)((AccessAddr & 0x30000) >> 15);
678     pci_write_config8(MEMCTRL, 0xd7, Data);
679
680     //step15.  issue MRS cycle
681     Data=pci_read_config8(MEMCTRL, 0xd3);
682     Data &= 0x7F;
683     pci_write_config8(MEMCTRL, 0xd3, Data);
684     Data |=  0x80;
685     pci_write_config8(MEMCTRL, 0xd3, Data);
686
687     //clear the address
688     Data = 0x00;
689     pci_write_config8(MEMCTRL, 0xda, Data);
690
691      //step16.  all banks precharge command enable
692     Data=pci_read_config8(MEMCTRL, 0xd7);
693     Data &= 0xC7;
694     Data |= 0x10;
695     pci_write_config8(MEMCTRL, 0xd7, Data);
696
697    
698    // step17. issue precharge all cycle
699     Data=pci_read_config8(MEMCTRL, 0xd3);
700     Data &= 0x7F;
701     pci_write_config8(MEMCTRL, 0xd3, Data);
702     Data |=  0x80;
703     pci_write_config8(MEMCTRL, 0xd3, Data);
704
705     //step18.  CBR cycle enable
706     Data=pci_read_config8(MEMCTRL, 0xd7);
707     Data &= 0xC7;
708     Data |= 0x20;
709     pci_write_config8(MEMCTRL, 0xd7, Data);
710
711     //step 19.20.21
712     //repeat issue 8 CBR cycle, between each cycle stop 100us
713     for (Idx = 0; Idx < 8; Idx++)
714     {
715          // issue CBR cycle
716     Data=pci_read_config8(MEMCTRL, 0xd3);
717     Data &= 0x7F;
718     pci_write_config8(MEMCTRL, 0xd3, Data);
719     Data |=  0x80;
720     pci_write_config8(MEMCTRL, 0xd3, Data);
721
722     WaitMicroSec(200);
723     }
724         
725     //step22. MSR enable
726     Data=pci_read_config8(MEMCTRL, 0xd7);
727     Data &= 0xC7;
728     Data |= 0x18;
729     pci_write_config8(MEMCTRL, 0xd7, Data);
730
731     Data=pci_read_config8(MEMCTRL, 0xd3);
732     Data &= 0xC7;
733     Data |= 0x00;
734     pci_write_config8(MEMCTRL, 0xd3, Data);
735
736   
737     //the SDRAM parameters.(Burst Length, CAS# Latency , Write recovery etc.)
738     //-------------------------------------------------------------
739     //Burst Length : really offset Rx6c[1]
740     Data=pci_read_config8(MEMCTRL, 0x6C);
741     BL = (Data & 0x02) >> 1;
742
743     // CL = really offset RX62[2:0]
744     Data=pci_read_config8(MEMCTRL, 0x62);
745     CL = Data & 0x03;
746
747     AccessAddr  = (u32)(CHB_DDR2_MRS_table[CL]);
748     if (BL)
749     {
750         AccessAddr += 8;
751     }
752
753     //Write recovery  : really offset Rx63[7:5]
754     Data=pci_read_config8(MEMCTRL, 0x63);
755     Twr = (Data & 0xE0) >> 5;
756
757     AccessAddr += CHB_DDR2_Twr_table[Twr];
758     //MSR Address use addr[20:3]
759     AccessAddr >>= 3;
760
761    //step 23. MSR command
762     Data = (u8)(AccessAddr & 0xFF);
763     pci_write_config8(MEMCTRL, 0xD9, Data);
764
765     Data = (u8)((AccessAddr & 0xFF00) >> 8);
766     pci_write_config8(MEMCTRL, 0xda, Data);
767
768     Data=pci_read_config8(MEMCTRL, 0xd7);
769     Data &= 0xF9;
770     Data |= (u8)(((AccessAddr & 0x30000)>>16) << 1);
771     pci_write_config8(MEMCTRL, 0xd7, Data);
772
773      //step 24.  issue MRS cycle
774     Data=pci_read_config8(MEMCTRL, 0xd3);
775     Data &= 0x7F;
776     pci_write_config8(MEMCTRL, 0xd3, Data);
777     Data |=  0x80;
778     pci_write_config8(MEMCTRL, 0xd3, Data);
779         
780     //step 25. EMRS enable
781     Data=pci_read_config8(MEMCTRL, 0xd7);
782     Data &= 0xC7;
783     Data |= 0x18;
784     pci_write_config8(MEMCTRL, 0xd7, Data);
785
786     Data=pci_read_config8(MEMCTRL, 0xd3);
787     Data &= 0xC7;
788     Data |= 0x08;
789     pci_write_config8(MEMCTRL, 0xd3, Data);
790         
791
792     //step 26. OCD default
793      AccessAddr = (CHB_OCD_Default_150ohm) >> 3;
794     Data =(u8) (AccessAddr & 0xff);
795     pci_write_config8(MEMCTRL, 0xd9, Data);
796
797     Data = (u8)((AccessAddr & 0xff00) >> 8);
798     pci_write_config8(MEMCTRL, 0xda, Data);
799
800     Data=pci_read_config8(MEMCTRL, 0xd7);
801     Data &= 0xF9;
802     Data |= (u8)((AccessAddr & 0x30000) >> 15);
803     pci_write_config8(MEMCTRL, 0xd7, Data);
804
805     //step 27.  issue EMRS cycle
806     Data=pci_read_config8(MEMCTRL, 0xd3);
807     Data &= 0x7F;
808     pci_write_config8(MEMCTRL, 0xd3, Data);
809     Data |=  0x80;
810     pci_write_config8(MEMCTRL, 0xd3, Data);
811         
812      //step 25. EMRS enable
813     Data=pci_read_config8(MEMCTRL, 0xd7);
814     Data &= 0xC7;
815     Data |= 0x18;
816     pci_write_config8(MEMCTRL, 0xd7, Data);
817
818     Data=pci_read_config8(MEMCTRL, 0xd3);
819     Data &= 0xC7;
820     Data |= 0x08;
821     pci_write_config8(MEMCTRL, 0xd3, Data);
822
823     //step 28. OCD Exit
824      AccessAddr = (CHB_OCD_Exit_150ohm) >> 3;
825      Data =(u8) (AccessAddr & 0xff);
826     pci_write_config8(MEMCTRL, 0xd9, Data);
827
828     Data = (u8)((AccessAddr & 0xff00) >> 8);
829     pci_write_config8(MEMCTRL, 0xda, Data);
830
831     Data=pci_read_config8(MEMCTRL, 0xd7);
832     Data &= 0xF9;
833     Data |= (u8)((AccessAddr & 0x30000) >> 15);
834     pci_write_config8(MEMCTRL, 0xd7, Data);
835
836      //step 29. issue EMRS cycle
837     Data=pci_read_config8(MEMCTRL, 0xd3);
838     Data &= 0x7F;
839     pci_write_config8(MEMCTRL, 0xd3, Data);
840     Data |=  0x80;
841     pci_write_config8(MEMCTRL, 0xd3, Data);
842
843     //clear  all the address
844     Data = 0x00;
845     pci_write_config8(MEMCTRL, 0xd9, Data);
846
847     Data = 0x00;
848     pci_write_config8(MEMCTRL, 0xda, Data);
849
850     Data=pci_read_config8(MEMCTRL, 0xd7);
851     Data &= 0xF9;
852     pci_write_config8(MEMCTRL, 0xd7, Data);
853
854     //step 30. normal SDRAM Mode
855     Data=pci_read_config8(MEMCTRL, 0xd7);
856     Data &= 0xC7;
857     Data |= 0x00;
858     pci_write_config8(MEMCTRL, 0xd7, Data);
859
860     Data=pci_read_config8(MEMCTRL, 0xd3);
861     Data &= 0xC7;
862     Data |= 0x00;
863     pci_write_config8(MEMCTRL, 0xd3, Data);
864
865     //step 31.  exit the initialization mode 
866     Data=pci_read_config8(MEMCTRL, 0xd3);
867     Data &= 0xBF;
868     pci_write_config8(MEMCTRL, 0xd3, Data);
869
870         
871     //step 32. Enable bank paging and multi page
872     Data=pci_read_config8(MEMCTRL, 0x69);
873     Data |= 0x03;
874     pci_write_config8(MEMCTRL, 0x69, Data);
875 }
876 */
877
878 /*===================================================================
879 Function   : InitDDR2CHC()
880 Precondition : 
881 Input      :  
882                    DramAttr:  pointer point to  DRAM_SYS_ATTR  which consist the DDR and Dimm information
883                                     in MotherBoard
884 Output     : Void
885 Purpose   : Initialize DDR2 of CHC by standard sequence
886 Reference  : 
887 ===================================================================*/
888 //                      DDR2                 CL=2          CL=3 CL=4   CL=5     (Burst type=interleave)(WR fine tune in code)
889 static const u16 CHC_MRS_table[4] = { 0x22B, 0x23B, 0x24B, 0x25B };     // Use 1X-bandwidth MA table to init DRAM
890
891 void InitDDR2CHC(DRAM_SYS_ATTR *DramAttr)
892 {
893         u8 Data, Idx, CL, Twr;
894         u32 AccessAddr;
895         CB_STATUS Status;
896
897         /* Step 3. Clear RxDF[2] to disable Tri-state output. */
898         Data = pci_read_config8(MEMCTRL, 0xdf);
899         Data &= 0xFB;
900         pci_write_config8(MEMCTRL, 0xdf, Data);
901
902         /*
903          * Step 4. Enable the initialization mode of DRAM Controller C with
904          * NB's PLL clock.
905          */
906         Data = pci_read_config8(MEMCTRL, 0xdb);
907         Data |= 0x60;
908         pci_write_config8(MEMCTRL, 0xdb, Data);
909
910         /* Step 5. NOP command enable. */
911         Data = pci_read_config8(MEMCTRL, 0xdb);
912         Data &= 0xE3;
913         Data |= 0x00;
914         pci_write_config8(MEMCTRL, 0xdb, Data);
915
916         /* Step 6. Issue a nop cycle, RegDB[1] 0 -> 1. */
917         Data = pci_read_config8(MEMCTRL, 0xdb);
918         Data |= 0x2;
919         pci_write_config8(MEMCTRL, 0xdb, Data);
920         Data &= 0xFD;
921         pci_write_config8(MEMCTRL, 0xdb, Data);
922
923         /*
924          * Step 7.
925          * A minimum pause of 200u sec will be provided after the NOP.
926          * - <<<    reduce BOOT UP time >>> -
927          * Loop 200us
928          */
929         for (Idx = 0; Idx < 0x10; Idx++)
930                 WaitMicroSec(100);
931
932         /* Step 8. Signal bank precharge command enable. */
933         Data = pci_read_config8(MEMCTRL, 0xdb);
934         Data &= 0xE3;
935         Data |= 0x14;
936         pci_write_config8(MEMCTRL, 0xdb, Data);
937
938         /* Set MA10 = 1, precharge all bank. */
939         Data = 0x00;
940         pci_write_config8(MEMCTRL, 0xf8, Data);
941
942         Data = 0x04;
943         pci_write_config8(MEMCTRL, 0xf9, Data);
944
945         /* step 9. Issue a precharge all cycle, RegD3[7] 0 -> 1. */
946         Data = pci_read_config8(MEMCTRL, 0xdb);
947         Data |= 0x2;
948         pci_write_config8(MEMCTRL, 0xdb, Data);
949         Data &= 0xFD;
950         pci_write_config8(MEMCTRL, 0xdb, Data);
951
952         /* Step 10. MRS enable. */
953         Data = pci_read_config8(MEMCTRL, 0xdb);
954         Data &= 0xE3;
955         Data |= 0x1C;
956         pci_write_config8(MEMCTRL, 0xdb, Data);
957
958         /* Step 11. EMRS DLL enable and Disable DQS. */
959         Data = 0x40;
960         pci_write_config8(MEMCTRL, 0xf8, Data);
961
962         Data = 0x24;
963         pci_write_config8(MEMCTRL, 0xf9, Data);
964
965         /* Step 12. Issue EMRS cycle. */
966         Data = pci_read_config8(MEMCTRL, 0xdb);
967         Data |= 0x2;
968         pci_write_config8(MEMCTRL, 0xdb, Data);
969         Data &= 0xFD;
970         pci_write_config8(MEMCTRL, 0xdb, Data);
971
972         /* Step 13. MSR enable. */
973         Data = pci_read_config8(MEMCTRL, 0xdb);
974         Data &= 0xE3;
975         Data |= 0x1C;
976         pci_write_config8(MEMCTRL, 0xdb, Data);
977
978         /* Step 14. MSR DLL Reset. */
979         Data = 0x00;
980         pci_write_config8(MEMCTRL, 0xf8, Data);
981
982         Data = 0x01;
983         pci_write_config8(MEMCTRL, 0xf9, Data);
984
985         /* Step 15. Issue MRS cycle. */
986         Data = pci_read_config8(MEMCTRL, 0xdb);
987         Data |= 0x2;
988         pci_write_config8(MEMCTRL, 0xdb, Data);
989         Data &= 0xFD;
990         pci_write_config8(MEMCTRL, 0xdb, Data);
991
992         /* Step 16. Signal banks precharge command enable. */
993         Data = pci_read_config8(MEMCTRL, 0xdb);
994         Data &= 0xE3;
995         Data |= 0x14;
996         pci_write_config8(MEMCTRL, 0xdb, Data);
997
998         /* Set MA10 = 1, precharge all bank. */
999         Data = 0x00;
1000         pci_write_config8(MEMCTRL, 0xf8, Data);
1001
1002         Data = 0x04;
1003         pci_write_config8(MEMCTRL, 0xf9, Data);
1004
1005         /* Step 17. Issue precharge all cycle. */
1006         Data = pci_read_config8(MEMCTRL, 0xdb);
1007         Data |= 0x2;
1008         pci_write_config8(MEMCTRL, 0xdb, Data);
1009         Data &= 0xFD;
1010         pci_write_config8(MEMCTRL, 0xdb, Data);
1011
1012         /* Step 18. CBR cycle enable. */
1013         Data = pci_read_config8(MEMCTRL, 0xdb);
1014         Data &= 0xE3;
1015         Data |= 0x18;
1016         pci_write_config8(MEMCTRL, 0xdb, Data);
1017
1018         Data = 0x00;
1019         pci_write_config8(MEMCTRL, 0xf8, Data);
1020
1021         Data = 0x00;
1022         pci_write_config8(MEMCTRL, 0xf9, Data);
1023
1024         //step 19.20.21
1025         //repeat issue 8 CBR cycle, between each cycle stop 100us
1026         for (Idx = 0; Idx < 8; Idx++) {
1027                 // issue CBR cycle
1028                 Data = pci_read_config8(MEMCTRL, 0xdb);
1029                 Data |= 0x2;
1030                 pci_write_config8(MEMCTRL, 0xdb, Data);
1031                 Data &= 0xFD;
1032                 pci_write_config8(MEMCTRL, 0xdb, Data);
1033                 WaitMicroSec(100);
1034         }
1035
1036         //the SDRAM parameters.(, CAS# Latency , Write recovery etc.)
1037         //------------------------------------------------------------
1038
1039         // CL = really offset RXDC[7:6]
1040         Data = pci_read_config8(MEMCTRL, 0xdc);
1041         CL = (Data & 0xC0) >> 6;
1042
1043         AccessAddr = (u32) (CHC_MRS_table[CL]);
1044
1045         //Write recovery  : really offset Rx63[7:5]
1046         Data = pci_read_config8(MEMCTRL, 0x63);
1047         Twr = (Data & 0xE0) >> 5;
1048
1049         AccessAddr += Twr * 0x200;
1050
1051         //step22. MSR enable
1052         Data = pci_read_config8(MEMCTRL, 0xdb);
1053         Data &= 0xE3;
1054         Data |= 0x1C;
1055         pci_write_config8(MEMCTRL, 0xdb, Data);
1056
1057         //step 23. MSR command
1058         Data = (u8) (AccessAddr & 0xFF);
1059         pci_write_config8(MEMCTRL, 0xf8, Data);
1060
1061         Data = (u8) ((AccessAddr & 0xFF00) >> 8);
1062         pci_write_config8(MEMCTRL, 0xf9, Data);
1063
1064         //step 24.  issue MRS cycle
1065         Data = pci_read_config8(MEMCTRL, 0xdb);
1066         Data |= 0x2;
1067         pci_write_config8(MEMCTRL, 0xdb, Data);
1068         Data &= 0xFD;
1069         pci_write_config8(MEMCTRL, 0xdb, Data);
1070
1071         //step 25. EMRS enable
1072         Data = pci_read_config8(MEMCTRL, 0xdb);
1073         Data &= 0xE3;
1074         Data |= 0x1C;
1075         pci_write_config8(MEMCTRL, 0xdb, Data);
1076
1077         //step 26. OCD default
1078         Data = 0xC0;
1079         pci_write_config8(MEMCTRL, 0xf8, Data);
1080
1081         Data = 0x27;
1082         pci_write_config8(MEMCTRL, 0xf9, Data);
1083
1084         //step 27.  issue EMRS cycle
1085         Data = pci_read_config8(MEMCTRL, 0xdb);
1086         Data |= 0x2;
1087         pci_write_config8(MEMCTRL, 0xdb, Data);
1088         Data &= 0xFD;
1089         pci_write_config8(MEMCTRL, 0xdb, Data);
1090
1091         //step 28. OCD Exit
1092         Data = 0x40;
1093         pci_write_config8(MEMCTRL, 0xf8, Data);
1094
1095         Data = 0x24;
1096         pci_write_config8(MEMCTRL, 0xf9, Data);
1097
1098         //step 29. issue EMRS cycle
1099         Data = pci_read_config8(MEMCTRL, 0xdb);
1100         Data |= 0x2;
1101         pci_write_config8(MEMCTRL, 0xdb, Data);
1102         Data &= 0xFD;
1103         pci_write_config8(MEMCTRL, 0xdb, Data);
1104
1105         Status = VerifyChc();
1106         if (Status != CB_SUCCESS)
1107                 PRINT_DEBUG_MEM("Error!!!!CHC init error!\r");
1108         //step 31.  exit the initialization mode 
1109         Data = pci_read_config8(MEMCTRL, 0xdb);
1110         Data &= 0x9F;
1111         pci_write_config8(MEMCTRL, 0xdb, Data);
1112 }
1113
1114 CB_STATUS VerifyChc(void)
1115 {
1116         u8 Data, ByteVal, Index, pad;
1117         u16 row;
1118
1119         //first write the pad to all the address
1120
1121         //the  row bits is 13 and  rank bit is 2, so the  address bits is 15 and the value is 0x7fff
1122         //verify each MA[0:12],BA[0:1]
1123         pad = 1;
1124         for (row = 0; row < 0x8000; row++) {
1125                 /* Set the write value, Verify each MD[15:0]. */
1126                 for (Data = pad, Index = 0; Index < 16; Index++) {
1127                         Data <<= 1;
1128                         if (Data == 0)
1129                                 Data = 1;
1130                         pci_write_config8(PCI_DEV(0, 0, 7), 0xC0 + Index, Data);
1131                 }
1132
1133                 /* Issue the bank active command. */
1134                 // bank active command enable
1135                 Data = pci_read_config8(MEMCTRL, 0xdb);
1136                 Data &= 0xE3;
1137                 Data |= 0x10;
1138                 pci_write_config8(MEMCTRL, 0xdb, Data);
1139
1140                 Data = (u8) (row && 0xFF);
1141                 pci_write_config8(MEMCTRL, 0xf8, Data);
1142
1143                 Data = (u8) ((row && 0xFF) >> 8);
1144                 pci_write_config8(MEMCTRL, 0xf9, Data);
1145
1146                 /* Issue active cycle. */
1147                 Data = pci_read_config8(MEMCTRL, 0xdb);
1148                 Data |= 0x2;
1149                 pci_write_config8(MEMCTRL, 0xdb, Data);
1150                 Data &= 0xFD;
1151                 pci_write_config8(MEMCTRL, 0xdb, Data);
1152
1153                 /* Issue ready/completion for read/write. */
1154                 // read/completion command enable
1155                 Data = pci_read_config8(MEMCTRL, 0xdb);
1156                 Data &= 0xE3;
1157                 Data |= 0x04;
1158                 pci_write_config8(MEMCTRL, 0xdb, Data);
1159
1160                 Data = 0x00;
1161                 pci_write_config8(MEMCTRL, 0xf8, Data);
1162
1163                 Data = 0x00;
1164                 pci_write_config8(MEMCTRL, 0xf9, Data);
1165
1166                 /* Issue read/completion cycle. */
1167                 Data = pci_read_config8(MEMCTRL, 0xdb);
1168                 Data |= 0x2;
1169                 pci_write_config8(MEMCTRL, 0xdb, Data);
1170                 Data &= 0xFD;
1171                 pci_write_config8(MEMCTRL, 0xdb, Data);
1172
1173                 /* Issue write command. */
1174                 // write command enable
1175                 Data = pci_read_config8(MEMCTRL, 0xdb);
1176                 Data &= 0xE3;
1177                 Data |= 0x0C;
1178                 pci_write_config8(MEMCTRL, 0xdb, Data);
1179
1180                 Data = 0x00;
1181                 pci_write_config8(MEMCTRL, 0xf8, Data);
1182
1183                 Data = (u8) ((row & 0x60) << 5);
1184                 pci_write_config8(MEMCTRL, 0xf9, Data);
1185
1186                 /* Issue write cycle. */
1187                 Data = pci_read_config8(MEMCTRL, 0xdb);
1188                 Data |= 0x2;
1189                 pci_write_config8(MEMCTRL, 0xdb, Data);
1190                 Data &= 0xFD;
1191                 pci_write_config8(MEMCTRL, 0xdb, Data);
1192
1193                 ////issue ready/completion for read/write
1194                 // read/completion command enable
1195                 Data = pci_read_config8(MEMCTRL, 0xdb);
1196                 Data &= 0xE3;
1197                 Data |= 0x04;
1198                 pci_write_config8(MEMCTRL, 0xdb, Data);
1199
1200                 Data = 0x00;
1201                 pci_write_config8(MEMCTRL, 0xf8, Data);
1202
1203                 Data = 0x00;
1204                 pci_write_config8(MEMCTRL, 0xf9, Data);
1205
1206                 /* Issue read/completion cycle. */
1207                 Data = pci_read_config8(MEMCTRL, 0xdb);
1208                 Data |= 0x2;
1209                 pci_write_config8(MEMCTRL, 0xdb, Data);
1210                 Data &= 0xFD;
1211                 pci_write_config8(MEMCTRL, 0xdb, Data);
1212
1213                 /* Issue the bank active command. */
1214                 // bank active command enable
1215                 Data = pci_read_config8(MEMCTRL, 0xdb);
1216                 Data &= 0xE3;
1217                 Data |= 0x10;
1218                 pci_write_config8(MEMCTRL, 0xdb, Data);
1219
1220                 Data = (u8) (row && 0xFF);
1221                 pci_write_config8(MEMCTRL, 0xf8, Data);
1222
1223                 Data = (u8) ((row && 0xFF) >> 8);
1224                 pci_write_config8(MEMCTRL, 0xf9, Data);
1225
1226                 //  issue active cycle
1227                 Data = pci_read_config8(MEMCTRL, 0xdb);
1228                 Data |= 0x2;
1229                 pci_write_config8(MEMCTRL, 0xdb, Data);
1230                 Data &= 0xFD;
1231                 pci_write_config8(MEMCTRL, 0xdb, Data);
1232
1233                 ////issue ready/completion for read/write
1234                 // read/completion command enable
1235                 Data = pci_read_config8(MEMCTRL, 0xdb);
1236                 Data &= 0xE3;
1237                 Data |= 0x04;
1238                 pci_write_config8(MEMCTRL, 0xdb, Data);
1239
1240                 Data = 0x00;
1241                 pci_write_config8(MEMCTRL, 0xf8, Data);
1242
1243                 Data = 0x00;
1244                 pci_write_config8(MEMCTRL, 0xf9, Data);
1245
1246                 //  issue read/completion cycle
1247                 Data = pci_read_config8(MEMCTRL, 0xdb);
1248                 Data |= 0x2;
1249                 pci_write_config8(MEMCTRL, 0xdb, Data);
1250                 Data &= 0xFD;
1251                 pci_write_config8(MEMCTRL, 0xdb, Data);
1252
1253                 ////issue read command
1254                 // read/completion command enable
1255                 Data = pci_read_config8(MEMCTRL, 0xdb);
1256                 Data &= 0xE3;
1257                 Data |= 0x08;
1258                 pci_write_config8(MEMCTRL, 0xdb, Data);
1259
1260                 Data = 0x00;
1261                 pci_write_config8(MEMCTRL, 0xf8, Data);
1262
1263                 Data = (u8) ((row & 0x60) << 5);
1264                 pci_write_config8(MEMCTRL, 0xf9, Data);
1265
1266                 //  issue read cycle
1267                 Data = pci_read_config8(MEMCTRL, 0xdb);
1268                 Data |= 0x2;
1269                 pci_write_config8(MEMCTRL, 0xdb, Data);
1270                 Data &= 0xFD;
1271                 pci_write_config8(MEMCTRL, 0xdb, Data);
1272
1273                 ////issue ready/completion for read/write
1274                 // read/completion command enable
1275                 Data = pci_read_config8(MEMCTRL, 0xdb);
1276                 Data &= 0xE3;
1277                 Data |= 0x04;
1278                 pci_write_config8(MEMCTRL, 0xdb, Data);
1279
1280                 Data = 0x00;
1281                 pci_write_config8(MEMCTRL, 0xf8, Data);
1282
1283                 Data = 0x00;
1284                 pci_write_config8(MEMCTRL, 0xf9, Data);
1285
1286                 /* Issue read/completion cycle. */
1287                 Data = pci_read_config8(MEMCTRL, 0xdb);
1288                 Data |= 0x2;
1289                 pci_write_config8(MEMCTRL, 0xdb, Data);
1290                 Data &= 0xFD;
1291                 pci_write_config8(MEMCTRL, 0xdb, Data);
1292
1293                 /* Verify the value. */
1294                 for (ByteVal = pad, Index = 0; Index < 16; Index++) {
1295                         Data = pci_read_config8(PCI_DEV(0, 0, 7), 0xD0 + Index);
1296                         if (ByteVal != Data) {
1297                                 PRINT_DEBUG_MEM("Error! row = %x, index =%x, "
1298                                                 "data = %x, byteval=%x\r");
1299                         }
1300                         ByteVal <<= 1;
1301                         if (ByteVal == 0)
1302                                 ByteVal = 1;
1303                 }
1304                 pad <<= 1;
1305                 if (pad == 0)
1306                         pad = 1;
1307         }
1308
1309         return CB_SUCCESS;
1310 }