2 * This file is part of the coreboot project.
4 * Copyright (C) 2009 One Laptop per Child, Association, Inc.
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.
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.
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
21 Driving setting: ODT/DQS/DQ/CS/MAA/MAB/DCLK
24 void DrivingODT(DRAM_SYS_ATTR * DramAttr);
26 void DrivingDQS(DRAM_SYS_ATTR * DramAttr);
28 void DrivingDQ(DRAM_SYS_ATTR * DramAttr);
30 void DrivingCS(DRAM_SYS_ATTR * DramAttr);
32 void DrivingMA(DRAM_SYS_ATTR * DramAttr);
34 void DrivingDCLK(DRAM_SYS_ATTR * DramAttr);
36 /* DRAM Driving Adjustment*/
37 void DRAMDriving(DRAM_SYS_ATTR * DramAttr)
39 PRINT_DEBUG_MEM("set ODT!\r");
42 PRINT_DEBUG_MEM("set DQS!\r");
45 PRINT_DEBUG_MEM(("set DQ!\r"));
48 PRINT_DEBUG_MEM("set CS!\r");
51 PRINT_DEBUG_MEM("set MAA!\r");
54 PRINT_DEBUG_MEM("set DCLK!\r");
55 DrivingDCLK(DramAttr);
59 ODT Control for DQ/DQS/CKE/SCMD/DCLKO in ChA & ChB
60 which include driving enable/range and strong/weak selection
62 Processing: According to DRAM frequency to ODT control bits.
63 Because function enable bit must be the last one to be set.
64 So the register VIA_NB3DRAM_REGD4 and VIA_NB3DRAM_REGD3 should be
65 the last register to be programmed.
67 //-------------------------------------------------------------------------------
69 //-------------------------------------------------------------------------------
75 #define NB_ODT_75ohm 0
76 #define NB_ODT_150ohm 1
78 #define DDR2_ODT_75ohm 0x20
79 #define DDR2_ODT_150ohm 0x40
81 // Setting of ODT Lookup TBL
82 // RankMAP , Rank 3 Rank 2 Rank 1 Rank 0 , DRAM & NB ODT setting
83 // db 0000b , Reserved
84 #define ODTLookup_Tbl_count 8
85 static const u8 ODTLookup_TBL[ODTLookup_Tbl_count][3] = {
88 (Rank3_ODT << 6) + (Rank2_ODT << 4) + (Rank1_ODT << 2) +
89 Rank0_ODT, DDR2_ODT_150ohm + NB_ODT_75ohm},
93 (Rank3_ODT << 6) + (Rank2_ODT << 4) + (Rank0_ODT << 2) +
94 Rank1_ODT, DDR2_ODT_150ohm + NB_ODT_75ohm},
97 (Rank3_ODT << 6) + (Rank2_ODT << 4) + (Rank1_ODT << 2) +
98 Rank0_ODT, DDR2_ODT_150ohm + NB_ODT_75ohm},
101 (Rank3_ODT << 6) + (Rank0_ODT << 4) + (Rank1_ODT << 2) +
102 Rank2_ODT, DDR2_ODT_75ohm + NB_ODT_150ohm},
106 (Rank3_ODT << 6) + (Rank0_ODT << 4) + (Rank2_ODT << 2) +
107 Rank2_ODT, DDR2_ODT_75ohm + NB_ODT_150ohm},
114 (Rank2_ODT << 6) + (Rank3_ODT << 4) + (Rank1_ODT << 2) +
115 Rank0_ODT, DDR2_ODT_150ohm + NB_ODT_75ohm},
118 (Rank0_ODT << 6) + (Rank0_ODT << 4) + (Rank1_ODT << 2) +
119 Rank2_ODT, DDR2_ODT_75ohm + NB_ODT_150ohm},
123 (Rank0_ODT << 6) + (Rank0_ODT << 4) + (Rank2_ODT << 2) +
124 Rank2_ODT, DDR2_ODT_75ohm + NB_ODT_150ohm}
127 #define ODT_Table_Width_DDR2 4
129 static const u8 ODT_Control_DDR2[ODT_Table_Width_DDR2] = { 0xFC, 0x01 };
131 void DrivingODT(DRAM_SYS_ATTR * DramAttr)
137 pci_write_config8(MEMCTRL, 0xD0, 0x88);
139 Data = ODT_Control_DDR2[0];
140 pci_write_config8(MEMCTRL, 0xd6, Data);
142 Data = ODT_Control_DDR2[1];
143 pci_write_config8(MEMCTRL, 0xd3, Data);
145 Data = pci_read_config8(MEMCTRL, 0x9e);
146 //set MD turn_around wait state
147 Data &= 0xCF; /*clear bit4,5 */
148 if (DIMMFREQ_400 == DramAttr->DramFreq)
150 else if (DIMMFREQ_533 == DramAttr->DramFreq)
152 else if (DIMMFREQ_667 == DramAttr->DramFreq)
154 else if (DIMMFREQ_800 == DramAttr->DramFreq)
158 pci_write_config8(MEMCTRL, 0x9e, Data);
160 if (DIMMFREQ_400 == DramAttr->DramFreq)
162 else if (DIMMFREQ_533 == DramAttr->DramFreq)
164 else if (DIMMFREQ_667 == DramAttr->DramFreq)
166 else if (DIMMFREQ_800 == DramAttr->DramFreq)
170 pci_write_config8(MEMCTRL, 0x9f, Data);
172 /*channel A ODT select */
173 if (DramAttr->DimmNumChA > 0) {
174 Data = pci_read_config8(MEMCTRL, 0xd5);
175 Data &= 0x5F; /*clear bit7,5 */
176 if (DramAttr->RankNumChA > 2)
177 Data |= 0xA0; /*if rank number > 2 (3or4), set bit7,5 */
179 Data |= 0x00; /*if rank number is 1or2, clear bit5 */
180 pci_write_config8(MEMCTRL, 0xd5, Data);
182 Data = pci_read_config8(MEMCTRL, 0xd7);
183 Data &= 0xEF; /*clear bit7 */
184 if (DramAttr->RankNumChA > 2)
185 Data |= 0x80; /*if rank number > 2 (3or4), set bit7 */
187 Data |= 0x00; /*if rank number is 1or2, clear bit7 */
188 pci_write_config8(MEMCTRL, 0xd7, Data);
191 Data = pci_read_config8(MEMCTRL, 0xd5);
192 Data &= 0xF3; //bit2,3
193 if (DramAttr->DimmNumChA == 2) /*2 Dimm, 3or4 Ranks */
195 else if (DramAttr->DimmNumChA == 1)
197 pci_write_config8(MEMCTRL, 0xd5, Data);
199 if ((DramAttr->RankPresentMap & 0x0F) != 0) { /*channel A */
200 // MAA ODT Lookup Table
202 for (i = 0; i < ODTLookup_Tbl_count; i++) {
203 if ((DramAttr->RankPresentMap & 0x0F) ==
204 ODTLookup_TBL[i][0]) {
205 Data = ODTLookup_TBL[i][1];
209 if (!bFound) { /*set default value */
211 ODTLookup_TBL[ODTLookup_Tbl_count - 1][1];
213 pci_write_config8(MEMCTRL, 0x9c, Data);
215 //set CHA MD ODT control State Dynamic-on
216 Data = pci_read_config8(MEMCTRL, 0xD4);
219 pci_write_config8(MEMCTRL, 0xD4, Data);
221 Data = pci_read_config8(MEMCTRL, 0x9e);
223 pci_write_config8(MEMCTRL, 0x9e, Data);
228 if (1 == ENABLE_CHC) {
229 //CHB has not auto compensation mode ,so must set it manual,or else CHB initialization will not successful
231 //pci_write_config8(MEMCTRL, 0xd0, Data);
233 Data = pci_read_config8(MEMCTRL, 0xd5);
235 if (DramAttr->RankNumChB > 2) /*rank number 3 or 4 */
239 pci_write_config8(MEMCTRL, 0xd5, Data);
241 Data = pci_read_config8(MEMCTRL, 0xd7);
242 Data &= 0xBF; /*clear bit6 */
243 if (DramAttr->RankNumChB > 2)
244 Data |= 0x40; /*if rank number > 2 (3or4), set bit7 */
246 Data |= 0x00; /*if rank number is 1or2, clear bit7 */
247 pci_write_config8(MEMCTRL, 0xd7, Data);
249 Data = pci_read_config8(MEMCTRL, 0xd5);
251 if (DramAttr->DimmNumChB == 2) /*2 Dimm, 3or4 Ranks */
252 Data |= 0x00; // 2 dimm RxD5[2,0]=0,0b
253 else if (DramAttr->DimmNumChB == 1)
254 Data |= 0x01; // 1 dimm RxD5[2,0]=1,1b
255 pci_write_config8(MEMCTRL, 0xd5, Data);
257 //set CHB MD ODT control State Dynamic-on
258 Data = pci_read_config8(MEMCTRL, 0xD4);
261 pci_write_config8(MEMCTRL, 0xD4, Data);
263 //enable CHB differential DQS input
264 Data = pci_read_config8(MEMCTRL, 0x9E);
266 pci_write_config8(MEMCTRL, 0x9E, Data);
269 Data = pci_read_config8(MEMCTRL, 0x9e);
271 pci_write_config8(MEMCTRL, 0x9e, Data);
274 void DrivingDQS(DRAM_SYS_ATTR * DramAttr)
279 if (DramAttr->RankNumChA > 0) {
280 Data = DDR2_DQSA_Driving_Table[DramAttr->RankNumChA - 1];
281 pci_write_config8(MEMCTRL, 0xe0, Data);
285 if (1 == ENABLE_CHC) {
286 Data = DDR2_DQSB_Driving_Table[DramAttr->RankNumChB - 1];
287 pci_write_config8(MEMCTRL, 0xe1, Data);
292 void DrivingDQ(DRAM_SYS_ATTR * DramAttr)
297 if (DramAttr->RankNumChA > 0) {
298 Data = DDR2_DQA_Driving_Table[DramAttr->RankNumChA - 1];
299 pci_write_config8(MEMCTRL, 0xe2, Data);
303 if (1 == ENABLE_CHC) {
304 Data = DDR2_DQB_Driving_Table[DramAttr->RankNumChB - 1];
305 pci_write_config8(MEMCTRL, 0xe3, Data);
309 void DrivingCS(DRAM_SYS_ATTR * DramAttr)
313 if (DramAttr->RankNumChA > 0) {
314 Data = DDR2_CSA_Driving_Table_x8[DramAttr->RankNumChA - 1];
315 pci_write_config8(MEMCTRL, 0xe4, Data);
318 if (1 == ENABLE_CHC) {
319 Data = DDR2_CSB_Driving_Table_x8[DramAttr->RankNumChB - 1];
320 pci_write_config8(MEMCTRL, 0xe5, Data);
324 void DrivingMA(DRAM_SYS_ATTR * DramAttr)
329 if (DramAttr->RankNumChA > 0) {
330 if (DIMMFREQ_400 == DramAttr->DramFreq)
332 else if (DIMMFREQ_533 == DramAttr->DramFreq)
334 else if (DIMMFREQ_667 == DramAttr->DramFreq)
336 else if (DIMMFREQ_800 == DramAttr->DramFreq)
340 for (i = 0; i < MA_Table; i++) {
341 if (DramAttr->LoadNumChA <=
342 DDR2_MAA_Driving_Table[i][0]) {
343 Data = DDR2_MAA_Driving_Table[i][FreqId];
347 pci_write_config8(MEMCTRL, 0xe8, Data);
349 if (1 == ENABLE_CHC) {
350 for (i = 0; i < MA_Table; i++) {
351 if (DramAttr->LoadNumChA <=
352 DDR2_MAB_Driving_Table[i][0]) {
353 Data = DDR2_MAB_Driving_Table[i][1];
357 pci_write_config8(MEMCTRL, 0xe9, Data);
361 void DrivingDCLK(DRAM_SYS_ATTR * DramAttr)
366 if (DIMMFREQ_400 == DramAttr->DramFreq)
368 else if (DIMMFREQ_533 == DramAttr->DramFreq)
370 else if (DIMMFREQ_667 == DramAttr->DramFreq)
372 else if (DIMMFREQ_800 == DramAttr->DramFreq)
378 if (DramAttr->RankNumChA > 0) {
379 Data = DDR2_DCLKA_Driving_Table[FreqId];
380 pci_write_config8(MEMCTRL, 0xe6, Data);
383 if (1 == ENABLE_CHC) {
384 Data = DDR2_DCLKB_Driving_Table[FreqId];
385 pci_write_config8(MEMCTRL, 0xe7, Data);