1 /* coherent hypertransport initialization for AMD64
2 * written by Stefan Reinauer <stepan@openbios.info>
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 #define WAIT_TIMES 1000
105 static void wait_ap_stop(u8 node)
109 for(i=0;i<WAIT_TIMES;i++) {
111 regx = pci_read_config32(NODE_HT(node),0x6c);
112 if((regx & (1<<4))==1) break;
114 reg = pci_read_config32(NODE_HT(node),0x6c);
115 reg &= ~(1<<4); // clear it
116 pci_write_config32(NODE_HT(node), 0x6c, reg);
119 static void notify_bsp_ap_is_stopped(void)
122 unsigned long apic_id;
123 apic_id = *((volatile unsigned long *)(APIC_DEFAULT_BASE+APIC_ID));
126 print_debug("applicaton cpu apic_id: ");
127 print_debug_hex32(apic_id);
130 /* AP apic_id == node_id ? */
132 /* set the ColdResetbit to notify BSP that AP is stopped */
133 reg = pci_read_config32(NODE_HT(apic_id), 0x6C);
135 pci_write_config32(NODE_HT(apic_id), 0x6C, reg);
141 static void enable_routing(u8 node)
145 /* HT Initialization Control Register
147 * [ 0: 0] Routing Table Disable
148 * 0 = Packets are routed according to routing tables
149 * 1 = Packets are routed according to the default link field
150 * [ 1: 1] Request Disable (BSP should clear this)
151 * 0 = Request packets may be generated
152 * 1 = Request packets may not be generated.
153 * [ 3: 2] Default Link (Read-only)
157 * 11 = CPU on same node
159 * - Scratch bit cleared by a cold reset
160 * [ 5: 5] BIOS Reset Detect
161 * - Scratch bit cleared by a cold reset
162 * [ 6: 6] INIT Detect
163 * - Scratch bit cleared by a warm or cold reset not by an INIT
167 /* Enable routing table */
168 print_debug("Enabling routing table for node ");
169 print_debug_hex32(node);
171 val=pci_read_config32(NODE_HT(node), 0x6c);
172 val &= ~((1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0));
173 pci_write_config32(NODE_HT(node), 0x6c, val);
182 print_debug(" done.\r\n");
185 #if CONFIG_MAX_CPUS > 1
187 static void rename_temp_node(u8 node)
191 print_debug("Renaming current temp node to ");
192 print_debug_hex32(node);
194 val=pci_read_config32(NODE_HT(7), 0x60);
195 val &= (~7); /* clear low bits. */
196 val |= node; /* new node */
197 pci_write_config32(NODE_HT(7), 0x60, val);
199 print_debug(" done.\r\n");
204 static bool check_connection(u8 src, u8 dest, u8 link)
206 /* this function does 2 things:
207 * 1) detect whether the coherent HT link is connected.
208 * 2) verify that the coherent hypertransport link
209 * is established and actually working by reading the
210 * remote node's vendor/device id
216 val=pci_read_config32(NODE_HT(src), 0x98+link);
217 if ( (val&0x17) != 0x03)
221 val=pci_read_config32(NODE_HT(dest),0);
222 if(val != 0x11001022)
228 static void fill_row(u8 node, u8 row, u32 value)
231 print_debug("fill_row: pci_write_config32(");
232 print_debug_hex32(NODE_HT(node));
233 print_debug_char(',');
234 print_debug_hex32(0x40 + (row << 2));
235 print_debug_char(',');
236 print_debug_hex32(value);
237 print_debug(")\r\n");
239 pci_write_config32(NODE_HT(node), 0x40+(row<<2), value);
242 static void setup_row(u8 source, u8 dest, u8 cpus)
245 printk_spew("setting up link from node %d to %d (%d cpus)\r\n",
249 fill_row(source,dest,generate_row(source,dest,cpus));
252 static void setup_temp_row(u8 source, u8 dest, u8 cpus)
255 printk_spew("setting up temp. link from node %d to %d (%d cpus)\r\n",
259 fill_row(source,7,generate_temp_row(source,dest,cpus));
262 static void setup_node(u8 node, u8 cpus)
265 for(row=0; row<cpus; row++)
266 setup_row(node, row, cpus);
269 static void setup_remote_row(u8 source, u8 dest, u8 cpus)
271 fill_row(7, dest, generate_row(source, dest, cpus));
274 static void setup_remote_node(u8 node, u8 cpus)
276 static const uint8_t pci_reg[] = {
277 0x44, 0x4c, 0x54, 0x5c, 0x64, 0x6c, 0x74, 0x7c,
278 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78,
279 0x84, 0x8c, 0x94, 0x9c, 0xa4, 0xac, 0xb4, 0xbc,
280 0x80, 0x88, 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8,
281 0xc4, 0xcc, 0xd4, 0xdc,
282 0xc0, 0xc8, 0xd0, 0xd8,
283 0xe0, 0xe4, 0xe8, 0xec,
288 print_debug("setup_remote_node\r\n");
290 for(row=0; row<cpus; row++)
291 setup_remote_row(node, row, cpus);
293 /* copy the default resource map from node 0 */
294 for(i = 0; i < sizeof(pci_reg)/sizeof(pci_reg[0]); i++) {
299 print_debug("copying reg: ");
300 print_debug_hex8(reg);
303 value = pci_read_config32(NODE_MP(0), reg);
304 pci_write_config32(NODE_MP(7), reg, value);
308 print_debug("setup_remote_done\r\n");
314 #if CONFIG_MAX_CPUS > 2
315 static void setup_temp_node(u8 node, u8 cpus)
318 for(row=0; row<cpus; row++)
319 fill_row(7,row,generate_row(node,row,cpus));
323 static u8 setup_uniprocessor(void)
325 print_debug("Enabling UP settings\r\n");
330 #if CONFIG_MAX_CPUS > 1
331 static u8 setup_smp(void)
335 print_debug("Enabling SMP settings\r\n");
338 /* Setup and check a temporary connection to node 1 */
339 setup_temp_row(0,1,cpus);
341 if (!check_connection(0, 7, CONNECTION_0_1)) {
342 print_debug("No connection to Node 1.\r\n");
343 clear_temp_row(0); /* delete temp connection */
344 setup_uniprocessor(); /* and get up working */
348 /* We found 2 nodes so far */
349 setup_node(0, cpus); /* Node 1 is there. Setup Node 0 correctly */
350 setup_remote_node(1, cpus); /* Setup the routes on the remote node */
351 rename_temp_node(1); /* Rename Node 7 to Node 1 */
352 enable_routing(1); /* Enable routing on Node 1 */
354 clear_temp_row(0); /* delete temporary connection */
356 #if CONFIG_MAX_CPUS > 2
359 /* Setup and check temporary connection from Node 0 to Node 2 */
360 setup_temp_row(0,2,cpus);
362 if (!check_connection(0, 7, CONNECTION_0_2)) {
363 print_debug("No connection to Node 2.\r\n");
364 clear_temp_row(0); /* delete temp connection */
368 /* We found 3 nodes so far. Now setup a temporary
369 * connection from node 0 to node 3 via node 1
372 setup_temp_row(0,1,cpus); /* temp. link between nodes 0 and 1 */
373 setup_temp_row(1,3,cpus); /* temp. link between nodes 1 and 3 */
375 if (!check_connection(1, 7, CONNECTION_1_3)) {
376 print_debug("No connection to Node 3.\r\n");
377 clear_temp_row(0); /* delete temp connection */
378 clear_temp_row(1); /* delete temp connection */
382 /* We found 4 nodes so far. Now setup all nodes for 4p */
384 setup_node(0, cpus); /* The first 2 nodes are configured */
385 setup_node(1, cpus); /* already. Just configure them for 4p */
387 setup_temp_row(0,2,cpus);
388 setup_temp_node(2,cpus);
392 setup_temp_row(0,1,cpus);
393 setup_temp_row(1,3,cpus);
394 setup_temp_node(3,cpus);
396 enable_routing(3); /* enable routing on node 3 (temp.) */
404 print_debug_hex32(cpus);
405 print_debug(" nodes initialized.\r\n");
410 #if CONFIG_MAX_CPUS > 1
411 static unsigned detect_mp_capabilities(unsigned cpus)
413 unsigned node, row, mask;
417 print_debug("detect_mp_capabilities: ");
418 print_debug_hex32(cpus);
422 mask=0x06; /* BigMPCap */
424 mask=0x02; /* MPCap */
426 for (node=0; node<cpus; node++) {
427 if ((pci_read_config32(NODE_MC(node), 0xe8) & mask)!=mask)
434 /* one of our cpus is not mp capable */
436 print_debug("One of the CPUs is not MP capable. Going back to UP\r\n");
438 for (node=cpus; node>0; node--)
439 for (row=cpus; row>0; row--)
440 fill_row(NODE_HT(node-1), row-1, DEFAULT);
442 return setup_uniprocessor();
447 /* this is a shrunken cpuid. */
449 static unsigned int cpuid(unsigned int op)
453 asm volatile ( "cpuid" : "=a" (ret) : "a" (op));
458 static void coherent_ht_finalize(unsigned cpus)
463 /* set up cpu count and node count and enable Limit
464 * Config Space Range for all available CPUs.
465 * Also clear non coherent hypertransport bus range
466 * registers on Hammer A0 revision.
470 print_debug("coherent_ht_finalize\r\n");
472 rev_a0=((cpuid(1)&0xffff)==0x0f10);
474 for (node=0; node<cpus; node++) {
476 val=pci_read_config32(NODE_HT(node), 0x60);
477 val &= (~0x000F0070);
478 val |= ((cpus-1)<<16)|((cpus-1)<<4);
479 pci_write_config32(NODE_HT(node),0x60,val);
481 val=pci_read_config32(NODE_HT(node), 0x68);
482 val |= 0x0f00c800; // 0x00008000->0f00c800 BY LYH
483 pci_write_config32(NODE_HT(node),0x68,val);
486 pci_write_config32(NODE_HT(node),0x94,0);
487 pci_write_config32(NODE_HT(node),0xb4,0);
488 pci_write_config32(NODE_HT(node),0xd4,0);
492 print_debug("done\r\n");
496 static int setup_coherent_ht_domain(void)
499 int reset_needed = 0;
501 enable_bsp_routing();
503 #if CONFIG_MAX_CPUS == 1
504 cpus=setup_uniprocessor();
507 cpus=detect_mp_capabilities(cpus);
509 coherent_ht_finalize(cpus);
511 /* this should probably go away again. */
512 coherent_ht_mainboard(cpus);