1 /*============================================================================
2 Copyright 2005 ADVANCED MICRO DEVICES, INC. All Rights Reserved.
3 This software and any related documentation (the "Materials") are the
4 confidential proprietary information of AMD. Unless otherwise provided in a
5 software agreement specifically licensing the Materials, the Materials are
6 provided in confidence and may not be distributed, modified, or reproduced in
7 whole or in part by any means.
8 LIMITATION OF LIABILITY: THE MATERIALS ARE PROVIDED "AS IS" WITHOUT ANY
9 EXPRESS OR IMPLIED WARRANTY OF ANY KIND, INCLUDING BUT NOT LIMITED TO
10 WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT, TITLE, FITNESS FOR ANY
11 PARTICULAR PURPOSE, OR WARRANTIES ARISING FROM CONDUCT, COURSE OF DEALING, OR
12 USAGE OF TRADE. IN NO EVENT SHALL AMD OR ITS LICENSORS BE LIABLE FOR ANY
13 DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS,
14 BUSINESS INTERRUPTION, OR LOSS OF INFORMATION) ARISING OUT OF THE USE OF OR
15 INABILITY TO USE THE MATERIALS, EVEN IF AMD HAS BEEN ADVISED OF THE
16 POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME JURISDICTIONS PROHIBIT THE EXCLUSION
17 OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE
18 LIMITATION MAY NOT APPLY TO YOU.
19 AMD does not assume any responsibility for any errors which may appear in the
20 Materials nor any responsibility to support or update the Materials. AMD
21 retains the right to modify the Materials at any time, without notice, and is
22 not obligated to provide such modified Materials to you.
23 NO SUPPORT OBLIGATION: AMD is not obligated to furnish, support, or make any
24 further information, software, technical information, know-how, or show-how
26 U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with "RESTRICTED
27 RIGHTS." Use, duplication, or disclosure by the Government is subject to the
28 restrictions as set forth in FAR 52.227-14 and DFAR 252.227-7013, et seq., or
29 its successor. Use of the Materials by the Government constitutes
30 acknowledgement of AMD's proprietary rights in them.
31 ============================================================================*/
32 /* Copyright 2007 coresystems GmbH */
34 // 2005.9 yhlu serengeti support
35 // 2005.9 yhlu modify that to more dynamic for AMD Opteron Based MB
36 // 2007.9 stepan improve code documentation
38 #include <console/console.h>
39 #include <device/pci.h>
40 #include <device/pci_ids.h>
44 #include <cpu/amd/amdk8_sysconf.h>
48 unsigned node_link_to_bus(unsigned node, unsigned link)
53 dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
57 for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
62 config_map = pci_read_config32(dev, reg);
63 if ((config_map & 3) != 3) {
66 dst_node = (config_map >> 4) & 7;
67 dst_link = (config_map >> 8) & 3;
68 bus_base = (config_map >> 16) & 0xff;
70 printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n",
71 dst_node, dst_link, bus_base,
74 if ((dst_node == node) && (dst_link == link))
85 * Why we need the pci1234[] array
87 * It will keep the sequence of HT devices in the HT link registers even when a
88 * given HT I/O card is not installed.
90 * The final result for pci1234[] will be
92 * pci1234[0] will record the south bridge link and bus range
93 * pci1234[i] will record HT chain i.
95 * For example, on the Tyan S2885 coreboot_ram will put the AMD8151 chain (HT
96 * link 0) into the register 0xE0, and the AMD8131/8111 HT chain into the
99 * So we need to make sure that the south bridge link will always be on
102 * Imagine a scenario with multiple HT I/O cards, where you don't install HT I/O 1,
103 * but you only install HT I/O 2 and HT I/O 3. The HT I/Os will end up in registers
106 * But we want to leave pci1234[1] to HT I/O 1 (even though it is disabled),
107 * and let HT I/O 2 and HT I/O 3 still use pci1234[2] and pci1234[3].
109 * So we keep the sequence. You need to preset the pci1234[1], pci1234[2],
110 * pci1234[3] for this purpose.
112 * For this example you need to set
114 * unsigned pci1234[] = {
116 * 0x0000f10, // HT IO 1 card always on node 1
117 * 0x0000f20, // HT IO 2 card always on node 2
118 * 0x0000f30 // HT IO 3 card always on node 3
121 * For 2P + htio(n1) + htio(n0_1) + htio(n1_1), 2P + htio(n1) + 2P + htio(n2) + htio(n3):
122 * You need an array pci1234[6]:
124 * unsigned pci1234[] = {
126 * 0x0000010, // HT IO 1 card always on node 1
127 * 0x0000f00, // HT IO 2 card always on node 0
128 * 0x0000110, // HT IO 3 card always on node 1
129 * 0x0000f20, // HT IO 4 card always on node 2
130 * 0x0000f30 // HT IO 5 card always on node 3
134 * For 4p+htio(n1)+htio(n2)+htio(n3),4p+htio(n1)+4p+htio(n6)+htio(n7):
135 * You need an array pci1234[6]:
137 * unsigned pci1234[] = {
139 * 0x0000f10, // HT IO 1 card always on node 1
140 * 0x0000f20, // HT IO 2 card always on node 2
141 * 0x0000f30, // HT IO 3 card always on node 3
142 * 0x0000f60, // HT IO 4 card always on node 6
143 * 0x0000f70 // HT IO 5 card always on node 7
147 * For 2p + htio(n1) + htio(n0_1) + htio(n1_1), 2P + htio(n1) + 2P +
148 * htio(n2) + htio(n3), 2P + htio(n1) + 4P + htio(n4) + htio(n5),
149 * you need an array pci1234[8]:
151 * unsigned pci1234[] = {
153 * 0x0000010, // HT IO 1 card always on node 1
154 * 0x0000f00, // HT IO 2 card always on node 0
155 * 0x0000110, // HT IO 3 card always on node 1
156 * 0x0000f20, // HT IO 4 card always on node 2
157 * 0x0000f30 // HT IO 5 card always on node 3
158 * 0x0000f40, // HT IO 6 card always on node 4
159 * 0x0000f50 // HT IO 7 card always on node 5
163 * For 4P + htio(n1) + htio(n2) + htio(n3), 4p + htio(n1) + 2p + htio(n4) +
164 * htio(n5), 4p + htio(n1) + 4p + htio(n6) + htio(n7),
165 * you need an array pci1234[8]:
167 * unsigned pci1234[] = {
169 * 0x0000f10, // HT IO 1 card always on node 1
170 * 0x0000f20, // HT IO 2 card always on node 2
171 * 0x0000f30, // HT IO 3 card always on node 3
172 * 0x0000f40, // HT IO 4 card always on node 4
173 * 0x0000f50 // HT IO 5 card always on node 5
174 * 0x0000f60, // HT IO 6 card always on node 6
175 * 0x0000f70 // HT IO 7 card always on node 7
179 * So the maximum posible value of HC_POSSIBLE_NUM is 8. (FIXME Why?)
188 * Just put all the possible HT Node/link to the list tp pci1234[] in
189 * src/mainboard/<vendor>/<mainboard>get_bus_conf.c
191 * Also don't forget to increase the ACPI_SSDTX_NUM etc (FIXME what else) if
192 * you have too many SSDTs
194 * What about co-processor in socket 1 on a 2 way system? Or socket 2 and
195 * socket 3 on a 4 way system? Treat that as an HC, too!
199 void get_sblk_pci1234(void)
206 /* read PCI_DEV(0,0x18,0) 0x64 bit [8:9] to find out SbLink m */
207 dev = dev_find_slot(0, PCI_DEVFN(0x18,0));
208 dword = pci_read_config32(dev, 0x64);
209 sysconf.sblk = (dword>>8) & 0x3;
213 sysconf.pci1234[0] = dword;
216 /* About hardcoded numbering for HT_IO support
218 * Set the node_id and link_id that could have a HT chain in the one
219 * array, (FIXME: which one?) then check if is enabled. Then update
223 /* Here we need to set hcdn
225 * 1. hypertransport.c needs to record hcdn_reg together with 0xe0,
226 * 0xe4, 0xe8, 0xec when are set (FIXME: when WHAT is set?)
228 * 2. So at the same time we need update hcdn with hcdn_reg here. FIXME: Why?
231 dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
235 dwordx = pci_read_config32(dev, 0xe0 + j*4);
236 dwordx &=0xffff0ff1; /* keep bus num, node_id, link_num, enable bits */
237 if((dwordx & 0xff1) == dword) { /* SBLINK */
238 sysconf.pci1234[0] = dwordx;
239 sysconf.hcdn[0] = sysconf.hcdn_reg[j];
243 if((dwordx & 1) == 1) {
244 /* We need to find out the number of HC
247 for(i=1;i<sysconf.hc_possible_num;i++) {
248 if((dwordx & 0xff0) == (sysconf.pci1234[i] & 0xff0)) {
249 sysconf.pci1234[i] = dwordx;
250 sysconf.hcdn[i] = sysconf.hcdn_reg[j];
255 /* For 0xff0 match or same node */
256 for(i=1;i<sysconf.hc_possible_num;i++) {
257 if((dwordx & 0xff0) == (dwordx & sysconf.pci1234[i] & 0xff0)) {
258 sysconf.pci1234[i] = dwordx;
259 sysconf.hcdn[i] = sysconf.hcdn_reg[j];
266 for(i=1;i<sysconf.hc_possible_num;i++) {
267 if((sysconf.pci1234[i] & 1) != 1) {
268 sysconf.pci1234[i] = 0;
269 sysconf.hcdn[i] = 0x20202020;