2 * This file is part of the LinuxBIOS project.
4 * Copyright (C) 2007 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
21 /* Low swap bit vs bank size encoding (physical, not logical address bit)
22 * ;To calculate the number by hand, add the number of Bank address bits
23 * ;(2 or 3) to the number of column address bits, plus 3 (the logical
24 * ;page size), and subtract 8.
26 static const u8 Tab_int_D[] = { 6,7,7,8,8,8,8,8,9,9,8,9 };
28 void InterleaveBanks_D(struct MCTStatStruc *pMCTstat,
29 struct DCTStatStruc *pDCTstat, u8 dct)
31 u8 ChipSel, EnChipSels;
32 u32 AddrLoMask, AddrHiMask;
33 u32 AddrLoMaskN, AddrHiMaskN, MemSize = 0;
34 u8 DoIntlv, _CsIntCap;
35 u32 BitDelta, BankEncd = 0;
43 DoIntlv = mctGet_NVbits(NV_BankIntlv);
47 dev = pDCTstat->dev_dct;
48 reg_off = 0x100 * dct;
50 ChipSel = 0; /* Find out if current configuration is capable */
51 while (DoIntlv && (ChipSel < MAX_CS_SUPPORTED)) {
52 reg = 0x40+(ChipSel<<2) + reg_off; /* Dram CS Base 0 */
53 val = Get_NB32(dev, reg);
54 if ( val & (1<<CSEnable)) {
56 reg = 0x60+((ChipSel>>1)<<2)+reg_off; /*Dram CS Mask 0 */
57 val = Get_NB32(dev, reg);
64 /*If mask sizes not same then skip */
67 reg = 0x80 + reg_off; /*Dram Bank Addressing */
68 val = Get_NB32(dev, reg);
69 val >>= (ChipSel>>1)<<2;
74 /*If number of Rows/Columns not equal, skip */
80 if (ChipSel == MAX_CS_SUPPORTED) {
81 if ((EnChipSels == 2) || (EnChipSels == 4) || (EnChipSels == 8))
87 pDCTstat->ErrStatus |= 1<<SB_BkIntDis;
93 val = Tab_int_D[BankEncd];
94 if (pDCTstat->Status & (1<<SB_128bitmode))
97 AddrLoMask = (EnChipSels - 1) << val;
98 AddrLoMaskN = ~AddrLoMask;
100 val = bsf(MemSize) + 19;
101 AddrHiMask = (EnChipSels -1) << val;
102 AddrHiMaskN = ~AddrHiMask;
104 BitDelta = bsf(AddrHiMask) - bsf(AddrLoMask);
106 for (ChipSel = 0; ChipSel < MAX_CS_SUPPORTED; ChipSel++) {
107 reg = 0x40+(ChipSel<<2) + reg_off; /*Dram CS Base 0 */
108 val = Get_NB32(dev, reg);
110 val_lo = val & AddrLoMask;
111 val_hi = val & AddrHiMask;
118 Set_NB32(dev, reg, val);
123 reg = 0x60 + ((ChipSel>>1)<<2) + reg_off; /*Dram CS Mask 0 */
124 val = Get_NB32(dev, reg);
125 val_lo = val & AddrLoMask;
126 val_hi = val & AddrHiMask;
133 Set_NB32(dev, reg, val);
136 print_t("InterleaveBanks_D: Banks Interleaved ");
139 // dump_pci_device(PCI_DEV(0, 0x18+pDCTstat->Node_ID, 2));
141 print_tx("InterleaveBanks_D: Status ", pDCTstat->Status);
142 print_tx("InterleaveBanks_D: ErrStatus ", pDCTstat->ErrStatus);
143 print_tx("InterleaveBanks_D: ErrCode ", pDCTstat->ErrCode);
144 print_t("InterleaveBanks_D: Done\n");