blob: 7b9b757e616ab7d683ec96b848873ba99708380c [file] [log] [blame]
Stefan Reinauerf622d592005-11-26 16:56:05 +00001/*============================================================================
2Copyright 2005 ADVANCED MICRO DEVICES, INC. All Rights Reserved.
3This software and any related documentation (the "Materials") are the
4confidential proprietary information of AMD. Unless otherwise provided in a
5software agreement specifically licensing the Materials, the Materials are
6provided in confidence and may not be distributed, modified, or reproduced in
7whole or in part by any means.
8LIMITATION OF LIABILITY: THE MATERIALS ARE PROVIDED "AS IS" WITHOUT ANY
9EXPRESS OR IMPLIED WARRANTY OF ANY KIND, INCLUDING BUT NOT LIMITED TO
10WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT, TITLE, FITNESS FOR ANY
11PARTICULAR PURPOSE, OR WARRANTIES ARISING FROM CONDUCT, COURSE OF DEALING, OR
12USAGE OF TRADE. IN NO EVENT SHALL AMD OR ITS LICENSORS BE LIABLE FOR ANY
13DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS,
14BUSINESS INTERRUPTION, OR LOSS OF INFORMATION) ARISING OUT OF THE USE OF OR
15INABILITY TO USE THE MATERIALS, EVEN IF AMD HAS BEEN ADVISED OF THE
16POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME JURISDICTIONS PROHIBIT THE EXCLUSION
17OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE
18LIMITATION MAY NOT APPLY TO YOU.
19AMD does not assume any responsibility for any errors which may appear in the
20Materials nor any responsibility to support or update the Materials. AMD
21retains the right to modify the Materials at any time, without notice, and is
22not obligated to provide such modified Materials to you.
23NO SUPPORT OBLIGATION: AMD is not obligated to furnish, support, or make any
24further information, software, technical information, know-how, or show-how
25available to you.
26U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with "RESTRICTED
27RIGHTS." Use, duplication, or disclosure by the Government is subject to the
28restrictions as set forth in FAR 52.227-14 and DFAR 252.227-7013, et seq., or
29its successor. Use of the Materials by the Government constitutes
30acknowledgement of AMD's proprietary rights in them.
31============================================================================*/
Stefan Reinauer741e1e62007-09-13 13:47:02 +000032/* Copyright 2007 coresystems GmbH */
33
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
Stefan Reinauerf622d592005-11-26 16:56:05 +000037
38#include <console/console.h>
39#include <device/pci.h>
40#include <device/pci_ids.h>
41#include <string.h>
42#include <stdint.h>
43
Yinghai Lud4b278c2006-10-04 20:46:15 +000044#include <cpu/amd/amdk8_sysconf.h>
45
Stefan Reinauerf622d592005-11-26 16:56:05 +000046
47#if 0
48unsigned node_link_to_bus(unsigned node, unsigned link)
49{
50 device_t dev;
51 unsigned reg;
52
53 dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
54 if (!dev) {
55 return 0;
56 }
57 for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
58 uint32_t config_map;
59 unsigned dst_node;
60 unsigned dst_link;
61 unsigned bus_base;
62 config_map = pci_read_config32(dev, reg);
63 if ((config_map & 3) != 3) {
64 continue;
65 }
66 dst_node = (config_map >> 4) & 7;
67 dst_link = (config_map >> 8) & 3;
68 bus_base = (config_map >> 16) & 0xff;
69#if 0
70 printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n",
71 dst_node, dst_link, bus_base,
72 reg, config_map);
73#endif
74 if ((dst_node == node) && (dst_link == link))
75 {
76 return bus_base;
77 }
78 }
79 return 0;
80}
81#endif
82
83
Stefan Reinauer741e1e62007-09-13 13:47:02 +000084/**
85 * Why we need the pci1234[] array
86 *
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.
89 *
90 * The final result for pci1234[] will be
91 *
92 * pci1234[0] will record the south bridge link and bus range
93 * pci1234[i] will record HT chain i.
94 *
Stefan Reinauer87c938f2008-08-02 19:17:42 +000095 * For example, on the Tyan S2885 coreboot_ram will put the AMD8151 chain (HT
Stefan Reinauer741e1e62007-09-13 13:47:02 +000096 * link 0) into the register 0xE0, and the AMD8131/8111 HT chain into the
97 * register 0xE4.
98 *
99 * So we need to make sure that the south bridge link will always be on
100 * pci1234[0].
101 *
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
104 * 0xE4 and 0xE8.
105 *
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].
108 *
109 * So we keep the sequence. You need to preset the pci1234[1], pci1234[2],
110 * pci1234[3] for this purpose.
111 *
112 * For this example you need to set
113 *
114 * unsigned pci1234[] = {
115 * 0x0000ff0,
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
119 * };
120 *
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]:
123 *
124 * unsigned pci1234[] = {
125 * 0x0000ff0,
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
131 * };
132 *
133 *
134 * For 4p+htio(n1)+htio(n2)+htio(n3),4p+htio(n1)+4p+htio(n6)+htio(n7):
135 * You need an array pci1234[6]:
136 *
137 * unsigned pci1234[] = {
138 * 0x0000ff0,
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
144 * };
145 *
146 *
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]:
150 *
151 * unsigned pci1234[] = {
152 * 0x0000ff0,
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
160 * };
161 *
162 *
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]:
166 *
167 * unsigned pci1234[] = {
168 * 0x0000ff0,
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
176 * };
177 *
178 *
179 * So the maximum posible value of HC_POSSIBLE_NUM is 8. (FIXME Why?)
180 *
181 * 1n: 3
182 * 2n: 2x2 - 1
183 * 4n: 1x4 - 2
184 * 6n: 2
185 * 8n: 2
186 * Total: 12
187 *
188 * Just put all the possible HT Node/link to the list tp pci1234[] in
189 * src/mainboard/<vendor>/<mainboard>get_bus_conf.c
190 *
191 * Also don't forget to increase the ACPI_SSDTX_NUM etc (FIXME what else) if
192 * you have too many SSDTs
193 *
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!
196 *
197 */
Stefan Reinauerf622d592005-11-26 16:56:05 +0000198
Stefan Reinauerf622d592005-11-26 16:56:05 +0000199void get_sblk_pci1234(void)
200{
201
202 device_t dev;
203 int i,j;
204 uint32_t dword;
205
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);
Yinghai Lud4b278c2006-10-04 20:46:15 +0000209 sysconf.sblk = (dword>>8) & 0x3;
Stefan Reinauerf622d592005-11-26 16:56:05 +0000210
211 dword &=0x0300;
212 dword |= 1;
Yinghai Lud4b278c2006-10-04 20:46:15 +0000213 sysconf.pci1234[0] = dword;
Yinghai Lu5f9624d2006-10-04 22:56:21 +0000214 sysconf.hcid[0] = 0;
Stefan Reinauerf622d592005-11-26 16:56:05 +0000215
Stefan Reinauer741e1e62007-09-13 13:47:02 +0000216 /* About hardcoded numbering for HT_IO support
217 *
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
220 * final value
221 */
222
223 /* Here we need to set hcdn
224 *
225 * 1. hypertransport.c needs to record hcdn_reg together with 0xe0,
226 * 0xe4, 0xe8, 0xec when are set (FIXME: when WHAT is set?)
227 *
228 * 2. So at the same time we need update hcdn with hcdn_reg here. FIXME: Why?
229 */
Stefan Reinauerbbdd8f42005-12-04 21:52:58 +0000230
Stefan Reinauerf622d592005-11-26 16:56:05 +0000231 dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
Stefan Reinauer741e1e62007-09-13 13:47:02 +0000232
Stefan Reinauerf622d592005-11-26 16:56:05 +0000233 for(j=0;j<4;j++) {
234 uint32_t dwordx;
Stefan Reinauer741e1e62007-09-13 13:47:02 +0000235 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 */
Yinghai Lud4b278c2006-10-04 20:46:15 +0000238 sysconf.pci1234[0] = dwordx;
239 sysconf.hcdn[0] = sysconf.hcdn_reg[j];
Stefan Reinauerf622d592005-11-26 16:56:05 +0000240 continue;
241 }
Stefan Reinauer741e1e62007-09-13 13:47:02 +0000242
Stefan Reinauerf622d592005-11-26 16:56:05 +0000243 if((dwordx & 1) == 1) {
Stefan Reinauer741e1e62007-09-13 13:47:02 +0000244 /* We need to find out the number of HC
245 * for exact match
246 */
Yinghai Lud4b278c2006-10-04 20:46:15 +0000247 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];
Stefan Reinauerf622d592005-11-26 16:56:05 +0000251 break;
252 }
253 }
Stefan Reinauer741e1e62007-09-13 13:47:02 +0000254
255 /* For 0xff0 match or same node */
Yinghai Lud4b278c2006-10-04 20:46:15 +0000256 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];
Stefan Reinauerf622d592005-11-26 16:56:05 +0000260 break;
261 }
262 }
263 }
264 }
265
Yinghai Lud4b278c2006-10-04 20:46:15 +0000266 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;
Stefan Reinauerf622d592005-11-26 16:56:05 +0000270 }
Yinghai Lu5f9624d2006-10-04 22:56:21 +0000271 sysconf.hcid[i] = 0;
Stefan Reinauerf622d592005-11-26 16:56:05 +0000272 }
273
274}
275