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_0
43 #define CONNECTION_1_0 ACROSS
46 #ifndef CONNECTION_1_3
47 #define CONNECTION_1_3 UP
50 /* when generating a temporary row configuration we
51 * don't want broadcast to be enabled for that node.
54 #define generate_temp_row(x...) ((generate_row(x)&(~0x0f0000))|0x010000)
55 #define clear_temp_row(x) fill_row(x,7,DEFAULT)
56 #define enable_bsp_routing() enable_routing(0)
58 #define NODE_HT(x) PCI_DEV(0,24+x,0)
59 #define NODE_MP(x) PCI_DEV(0,24+x,1)
60 #define NODE_MC(x) PCI_DEV(0,24+x,3)
62 #define DEFAULT 0x00010101 /* default row entry */
71 static void disable_probes(void)
73 /* disable read/write/fill probes for uniprocessor setup
74 * they don't make sense if only one cpu is available
77 /* Hypetransport Transaction Control Register
79 * [ 0: 0] Disable read byte probe
81 * 1 = Probes not issued
82 * [ 1: 1] Disable Read Doubleword probe
84 * 1 = Probes not issued
85 * [ 2: 2] Disable write byte probes
87 * 1 = Probes not issued
88 * [ 3: 3] Disable Write Doubleword Probes
90 * 1 = Probes not issued.
91 * [10:10] Disable Fill Probe
92 * 0 = Probes issued for cache fills
93 * 1 = Probes not issued for cache fills.
98 print_debug("Disabling read/write/fill probes for UP... ");
100 val=pci_read_config32(NODE_HT(0), 0x68);
101 val |= (1<<10)|(1<<9)|(1<<8)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|(1 << 0);
102 pci_write_config32(NODE_HT(0), 0x68, val);
104 print_debug("done.\r\n");
109 #define WAIT_TIMES 1000
110 static void wait_ap_stop(u8 node)
114 for(i=0;i<WAIT_TIMES;i++) {
116 regx = pci_read_config32(NODE_HT(node),0x6c);
117 if((regx & (1<<4))==1) break;
119 reg = pci_read_config32(NODE_HT(node),0x6c);
120 reg &= ~(1<<4); // clear it
121 pci_write_config32(NODE_HT(node), 0x6c, reg);
124 static void notify_bsp_ap_is_stopped(void)
127 unsigned long apic_id;
128 apic_id = *((volatile unsigned long *)(APIC_DEFAULT_BASE+APIC_ID));
130 /* print_debug("applicaton cpu apic_id: ");
131 print_debug_hex32(apic_id);
133 if(apic_id!=0) { //AP apic_id == node_id ??
134 // set the ColdResetbit to notify BSP that AP is stopped
135 reg = pci_read_config32(NODE_HT(apic_id), 0x6C);
137 pci_write_config32(NODE_HT(apic_id), 0x6C, reg);
144 static void enable_routing(u8 node)
148 /* HT Initialization Control Register
150 * [ 0: 0] Routing Table Disable
151 * 0 = Packets are routed according to routing tables
152 * 1 = Packets are routed according to the default link field
153 * [ 1: 1] Request Disable (BSP should clear this)
154 * 0 = Request packets may be generated
155 * 1 = Request packets may not be generated.
156 * [ 3: 2] Default Link (Read-only)
160 * 11 = CPU on same node
162 * - Scratch bit cleared by a cold reset
163 * [ 5: 5] BIOS Reset Detect
164 * - Scratch bit cleared by a cold reset
165 * [ 6: 6] INIT Detect
166 * - Scratch bit cleared by a warm or cold reset not by an INIT
170 /* Enable routing table */
171 print_debug("Enabling routing table for node ");
172 print_debug_hex32(node);
174 val=pci_read_config32(NODE_HT(node), 0x6c);
175 val &= ~((1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0));
176 pci_write_config32(NODE_HT(node), 0x6c, val);
178 print_debug(" done.\r\n");
181 #if CONFIG_MAX_CPUS > 1
183 static void rename_temp_node(u8 node)
187 print_debug("Renaming current temp node to ");
188 print_debug_hex32(node);
190 val=pci_read_config32(NODE_HT(7), 0x60);
191 val &= (~7); /* clear low bits. */
192 val |= node; /* new node */
193 pci_write_config32(NODE_HT(7), 0x60, val);
204 print_debug(" done.\r\n");
209 static bool check_connection(u8 src, u8 dest, u8 link)
211 /* this function does 2 things:
212 * 1) detect whether the coherent HT link is connected.
213 * 2) verify that the coherent hypertransport link
214 * is established and actually working by reading the
215 * remote node's vendor/device id
221 val=pci_read_config32(NODE_HT(src), 0x98+link);
222 if ( (val&0x17) != 0x03)
226 val=pci_read_config32(NODE_HT(dest),0);
227 if(val != 0x11001022)
233 static void optimize_connection(u8 node1, u8 link1, u8 node2, u8 link2)
235 static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
236 static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
237 uint16_t freq_cap1, freq_cap2, freq_cap, freq_mask;
238 uint8_t width_cap1, width_cap2, width_cap, width, ln_width1, ln_width2;
240 /* Set link width and frequency */
242 /* Get the frequency capabilities */
243 freq_cap1 = pci_read_config16(NODE_HT(node1), 0x80 + link1 + PCI_HT_CAP_HOST_FREQ_CAP);
244 freq_cap2 = pci_read_config16(NODE_HT(node2), 0x80 + link2 + PCI_HT_CAP_HOST_FREQ_CAP);
246 /* Calculate the highest possible frequency */
249 * This method of computing the fastes frequency is broken.
250 * Because the frequencies (i.e. 100Mhz) are not ordered.
252 freq = log2(freq_cap1 & freq_cap2 & 0xff);
254 /* Only allow supported frequencies 800Mhz and below */
255 freq = log2(freq_cap1 & freq_cap2 & 0x3f);
258 /* Set the Calulcated link frequency */
259 pci_write_config8(NODE_HT(node1), 0x80 + link1 + PCI_HT_CAP_HOST_FREQ, freq);
260 pci_write_config8(NODE_HT(node2), 0x80 + link2 + PCI_HT_CAP_HOST_FREQ, freq);
262 /* Get the width capabilities */
263 width_cap1 = pci_read_config8(NODE_HT(node1), 0x80 + link1 + PCI_HT_CAP_HOST_WIDTH);
264 width_cap2 = pci_read_config8(NODE_HT(node2), 0x80 + link2 + PCI_HT_CAP_HOST_WIDTH);
266 /* Calculate node1's input width */
267 ln_width1 = link_width_to_pow2[width_cap1 & 7];
268 ln_width2 = link_width_to_pow2[(width_cap2 >> 4) & 7];
269 if (ln_width1 > ln_width2) {
270 ln_width1 = ln_width2;
272 width = pow2_to_link_width[ln_width1];
273 /* Calculate node1's output width */
274 ln_width1 = link_width_to_pow2[(width_cap1 >> 4) & 7];
275 ln_width2 = link_width_to_pow2[width_cap2 & 7];
276 if (ln_width1 > ln_width2) {
277 ln_width1 = ln_width2;
279 width |= pow2_to_link_width[ln_width1] << 4;
281 /* Set node1's widths */
282 pci_write_config8(NODE_HT(node1), 0x80 + link1 + PCI_HT_CAP_HOST_WIDTH + 1, width);
284 /* Set node2's widths */
285 width = ((width & 0x70) >> 4) | ((width & 0x7) << 4);
286 pci_write_config8(NODE_HT(node2), 0x80 + link2 + PCI_HT_CAP_HOST_WIDTH + 1, width);
289 static void fill_row(u8 node, u8 row, u32 value)
292 print_debug("fill_row: pci_write_config32(");
293 print_debug_hex32(NODE_HT(node));
294 print_debug_char(',');
295 print_debug_hex32(0x40 + (row << 2));
296 print_debug_char(',');
297 print_debug_hex32(value);
298 print_debug(")\r\n");
300 pci_write_config32(NODE_HT(node), 0x40+(row<<2), value);
303 static void setup_row(u8 source, u8 dest, u8 cpus)
306 printk_spew("setting up link from node %d to %d (%d cpus)\r\n",
310 fill_row(source,dest,generate_row(source,dest,cpus));
313 static void setup_temp_row(u8 source, u8 dest, u8 cpus)
316 printk_spew("setting up temp. link from node %d to %d (%d cpus)\r\n",
320 fill_row(source,7,generate_temp_row(source,dest,cpus));
323 static void setup_node(u8 node, u8 cpus)
326 for(row=0; row<cpus; row++)
327 setup_row(node, row, cpus);
330 static void setup_remote_row(u8 source, u8 dest, u8 cpus)
332 fill_row(7, dest, generate_row(source, dest, cpus));
335 static void setup_remote_node(u8 node, u8 cpus)
337 static const uint8_t pci_reg[] = {
338 0x44, 0x4c, 0x54, 0x5c, 0x64, 0x6c, 0x74, 0x7c,
339 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78,
340 0x84, 0x8c, 0x94, 0x9c, 0xa4, 0xac, 0xb4, 0xbc,
341 0x80, 0x88, 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8,
342 0xc4, 0xcc, 0xd4, 0xdc,
343 0xc0, 0xc8, 0xd0, 0xd8,
344 0xe0, 0xe4, 0xe8, 0xec,
349 print_debug("setup_remote_node\r\n");
351 for(row=0; row<cpus; row++)
352 setup_remote_row(node, row, cpus);
354 /* copy the default resource map from node 0 */
355 for(i = 0; i < sizeof(pci_reg)/sizeof(pci_reg[0]); i++) {
360 print_debug("copying reg: ");
361 print_debug_hex8(reg);
364 value = pci_read_config32(NODE_MP(0), reg);
365 pci_write_config32(NODE_MP(7), reg, value);
369 print_debug("setup_remote_done\r\n");
375 #if CONFIG_MAX_CPUS > 2
376 static void setup_temp_node(u8 node, u8 cpus)
379 for(row=0; row<cpus; row++)
380 fill_row(7,row,generate_row(node,row,cpus));
384 static u8 setup_uniprocessor(void)
386 print_debug("Enabling UP settings\r\n");
391 #if CONFIG_MAX_CPUS > 1
392 static u8 setup_smp(void)
396 print_debug("Enabling SMP settings\r\n");
399 /* Setup and check a temporary connection to node 1 */
400 setup_temp_row(0,1,cpus);
402 if (!check_connection(0, 7, CONNECTION_0_1)) {
403 print_debug("No connection to Node 1.\r\n");
404 clear_temp_row(0); /* delete temp connection */
405 setup_uniprocessor(); /* and get up working */
409 /* We found 2 nodes so far */
410 optimize_connection(0, CONNECTION_0_1, 7, CONNECTION_1_0);
411 setup_node(0, cpus); /* Node 1 is there. Setup Node 0 correctly */
412 setup_remote_node(1, cpus); /* Setup the routes on the remote node */
413 rename_temp_node(1); /* Rename Node 7 to Node 1 */
414 enable_routing(1); /* Enable routing on Node 1 */
416 clear_temp_row(0); /* delete temporary connection */
418 #if CONFIG_MAX_CPUS > 2
421 /* Setup and check temporary connection from Node 0 to Node 2 */
422 setup_temp_row(0,2,cpus);
424 if (!check_connection(0, 7, CONNECTION_0_2)) {
425 print_debug("No connection to Node 2.\r\n");
426 clear_temp_row(0); /* delete temp connection */
430 /* We found 3 nodes so far. Now setup a temporary
431 * connection from node 0 to node 3 via node 1
434 setup_temp_row(0,1,cpus); /* temp. link between nodes 0 and 1 */
435 setup_temp_row(1,3,cpus); /* temp. link between nodes 1 and 3 */
437 if (!check_connection(1, 7, CONNECTION_1_3)) {
438 print_debug("No connection to Node 3.\r\n");
439 clear_temp_row(0); /* delete temp connection */
440 clear_temp_row(1); /* delete temp connection */
444 /* We found 4 nodes so far. Now setup all nodes for 4p */
446 setup_node(0, cpus); /* The first 2 nodes are configured */
447 setup_node(1, cpus); /* already. Just configure them for 4p */
449 setup_temp_row(0,2,cpus);
450 setup_temp_node(2,cpus);
454 setup_temp_row(0,1,cpus);
455 setup_temp_row(1,3,cpus);
456 setup_temp_node(3,cpus);
458 enable_routing(3); /* enable routing on node 3 (temp.) */
466 print_debug_hex32(cpus);
467 print_debug(" nodes initialized.\r\n");
472 #if CONFIG_MAX_CPUS > 1
473 static unsigned detect_mp_capabilities(unsigned cpus)
475 unsigned node, row, mask;
479 print_debug("detect_mp_capabilities: ");
480 print_debug_hex32(cpus);
484 mask=0x06; /* BigMPCap */
486 mask=0x02; /* MPCap */
488 for (node=0; node<cpus; node++) {
489 if ((pci_read_config32(NODE_MC(node), 0xe8) & mask)!=mask)
496 /* one of our cpus is not mp capable */
498 print_debug("One of the CPUs is not MP capable. Going back to UP\r\n");
500 for (node=cpus; node>0; node--)
501 for (row=cpus; row>0; row--)
502 fill_row(NODE_HT(node-1), row-1, DEFAULT);
504 return setup_uniprocessor();
509 static void coherent_ht_finalize(unsigned cpus)
514 /* set up cpu count and node count and enable Limit
515 * Config Space Range for all available CPUs.
516 * Also clear non coherent hypertransport bus range
517 * registers on Hammer A0 revision.
521 print_debug("coherent_ht_finalize\r\n");
523 rev_a0= is_cpu_rev_a0();
525 for (node=0; node<cpus; node++) {
527 val=pci_read_config32(NODE_HT(node), 0x60);
528 val &= (~0x000F0070);
529 val |= ((cpus-1)<<16)|((cpus-1)<<4);
530 pci_write_config32(NODE_HT(node),0x60,val);
532 val=pci_read_config32(NODE_HT(node), 0x68);
536 val |= 0x0f00c800; // 0x00008000->0f00c800 BY LYH
538 pci_write_config32(NODE_HT(node),0x68,val);
541 pci_write_config32(NODE_HT(node),0x94,0);
542 pci_write_config32(NODE_HT(node),0xb4,0);
543 pci_write_config32(NODE_HT(node),0xd4,0);
547 print_debug("done\r\n");
551 static int setup_coherent_ht_domain(void)
554 int reset_needed = 0;
556 enable_bsp_routing();
558 #if CONFIG_MAX_CPUS == 1
559 cpus=setup_uniprocessor();
562 cpus=detect_mp_capabilities(cpus);
564 coherent_ht_finalize(cpus);
566 /* FIXME this should probably go away again. */
567 coherent_ht_mainboard(cpus);