Please bear with me - another rename checkin. This qualifies as trivial, no
[coreboot.git] / src / northbridge / amd / amdmct / mct / mctchi_d.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2007 Advanced Micro Devices, Inc.
5  *
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.
9  *
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.
14  *
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
18  */
19
20
21
22 void InterleaveChannels_D(struct MCTStatStruc *pMCTstat,
23                         struct DCTStatStruc *pDCTstatA)
24 {
25
26         u8 Node;
27         u32 DramBase, DctSelBase;
28         u8 DctSelIntLvAddr, DctSelHi;
29         u8 HoleValid = 0;
30         u32 HoleSize, HoleBase = 0;
31         u32 val, tmp;
32         u32 dct0_size, dct1_size;
33         u8 enabled;
34         struct DCTStatStruc *pDCTstat;
35
36         /* HoleValid - indicates whether the current Node contains hole.
37          * HoleSize - indicates whether there is IO hole in the whole system
38          * memory.
39          */
40
41         /* call back to wrapper not needed ManualChannelInterleave_D(); */
42         /* call back - DctSelIntLvAddr = mctGet_NVbits(NV_ChannelIntlv);*/      /* override interleave */
43         // FIXME: Check for Cx
44         DctSelIntLvAddr = 5;    /* use default: Enable channel interleave */
45         enabled = 1;            /* with Hash*: exclusive OR of address bits[20:16, 6]. */
46         beforeInterleaveChannels_D(pDCTstatA, &enabled);
47
48         if (enabled) {
49                 DctSelIntLvAddr >>= 1;
50                 HoleSize = 0;
51                 if ((pMCTstat->GStatus & (1 << GSB_SoftHole)) ||
52                      (pMCTstat->GStatus & (1 << GSB_HWHole))) {
53                         if (pMCTstat->HoleBase) {
54                                 HoleBase = pMCTstat->HoleBase >> 8;
55                                 HoleSize = HoleBase & 0xFFFF0000;
56                                 HoleSize |= ((~HoleBase) + 1) & 0xFFFF;
57                         }
58                 }
59                 Node = 0;
60                 while (Node < MAX_NODES_SUPPORTED) {
61                         pDCTstat = pDCTstatA + Node;
62                         val = Get_NB32(pDCTstat->dev_map, 0xF0);
63                         if (val & (1 << DramHoleValid))
64                                 HoleValid = 1;
65                         if (!pDCTstat->GangedMode && pDCTstat->DIMMValidDCT[0] && pDCTstat->DIMMValidDCT[1]) {
66                                 DramBase = pDCTstat->NodeSysBase >> 8;
67                                 dct1_size = ((pDCTstat->NodeSysLimit) + 2) >> 8;
68                                 dct0_size = Get_NB32(pDCTstat->dev_dct, 0x114);
69                                         if (dct0_size >= 0x10000) {
70                                                 dct0_size -= HoleSize;
71                                         }
72
73                                 dct0_size -= DramBase;
74                                 dct1_size -= dct0_size;
75                                 DctSelHi = 0x05;                /* DctSelHiRngEn = 1, DctSelHi = 0 */
76                                 if (dct1_size == dct0_size) {
77                                         dct1_size = 0;
78                                         DctSelHi = 0x04;        /* DctSelHiRngEn = 0 */
79                                 } else if (dct1_size > dct0_size ) {
80                                         dct1_size = dct0_size;
81                                         DctSelHi = 0x07;        /* DctSelHiRngEn = 1, DctSelHi = 1 */
82                                 }
83                                 dct0_size = dct1_size;
84                                 dct0_size += DramBase;
85                                 dct0_size += dct1_size;
86                                 if (dct0_size >= HoleBase)      /* if DctSelBaseAddr > HoleBase */
87                                         dct0_size += HoleBase;
88                                 DctSelBase = dct0_size;
89
90                                 if (dct1_size == 0)
91                                         dct0_size = 0;
92                                 dct0_size -= dct1_size;         /* DctSelBaseOffset = DctSelBaseAddr - Interleaved region */
93                                 Set_NB32(pDCTstat->dev_dct, 0x114, dct0_size);
94
95                                 if (dct1_size == 0)
96                                         dct1_size = DctSelBase;
97                                 val = Get_NB32(pDCTstat->dev_dct, 0x110);
98                                 val &= 0x7F8;
99                                 val |= dct1_size;
100                                 val |= DctSelHi;
101                                 val |= (DctSelIntLvAddr << 6) & 0xFF;
102                                 Set_NB32(pDCTstat->dev_dct, 0x110, val);
103                                 print_tx("InterleaveChannels: DRAM Controller Select Low Register = ", val);
104
105                                 if (HoleValid) {
106                                         tmp = DramBase;
107                                         val = DctSelBase;
108                                         if (val < HoleBase) {   /* DctSelBaseAddr < DramHoleBase */
109                                                 val -= DramBase;
110                                                 val >>= 1;
111                                                 tmp += val;
112                                         }
113                                         tmp += HoleSize;
114                                         val = Get_NB32(pDCTstat->dev_map, 0xF0);        /* DramHoleOffset */
115                                         val &= 0x7F;
116                                         val |= (tmp & 0xFF);
117                                         Set_NB32(pDCTstat->dev_map, 0xF0, val);
118 print_tx("InterleaveChannels:0xF0 = ", val);
119
120                                 }
121                         }
122                         print_tx("InterleaveChannels_D: Node ", Node);
123                         print_tx("InterleaveChannels_D: Status ", pDCTstat->Status);
124                         print_tx("InterleaveChannels_D: ErrStatus ", pDCTstat->ErrStatus);
125                         print_tx("InterleaveChannels_D: ErrCode ", pDCTstat->ErrCode);
126                         Node++;
127                 }
128         }
129         print_t("InterleaveChannels_D: Done\n");
130 }