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
20 #define SMBUS_ADDR_CH_A_1 0xA0 // Dimmx
21 #define SMBUS_ADDR_CH_A_2 0xA2 // Dimmx
22 #define SMBUS_ADDR_CH_B_1 0xA4 // Dimmx
23 #define SMBUS_ADDR_CH_B_2 0xA6 // Dimmx
26 CB_STATUS GetSPDData(u8 Slot, u8 Length, u8 * Buf);
28 void DRAMCmdRate(DRAM_SYS_ATTR * DramAttr);
32 CB_STATUS GetInfoFromSPD(DRAM_SYS_ATTR * DramAttr);
34 CB_STATUS GetSPDData(u8 Slot, u8 Length, u8 * Buf)
36 // CB_STATUS Status = CB_NOT_READY;
40 if (1 > Length || NULL == Buf)
41 return CB_INVALID_PARAMETER;
43 for (i = 0; i < Length; i++) {
44 Val = get_spd_data(ctrl.channel0[Slot], i);
50 CB_STATUS DRAMDetect(DRAM_SYS_ATTR * DramAttr)
52 CB_STATUS Status = CB_SUCCESS;
54 PRINT_DEBUG_MEM("Dram Detection \r");
56 /*Read D0F3Rx6C , detect memory type DDR1 or DDR2 */
57 // 353 supports DDR2 only
58 DramAttr->DramType = RAMTYPE_SDRAMDDR2;
59 /*get information for SPD */
60 Status = GetInfoFromSPD(DramAttr);
61 if (CB_SUCCESS == Status) {
64 // if (RAMTYPE_SDRAMDDR == DramAttr->DramType)
66 /*select command rate */
67 DRAMCmdRate(DramAttr);
73 // Determine 1T or 2T Command Rate:
74 // To enable 1T command Rate, the system will satisfy the following 3 conditions:
75 // 1. Each DRAM channel may have 1 or 2 ranks of DIMM. 3/4 ranks can not support 1T command rate
76 // It's for loading issue. 1T can supports (a). only one socket with two ranks OR
77 // (b). two sockets each with 1 rank.
78 // 2. User wishes to enable 1T command rate mode and turn on by Setup menu
79 // 3. If 1T command rate can be enabled, just set EBP bit here.
80 void DRAMCmdRate(DRAM_SYS_ATTR * DramAttr)
84 // 5.1t/2t command rate, use the stable set
86 DramAttr->CmdRate = 2;
87 Data = pci_read_config8(MEMCTRL, 0x50);
88 Data = (u8) (Data & 0xEE);
89 pci_write_config8(MEMCTRL, 0x50, Data);
92 /*get SPD data and set RANK presence map*/
94 Sockets0,1 is Channel A / Sockets2,3 is Channel B
95 socket0 SPD device address 0x50 / socket1 SPD device address 0x51
96 socket2 SPD device address 0x52 / socket3 SPD device address 0x53
98 CB_STATUS GetInfoFromSPD(DRAM_SYS_ATTR * DramAttr)
109 Status = CB_DEVICE_ERROR;
111 for (Sockets = 0; Sockets < MAX_SOCKETS; Sockets++) {
112 pSPDDataBuf = DramAttr->DimmInfo[Sockets].SPDDataBuf;
113 pSPDDataBuf[SPD_MEMORY_TYPE] =
114 get_spd_data(ctrl.channel0[Sockets], SPD_MEMORY_TYPE);
115 if (pSPDDataBuf[SPD_MEMORY_TYPE] == 0) {
116 Status = CB_NOT_READY;
119 GetSPDData(Sockets, SPD_DATA_SIZE,
121 PRINT_DEBUG_MEM("SPD : \r");
122 for (i = 0; i < SPD_DATA_SIZE; i++) {
123 PRINT_DEBUG_MEM(" ");
124 PRINT_DEBUG_MEM_HEX8(pSPDDataBuf[i]);
127 if (CB_SUCCESS == Status) {
128 /*if Dram Controller detected type not same as the type got from SPD, There are ERROR */
129 if (pSPDDataBuf[SPD_MEMORY_TYPE] !=
130 DramAttr->DramType) {
131 Status = CB_DEVICE_ERROR; /*Memory int error */
133 ("Memory Device ERROR: Dram Controller detected type != type got from SPD \r");
136 DramAttr->DimmInfo[Sockets].bPresence = TRUE;
137 /*calculate load number (chips number) */
139 (u8) (DramAttr->DimmInfo[Sockets].
140 SPDDataBuf[SPD_SDRAM_MOD_DATA_WIDTH +
142 ModuleDataWidth = (u8) (ModuleDataWidth << 8);
144 (u8) (DramAttr->DimmInfo[Sockets].
145 SPDDataBuf[SPD_SDRAM_MOD_DATA_WIDTH]);
147 (u8) ((DramAttr->DimmInfo[Sockets].
148 SPDDataBuf[SPD_SDRAM_WIDTH]) & 0x7F);
149 LoadNum = (u8) (ModuleDataWidth / ChipWidth);
151 /*set the RANK map */
152 RankNum = (u8) (pSPDDataBuf[SPD_SDRAM_DIMM_RANKS] & 0x3); /*get bit0,1, the Most number of supported RANK is 2 */
153 if (RAMTYPE_SDRAMDDR2 == DramAttr->DramType)
154 RankNum++; /*for DDR bit[0,1] 01->1 RANK 10->2 RANK; for DDR2 bit[0,1] = 00 -> 1 RANK 01 -> 2 RANK */
155 if (RankNum != 2 && RankNum != 1) { /*every DIMM have 1 or 2 ranks */
156 Status = CB_DEVICE_ERROR;
158 ("Memory Device ERROR: the number of RANK not support!\r");
162 if (Sockets < 2) { /*sockets0,1 is channel A */
163 DramAttr->RankNumChA =
164 (u8) (DramAttr->RankNumChA + RankNum);
165 DramAttr->DimmNumChA++;
166 DramAttr->LoadNumChA =
167 (u8) (DramAttr->LoadNumChA * LoadNum *
169 } else { /*sockets2,3 is channel B */
171 DramAttr->RankNumChB =
172 (u8) (DramAttr->RankNumChB + RankNum);
173 DramAttr->DimmNumChB++;
174 DramAttr->LoadNumChB =
175 (u8) (DramAttr->LoadNumChB * LoadNum *
178 RankNum |= 1; /*set rank map */
179 DramAttr->RankPresentMap |=
180 (RankNum << (Sockets * 2));
184 PRINT_DEBUG_MEM("Rank Present Map:");
185 PRINT_DEBUG_MEM_HEX8(DramAttr->RankPresentMap);
186 PRINT_DEBUG_MEM("\r");