1 /* coherent hypertransport initialization for AMD64
2 * written by Stefan Reinauer <stepan@openbios.org>
3 * (c) 2003 by SuSE Linux AG
5 * This code is licensed under GPL.
9 * This algorithm assumes a grid configuration as follows:
12 * org. : 1x1 2x1 2x2 2x3 2x4
16 #include <device/pci_def.h>
17 #include "arch/romcc_io.h"
20 * Until we have a completely dynamic setup we want
21 * to be able to map different cpu graphs.
29 * set some default values. These are used if they are not
30 * differently defined in the motherboard's auto.c file.
31 * See src/mainboard/amd/quartet/auto.c for an example.
34 #ifndef CONNECTION_0_1
35 #define CONNECTION_0_1 ACROSS
38 #ifndef CONNECTION_0_2
39 #define CONNECTION_0_2 UP
42 #ifndef CONNECTION_1_3
43 #define CONNECTION_1_3 UP
46 /* when generating a temporary row configuration we
47 * don't want broadcast to be enabled for that node.
50 #define generate_temp_row(x...) ((generate_row(x)&(~0x0f0000))|0x010000)
51 #define clear_temp_row(x) fill_row(x,7,DEFAULT)
52 #define enable_bsp_routing() enable_routing(0)
54 #define NODE_HT(x) PCI_DEV(0,24+x,0)
55 #define NODE_MP(x) PCI_DEV(0,24+x,1)
56 #define NODE_MC(x) PCI_DEV(0,24+x,3)
58 #define DEFAULT 0x00010101 /* default row entry */
67 static void disable_probes(void)
69 /* disable read/write/fill probes for uniprocessor setup
70 * they don't make sense if only one cpu is available
73 /* Hypetransport Transaction Control Register
75 * [ 0: 0] Disable read byte probe
77 * 1 = Probes not issued
78 * [ 1: 1] Disable Read Doubleword probe
80 * 1 = Probes not issued
81 * [ 2: 2] Disable write byte probes
83 * 1 = Probes not issued
84 * [ 3: 3] Disable Write Doubleword Probes
86 * 1 = Probes not issued.
87 * [10:10] Disable Fill Probe
88 * 0 = Probes issued for cache fills
89 * 1 = Probes not issued for cache fills.
94 print_debug("Disabling read/write/fill probes for UP... ");
96 val=pci_read_config32(NODE_HT(0), 0x68);
97 val |= (1<<10)|(1<<9)|(1<<8)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|(1 << 0);
98 pci_write_config32(NODE_HT(0), 0x68, val);
100 print_debug("done.\r\n");
104 static void enable_routing(u8 node)
108 /* HT Initialization Control Register
110 * [ 0: 0] Routing Table Disable
111 * 0 = Packets are routed according to routing tables
112 * 1 = Packets are routed according to the default link field
113 * [ 1: 1] Request Disable (BSP should clear this)
114 * 0 = Request packets may be generated
115 * 1 = Request packets may not be generated.
116 * [ 3: 2] Default Link (Read-only)
120 * 11 = CPU on same node
122 * - Scratch bit cleared by a cold reset
123 * [ 5: 5] BIOS Reset Detect
124 * - Scratch bit cleared by a cold reset
125 * [ 6: 6] INIT Detect
126 * - Scratch bit cleared by a warm or cold reset not by an INIT
130 /* Enable routing table */
131 print_debug("Enabling routing table for node ");
132 print_debug_hex32(node);
134 val=pci_read_config32(NODE_HT(node), 0x6c);
135 val &= ~((1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0));
136 pci_write_config32(NODE_HT(node), 0x6c, val);
138 print_debug(" done.\r\n");
141 #if CONFIG_MAX_CPUS > 1
143 static void rename_temp_node(u8 node)
147 print_debug("Renaming current temp node to ");
148 print_debug_hex32(node);
150 val=pci_read_config32(NODE_HT(7), 0x60);
151 val &= (~7); /* clear low bits. */
152 val |= node; /* new node */
153 pci_write_config32(NODE_HT(7), 0x60, val);
155 print_debug(" done.\r\n");
160 static bool check_connection(u8 src, u8 dest, u8 link)
162 /* this function does 2 things:
163 * 1) detect whether the coherent HT link is connected.
164 * 2) verify that the coherent hypertransport link
165 * is established and actually working by reading the
166 * remote node's vendor/device id
172 val=pci_read_config32(NODE_HT(src), 0x98+link);
173 if ( (val&0x17) != 0x03)
177 val=pci_read_config32(NODE_HT(dest),0);
178 if(val != 0x11001022)
184 static void optimize_connection(u8 node1, u8 link1, u8 node2, u8 link2)
186 static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
187 static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
188 uint16_t freq_cap1, freq_cap2, freq_cap, freq_mask;
189 uint8_t width_cap1, width_cap2, width_cap, width, ln_width1, ln_width2;
191 /* Set link width and frequency */
193 /* Get the frequency capabilities */
194 freq_cap1 = pci_read_config16(NODE_HT(node1), 0x80 + link1 + PCI_HT_CAP_HOST_FREQ_CAP);
195 freq_cap2 = pci_read_config16(NODE_HT(node2), 0x80 + link2 + PCI_HT_CAP_HOST_FREQ_CAP);
197 /* Calculate the highest possible frequency */
200 * This method of computing the fastes frequency is broken.
201 * Because the frequencies (i.e. 100Mhz) are not ordered.
203 freq = log2(freq_cap1 & freq_cap2 & 0xff);
205 /* Only allow supported frequencies 800Mhz and below */
206 freq = log2(freq_cap1 & freq_cap2 & 0x3f);
209 /* Set the Calulcated link frequency */
210 pci_write_config8(NODE_HT(node1), 0x80 + link1 + PCI_HT_CAP_HOST_FREQ, freq);
211 pci_write_config8(NODE_HT(node2), 0x80 + link2 + PCI_HT_CAP_HOST_FREQ, freq);
213 /* Get the width capabilities */
214 width_cap1 = pci_read_config8(NODE_HT(node1), 0x80 + link1 + PCI_HT_CAP_HOST_WIDTH);
215 width_cap2 = pci_read_config8(NODE_HT(node2), 0x80 + link2 + PCI_HT_CAP_HOST_WIDTH);
217 /* Calculate node1's input width */
218 ln_width1 = link_width_to_pow2[width_cap1 & 7];
219 ln_width2 = link_width_to_pow2[(width_cap2 >> 4) & 7];
220 if (ln_width1 > ln_width2) {
221 ln_width1 = ln_width2;
223 width = pow2_to_link_width[ln_width1];
224 /* Calculate node1's output width */
225 ln_width1 = link_width_to_pow2[(width_cap1 >> 4) & 7];
226 ln_width2 = link_width_to_pow2[width_cap2 & 7];
227 if (ln_width1 > ln_width2) {
228 ln_width1 = ln_width2;
230 width |= pow2_to_link_width[ln_width1] << 4;
232 /* Set node1's widths */
233 pci_write_config8(NODE_HT(node1), 0x80 + link1 + PCI_HT_CAP_HOST_WIDTH + 1, width);
235 /* Set node2's widths */
236 width = ((width & 0x70) >> 4) | ((width & 0x7) << 4);
237 pci_write_config8(NODE_HT(node2), 0x80 + link2 + PCI_HT_CAP_HOST_WIDTH + 1, width);
240 static void fill_row(u8 node, u8 row, u32 value)
243 print_debug("fill_row: pci_write_config32(");
244 print_debug_hex32(NODE_HT(node));
245 print_debug_char(',');
246 print_debug_hex32(0x40 + (row << 2));
247 print_debug_char(',');
248 print_debug_hex32(value);
249 print_debug(")\r\n");
251 pci_write_config32(NODE_HT(node), 0x40+(row<<2), value);
254 static void setup_row(u8 source, u8 dest, u8 cpus)
257 printk_spew("setting up link from node %d to %d (%d cpus)\r\n",
261 fill_row(source,dest,generate_row(source,dest,cpus));
264 static void setup_temp_row(u8 source, u8 dest, u8 cpus)
267 printk_spew("setting up temp. link from node %d to %d (%d cpus)\r\n",
271 fill_row(source,7,generate_temp_row(source,dest,cpus));
274 static void setup_node(u8 node, u8 cpus)
277 for(row=0; row<cpus; row++)
278 setup_row(node, row, cpus);
281 static void setup_remote_row(u8 source, u8 dest, u8 cpus)
283 fill_row(7, dest, generate_row(source, dest, cpus));
286 static void setup_remote_node(u8 node, u8 cpus)
288 static const uint8_t pci_reg[] = {
289 0x44, 0x4c, 0x54, 0x5c, 0x64, 0x6c, 0x74, 0x7c,
290 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78,
291 0x84, 0x8c, 0x94, 0x9c, 0xa4, 0xac, 0xb4, 0xbc,
292 0x80, 0x88, 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8,
293 0xc4, 0xcc, 0xd4, 0xdc,
294 0xc0, 0xc8, 0xd0, 0xd8,
295 0xe0, 0xe4, 0xe8, 0xec,
300 print_debug("setup_remote_node\r\n");
302 for(row=0; row<cpus; row++)
303 setup_remote_row(node, row, cpus);
305 /* copy the default resource map from node 0 */
306 for(i = 0; i < sizeof(pci_reg)/sizeof(pci_reg[0]); i++) {
311 print_debug("copying reg: ");
312 print_debug_hex8(reg);
315 value = pci_read_config32(NODE_MP(0), reg);
316 pci_write_config32(NODE_MP(7), reg, value);
320 print_debug("setup_remote_done\r\n");
326 #if CONFIG_MAX_CPUS > 2
327 static void setup_temp_node(u8 node, u8 cpus)
330 for(row=0; row<cpus; row++)
331 fill_row(7,row,generate_row(node,row,cpus));
335 static u8 setup_uniprocessor(void)
337 print_debug("Enabling UP settings\r\n");
342 #if CONFIG_MAX_CPUS > 1
343 static u8 setup_smp(void)
347 print_debug("Enabling SMP settings\r\n");
350 /* Setup and check a temporary connection to node 1 */
351 setup_temp_row(0,1,cpus);
353 if (!check_connection(0, 7, CONNECTION_0_1)) {
354 print_debug("No connection to Node 1.\r\n");
355 clear_temp_row(0); /* delete temp connection */
356 setup_uniprocessor(); /* and get up working */
360 /* We found 2 nodes so far */
361 optimize_connection(0, ACROSS, 7, ACROSS);
362 setup_node(0, cpus); /* Node 1 is there. Setup Node 0 correctly */
363 setup_remote_node(1, cpus); /* Setup the routes on the remote node */
364 rename_temp_node(1); /* Rename Node 7 to Node 1 */
365 enable_routing(1); /* Enable routing on Node 1 */
367 clear_temp_row(0); /* delete temporary connection */
369 #if CONFIG_MAX_CPUS > 2
372 /* Setup and check temporary connection from Node 0 to Node 2 */
373 setup_temp_row(0,2,cpus);
375 if (!check_connection(0, 7, CONNECTION_0_2)) {
376 print_debug("No connection to Node 2.\r\n");
377 clear_temp_row(0); /* delete temp connection */
381 /* We found 3 nodes so far. Now setup a temporary
382 * connection from node 0 to node 3 via node 1
385 setup_temp_row(0,1,cpus); /* temp. link between nodes 0 and 1 */
386 setup_temp_row(1,3,cpus); /* temp. link between nodes 1 and 3 */
388 if (!check_connection(1, 7, CONNECTION_1_3)) {
389 print_debug("No connection to Node 3.\r\n");
390 clear_temp_row(0); /* delete temp connection */
391 clear_temp_row(1); /* delete temp connection */
395 /* We found 4 nodes so far. Now setup all nodes for 4p */
397 setup_node(0, cpus); /* The first 2 nodes are configured */
398 setup_node(1, cpus); /* already. Just configure them for 4p */
400 setup_temp_row(0,2,cpus);
401 setup_temp_node(2,cpus);
405 setup_temp_row(0,1,cpus);
406 setup_temp_row(1,3,cpus);
407 setup_temp_node(3,cpus);
409 enable_routing(3); /* enable routing on node 3 (temp.) */
417 print_debug_hex32(cpus);
418 print_debug(" nodes initialized.\r\n");
423 #if CONFIG_MAX_CPUS > 1
424 static unsigned detect_mp_capabilities(unsigned cpus)
426 unsigned node, row, mask;
430 print_debug("detect_mp_capabilities: ");
431 print_debug_hex32(cpus);
435 mask=0x06; /* BigMPCap */
437 mask=0x02; /* MPCap */
439 for (node=0; node<cpus; node++) {
440 if ((pci_read_config32(NODE_MC(node), 0xe8) & mask)!=mask)
447 /* one of our cpus is not mp capable */
449 print_debug("One of the CPUs is not MP capable. Going back to UP\r\n");
451 for (node=cpus; node>0; node--)
452 for (row=cpus; row>0; row--)
453 fill_row(NODE_HT(node-1), row-1, DEFAULT);
455 return setup_uniprocessor();
460 static void coherent_ht_finalize(unsigned cpus)
465 /* set up cpu count and node count and enable Limit
466 * Config Space Range for all available CPUs.
467 * Also clear non coherent hypertransport bus range
468 * registers on Hammer A0 revision.
472 print_debug("coherent_ht_finalize\r\n");
474 rev_a0= is_cpu_rev_a0();
476 for (node=0; node<cpus; node++) {
478 val=pci_read_config32(NODE_HT(node), 0x60);
479 val &= (~0x000F0070);
480 val |= ((cpus-1)<<16)|((cpus-1)<<4);
481 pci_write_config32(NODE_HT(node),0x60,val);
483 val=pci_read_config32(NODE_HT(node), 0x68);
487 val |= 0x0f00c800; // 0x00008000->0f00c800 BY LYH
489 pci_write_config32(NODE_HT(node),0x68,val);
492 pci_write_config32(NODE_HT(node),0x94,0);
493 pci_write_config32(NODE_HT(node),0xb4,0);
494 pci_write_config32(NODE_HT(node),0xd4,0);
498 print_debug("done\r\n");
502 static int setup_coherent_ht_domain(void)
505 int reset_needed = 0;
507 enable_bsp_routing();
509 #if CONFIG_MAX_CPUS == 1
510 cpus=setup_uniprocessor();
513 cpus=detect_mp_capabilities(cpus);
515 coherent_ht_finalize(cpus);
517 /* FIXME this should probably go away again. */
518 coherent_ht_mainboard(cpus);