2 * This file is part of the coreboot project.
4 * Copyright (C) 2010 Advanced Micro Devices, 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 static u32 mct_ControlRC(struct MCTStatStruc *pMCTstat,
21 struct DCTStatStruc *pDCTstat, u32 MrsChipSel, u32 CtrlWordNum)
23 u8 Dimms, DimmNum, MaxDimm, Speed;
28 DimmNum = MrsChipSel >> 20;
35 MaxDimm = mctGet_NVbits(NV_MAX_DIMMS);
36 Speed = pDCTstat->DIMMAutoSpeed;
38 if (pDCTstat->CSPresent_DCT[0] > 0) {
40 } else if (pDCTstat->CSPresent_DCT[1] > 0 ){
43 reg_off = 0x100 * dct;
44 Dimms = pDCTstat->MAdimms[dct];
49 else if (CtrlWordNum == 1) {
50 if (!((pDCTstat->DimmDRPresent | pDCTstat->DimmQRPresent) & (1 << DimmNum)))
51 val |= 0xC; /* if single rank, set DBA1 and DBA0 */
53 else if (CtrlWordNum == 2) {
56 if (((pDCTstat->DimmQRPresent & (1 << DimmNum)) && (Dimms == 1)) || Dimms == 2)
57 if (!(pDCTstat->MirrPresU_NumRegR & (1 << DimmNum)))
60 if (pDCTstat->MirrPresU_NumRegR & (1 << DimmNum))
67 } else if (CtrlWordNum == 3) {
68 val = pDCTstat->CtrlWrd3 >> (DimmNum << 2);
69 } else if (CtrlWordNum == 4) {
70 val = pDCTstat->CtrlWrd4 >> (DimmNum << 2);
71 } else if (CtrlWordNum == 5) {
72 val = pDCTstat->CtrlWrd5 >> (DimmNum << 2);
73 } else if (CtrlWordNum == 8) {
76 if (pDCTstat->MirrPresU_NumRegR & (1 << DimmNum))
78 } else if (CtrlWordNum == 9) {
79 val |= 0xD; /* DBA1, DBA0, DA3 = 0 */
83 val = MrsChipSel | ((val >> 2) & 3) << 16 | MrsChipSel | ((val >> 2) & 3);
85 /* transfer Control word number to address [BA2,A2,A1,A0] */
86 if (CtrlWordNum > 7) {
95 static void mct_SendCtrlWrd(struct MCTStatStruc *pMCTstat,
96 struct DCTStatStruc *pDCTstat, u32 val)
99 u32 dev = pDCTstat->dev_dct;
101 if (pDCTstat->CSPresent_DCT[0] > 0) {
103 } else if (pDCTstat->CSPresent_DCT[1] > 0 ){
107 val |= Get_NB32(dev, reg_off + 0x7C) & ~0xFFFFFF;
108 val |= 1 << SendControlWord;
109 Set_NB32(dev, reg_off + 0x7C, val);
112 val = Get_NB32(dev, reg_off + 0x7C);
113 } while (val & (1 << SendControlWord));
116 void mct_DramControlReg_Init_D(struct MCTStatStruc *pMCTstat,
117 struct DCTStatStruc *pDCTstat, u8 dct)
120 u32 dev = pDCTstat->dev_dct;
122 u32 reg_off = 0x100 * dct;
128 for (MrsChipSel = 0; MrsChipSel < 8; MrsChipSel ++, MrsChipSel ++) {
129 if (pDCTstat->CSPresent & (1 << MrsChipSel)) {
130 val = Get_NB32(dev, reg_off + 0xA8);
133 switch (MrsChipSel) {
139 val |= (3 << 2) << 8;
142 val |= (3 << 4) << 8;
145 val |= (3 << 6) << 8;
147 Set_NB32(dev, reg_off + 0xA8 , val);
149 for (cw=0; cw <=15; cw ++) {
151 if (!(cw==6 || cw==7)) {
152 val = mct_ControlRC(pMCTstat, pDCTstat, MrsChipSel << 20, cw);
153 mct_SendCtrlWrd(pMCTstat, pDCTstat, val);
162 void FreqChgCtrlWrd(struct MCTStatStruc *pMCTstat,
163 struct DCTStatStruc *pDCTstat)
165 u32 SaveSpeed = pDCTstat->DIMMAutoSpeed;
167 u32 dev = pDCTstat->dev_dct;
170 pDCTstat->DIMMAutoSpeed = pDCTstat->TargetFreq;
171 for (MrsChipSel=0; MrsChipSel < 8; MrsChipSel++, MrsChipSel++) {
172 if (pDCTstat->CSPresent & (1 << MrsChipSel)) {
173 val = Get_NB32(dev, 0xA8);
175 val |= (0x3 << MrsChipSel) << 8;
176 Set_NB32(dev, 0xA8, val);
179 switch (pDCTstat->TargetFreq) {
181 mct_SendCtrlWrd(pMCTstat, pDCTstat, MrsChipSel << 20 | 0x4000A);
184 mct_SendCtrlWrd(pMCTstat, pDCTstat, MrsChipSel << 20 | 0x40012);
187 mct_SendCtrlWrd(pMCTstat, pDCTstat, MrsChipSel << 20 | 0x4001A);
193 val = mct_ControlRC(pMCTstat, pDCTstat, MrsChipSel << 20, 2);
194 mct_SendCtrlWrd(pMCTstat, pDCTstat, val);
198 /* Resend control word 8 */
199 val = mct_ControlRC(pMCTstat, pDCTstat, MrsChipSel << 20, 8);
200 mct_SendCtrlWrd(pMCTstat, pDCTstat, val);
205 pDCTstat->DIMMAutoSpeed = SaveSpeed;