1 /* coherent hypertransport initialization for AMD64
3 * written by Stefan Reinauer <stepan@openbios.org>
4 * (c) 2003-2004 by SuSE Linux AG
6 * (c) 2004 Tyan Computer
7 * 2004.12 yhlu added support to create routing table dynamically.
8 * it also support 8 ways too. (8 ways ladder or 8 ways crossbar)
10 * This code is licensed under GPL.
14 * This algorithm assumes a grid configuration as follows:
17 * org. : 1x1 2x1 2x2 2x3 2x4
66 #include <device/pci_def.h>
67 #include <device/pci_ids.h>
68 #include <device/hypertransport_def.h>
69 #include "arch/romcc_io.h"
72 #define enable_bsp_routing() enable_routing(0)
74 #define NODE_HT(x) PCI_DEV(0,24+x,0)
75 #define NODE_MP(x) PCI_DEV(0,24+x,1)
76 #define NODE_MC(x) PCI_DEV(0,24+x,3)
78 #define DEFAULT 0x00010101 /* default row entry */
83 #ifndef CROSS_BAR_47_56
84 #define CROSS_BAR_47_56 0
87 #ifndef TRY_HIGH_FIRST
88 #define TRY_HIGH_FIRST 0
91 #ifndef K8_HT_FREQ_1G_SUPPORT
92 #define K8_HT_FREQ_1G_SUPPORT 0
95 #ifndef K8_HT_CHECK_PENDING_LINK
96 #if CONFIG_MAX_PHYSICAL_CPUS >= 4
97 #define K8_HT_CHECK_PENDING_LINK 1
99 #define K8_HT_CHECK_PENDING_LINK 0
103 #ifndef CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED
104 #define CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED 0
108 static inline void print_linkn (const char *strval, uint8_t byteval)
111 print_debug(strval); print_debug_hex8(byteval); print_debug("\r\n");
115 static void disable_probes(void)
117 /* disable read/write/fill probes for uniprocessor setup
118 * they don't make sense if only one cpu is available
121 /* Hypetransport Transaction Control Register
123 * [ 0: 0] Disable read byte probe
125 * 1 = Probes not issued
126 * [ 1: 1] Disable Read Doubleword probe
128 * 1 = Probes not issued
129 * [ 2: 2] Disable write byte probes
131 * 1 = Probes not issued
132 * [ 3: 3] Disable Write Doubleword Probes
134 * 1 = Probes not issued.
135 * [10:10] Disable Fill Probe
136 * 0 = Probes issued for cache fills
137 * 1 = Probes not issued for cache fills.
142 print_spew("Disabling read/write/fill probes for UP... ");
144 val=pci_read_config32(NODE_HT(0), 0x68);
145 val |= (1<<10)|(1<<9)|(1<<8)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|(1 << 0);
146 pci_write_config32(NODE_HT(0), 0x68, val);
148 print_spew("done.\r\n");
153 #ifndef ENABLE_APIC_EXT_ID
154 #define ENABLE_APIC_EXT_ID 0
157 static void enable_apic_ext_id(u8 node)
159 #if ENABLE_APIC_EXT_ID==1
160 #warning "FIXME Is the right place to enable apic ext id here?"
164 val = pci_read_config32(NODE_HT(node), 0x68);
165 val |= (HTTC_APIC_EXT_SPUR | HTTC_APIC_EXT_ID | HTTC_APIC_EXT_BRD_CST);
166 pci_write_config32(NODE_HT(node), 0x68, val);
172 static void enable_routing(u8 node)
176 /* HT Initialization Control Register
178 * [ 0: 0] Routing Table Disable
179 * 0 = Packets are routed according to routing tables
180 * 1 = Packets are routed according to the default link field
181 * [ 1: 1] Request Disable (BSP should clear this)
182 * 0 = Request packets may be generated
183 * 1 = Request packets may not be generated.
184 * [ 3: 2] Default Link (Read-only)
188 * 11 = CPU on same node
190 * - Scratch bit cleared by a cold reset
191 * [ 5: 5] BIOS Reset Detect
192 * - Scratch bit cleared by a cold reset
193 * [ 6: 6] INIT Detect
194 * - Scratch bit cleared by a warm or cold reset not by an INIT
198 /* Enable routing table */
199 print_spew("Enabling routing table for node ");
200 print_spew_hex8(node);
202 val=pci_read_config32(NODE_HT(node), 0x6c);
203 val &= ~((1<<1)|(1<<0));
204 pci_write_config32(NODE_HT(node), 0x6c, val);
206 print_spew(" done.\r\n");
209 static void fill_row(u8 node, u8 row, u32 value)
211 pci_write_config32(NODE_HT(node), 0x40+(row<<2), value);
214 #if CONFIG_MAX_PHYSICAL_CPUS > 1
215 static u8 link_to_register(int ldt)
218 * [ 0: 3] Request Route
219 * [0] Route to this node
220 * [1] Route to Link 0
221 * [2] Route to Link 1
222 * [3] Route to Link 2
225 if (ldt&0x08) return 0x40;
226 if (ldt&0x04) return 0x20;
227 if (ldt&0x02) return 0x00;
229 /* we should never get here */
230 print_spew("Unknown Link\n");
234 static u32 get_row(u8 node, u8 row)
236 return pci_read_config32(NODE_HT(node), 0x40+(row<<2));
239 static int link_connection(u8 src, u8 dest)
241 return get_row(src, dest) & 0x0f;
244 static void rename_temp_node(u8 node)
248 print_spew("Renaming current temporary node to ");
249 print_spew_hex8(node);
251 val=pci_read_config32(NODE_HT(7), 0x60);
252 val &= (~7); /* clear low bits. */
253 val |= node; /* new node */
254 pci_write_config32(NODE_HT(7), 0x60, val);
256 print_spew(" done.\r\n");
258 #if K8_HT_CHECK_PENDING_LINK == 1
259 static void wait_ht_stable(uint8_t node)
262 for(linkn = 0; linkn<3; linkn++) {
266 regpos = 0x98 + 0x20 * linkn;
267 for(i = 0; i < 0xff; i++) { //wait to make sure it is done
268 reg = pci_read_config32(NODE_HT(node), regpos);
269 if ((reg & 0x10) == 0) break; // init complete
276 static int check_connection(u8 dest)
278 /* See if we have a valid connection to dest */
281 /* Verify that the coherent hypertransport link is
282 * established and actually working by reading the
283 * remode node's vendor/device id
285 val = pci_read_config32(NODE_HT(dest),0);
286 if(val != 0x11001022)
289 #if K8_HT_CHECK_PENDING_LINK == 1
290 wait_ht_stable(dest);
296 static uint16_t read_freq_cap(device_t dev, uint8_t pos)
298 /* Handle bugs in valid hypertransport frequency reporting */
302 freq_cap = pci_read_config16(dev, pos);
303 freq_cap &= ~(1 << HT_FREQ_VENDOR); /* Ignore Vendor HT frequencies */
306 #if K8_HT_FREQ_1G_SUPPORT == 1
307 if (!is_cpu_pre_e0())
311 id = pci_read_config32(dev, 0);
313 /* AMD K8 Unsupported 1Ghz? */
314 if (id == (PCI_VENDOR_ID_AMD | (0x1100 << 16))) {
315 freq_cap &= ~(1 << HT_FREQ_1000Mhz);
321 static int optimize_connection(device_t node1, uint8_t link1, device_t node2, uint8_t link2)
323 static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
324 static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
325 uint16_t freq_cap1, freq_cap2, freq_cap, freq_mask;
326 uint8_t width_cap1, width_cap2, width_cap, width, old_width, ln_width1, ln_width2;
327 uint8_t freq, old_freq;
329 /* Set link width and frequency */
331 /* Initially assume everything is already optimized and I don't need a reset */
334 /* Get the frequency capabilities */
335 freq_cap1 = read_freq_cap(node1, link1 + PCI_HT_CAP_HOST_FREQ_CAP);
336 freq_cap2 = read_freq_cap(node2, link2 + PCI_HT_CAP_HOST_FREQ_CAP);
338 /* Calculate the highest possible frequency */
339 freq = log2(freq_cap1 & freq_cap2);
341 /* See if I am changing the link freqency */
342 old_freq = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_FREQ);
343 needs_reset |= old_freq != freq;
344 old_freq = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_FREQ);
345 needs_reset |= old_freq != freq;
347 /* Set the Calulcated link frequency */
348 pci_write_config8(node1, link1 + PCI_HT_CAP_HOST_FREQ, freq);
349 pci_write_config8(node2, link2 + PCI_HT_CAP_HOST_FREQ, freq);
351 /* Get the width capabilities */
352 width_cap1 = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH);
353 width_cap2 = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH);
355 /* Calculate node1's input width */
356 ln_width1 = link_width_to_pow2[width_cap1 & 7];
357 ln_width2 = link_width_to_pow2[(width_cap2 >> 4) & 7];
358 if (ln_width1 > ln_width2) {
359 ln_width1 = ln_width2;
361 width = pow2_to_link_width[ln_width1];
362 /* Calculate node1's output width */
363 ln_width1 = link_width_to_pow2[(width_cap1 >> 4) & 7];
364 ln_width2 = link_width_to_pow2[width_cap2 & 7];
365 if (ln_width1 > ln_width2) {
366 ln_width1 = ln_width2;
368 width |= pow2_to_link_width[ln_width1] << 4;
370 /* See if I am changing node1's width */
371 old_width = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH + 1);
372 needs_reset |= old_width != width;
374 /* Set node1's widths */
375 pci_write_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH + 1, width);
377 // * Calculate node2's width */
378 width = ((width & 0x70) >> 4) | ((width & 0x7) << 4);
380 /* See if I am changing node2's width */
381 old_width = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH + 1);
382 needs_reset |= old_width != width;
384 /* Set node2's widths */
385 pci_write_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH + 1, width);
390 static uint8_t get_linkn_first(uint8_t byte)
392 if(byte & 0x02) { byte = 0; }
393 else if(byte & 0x04) { byte = 1; }
394 else if(byte & 0x08) { byte = 2; }
398 static uint8_t get_linkn_last(uint8_t byte)
400 if(byte & 0x02) { byte &= 0x0f; byte |= 0x00; }
401 if(byte & 0x04) { byte &= 0x0f; byte |= 0x10; }
402 if(byte & 0x08) { byte &= 0x0f; byte |= 0x20; }
406 static uint8_t get_linkn_last_count(uint8_t byte)
409 if(byte & 0x02) { byte &= 0xcf; byte |= 0x00; byte+=0x40; }
410 if(byte & 0x04) { byte &= 0xcf; byte |= 0x10; byte+=0x40; }
411 if(byte & 0x08) { byte &= 0xcf; byte |= 0x20; byte+=0x40; }
415 static void setup_row_local(u8 source, u8 row) /* source will be 7 when it is for temp use*/
420 for(linkn = 0; linkn<3; linkn++) {
423 regpos = 0x98 + 0x20 * linkn;
424 reg = pci_read_config32(NODE_HT(source), regpos);
425 if ((reg & 0x17) != 3) continue; /* it is not conherent or not connected*/
430 fill_row(source,row, val);
433 static void setup_row_direct_x(u8 temp, u8 source, u8 dest, u8 linkn)
438 val |= 1<<(linkn+1+8); /*for direct connect response route should equal to request table*/
440 if(((source &1)!=(dest &1))
442 && ( (source<4)||(source>5) ) //(6,7) (7,6) should still be here
443 //(6,5) (7,4) should be here
448 /*for CROSS_BAR_47_56 47, 56, should be here too
449 and for 47, 56, 57, 75, 46, 64 we need to substract another link to
452 val_s = get_row(temp, source);
453 val |= ((val_s>>16) - (1<<(linkn+1)))<<16;
456 fill_row(temp,dest, val );
460 static void opt_broadcast_rt(u8 source, u8 dest, u8 kickout) {
462 val = get_row(source, dest);
463 val -= link_connection(source, kickout)<<16;
464 fill_row(source, dest, val);
467 static void opt_broadcast_rt_group(const u8 *conn, int num) {
470 for(i=0; i<num; i+=3) {
471 opt_broadcast_rt(conn[i], conn[i+1],conn[i+2]);
474 static void opt_broadcast_rt_plus(u8 source, u8 dest, u8 kickout) {
476 val = get_row(source, dest);
477 val += link_connection(source, kickout)<<16;
478 fill_row(source, dest, val);
481 static void opt_broadcast_rt_plus_group(const u8 *conn, int num) {
484 for(i=0; i<num; i+=3) {
485 opt_broadcast_rt_plus(conn[i], conn[i+1],conn[i+2]);
490 static void setup_row_direct(u8 source, u8 dest, u8 linkn){
491 setup_row_direct_x(source, source, dest, linkn);
494 static void setup_remote_row_direct(u8 source, u8 dest, u8 linkn){
495 setup_row_direct_x(7, source, dest, linkn);
498 static void setup_temp_row(u8 source, u8 dest)
500 /* copy val from (source, dest) to (source,7) */
501 fill_row(source,7,get_row(source,dest));
504 static void clear_temp_row(u8 source)
506 fill_row(source, 7, DEFAULT);
509 static void setup_remote_node(u8 node)
511 static const uint8_t pci_reg[] = {
512 0x44, 0x4c, 0x54, 0x5c, 0x64, 0x6c, 0x74, 0x7c,
513 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78,
514 0x84, 0x8c, 0x94, 0x9c, 0xa4, 0xac, 0xb4, 0xbc,
515 0x80, 0x88, 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8,
516 0xc4, 0xcc, 0xd4, 0xdc,
517 0xc0, 0xc8, 0xd0, 0xd8,
518 0xe0, 0xe4, 0xe8, 0xec,
522 print_spew("setup_remote_node: ");
524 /* copy the default resource map from node 0 */
525 for(i = 0; i < sizeof(pci_reg)/sizeof(pci_reg[0]); i++) {
529 value = pci_read_config32(NODE_MP(0), reg);
530 pci_write_config32(NODE_MP(7), reg, value);
533 print_spew("done\r\n");
536 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 1*/
539 #if CONFIG_MAX_PHYSICAL_CPUS > 2
541 static void setup_row_indirect_x(u8 temp, u8 source, u8 dest)
543 static void setup_row_indirect_x(u8 temp, u8 source, u8 dest, u8 gateway, u8 diff)
546 /*for indirect connection, we need to compute the val from val_s(source, source), and val_g(source, gateway) */
553 gateway = source + 2;
555 gateway = source - 2;
558 val_s = get_row(temp, source);
559 val = get_row(temp, gateway);
566 diff = ((source&1)!=(dest &1));
569 if(diff && (val_s!=(val&0xff)) ) { /* use another connect as response*/
571 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
573 /* Some node have two links left
574 * don't worry we only have (2, (3 as source need to handle
577 byte = get_linkn_last_count(byte);
578 if((byte>>2)>1) { /* make sure not the corner*/
580 val_s-=link_connection(temp, source-2); /* -down*/
585 val_s-=link_connection(temp, 6); // for 7,2 via 5
586 } else if (source==6){
587 val_s-=link_connection(temp, 7); // for 6,3 via 4
590 if (source < gateway) { // for 5, 4 via 7
591 val_s-=link_connection(temp, source-2);
594 val_s-=link_connection(temp, source+2); /* -up*/
602 if(diff) { /* cross rung?*/
606 val_s = get_row(temp, source);
607 val |= ((val_s>>16) - link_connection(temp, gateway))<<16;
610 fill_row(temp, dest, val);
615 static void setup_row_indirect(u8 source, u8 dest)
617 setup_row_indirect_x(source, source, dest);
620 static void setup_row_indirect(u8 source, u8 dest, u8 gateway, u8 diff)
622 setup_row_indirect_x(source, source, dest, gateway, diff);
626 static void setup_row_indirect_group(const u8 *conn, int num)
631 for(i=0; i<num; i+=2) {
632 setup_row_indirect(conn[i], conn[i+1]);
634 for(i=0; i<num; i+=4) {
635 setup_row_indirect(conn[i], conn[i+1],conn[i+2], conn[i+3]);
642 static void setup_remote_row_indirect(u8 source, u8 dest)
644 setup_row_indirect_x(7, source, dest);
647 static void setup_remote_row_indirect(u8 source, u8 dest, u8 gateway, u8 diff)
649 setup_row_indirect_x(7, source, dest, gateway, diff);
653 static void setup_remote_row_indirect_group(const u8 *conn, int num)
658 for(i=0; i<num; i+=2) {
659 setup_remote_row_indirect(conn[i], conn[i+1]);
661 for(i=0; i<num; i+=4) {
662 setup_remote_row_indirect(conn[i], conn[i+1],conn[i+2], conn[i+3]);
667 #endif /*CONFIG_MAX_PHYSICAL_CPUS > 2*/
670 static void setup_uniprocessor(void)
672 print_spew("Enabling UP settings\r\n");
673 #if CONFIG_LOGICAL_CPUS==1
674 unsigned tmp = (pci_read_config32(NODE_MC(0), 0xe8) >> 12) & 3;
680 struct setup_smp_result {
685 #if CONFIG_MAX_PHYSICAL_CPUS > 2
686 static int optimize_connection_group(const u8 *opt_conn, int num) {
689 for(i=0; i<num; i+=2) {
690 needs_reset = optimize_connection(
691 NODE_HT(opt_conn[i]), 0x80 + link_to_register(link_connection(opt_conn[i],opt_conn[i+1])),
692 NODE_HT(opt_conn[i+1]), 0x80 + link_to_register(link_connection(opt_conn[i+1],opt_conn[i])) );
698 #if CONFIG_MAX_PHYSICAL_CPUS > 1
699 static struct setup_smp_result setup_smp2(void)
701 struct setup_smp_result result;
705 result.needs_reset = 0;
707 setup_row_local(0, 0); /* it will update the broadcast RT*/
710 byte = (val>>16) & 0xfe;
711 if(byte<0x2) { /* no coherent connection so get out.*/
716 /* Setup and check a temporary connection to node 1 */
717 #if TRY_HIGH_FIRST == 1
718 byte = get_linkn_last(byte); /* Max Link to node1 */
720 byte = get_linkn_first(byte); /*Min Link to node1 --- according to AMD*/
722 print_linkn("(0,1) link=", byte);
723 setup_row_direct(0,1, byte);
724 setup_temp_row(0, 1);
728 /* We found 2 nodes so far */
729 val = pci_read_config32(NODE_HT(7), 0x6c);
730 byte = (val>>2) & 0x3; /*get default link on node7 to node0*/
731 print_linkn("(1,0) link=", byte);
732 setup_row_local(7,1);
733 setup_remote_row_direct(1, 0, byte);
735 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
737 byte = (val>>16) & 0xfe;
738 byte = get_linkn_last_count(byte);
739 if((byte>>2)==3) { /* Oh! we need to treat it as node2. So use another link*/
741 byte = (val>>16) & 0xfe;
742 #if TRY_HIGH_FIRST == 1
743 byte = get_linkn_first(byte); /* Min link to Node1 */
745 byte = get_linkn_last(byte); /* Max link to Node1*/
747 print_linkn("\t-->(0,1) link=", byte);
748 setup_row_direct(0,1, byte);
749 setup_temp_row(0, 1);
753 /* We found 2 nodes so far */
754 val = pci_read_config32(NODE_HT(7), 0x6c);
755 byte = (val>>2) & 0x3; /* get default link on node7 to node0*/
756 print_linkn("\t-->(1,0) link=", byte);
757 setup_row_local(7,1);
758 setup_remote_row_direct(1, 0, byte);
762 setup_remote_node(1); /* Setup the regs on the remote node */
763 rename_temp_node(1); /* Rename Node 7 to Node 1 */
764 enable_routing(1); /* Enable routing on Node 1 */
766 /*don't need and it is done by clear_dead_links */
770 result.needs_reset |= optimize_connection(
771 NODE_HT(0), 0x80 + link_to_register(link_connection(0,1)),
772 NODE_HT(1), 0x80 + link_to_register(link_connection(1,0)) );
776 #endif /*CONFIG_MAX_PHYSICAL_CPUS > 1 */
778 #if CONFIG_MAX_PHYSICAL_CPUS > 2
780 static struct setup_smp_result setup_smp4(int needs_reset)
782 struct setup_smp_result result;
787 result.needs_reset = needs_reset;
789 /* Setup and check temporary connection from Node 0 to Node 2 */
791 byte = ((val>>16) & 0xfe) - link_connection(0,1);
792 byte = get_linkn_last_count(byte);
794 if((byte>>2)==0) { /* We should have two coherent for 4p and above*/
799 byte &= 3; /* bit [3,2] is count-1*/
800 print_linkn("(0,2) link=", byte);
801 setup_row_direct(0, 2, byte); /*(0,2) direct link done*/
803 /* We found 3 nodes so far. Now setup a temporary
804 * connection from node 0 to node 3 via node 1
806 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
807 /* here should setup_row_direct(1,3) at first, before that we should find the link in node 1 to 3*/
809 byte = ((val>>16) & 0xfe) - link_connection(1,0);
810 byte = get_linkn_first(byte);
811 print_linkn("(1,3) link=", byte);
812 setup_row_direct(1,3,byte); /* (1, 3) direct link done*/
814 /* We found 4 nodes so far. Now setup all nodes for 4p */
815 // We need to make sure 0,2 and 1,3 link is set already
817 static const u8 conn4_1[] = {
822 static const u8 conn4_1[] = {
828 setup_row_indirect_group(conn4_1, sizeof(conn4_1)/sizeof(conn4_1[0]));
832 val = pci_read_config32(NODE_HT(7), 0x6c);
833 byte = (val>>2) & 0x3; /* get default link on 7 to 0*/
834 print_linkn("(2,0) link=", byte);
836 setup_row_local(7,2);
837 setup_remote_row_direct(2, 0, byte); /* node 2 to node 0 direct link done */
838 setup_remote_node(2); /* Setup the regs on the remote node */
840 rename_temp_node(2); /* Rename Node 7 to Node 2 */
841 enable_routing(2); /* Enable routing on Node 2 */
847 val = pci_read_config32(NODE_HT(7), 0x6c);
848 byte = (val>>2) & 0x3; /* get default link on 7 to 1*/
849 print_linkn("(3,1) link=", byte);
851 setup_row_local(7,3);
852 setup_remote_row_direct(3, 1, byte); /* node 3 to node 1 direct link done */
853 setup_remote_node(3); /* Setup the regs on the remote node */
855 /* We need to init link between 2, and 3 direct link */
857 byte = ((val>>16) & 0xfe) - link_connection(2,0);
858 byte = get_linkn_last_count(byte);
859 print_linkn("(2,3) link=", byte & 3);
861 setup_row_direct(2,3, byte & 0x3);
864 check_connection(7); /* to 3*/
866 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
867 /* We need to find out which link is to node3 */
868 if((byte>>2)==2) { /* one to node3, one to node0, one to node4*/
870 if((val>>16) == 1) { /* that link is to node4, because via node1 it has been set, recompute it*/
872 byte = ((val>>16) & 0xfe) - link_connection(2,0);
873 byte = get_linkn_first(byte);
874 print_linkn("\t-->(2,3) link=", byte);
875 setup_row_direct(2,3,byte);
877 check_connection(7); /* to 3*/
882 val = pci_read_config32(NODE_HT(7), 0x6c);
883 byte = (val>>2) & 0x3; /* get default link on 7 to 2*/
884 print_linkn("(3,2) link=", byte);
885 setup_remote_row_direct(3,2, byte);
887 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
888 /* set link from 3 to 5 before enable it*/
890 byte = ((val>>16) & 0xfe) - link_connection(7,2) - link_connection(7,1);
891 byte = get_linkn_last_count(byte);
892 if((byte>>2)==1) { /* We should have three coherent links on node 3 for 6p and above*/
893 byte &= 3; /*bit [3,2] is count-2*/
894 print_linkn("(3,5) link=", byte);
895 setup_remote_row_direct(3, 5, byte);
899 byte = ((val>>16) & 0xfe) - link_connection(2,3) - link_connection(2,0);
900 byte = get_linkn_last_count(byte);
902 if((byte>>2)==1) { /* We should have three coherent link on node 2 for 6p and above*/
903 byte &= 3; /* bit [3,2] is count-2*/
904 print_linkn("(2,4) link=", byte);
905 setup_row_direct(2, 4, byte);
909 //Beside 3, 1 is set, We need to make sure 3, 5 is set already in case has three link in 3
911 static const u8 conn4_3[] = {
915 static const u8 conn4_3[] = {
919 setup_remote_row_indirect_group(conn4_3, sizeof(conn4_3)/sizeof(conn4_3[0]));
921 /* ready to enable RT for Node 3 */
923 enable_routing(3); /* enable routing on node 3 (temp.) */
925 // beside 2, 0 is set, We need to make sure 2, 4 link is set already in case has three link in 2
927 static const u8 conn4_2[] = {
931 static const u8 conn4_2[] = {
935 setup_row_indirect_group(conn4_2, sizeof(conn4_2)/sizeof(conn4_2[0]));
938 /*We need to do sth to reverse work for setup_temp_row (0,1) (1,3) */
939 /* it will be done by clear_dead_links */
944 /* optimize physical connections - by LYH */
945 static const u8 opt_conn4[] = {
951 result.needs_reset |= optimize_connection_group(opt_conn4, sizeof(opt_conn4)/sizeof(opt_conn4[0]));
957 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 2 */
959 #if CONFIG_MAX_PHYSICAL_CPUS > 4
961 static struct setup_smp_result setup_smp6(int needs_reset)
963 struct setup_smp_result result;
968 result.needs_reset = needs_reset;
970 /* Setup and check temporary connection from Node 0 to Node 4 through 2*/
972 byte = ((val>>16) & 0xfe) - link_connection(2,3) - link_connection(2,0);
973 byte = get_linkn_last_count(byte);
975 if((byte>>2)==0) { /* We should have three coherent link on node 2 for 6p and above*/
980 /* Setup and check temporary connection from Node 0 to Node 5 through 1, 3*/
981 /* set link from 3 to 5 before enable it*/
983 byte = ((val>>16) & 0xfe) - link_connection(3,2) - link_connection(3,1);
984 byte = get_linkn_last_count(byte);
985 if((byte>>2)==0) { /* We should have three coherent links on node 3 for 6p and above*/
990 /* We found 6 nodes so far. Now setup all nodes for 6p */
991 #warning "FIXME we need to find out the correct gateway for 6p"
992 static const u8 conn6_1[] = {
1010 setup_row_indirect_group(conn6_1, sizeof(conn6_1)/sizeof(conn6_1[0]));
1012 for(byte=0; byte<4; byte+=2) {
1013 setup_temp_row(byte,byte+2);
1015 check_connection(7);
1016 val = pci_read_config32(NODE_HT(7), 0x6c);
1017 byte = (val>>2) & 0x3; /*get default link on 7 to 2*/
1018 print_linkn("(4,2) link=", byte);
1020 setup_row_local(7,4);
1021 setup_remote_row_direct(4, 2, byte);
1022 setup_remote_node(4); /* Setup the regs on the remote node */
1024 /* Set indirect connection to 0, to 3 */
1025 //we only need to set 4,0 here
1026 static const u8 conn6_2[] = {
1027 #if !CROSS_BAR_47_56
1034 setup_remote_row_indirect_group(conn6_2, sizeof(conn6_2)/sizeof(conn6_2[0]));
1036 rename_temp_node(4);
1039 setup_temp_row(0,1);
1040 for(byte=0; byte<4; byte+=2) {
1041 setup_temp_row(byte+1,byte+3);
1043 check_connection(7);
1045 val = pci_read_config32(NODE_HT(7), 0x6c);
1046 byte = (val>>2) & 0x3; /* get default link on 7 to 3*/
1047 print_linkn("(5,3) link=", byte);
1048 setup_row_local(7,5);
1049 setup_remote_row_direct(5, 3, byte);
1050 setup_remote_node(5); /* Setup the regs on the remote node */
1052 #if !CROSS_BAR_47_56
1053 /* We need to init link between 4, and 5 direct link */
1055 byte = ((val>>16) & 0xfe) - link_connection(4,2);
1056 byte = get_linkn_last_count(byte);
1057 print_linkn("(4,5) link=", byte & 3);
1059 setup_row_direct(4,5, byte & 0x3);
1060 setup_temp_row(0,2);
1061 setup_temp_row(2,4);
1062 setup_temp_row(4,5);
1063 check_connection(7); /* to 5*/
1065 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1066 /* We need to find out which link is to node5 */
1068 if((byte>>2)==2) { /* one to node5, one to node2, one to node6*/
1070 if((val>>16) == 1) { /* that link is to node6, because via node 3 node 5 has been set*/
1072 byte = ((val>>16) & 0xfe) - link_connection(4,2);
1073 byte = get_linkn_first(byte);
1074 print_linkn("\t-->(4,5) link=", byte);
1075 setup_row_direct(4,5,byte);
1076 setup_temp_row(4,5);
1077 check_connection(7); /* to 5*/
1082 val = pci_read_config32(NODE_HT(7), 0x6c);
1083 byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
1084 print_linkn("(5,4) link=", byte);
1085 setup_remote_row_direct(5,4, byte);
1089 byte = ((val>>16) & 0xfe) - link_connection(7,4) - link_connection(7,3);
1090 byte = get_linkn_last_count(byte);
1091 if((byte>>2)==1) { /* We should have three coherent links on node 5 for 6p and above*/
1092 byte &= 3; /*bit [3,2] is count-2*/
1093 print_linkn("(5,7) link=", byte);
1094 setup_remote_row_direct(5, 7, byte);
1099 byte = ((val>>16) & 0xfe) - link_connection(4,5) - link_connection(4,2);
1100 byte = get_linkn_last_count(byte);
1102 if((byte>>2)==1) { /* We should have three coherent link on node 4 for 6p and above*/
1103 byte &= 3; /* bit [3,2] is count-2*/
1104 print_linkn("(4,6) link=", byte);
1105 setup_row_direct(4, 6, byte);
1110 //We need to set 5,0 here only, We need to set up 5, 7 to make 5,0
1111 /* Set indirect connection to 0, to 3 for indirect we will use clockwise routing */
1112 static const u8 conn6_3[] = {
1113 #if !CROSS_BAR_47_56
1120 setup_remote_row_indirect_group(conn6_3, sizeof(conn6_3)/sizeof(conn6_3[0]));
1122 /* ready to enable RT for 5 */
1123 rename_temp_node(5);
1124 enable_routing(5); /* enable routing on node 5 (temp.) */
1126 static const u8 conn6_4[] = {
1127 #if !CROSS_BAR_47_56
1146 setup_row_indirect_group(conn6_4, sizeof(conn6_4)/sizeof(conn6_4[0]));
1149 /* We need to do sth about reverse about setup_temp_row (0,1), (2,4), (1, 3), (3,5)
1150 * It will be done by clear_dead_links
1152 for(byte=0; byte<4; byte++) {
1153 clear_temp_row(byte);
1157 /* optimize physical connections - by LYH */
1158 static const uint8_t opt_conn6[] ={
1161 #if !CROSS_BAR_47_56
1165 result.needs_reset |= optimize_connection_group(opt_conn6, sizeof(opt_conn6)/sizeof(opt_conn6[0]));
1171 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 4 */
1173 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1175 static struct setup_smp_result setup_smp8(int needs_reset)
1177 struct setup_smp_result result;
1182 result.needs_reset = needs_reset;
1184 /* Setup and check temporary connection from Node 0 to Node 6 via 2 and 4 to 7 */
1187 byte = ((val>>16) & 0xfe) - link_connection(4,2);
1189 byte = ((val>>16) & 0xfe) - link_connection(4,5) - link_connection(4,2);
1190 byte = get_linkn_last_count(byte); /* Max link to 6*/
1191 if((byte>>2)==0) { /* We should have two or three coherent links on node 4 for 8p*/
1198 byte = get_linkn_last_count(byte); /* Max link to 6*/
1199 if((byte>>2)<2) { /* We should have two or three coherent links on node 4 for 8p*/
1203 #if TRY_HIGH_FIRST == 1
1204 byte = ((val>>16) & 0xfe) - link_connection(4,2);
1205 byte = get_linkn_first(byte); /*Min link to 6*/
1207 byte &= 3; /* bit [3,2] is count-1 or 2*/
1209 print_linkn("(4,6) link=", byte);
1210 setup_row_direct(4, 6, byte);
1213 #if !CROSS_BAR_47_56
1214 /* Setup and check temporary connection from Node 0 to Node 7 through 1, 3, 5*/
1216 byte = ((val>>16) & 0xfe) - link_connection(5,4) - link_connection(5,3);
1217 byte = get_linkn_last_count(byte);
1218 if((byte>>2)==0) { /* We should have three coherent links on node 5 for 6p and above*/
1224 /* We found 8 nodes so far. Now setup all nodes for 8p */
1225 static const u8 conn8_1[] = {
1226 #if !CROSS_BAR_47_56
1248 setup_row_indirect_group(conn8_1,sizeof(conn8_1)/sizeof(conn8_1[0]));
1250 for(byte=0; byte<6; byte+=2) {
1251 setup_temp_row(byte,byte+2);
1253 check_connection(7);
1254 val = pci_read_config32(NODE_HT(7), 0x6c);
1255 byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
1256 print_linkn("(6,4) link=", byte);
1258 setup_row_local(7,6);
1259 setup_remote_row_direct(6, 4, byte);
1260 setup_remote_node(6); /* Setup the regs on the remote node */
1261 /* Set indirect connection to 0, to 3 */
1262 #warning "FIXME we need to find out the correct gateway for 8p"
1263 static const u8 conn8_2[] = {
1264 #if !CROSS_BAR_47_56
1271 setup_remote_row_indirect_group(conn8_2, sizeof(conn8_2)/sizeof(conn8_2[0]));
1275 /* here init 5, 6 */
1276 /* Setup and check temporary connection from Node 0 to Node 5 through 1, 3, 5*/
1278 byte = ((val>>16) & 0xfe) - link_connection(5,3);
1279 #if TRY_HIGH_FIRST == 1
1280 byte = get_linkn_first(byte);
1282 byte = get_linkn_last(byte);
1284 print_linkn("(5,6) link=", byte);
1285 setup_row_direct(5, 6, byte);
1287 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
1288 for(byte=0; byte<4; byte+=2) {
1289 setup_temp_row(byte+1,byte+3);
1291 setup_temp_row(5,6);
1293 check_connection(7);
1295 val = get_row(7,6); // to chect it if it is node6 before renaming
1296 if( (val>>16) == 1) { // it is real node 7 so swap it
1297 /* We need to recompute link to 6 */
1299 byte = ((val>>16) & 0xfe) - link_connection(5,3);
1300 #if TRY_HIGH_FIRST == 1
1301 byte = get_linkn_first(byte);
1303 byte = get_linkn_last(byte);
1305 print_linkn("\t-->(5,6) link=", byte);
1306 setup_row_direct(5, 6, byte);
1308 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
1309 for(byte=0; byte<4; byte+=2) {
1310 setup_temp_row(byte+1,byte+3);
1313 setup_temp_row(5,6);
1315 check_connection(7);
1317 val = pci_read_config32(NODE_HT(7), 0x6c);
1318 byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
1319 print_linkn("(6,5) link=", byte);
1320 setup_remote_row_direct(6, 5, byte);
1321 /*Till now 56, 65 done */
1324 rename_temp_node(6);
1327 #if !CROSS_BAR_47_56
1328 setup_temp_row(0,1);
1329 for(byte=0; byte<6; byte+=2) {
1330 setup_temp_row(byte+1,byte+3);
1333 check_connection(7);
1335 val = pci_read_config32(NODE_HT(7), 0x6c);
1336 byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
1337 print_linkn("(7,5) link=", byte);
1338 setup_row_local(7,7);
1339 setup_remote_row_direct(7, 5, byte);
1343 byte = ((val>>16) & 0xfe) - link_connection(4,2) - link_connection(4,6);
1344 byte = get_linkn_first(byte);
1345 print_linkn("(4,7) link=", byte);
1346 setup_row_direct(4, 7, byte);
1348 /* Setup and check temporary connection from Node 0 to Node 7 through 2, and 4*/
1349 for(byte=0; byte<4; byte+=2) {
1350 setup_temp_row(byte,byte+2);
1353 check_connection(7);
1355 val = pci_read_config32(NODE_HT(7), 0x6c);
1356 byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
1357 print_linkn("(7,4) link=", byte);
1358 setup_row_local(7,7);
1359 setup_remote_row_direct(7, 4, byte);
1360 /* till now 4-7, 7-4 done. */
1362 setup_remote_node(7); /* Setup the regs on the remote node */
1365 /* here init 5, 7 */
1366 /* Setup and check temporary connection from Node 0 to Node 5 through 1, 3, 5*/
1368 byte = ((val>>16) & 0xfe) - link_connection(5,3) - link_connection(5,6);
1369 byte = get_linkn_first(byte);
1370 print_linkn("(5,7) link=", byte);
1371 setup_row_direct(5, 7, byte);
1373 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
1374 for(byte=0; byte<4; byte+=2) {
1375 setup_temp_row(byte+1,byte+3);
1378 check_connection(7);
1380 val = pci_read_config32(NODE_HT(7), 0x6c);
1381 byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
1382 print_linkn("(7,5) link=", byte);
1383 setup_remote_row_direct(7, 5, byte);
1384 /*Till now 57, 75 done */
1388 /* We need to init link between 6, and 7 direct link */
1390 #if !CROSS_BAR_47_56
1391 byte = ((val>>16) & 0xfe) - link_connection(6,4);
1393 byte = ((val>>16) & 0xfe) - link_connection(6,4) - link_connection(6,5);
1395 byte = get_linkn_first(byte);
1396 print_linkn("(6,7) link=", byte);
1397 setup_row_direct(6,7, byte);
1400 #if !CROSS_BAR_47_56
1401 byte = ((val>>16) & 0xfe) - link_connection(7,5);
1403 byte = ((val>>16) & 0xfe) - link_connection(7,5) - link_connection(7,4);
1405 byte = get_linkn_first(byte);
1406 print_linkn("(7,6) link=", byte);
1407 setup_row_direct(7,6, byte);
1409 /* Set indirect connection to 0, to 3 for indirect we will use clockwise routing */
1410 static const u8 conn8_3[] = {
1411 #if !CROSS_BAR_47_56
1412 0, 7, /* restore it*/
1434 6, 1, 5, 0, // or 4, 1
1436 6, 3, 5, 0, // or 4, 1
1438 7, 0, 4, 0, // or 5, 1
1440 7, 2, 4, 0, // or 5, 1
1443 0, 7, 2, 0, /* restore it*/
1448 2, 5, 4, 1, /* reset it */
1451 4, 1, 2, 1, /* reset it */
1454 5, 2, 3, 1, /* reset it */
1460 setup_row_indirect_group(conn8_3, sizeof(conn8_3)/sizeof(conn8_3[0]));
1463 /* for 47, 56, 57, 75, 46, 64 we need to substract another link to
1465 static const u8 conn8_4[] = {
1488 6, 1, 7, // needed for via 5
1491 6, 3, 7, // needed for via 5
1493 7, 0, 6, // needed for via 4
1496 7, 2, 6, // needed for via 4
1501 opt_broadcast_rt_group(conn8_4, sizeof(conn8_4)/sizeof(conn8_4[0]));
1503 static const u8 conn8_5[] = {
1509 opt_broadcast_rt_plus_group(conn8_5, sizeof(conn8_5)/sizeof(conn8_5[0]));
1514 /* ready to enable RT for Node 7 */
1515 enable_routing(7); /* enable routing on node 7 (temp.) */
1517 static const uint8_t opt_conn8[] ={
1526 /* optimize physical connections - by LYH */
1527 result.needs_reset |= optimize_connection_group(opt_conn8, sizeof(opt_conn8)/sizeof(opt_conn8[0]));
1532 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 6 */
1535 #if CONFIG_MAX_PHYSICAL_CPUS > 1
1537 static struct setup_smp_result setup_smp(void)
1539 struct setup_smp_result result;
1541 print_spew("Enabling SMP settings\r\n");
1543 result = setup_smp2();
1544 #if CONFIG_MAX_PHYSICAL_CPUS > 2
1545 if(result.nodes == 2)
1546 result = setup_smp4(result.needs_reset);
1549 #if CONFIG_MAX_PHYSICAL_CPUS > 4
1550 if(result.nodes == 4)
1551 result = setup_smp6(result.needs_reset);
1554 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1555 if(result.nodes == 6)
1556 result = setup_smp8(result.needs_reset);
1559 print_debug_hex8(result.nodes);
1560 print_debug(" nodes initialized.\r\n");
1566 static unsigned verify_mp_capabilities(unsigned nodes)
1568 unsigned node, mask;
1570 mask = 0x06; /* BigMPCap */
1572 for (node=0; node<nodes; node++) {
1573 mask &= pci_read_config32(NODE_MC(node), 0xe8);
1577 #if CONFIG_MAX_PHYSICAL_CPUS > 2
1578 case 0x02: /* MPCap */
1580 print_err("Going back to DP\r\n");
1585 case 0x00: /* Non SMP */
1587 print_err("Going back to UP\r\n");
1598 static void clear_dead_routes(unsigned nodes)
1602 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1603 if(nodes==8) return;/* don't touch (7,7)*/
1609 for(node = 7; node >= 0; node--) {
1610 for(row = 7; row >= last_row; row--) {
1611 fill_row(node, row, DEFAULT);
1615 /* Update the local row */
1616 for( node=0; node<nodes; node++) {
1618 for(row =0; row<nodes; row++) {
1619 val |= get_row(node, row);
1621 fill_row(node, node, (((val & 0xff) | ((val >> 8) & 0xff)) << 16) | 0x0101);
1624 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 1 */
1626 #if CONFIG_LOGICAL_CPUS==1
1627 static unsigned verify_dualcore(unsigned nodes)
1629 unsigned node, totalcpus, tmp;
1632 for (node=0; node<nodes; node++) {
1633 tmp = (pci_read_config32(NODE_MC(node), 0xe8) >> 12) & 3 ;
1634 totalcpus += (tmp + 1);
1642 static void coherent_ht_finalize(unsigned nodes)
1646 #if CONFIG_LOGICAL_CPUS==1
1647 unsigned total_cpus;
1649 if(read_option(CMOS_VSTART_dual_core, CMOS_VLEN_dual_core, 0) == 0) { /* dual_core */
1650 total_cpus = verify_dualcore(nodes);
1657 /* set up cpu count and node count and enable Limit
1658 * Config Space Range for all available CPUs.
1659 * Also clear non coherent hypertransport bus range
1660 * registers on Hammer A0 revision.
1663 print_spew("coherent_ht_finalize\r\n");
1664 rev_a0 = is_cpu_rev_a0();
1665 for (node = 0; node < nodes; node++) {
1668 dev = NODE_HT(node);
1670 /* Set the Total CPU and Node count in the system */
1671 val = pci_read_config32(dev, 0x60);
1672 val &= (~0x000F0070);
1673 #if CONFIG_LOGICAL_CPUS==1
1674 val |= ((total_cpus-1)<<16)|((nodes-1)<<4);
1676 val |= ((nodes-1)<<16)|((nodes-1)<<4);
1678 pci_write_config32(dev, 0x60, val);
1680 /* Only respond to real cpu pci configuration cycles
1681 * and optimize the HT settings
1683 val=pci_read_config32(dev, 0x68);
1684 val &= ~((HTTC_BUF_REL_PRI_MASK << HTTC_BUF_REL_PRI_SHIFT) |
1685 (HTTC_MED_PRI_BYP_CNT_MASK << HTTC_MED_PRI_BYP_CNT_SHIFT) |
1686 (HTTC_HI_PRI_BYP_CNT_MASK << HTTC_HI_PRI_BYP_CNT_SHIFT));
1687 val |= HTTC_LIMIT_CLDT_CFG |
1688 (HTTC_BUF_REL_PRI_8 << HTTC_BUF_REL_PRI_SHIFT) |
1690 (3 << HTTC_MED_PRI_BYP_CNT_SHIFT) |
1691 (3 << HTTC_HI_PRI_BYP_CNT_SHIFT);
1692 pci_write_config32(dev, 0x68, val);
1695 print_spew("shit it is an old cup\n");
1696 pci_write_config32(dev, 0x94, 0);
1697 pci_write_config32(dev, 0xb4, 0);
1698 pci_write_config32(dev, 0xd4, 0);
1702 print_spew("done\r\n");
1705 static int apply_cpu_errata_fixes(unsigned nodes, int needs_reset)
1708 for(node = 0; node < nodes; node++) {
1711 dev = NODE_MC(node);
1712 if (is_cpu_pre_c0()) {
1715 * Limit the number of downstream posted requests to 1
1717 cmd = pci_read_config32(dev, 0x70);
1718 if ((cmd & (3 << 0)) != 2) {
1721 pci_write_config32(dev, 0x70, cmd );
1724 cmd = pci_read_config32(dev, 0x7c);
1725 if ((cmd & (3 << 4)) != 0) {
1728 pci_write_config32(dev, 0x7c, cmd );
1731 /* Clock Power/Timing Low */
1732 cmd = pci_read_config32(dev, 0xd4);
1733 if (cmd != 0x000D0001) {
1735 pci_write_config32(dev, 0xd4, cmd);
1736 needs_reset = 1; /* Needed? */
1740 else if(is_cpu_pre_d0()) { // d0 later don't need it
1743 * Set Clk Ramp Hystersis to 7
1744 * Clock Power/Timing Low
1746 cmd_ref = 0x04e20707; /* Registered */
1747 cmd = pci_read_config32(dev, 0xd4);
1748 if(cmd != cmd_ref) {
1749 pci_write_config32(dev, 0xd4, cmd_ref );
1750 needs_reset = 1; /* Needed? */
1757 static int optimize_link_read_pointers(unsigned nodes, int needs_reset)
1760 for(node = 0; node < nodes; node++) {
1761 device_t f0_dev, f3_dev;
1762 uint32_t cmd_ref, cmd;
1764 f0_dev = NODE_HT(node);
1765 f3_dev = NODE_MC(node);
1766 cmd_ref = cmd = pci_read_config32(f3_dev, 0xdc);
1767 for(link = 0; link < 3; link++) {
1770 /* This works on an Athlon64 because unimplemented links return 0 */
1771 reg = 0x98 + (link * 0x20);
1772 link_type = pci_read_config32(f0_dev, reg);
1773 if ((link_type & 7) == 3) { /* only handle coherent link here*/
1774 cmd &= ~(0xff << (link *8));
1775 cmd |= 0x25 << (link *8);
1778 if (cmd != cmd_ref) {
1779 pci_write_config32(f3_dev, 0xdc, cmd);
1786 static int setup_coherent_ht_domain(void)
1788 struct setup_smp_result result;
1790 #if K8_HT_CHECK_PENDING_LINK == 1
1794 enable_bsp_routing();
1796 #if CONFIG_MAX_PHYSICAL_CPUS > 1
1797 result = setup_smp();
1798 result.nodes = verify_mp_capabilities(result.nodes);
1799 clear_dead_routes(result.nodes);
1802 result.needs_reset = 0;
1805 if (result.nodes == 1) {
1806 setup_uniprocessor();
1808 coherent_ht_finalize(result.nodes);
1809 result.needs_reset = apply_cpu_errata_fixes(result.nodes, result.needs_reset);
1810 result.needs_reset = optimize_link_read_pointers(result.nodes, result.needs_reset);
1811 return result.needs_reset;