blob: 253a89fbc0f794b818caa2108479029ad5811973 [file] [log] [blame]
Zheng Baoeb75f652010-04-23 17:32:48 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2010 Advanced Micro Devices, Inc.
Timothy Pearson730a0432015-10-16 13:51:51 -05005 * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
Zheng Baoeb75f652010-04-23 17:32:48 +00006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
Zheng Baoeb75f652010-04-23 17:32:48 +000015 */
16
17/* Low swap bit vs bank size encoding (physical, not logical address bit)
18 * ;To calculate the number by hand, add the number of Bank address bits
19 * ;(2 or 3) to the number of column address bits, plus 3 (the logical
20 * ;page size), and subtract 8.
21 */
22static const u8 Tab_int_D[] = {6,7,7,8,8,8,8,8,9,9,8,9};
23
24void InterleaveBanks_D(struct MCTStatStruc *pMCTstat,
25 struct DCTStatStruc *pDCTstat, u8 dct)
26{
27 u8 ChipSel, EnChipSels;
28 u32 AddrLoMask, AddrHiMask;
29 u32 AddrLoMaskN, AddrHiMaskN, MemSize = 0;
30 u8 DoIntlv, _CsIntCap;
31 u32 BitDelta, BankEncd = 0;
32
33 u32 dev;
34 u32 reg;
Zheng Baoeb75f652010-04-23 17:32:48 +000035 u32 val;
36 u32 val_lo, val_hi;
37
38 DoIntlv = mctGet_NVbits(NV_BankIntlv);
39 _CsIntCap = 0;
40 EnChipSels = 0;
41
42 dev = pDCTstat->dev_dct;
Zheng Baoeb75f652010-04-23 17:32:48 +000043
44 ChipSel = 0; /* Find out if current configuration is capable */
45 while (DoIntlv && (ChipSel < MAX_CS_SUPPORTED)) {
Timothy Pearson730a0432015-10-16 13:51:51 -050046 reg = 0x40+(ChipSel<<2); /* Dram CS Base 0 */
47 val = Get_NB32_DCT(dev, dct, reg);
Zheng Baoeb75f652010-04-23 17:32:48 +000048 if ( val & (1<<CSEnable)) {
49 EnChipSels++;
Timothy Pearson730a0432015-10-16 13:51:51 -050050 reg = 0x60+((ChipSel>>1)<<2); /*Dram CS Mask 0 */
51 val = Get_NB32_DCT(dev, dct, reg);
Zheng Baoeb75f652010-04-23 17:32:48 +000052 val >>= 19;
53 val &= 0x3ff;
54 val++;
55 if (EnChipSels == 1)
56 MemSize = val;
57 else
58 /*If mask sizes not same then skip */
59 if (val != MemSize)
60 break;
Timothy Pearson730a0432015-10-16 13:51:51 -050061 reg = 0x80; /*Dram Bank Addressing */
62 val = Get_NB32_DCT(dev, dct, reg);
Zheng Baoeb75f652010-04-23 17:32:48 +000063 val >>= (ChipSel>>1)<<2;
64 val &= 0x0f;
65 if(EnChipSels == 1)
66 BankEncd = val;
67 else
68 /*If number of Rows/Columns not equal, skip */
69 if (val != BankEncd)
70 break;
71 }
72 ChipSel++;
73 }
74 if (ChipSel == MAX_CS_SUPPORTED) {
75 if ((EnChipSels == 2) || (EnChipSels == 4) || (EnChipSels == 8))
76 _CsIntCap = 1;
77 }
78
79 if (DoIntlv) {
80 if(!_CsIntCap) {
81 pDCTstat->ErrStatus |= 1<<SB_BkIntDis;
82 DoIntlv = 0;
83 }
84 }
85
86 if(DoIntlv) {
87 val = Tab_int_D[BankEncd];
88 if (pDCTstat->Status & (1<<SB_128bitmode))
89 val++;
90
91 AddrLoMask = (EnChipSels - 1) << val;
92 AddrLoMaskN = ~AddrLoMask;
93
94 val = bsf(MemSize) + 19;
95 AddrHiMask = (EnChipSels -1) << val;
96 AddrHiMaskN = ~AddrHiMask;
97
98 BitDelta = bsf(AddrHiMask) - bsf(AddrLoMask);
99
100 for (ChipSel = 0; ChipSel < MAX_CS_SUPPORTED; ChipSel++) {
Timothy Pearson730a0432015-10-16 13:51:51 -0500101 reg = 0x40+(ChipSel<<2); /*Dram CS Base 0 */
102 val = Get_NB32_DCT(dev, dct, reg);
Zheng Baoeb75f652010-04-23 17:32:48 +0000103 if (val & 3) {
104 val_lo = val & AddrLoMask;
105 val_hi = val & AddrHiMask;
106 val &= AddrLoMaskN;
107 val &= AddrHiMaskN;
108 val_lo <<= BitDelta;
109 val_hi >>= BitDelta;
110 val |= val_lo;
111 val |= val_hi;
Timothy Pearson730a0432015-10-16 13:51:51 -0500112 Set_NB32_DCT(dev, dct, reg, val);
Zheng Baoeb75f652010-04-23 17:32:48 +0000113
114 if(ChipSel & 1)
115 continue;
116
Timothy Pearson730a0432015-10-16 13:51:51 -0500117 reg = 0x60 + ((ChipSel>>1)<<2); /*Dram CS Mask 0 */
118 val = Get_NB32_DCT(dev, dct, reg);
Zheng Baoeb75f652010-04-23 17:32:48 +0000119 val_lo = val & AddrLoMask;
120 val_hi = val & AddrHiMask;
121 val &= AddrLoMaskN;
122 val &= AddrHiMaskN;
123 val_lo <<= BitDelta;
124 val_hi >>= BitDelta;
125 val |= val_lo;
126 val |= val_hi;
Timothy Pearson730a0432015-10-16 13:51:51 -0500127 Set_NB32_DCT(dev, dct, reg, val);
Zheng Baoeb75f652010-04-23 17:32:48 +0000128 }
129 }
130 } /* DoIntlv */
131
132 /* dump_pci_device(PCI_DEV(0, 0x18+pDCTstat->Node_ID, 2)); */
133
134 printk(BIOS_DEBUG, "InterleaveBanks_D: Status %x\n", pDCTstat->Status);
135 printk(BIOS_DEBUG, "InterleaveBanks_D: ErrStatus %x\n", pDCTstat->ErrStatus);
136 printk(BIOS_DEBUG, "InterleaveBanks_D: ErrCode %x\n", pDCTstat->ErrCode);
137 printk(BIOS_DEBUG, "InterleaveBanks_D: Done\n\n");
138}