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");
105 #define WAIT_TIMES 1000
106 static void wait_ap_stop(u8 node)
110 for(i=0;i<WAIT_TIMES;i++) {
112 regx = pci_read_config32(NODE_HT(node),0x6c);
113 if((regx & (1<<4))==1) break;
115 reg = pci_read_config32(NODE_HT(node),0x6c);
116 reg &= ~(1<<4); // clear it
117 pci_write_config32(NODE_HT(node), 0x6c, reg);
120 static void notify_bsp_ap_is_stopped(void)
123 unsigned long apic_id;
124 apic_id = *((volatile unsigned long *)(APIC_DEFAULT_BASE+APIC_ID));
126 /* print_debug("applicaton cpu apic_id: ");
127 print_debug_hex32(apic_id);
129 if(apic_id!=0) { //AP apic_id == node_id ??
130 // set the ColdResetbit to notify BSP that AP is stopped
131 reg = pci_read_config32(NODE_HT(apic_id), 0x6C);
133 pci_write_config32(NODE_HT(apic_id), 0x6C, reg);
140 static void enable_routing(u8 node)
144 /* HT Initialization Control Register
146 * [ 0: 0] Routing Table Disable
147 * 0 = Packets are routed according to routing tables
148 * 1 = Packets are routed according to the default link field
149 * [ 1: 1] Request Disable (BSP should clear this)
150 * 0 = Request packets may be generated
151 * 1 = Request packets may not be generated.
152 * [ 3: 2] Default Link (Read-only)
156 * 11 = CPU on same node
158 * - Scratch bit cleared by a cold reset
159 * [ 5: 5] BIOS Reset Detect
160 * - Scratch bit cleared by a cold reset
161 * [ 6: 6] INIT Detect
162 * - Scratch bit cleared by a warm or cold reset not by an INIT
166 /* Enable routing table */
167 print_debug("Enabling routing table for node ");
168 print_debug_hex32(node);
170 val=pci_read_config32(NODE_HT(node), 0x6c);
171 val &= ~((1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0));
172 pci_write_config32(NODE_HT(node), 0x6c, val);
174 print_debug(" done.\r\n");
177 #if CONFIG_MAX_CPUS > 1
179 static void rename_temp_node(u8 node)
183 print_debug("Renaming current temp node to ");
184 print_debug_hex32(node);
186 val=pci_read_config32(NODE_HT(7), 0x60);
187 val &= (~7); /* clear low bits. */
188 val |= node; /* new node */
189 pci_write_config32(NODE_HT(7), 0x60, val);
200 print_debug(" done.\r\n");
205 static bool check_connection(u8 src, u8 dest, u8 link)
207 /* this function does 2 things:
208 * 1) detect whether the coherent HT link is connected.
209 * 2) verify that the coherent hypertransport link
210 * is established and actually working by reading the
211 * remote node's vendor/device id
217 val=pci_read_config32(NODE_HT(src), 0x98+link);
218 if ( (val&0x17) != 0x03)
222 val=pci_read_config32(NODE_HT(dest),0);
223 if(val != 0x11001022)
229 static void optimize_connection(u8 node1, u8 link1, u8 node2, u8 link2)
231 static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
232 static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
233 uint16_t freq_cap1, freq_cap2, freq_cap, freq_mask;
234 uint8_t width_cap1, width_cap2, width_cap, width, ln_width1, ln_width2;
236 /* Set link width and frequency */
238 /* Get the frequency capabilities */
239 freq_cap1 = pci_read_config16(NODE_HT(node1), 0x80 + link1 + PCI_HT_CAP_HOST_FREQ_CAP);
240 freq_cap2 = pci_read_config16(NODE_HT(node2), 0x80 + link2 + PCI_HT_CAP_HOST_FREQ_CAP);
242 /* Calculate the highest possible frequency */
245 * This method of computing the fastes frequency is broken.
246 * Because the frequencies (i.e. 100Mhz) are not ordered.
248 freq = log2(freq_cap1 & freq_cap2 & 0xff);
250 /* Only allow supported frequencies 800Mhz and below */
251 freq = log2(freq_cap1 & freq_cap2 & 0x3f);
254 /* Set the Calulcated link frequency */
255 pci_write_config8(NODE_HT(node1), 0x80 + link1 + PCI_HT_CAP_HOST_FREQ, freq);
256 pci_write_config8(NODE_HT(node2), 0x80 + link2 + PCI_HT_CAP_HOST_FREQ, freq);
258 /* Get the width capabilities */
259 width_cap1 = pci_read_config8(NODE_HT(node1), 0x80 + link1 + PCI_HT_CAP_HOST_WIDTH);
260 width_cap2 = pci_read_config8(NODE_HT(node2), 0x80 + link2 + PCI_HT_CAP_HOST_WIDTH);
262 /* Calculate node1's input width */
263 ln_width1 = link_width_to_pow2[width_cap1 & 7];
264 ln_width2 = link_width_to_pow2[(width_cap2 >> 4) & 7];
265 if (ln_width1 > ln_width2) {
266 ln_width1 = ln_width2;
268 width = pow2_to_link_width[ln_width1];
269 /* Calculate node1's output width */
270 ln_width1 = link_width_to_pow2[(width_cap1 >> 4) & 7];
271 ln_width2 = link_width_to_pow2[width_cap2 & 7];
272 if (ln_width1 > ln_width2) {
273 ln_width1 = ln_width2;
275 width |= pow2_to_link_width[ln_width1] << 4;
277 /* Set node1's widths */
278 pci_write_config8(NODE_HT(node1), 0x80 + link1 + PCI_HT_CAP_HOST_WIDTH + 1, width);
280 /* Set node2's widths */
281 width = ((width & 0x70) >> 4) | ((width & 0x7) << 4);
282 pci_write_config8(NODE_HT(node2), 0x80 + link2 + PCI_HT_CAP_HOST_WIDTH + 1, width);
285 static void fill_row(u8 node, u8 row, u32 value)
288 print_debug("fill_row: pci_write_config32(");
289 print_debug_hex32(NODE_HT(node));
290 print_debug_char(',');
291 print_debug_hex32(0x40 + (row << 2));
292 print_debug_char(',');
293 print_debug_hex32(value);
294 print_debug(")\r\n");
296 pci_write_config32(NODE_HT(node), 0x40+(row<<2), value);
299 static void setup_row(u8 source, u8 dest, u8 cpus)
302 printk_spew("setting up link from node %d to %d (%d cpus)\r\n",
306 fill_row(source,dest,generate_row(source,dest,cpus));
309 static void setup_temp_row(u8 source, u8 dest, u8 cpus)
312 printk_spew("setting up temp. link from node %d to %d (%d cpus)\r\n",
316 fill_row(source,7,generate_temp_row(source,dest,cpus));
319 static void setup_node(u8 node, u8 cpus)
322 for(row=0; row<cpus; row++)
323 setup_row(node, row, cpus);
326 static void setup_remote_row(u8 source, u8 dest, u8 cpus)
328 fill_row(7, dest, generate_row(source, dest, cpus));
331 static void setup_remote_node(u8 node, u8 cpus)
333 static const uint8_t pci_reg[] = {
334 0x44, 0x4c, 0x54, 0x5c, 0x64, 0x6c, 0x74, 0x7c,
335 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78,
336 0x84, 0x8c, 0x94, 0x9c, 0xa4, 0xac, 0xb4, 0xbc,
337 0x80, 0x88, 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8,
338 0xc4, 0xcc, 0xd4, 0xdc,
339 0xc0, 0xc8, 0xd0, 0xd8,
340 0xe0, 0xe4, 0xe8, 0xec,
345 print_debug("setup_remote_node\r\n");
347 for(row=0; row<cpus; row++)
348 setup_remote_row(node, row, cpus);
350 /* copy the default resource map from node 0 */
351 for(i = 0; i < sizeof(pci_reg)/sizeof(pci_reg[0]); i++) {
356 print_debug("copying reg: ");
357 print_debug_hex8(reg);
360 value = pci_read_config32(NODE_MP(0), reg);
361 pci_write_config32(NODE_MP(7), reg, value);
365 print_debug("setup_remote_done\r\n");
371 #if CONFIG_MAX_CPUS > 2
372 static void setup_temp_node(u8 node, u8 cpus)
375 for(row=0; row<cpus; row++)
376 fill_row(7,row,generate_row(node,row,cpus));
380 static u8 setup_uniprocessor(void)
382 print_debug("Enabling UP settings\r\n");
387 #if CONFIG_MAX_CPUS > 1
388 static u8 setup_smp(void)
392 print_debug("Enabling SMP settings\r\n");
395 /* Setup and check a temporary connection to node 1 */
396 setup_temp_row(0,1,cpus);
398 if (!check_connection(0, 7, CONNECTION_0_1)) {
399 print_debug("No connection to Node 1.\r\n");
400 clear_temp_row(0); /* delete temp connection */
401 setup_uniprocessor(); /* and get up working */
405 /* We found 2 nodes so far */
406 optimize_connection(0, ACROSS, 7, ACROSS);
407 setup_node(0, cpus); /* Node 1 is there. Setup Node 0 correctly */
408 setup_remote_node(1, cpus); /* Setup the routes on the remote node */
409 rename_temp_node(1); /* Rename Node 7 to Node 1 */
410 enable_routing(1); /* Enable routing on Node 1 */
412 clear_temp_row(0); /* delete temporary connection */
414 #if CONFIG_MAX_CPUS > 2
417 /* Setup and check temporary connection from Node 0 to Node 2 */
418 setup_temp_row(0,2,cpus);
420 if (!check_connection(0, 7, CONNECTION_0_2)) {
421 print_debug("No connection to Node 2.\r\n");
422 clear_temp_row(0); /* delete temp connection */
426 /* We found 3 nodes so far. Now setup a temporary
427 * connection from node 0 to node 3 via node 1
430 setup_temp_row(0,1,cpus); /* temp. link between nodes 0 and 1 */
431 setup_temp_row(1,3,cpus); /* temp. link between nodes 1 and 3 */
433 if (!check_connection(1, 7, CONNECTION_1_3)) {
434 print_debug("No connection to Node 3.\r\n");
435 clear_temp_row(0); /* delete temp connection */
436 clear_temp_row(1); /* delete temp connection */
440 /* We found 4 nodes so far. Now setup all nodes for 4p */
442 setup_node(0, cpus); /* The first 2 nodes are configured */
443 setup_node(1, cpus); /* already. Just configure them for 4p */
445 setup_temp_row(0,2,cpus);
446 setup_temp_node(2,cpus);
450 setup_temp_row(0,1,cpus);
451 setup_temp_row(1,3,cpus);
452 setup_temp_node(3,cpus);
454 enable_routing(3); /* enable routing on node 3 (temp.) */
462 print_debug_hex32(cpus);
463 print_debug(" nodes initialized.\r\n");
468 #if CONFIG_MAX_CPUS > 1
469 static unsigned detect_mp_capabilities(unsigned cpus)
471 unsigned node, row, mask;
475 print_debug("detect_mp_capabilities: ");
476 print_debug_hex32(cpus);
480 mask=0x06; /* BigMPCap */
482 mask=0x02; /* MPCap */
484 for (node=0; node<cpus; node++) {
485 if ((pci_read_config32(NODE_MC(node), 0xe8) & mask)!=mask)
492 /* one of our cpus is not mp capable */
494 print_debug("One of the CPUs is not MP capable. Going back to UP\r\n");
496 for (node=cpus; node>0; node--)
497 for (row=cpus; row>0; row--)
498 fill_row(NODE_HT(node-1), row-1, DEFAULT);
500 return setup_uniprocessor();
505 static void coherent_ht_finalize(unsigned cpus)
510 /* set up cpu count and node count and enable Limit
511 * Config Space Range for all available CPUs.
512 * Also clear non coherent hypertransport bus range
513 * registers on Hammer A0 revision.
517 print_debug("coherent_ht_finalize\r\n");
519 rev_a0= is_cpu_rev_a0();
521 for (node=0; node<cpus; node++) {
523 val=pci_read_config32(NODE_HT(node), 0x60);
524 val &= (~0x000F0070);
525 val |= ((cpus-1)<<16)|((cpus-1)<<4);
526 pci_write_config32(NODE_HT(node),0x60,val);
528 val=pci_read_config32(NODE_HT(node), 0x68);
532 val |= 0x0f00c800; // 0x00008000->0f00c800 BY LYH
534 pci_write_config32(NODE_HT(node),0x68,val);
537 pci_write_config32(NODE_HT(node),0x94,0);
538 pci_write_config32(NODE_HT(node),0xb4,0);
539 pci_write_config32(NODE_HT(node),0xd4,0);
543 print_debug("done\r\n");
547 static int setup_coherent_ht_domain(void)
550 int reset_needed = 0;
552 enable_bsp_routing();
554 #if CONFIG_MAX_CPUS == 1
555 cpus=setup_uniprocessor();
558 cpus=detect_mp_capabilities(cpus);
560 coherent_ht_finalize(cpus);
562 /* FIXME this should probably go away again. */
563 coherent_ht_mainboard(cpus);