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)
112 printk_debug("%s%02x\r\n", strval, byteval);
114 print_debug(strval); print_debug_hex8(byteval); print_debug("\r\n");
119 static void disable_probes(void)
121 /* disable read/write/fill probes for uniprocessor setup
122 * they don't make sense if only one cpu is available
125 /* Hypetransport Transaction Control Register
127 * [ 0: 0] Disable read byte probe
129 * 1 = Probes not issued
130 * [ 1: 1] Disable Read Doubleword probe
132 * 1 = Probes not issued
133 * [ 2: 2] Disable write byte probes
135 * 1 = Probes not issued
136 * [ 3: 3] Disable Write Doubleword Probes
138 * 1 = Probes not issued.
139 * [10:10] Disable Fill Probe
140 * 0 = Probes issued for cache fills
141 * 1 = Probes not issued for cache fills.
146 print_spew("Disabling read/write/fill probes for UP... ");
148 val=pci_read_config32(NODE_HT(0), HT_TRANSACTION_CONTROL);
149 val |= HTTC_DIS_FILL_P | HTTC_DIS_RMT_MEM_C | HTTC_DIS_P_MEM_C |
150 HTTC_DIS_MTS | HTTC_DIS_WR_DW_P | HTTC_DIS_WR_B_P |
151 HTTC_DIS_RD_DW_P | HTTC_DIS_RD_B_P;
152 pci_write_config32(NODE_HT(0), HT_TRANSACTION_CONTROL, val);
154 print_spew("done.\r\n");
158 #ifndef ENABLE_APIC_EXT_ID
159 #define ENABLE_APIC_EXT_ID 0
162 static void enable_apic_ext_id(u8 node)
164 #if ENABLE_APIC_EXT_ID==1
165 #warning "FIXME Is the right place to enable apic ext id here?"
169 val = pci_read_config32(NODE_HT(node), 0x68);
170 val |= (HTTC_APIC_EXT_SPUR | HTTC_APIC_EXT_ID | HTTC_APIC_EXT_BRD_CST);
171 pci_write_config32(NODE_HT(node), 0x68, val);
175 static void enable_routing(u8 node)
179 /* HT Initialization Control Register
181 * [ 0: 0] Routing Table Disable
182 * 0 = Packets are routed according to routing tables
183 * 1 = Packets are routed according to the default link field
184 * [ 1: 1] Request Disable (BSP should clear this)
185 * 0 = Request packets may be generated
186 * 1 = Request packets may not be generated.
187 * [ 3: 2] Default Link (Read-only)
191 * 11 = CPU on same node
193 * - Scratch bit cleared by a cold reset
194 * [ 5: 5] BIOS Reset Detect
195 * - Scratch bit cleared by a cold reset
196 * [ 6: 6] INIT Detect
197 * - Scratch bit cleared by a warm or cold reset not by an INIT
201 /* Enable routing table */
202 print_spew("Enabling routing table for node ");
203 print_spew_hex8(node);
205 val=pci_read_config32(NODE_HT(node), 0x6c);
206 val &= ~((1<<1)|(1<<0));
207 pci_write_config32(NODE_HT(node), 0x6c, val);
209 print_spew(" done.\r\n");
212 static void fill_row(u8 node, u8 row, u32 value)
214 pci_write_config32(NODE_HT(node), 0x40+(row<<2), value);
217 #if CONFIG_MAX_PHYSICAL_CPUS > 1
218 static u8 link_to_register(int ldt)
221 * [ 0: 3] Request Route
222 * [0] Route to this node
223 * [1] Route to Link 0
224 * [2] Route to Link 1
225 * [3] Route to Link 2
228 if (ldt&0x08) return 0x40;
229 if (ldt&0x04) return 0x20;
230 if (ldt&0x02) return 0x00;
232 /* we should never get here */
233 print_spew("Unknown Link\n");
237 static u32 get_row(u8 node, u8 row)
239 return pci_read_config32(NODE_HT(node), 0x40+(row<<2));
242 static int link_connection(u8 src, u8 dest)
244 return get_row(src, dest) & 0x0f;
247 static void rename_temp_node(u8 node)
251 print_spew("Renaming current temporary node to ");
252 print_spew_hex8(node);
254 val=pci_read_config32(NODE_HT(7), 0x60);
255 val &= (~7); /* clear low bits. */
256 val |= node; /* new node */
257 pci_write_config32(NODE_HT(7), 0x60, val);
259 print_spew(" done.\r\n");
261 #if K8_HT_CHECK_PENDING_LINK == 1
262 static void wait_ht_stable(uint8_t node)
265 for(linkn = 0; linkn<3; linkn++) {
269 regpos = 0x98 + 0x20 * linkn;
270 for(i = 0; i < 0xff; i++) { //wait to make sure it is done
271 reg = pci_read_config32(NODE_HT(node), regpos);
272 if ((reg & 0x10) == 0) break; // init complete
279 static int verify_connection(u8 dest)
281 /* See if we have a valid connection to dest */
284 /* Verify that the coherent hypertransport link is
285 * established and actually working by reading the
286 * remode node's vendor/device id
288 val = pci_read_config32(NODE_HT(dest),0);
289 if(val != 0x11001022)
295 static uint16_t read_freq_cap(device_t dev, uint8_t pos)
297 /* Handle bugs in valid hypertransport frequency reporting */
301 freq_cap = pci_read_config16(dev, pos);
302 freq_cap &= ~(1 << HT_FREQ_VENDOR); /* Ignore Vendor HT frequencies */
304 #if K8_HT_FREQ_1G_SUPPORT == 1
305 if (!is_cpu_pre_e0()) {
310 id = pci_read_config32(dev, 0);
312 /* AMD K8 Unsupported 1Ghz? */
313 if (id == (PCI_VENDOR_ID_AMD | (0x1100 << 16))) {
314 freq_cap &= ~(1 << HT_FREQ_1000Mhz);
320 static int optimize_connection(device_t node1, uint8_t link1, device_t node2, uint8_t link2)
322 static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
323 static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
324 uint16_t freq_cap1, freq_cap2, freq_cap, freq_mask;
325 uint8_t width_cap1, width_cap2, width_cap, width, old_width, ln_width1, ln_width2;
326 uint8_t freq, old_freq;
328 /* Set link width and frequency */
330 /* Initially assume everything is already optimized and I don't need a reset */
333 /* Get the frequency capabilities */
334 freq_cap1 = read_freq_cap(node1, link1 + PCI_HT_CAP_HOST_FREQ_CAP);
335 freq_cap2 = read_freq_cap(node2, link2 + PCI_HT_CAP_HOST_FREQ_CAP);
337 /* Calculate the highest possible frequency */
338 freq = log2(freq_cap1 & freq_cap2);
340 /* See if I am changing the link freqency */
341 old_freq = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_FREQ);
342 needs_reset |= old_freq != freq;
343 old_freq = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_FREQ);
344 needs_reset |= old_freq != freq;
346 /* Set the Calulcated link frequency */
347 pci_write_config8(node1, link1 + PCI_HT_CAP_HOST_FREQ, freq);
348 pci_write_config8(node2, link2 + PCI_HT_CAP_HOST_FREQ, freq);
350 /* Get the width capabilities */
351 width_cap1 = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH);
352 width_cap2 = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH);
354 /* Calculate node1's input width */
355 ln_width1 = link_width_to_pow2[width_cap1 & 7];
356 ln_width2 = link_width_to_pow2[(width_cap2 >> 4) & 7];
357 if (ln_width1 > ln_width2) {
358 ln_width1 = ln_width2;
360 width = pow2_to_link_width[ln_width1];
361 /* Calculate node1's output width */
362 ln_width1 = link_width_to_pow2[(width_cap1 >> 4) & 7];
363 ln_width2 = link_width_to_pow2[width_cap2 & 7];
364 if (ln_width1 > ln_width2) {
365 ln_width1 = ln_width2;
367 width |= pow2_to_link_width[ln_width1] << 4;
369 /* See if I am changing node1's width */
370 old_width = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH + 1);
371 needs_reset |= old_width != width;
373 /* Set node1's widths */
374 pci_write_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH + 1, width);
376 // * Calculate node2's width */
377 width = ((width & 0x70) >> 4) | ((width & 0x7) << 4);
379 /* See if I am changing node2's width */
380 old_width = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH + 1);
381 needs_reset |= old_width != width;
383 /* Set node2's widths */
384 pci_write_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH + 1, width);
389 static uint8_t get_linkn_first(uint8_t byte)
391 if(byte & 0x02) { byte = 0; }
392 else if(byte & 0x04) { byte = 1; }
393 else if(byte & 0x08) { byte = 2; }
397 static uint8_t get_linkn_last(uint8_t byte)
399 if(byte & 0x02) { byte &= 0x0f; byte |= 0x00; }
400 if(byte & 0x04) { byte &= 0x0f; byte |= 0x10; }
401 if(byte & 0x08) { byte &= 0x0f; byte |= 0x20; }
405 static uint8_t get_linkn_last_count(uint8_t byte)
408 if(byte & 0x02) { byte &= 0xcf; byte |= 0x00; byte+=0x40; }
409 if(byte & 0x04) { byte &= 0xcf; byte |= 0x10; byte+=0x40; }
410 if(byte & 0x08) { byte &= 0xcf; byte |= 0x20; byte+=0x40; }
414 static void setup_row_local(u8 source, u8 row) /* source will be 7 when it is for temp use*/
419 for(linkn = 0; linkn<3; linkn++) {
422 regpos = 0x98 + 0x20 * linkn;
423 reg = pci_read_config32(NODE_HT(source), regpos);
424 if ((reg & 0x17) != 3) continue; /* it is not conherent or not connected*/
429 fill_row(source,row, val);
432 static void setup_row_direct_x(u8 temp, u8 source, u8 dest, u8 linkn)
437 val |= 1<<(linkn+1+8); /*for direct connect response route should equal to request table*/
439 if(((source &1)!=(dest &1))
441 && ( (source<4)||(source>5) ) //(6,7) (7,6) should still be here
442 //(6,5) (7,4) should be here
447 /*for CROSS_BAR_47_56 47, 56, should be here too
448 and for 47, 56, 57, 75, 46, 64 we need to substract another link to
451 val_s = get_row(temp, source);
452 val |= ((val_s>>16) - (1<<(linkn+1)))<<16;
455 fill_row(temp,dest, val );
459 static void opt_broadcast_rt(u8 source, u8 dest, u8 kickout) {
461 val = get_row(source, dest);
462 val -= link_connection(source, kickout)<<16;
463 fill_row(source, dest, val);
466 static void opt_broadcast_rt_group(const u8 *conn, int num) {
469 for(i=0; i<num; i+=3) {
470 opt_broadcast_rt(conn[i], conn[i+1],conn[i+2]);
473 static void opt_broadcast_rt_plus(u8 source, u8 dest, u8 kickout) {
475 val = get_row(source, dest);
476 val += link_connection(source, kickout)<<16;
477 fill_row(source, dest, val);
480 static void opt_broadcast_rt_plus_group(const u8 *conn, int num) {
483 for(i=0; i<num; i+=3) {
484 opt_broadcast_rt_plus(conn[i], conn[i+1],conn[i+2]);
489 static void setup_row_direct(u8 source, u8 dest, u8 linkn){
490 setup_row_direct_x(source, source, dest, linkn);
493 static void setup_remote_row_direct(u8 source, u8 dest, u8 linkn){
494 setup_row_direct_x(7, source, dest, linkn);
497 static void setup_temp_row(u8 source, u8 dest)
499 /* copy val from (source, dest) to (source,7) */
500 fill_row(source,7,get_row(source,dest));
503 static void clear_temp_row(u8 source)
505 fill_row(source, 7, DEFAULT);
508 static void setup_remote_node(u8 node)
510 static const uint8_t pci_reg[] = {
511 0x44, 0x4c, 0x54, 0x5c, 0x64, 0x6c, 0x74, 0x7c,
512 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78,
513 0x84, 0x8c, 0x94, 0x9c, 0xa4, 0xac, 0xb4, 0xbc,
514 0x80, 0x88, 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8,
515 0xc4, 0xcc, 0xd4, 0xdc,
516 0xc0, 0xc8, 0xd0, 0xd8,
517 0xe0, 0xe4, 0xe8, 0xec,
521 print_spew("setup_remote_node: ");
523 /* copy the default resource map from node 0 */
524 for(i = 0; i < sizeof(pci_reg)/sizeof(pci_reg[0]); i++) {
528 value = pci_read_config32(NODE_MP(0), reg);
529 pci_write_config32(NODE_MP(7), reg, value);
532 print_spew("done\r\n");
535 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 1*/
538 #if CONFIG_MAX_PHYSICAL_CPUS > 2
540 static void setup_row_indirect_x(u8 temp, u8 source, u8 dest)
542 static void setup_row_indirect_x(u8 temp, u8 source, u8 dest, u8 gateway, u8 diff)
545 /*for indirect connection, we need to compute the val from val_s(source, source), and val_g(source, gateway) */
552 gateway = source + 2;
554 gateway = source - 2;
557 val_s = get_row(temp, source);
558 val = get_row(temp, gateway);
565 diff = ((source&1)!=(dest &1));
568 if(diff && (val_s!=(val&0xff)) ) { /* use another connect as response*/
570 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
572 /* Some node have two links left
573 * don't worry we only have (2, (3 as source need to handle
576 byte = get_linkn_last_count(byte);
577 if((byte>>2)>1) { /* make sure not the corner*/
579 val_s-=link_connection(temp, source-2); /* -down*/
584 val_s-=link_connection(temp, 6); // for 7,2 via 5
585 } else if (source==6){
586 val_s-=link_connection(temp, 7); // for 6,3 via 4
589 if (source < gateway) { // for 5, 4 via 7
590 val_s-=link_connection(temp, source-2);
593 val_s-=link_connection(temp, source+2); /* -up*/
601 if(diff) { /* cross rung?*/
605 val_s = get_row(temp, source);
606 val |= ((val_s>>16) - link_connection(temp, gateway))<<16;
609 fill_row(temp, dest, val);
614 static void setup_row_indirect(u8 source, u8 dest)
616 setup_row_indirect_x(source, source, dest);
619 static void setup_row_indirect(u8 source, u8 dest, u8 gateway, u8 diff)
621 setup_row_indirect_x(source, source, dest, gateway, diff);
625 static void setup_row_indirect_group(const u8 *conn, int num)
630 for(i=0; i<num; i+=2) {
631 setup_row_indirect(conn[i], conn[i+1]);
633 for(i=0; i<num; i+=4) {
634 setup_row_indirect(conn[i], conn[i+1],conn[i+2], conn[i+3]);
641 static void setup_remote_row_indirect(u8 source, u8 dest)
643 setup_row_indirect_x(7, source, dest);
646 static void setup_remote_row_indirect(u8 source, u8 dest, u8 gateway, u8 diff)
648 setup_row_indirect_x(7, source, dest, gateway, diff);
652 static void setup_remote_row_indirect_group(const u8 *conn, int num)
657 for(i=0; i<num; i+=2) {
658 setup_remote_row_indirect(conn[i], conn[i+1]);
660 for(i=0; i<num; i+=4) {
661 setup_remote_row_indirect(conn[i], conn[i+1],conn[i+2], conn[i+3]);
666 #endif /*CONFIG_MAX_PHYSICAL_CPUS > 2*/
669 static void setup_uniprocessor(void)
671 print_spew("Enabling UP settings\r\n");
672 #if CONFIG_LOGICAL_CPUS==1
673 unsigned tmp = (pci_read_config32(NODE_MC(0), 0xe8) >> 12) & 3;
679 struct setup_smp_result {
684 #if CONFIG_MAX_PHYSICAL_CPUS > 2
685 static int optimize_connection_group(const u8 *opt_conn, int num) {
688 for(i=0; i<num; i+=2) {
689 needs_reset = optimize_connection(
690 NODE_HT(opt_conn[i]), 0x80 + link_to_register(link_connection(opt_conn[i],opt_conn[i+1])),
691 NODE_HT(opt_conn[i+1]), 0x80 + link_to_register(link_connection(opt_conn[i+1],opt_conn[i])) );
697 #if CONFIG_MAX_PHYSICAL_CPUS > 1
698 static struct setup_smp_result setup_smp2(void)
700 struct setup_smp_result result;
704 result.needs_reset = 0;
706 setup_row_local(0, 0); /* it will update the broadcast RT*/
709 byte = (val>>16) & 0xfe;
710 if(byte<0x2) { /* no coherent connection so get out.*/
715 /* Setup and check a temporary connection to node 1 */
716 #if TRY_HIGH_FIRST == 1
717 byte = get_linkn_last(byte); /* Max Link to node1 */
719 byte = get_linkn_first(byte); /*Min Link to node1 --- according to AMD*/
721 print_linkn("(0,1) link=", byte);
722 setup_row_direct(0,1, byte);
723 setup_temp_row(0, 1);
725 verify_connection(7);
727 /* We found 2 nodes so far */
728 val = pci_read_config32(NODE_HT(7), 0x6c);
729 byte = (val>>2) & 0x3; /*get default link on node7 to node0*/
730 print_linkn("(1,0) link=", byte);
731 setup_row_local(7,1);
732 setup_remote_row_direct(1, 0, byte);
734 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
736 byte = (val>>16) & 0xfe;
737 byte = get_linkn_last_count(byte);
738 if((byte>>2)==3) { /* Oh! we need to treat it as node2. So use another link*/
740 byte = (val>>16) & 0xfe;
741 #if TRY_HIGH_FIRST == 1
742 byte = get_linkn_first(byte); /* Min link to Node1 */
744 byte = get_linkn_last(byte); /* Max link to Node1*/
746 print_linkn("\t-->(0,1) link=", byte);
747 setup_row_direct(0,1, byte);
748 setup_temp_row(0, 1);
750 verify_connection(7);
752 /* We found 2 nodes so far */
753 val = pci_read_config32(NODE_HT(7), 0x6c);
754 byte = (val>>2) & 0x3; /* get default link on node7 to node0*/
755 print_linkn("\t-->(1,0) link=", byte);
756 setup_row_local(7,1);
757 setup_remote_row_direct(1, 0, byte);
761 setup_remote_node(1); /* Setup the regs on the remote node */
762 rename_temp_node(1); /* Rename Node 7 to Node 1 */
763 enable_routing(1); /* Enable routing on Node 1 */
765 /*don't need and it is done by clear_dead_links */
769 result.needs_reset |= optimize_connection(
770 NODE_HT(0), 0x80 + link_to_register(link_connection(0,1)),
771 NODE_HT(1), 0x80 + link_to_register(link_connection(1,0)) );
775 #endif /*CONFIG_MAX_PHYSICAL_CPUS > 1 */
777 #if CONFIG_MAX_PHYSICAL_CPUS > 2
779 static struct setup_smp_result setup_smp4(int needs_reset)
781 struct setup_smp_result result;
786 result.needs_reset = needs_reset;
788 /* Setup and check temporary connection from Node 0 to Node 2 */
790 byte = ((val>>16) & 0xfe) - link_connection(0,1);
791 byte = get_linkn_last_count(byte);
793 if((byte>>2)==0) { /* We should have two coherent for 4p and above*/
798 byte &= 3; /* bit [3,2] is count-1*/
799 print_linkn("(0,2) link=", byte);
800 setup_row_direct(0, 2, byte); /*(0,2) direct link done*/
802 /* We found 3 nodes so far. Now setup a temporary
803 * connection from node 0 to node 3 via node 1
805 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
806 /* here should setup_row_direct(1,3) at first, before that we should find the link in node 1 to 3*/
808 byte = ((val>>16) & 0xfe) - link_connection(1,0);
809 byte = get_linkn_first(byte);
810 print_linkn("(1,3) link=", byte);
811 setup_row_direct(1,3,byte); /* (1, 3) direct link done*/
813 /* We found 4 nodes so far. Now setup all nodes for 4p */
814 // We need to make sure 0,2 and 1,3 link is set already
816 static const u8 conn4_1[] = {
821 static const u8 conn4_1[] = {
827 setup_row_indirect_group(conn4_1, sizeof(conn4_1)/sizeof(conn4_1[0]));
830 verify_connection(7);
831 val = pci_read_config32(NODE_HT(7), 0x6c);
832 byte = (val>>2) & 0x3; /* get default link on 7 to 0*/
833 print_linkn("(2,0) link=", byte);
835 setup_row_local(7,2);
836 setup_remote_row_direct(2, 0, byte); /* node 2 to node 0 direct link done */
837 setup_remote_node(2); /* Setup the regs on the remote node */
839 rename_temp_node(2); /* Rename Node 7 to Node 2 */
840 enable_routing(2); /* Enable routing on Node 2 */
844 verify_connection(7);
846 val = pci_read_config32(NODE_HT(7), 0x6c);
847 byte = (val>>2) & 0x3; /* get default link on 7 to 1*/
848 print_linkn("(3,1) link=", byte);
850 setup_row_local(7,3);
851 setup_remote_row_direct(3, 1, byte); /* node 3 to node 1 direct link done */
852 setup_remote_node(3); /* Setup the regs on the remote node */
854 /* We need to init link between 2, and 3 direct link */
856 byte = ((val>>16) & 0xfe) - link_connection(2,0);
857 byte = get_linkn_last_count(byte);
858 print_linkn("(2,3) link=", byte & 3);
860 setup_row_direct(2,3, byte & 0x3);
863 verify_connection(7); /* to 3*/
865 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
866 /* We need to find out which link is to node3 */
867 if((byte>>2)==2) { /* one to node3, one to node0, one to node4*/
869 if((val>>16) == 1) { /* that link is to node4, because via node1 it has been set, recompute it*/
871 byte = ((val>>16) & 0xfe) - link_connection(2,0);
872 byte = get_linkn_first(byte);
873 print_linkn("\t-->(2,3) link=", byte);
874 setup_row_direct(2,3,byte);
876 verify_connection(7); /* to 3*/
881 val = pci_read_config32(NODE_HT(7), 0x6c);
882 byte = (val>>2) & 0x3; /* get default link on 7 to 2*/
883 print_linkn("(3,2) link=", byte);
884 setup_remote_row_direct(3,2, byte);
886 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
887 /* set link from 3 to 5 before enable it*/
889 byte = ((val>>16) & 0xfe) - link_connection(7,2) - link_connection(7,1);
890 byte = get_linkn_last_count(byte);
891 if((byte>>2)==1) { /* We should have three coherent links on node 3 for 6p and above*/
892 byte &= 3; /*bit [3,2] is count-2*/
893 print_linkn("(3,5) link=", byte);
894 setup_remote_row_direct(3, 5, byte);
898 byte = ((val>>16) & 0xfe) - link_connection(2,3) - link_connection(2,0);
899 byte = get_linkn_last_count(byte);
901 if((byte>>2)==1) { /* We should have three coherent link on node 2 for 6p and above*/
902 byte &= 3; /* bit [3,2] is count-2*/
903 print_linkn("(2,4) link=", byte);
904 setup_row_direct(2, 4, byte);
908 //Beside 3, 1 is set, We need to make sure 3, 5 is set already in case has three link in 3
910 static const u8 conn4_3[] = {
914 static const u8 conn4_3[] = {
918 setup_remote_row_indirect_group(conn4_3, sizeof(conn4_3)/sizeof(conn4_3[0]));
920 /* ready to enable RT for Node 3 */
922 enable_routing(3); /* enable routing on node 3 (temp.) */
924 // beside 2, 0 is set, We need to make sure 2, 4 link is set already in case has three link in 2
926 static const u8 conn4_2[] = {
930 static const u8 conn4_2[] = {
934 setup_row_indirect_group(conn4_2, sizeof(conn4_2)/sizeof(conn4_2[0]));
937 /*We need to do sth to reverse work for setup_temp_row (0,1) (1,3) */
938 /* it will be done by clear_dead_links */
943 /* optimize physical connections - by LYH */
944 static const u8 opt_conn4[] = {
950 result.needs_reset |= optimize_connection_group(opt_conn4, sizeof(opt_conn4)/sizeof(opt_conn4[0]));
956 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 2 */
958 #if CONFIG_MAX_PHYSICAL_CPUS > 4
960 static struct setup_smp_result setup_smp6(int needs_reset)
962 struct setup_smp_result result;
967 result.needs_reset = needs_reset;
969 /* Setup and check temporary connection from Node 0 to Node 4 through 2*/
971 byte = ((val>>16) & 0xfe) - link_connection(2,3) - link_connection(2,0);
972 byte = get_linkn_last_count(byte);
974 if((byte>>2)==0) { /* We should have three coherent link on node 2 for 6p and above*/
979 /* Setup and check temporary connection from Node 0 to Node 5 through 1, 3*/
980 /* set link from 3 to 5 before enable it*/
982 byte = ((val>>16) & 0xfe) - link_connection(3,2) - link_connection(3,1);
983 byte = get_linkn_last_count(byte);
984 if((byte>>2)==0) { /* We should have three coherent links on node 3 for 6p and above*/
989 /* We found 6 nodes so far. Now setup all nodes for 6p */
990 #warning "FIXME we need to find out the correct gateway for 6p"
991 static const u8 conn6_1[] = {
1009 setup_row_indirect_group(conn6_1, sizeof(conn6_1)/sizeof(conn6_1[0]));
1011 for(byte=0; byte<4; byte+=2) {
1012 setup_temp_row(byte,byte+2);
1014 verify_connection(7);
1015 val = pci_read_config32(NODE_HT(7), 0x6c);
1016 byte = (val>>2) & 0x3; /*get default link on 7 to 2*/
1017 print_linkn("(4,2) link=", byte);
1019 setup_row_local(7,4);
1020 setup_remote_row_direct(4, 2, byte);
1021 setup_remote_node(4); /* Setup the regs on the remote node */
1023 /* Set indirect connection to 0, to 3 */
1024 //we only need to set 4,0 here
1025 static const u8 conn6_2[] = {
1026 #if !CROSS_BAR_47_56
1033 setup_remote_row_indirect_group(conn6_2, sizeof(conn6_2)/sizeof(conn6_2[0]));
1035 rename_temp_node(4);
1038 setup_temp_row(0,1);
1039 for(byte=0; byte<4; byte+=2) {
1040 setup_temp_row(byte+1,byte+3);
1042 verify_connection(7);
1044 val = pci_read_config32(NODE_HT(7), 0x6c);
1045 byte = (val>>2) & 0x3; /* get default link on 7 to 3*/
1046 print_linkn("(5,3) link=", byte);
1047 setup_row_local(7,5);
1048 setup_remote_row_direct(5, 3, byte);
1049 setup_remote_node(5); /* Setup the regs on the remote node */
1051 #if !CROSS_BAR_47_56
1052 /* We need to init link between 4, and 5 direct link */
1054 byte = ((val>>16) & 0xfe) - link_connection(4,2);
1055 byte = get_linkn_last_count(byte);
1056 print_linkn("(4,5) link=", byte & 3);
1058 setup_row_direct(4,5, byte & 0x3);
1059 setup_temp_row(0,2);
1060 setup_temp_row(2,4);
1061 setup_temp_row(4,5);
1062 verify_connection(7); /* to 5*/
1064 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1065 /* We need to find out which link is to node5 */
1067 if((byte>>2)==2) { /* one to node5, one to node2, one to node6*/
1069 if((val>>16) == 1) { /* that link is to node6, because via node 3 node 5 has been set*/
1071 byte = ((val>>16) & 0xfe) - link_connection(4,2);
1072 byte = get_linkn_first(byte);
1073 print_linkn("\t-->(4,5) link=", byte);
1074 setup_row_direct(4,5,byte);
1075 setup_temp_row(4,5);
1076 verify_connection(7); /* to 5*/
1081 val = pci_read_config32(NODE_HT(7), 0x6c);
1082 byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
1083 print_linkn("(5,4) link=", byte);
1084 setup_remote_row_direct(5,4, byte);
1088 byte = ((val>>16) & 0xfe) - link_connection(7,4) - link_connection(7,3);
1089 byte = get_linkn_last_count(byte);
1090 if((byte>>2)==1) { /* We should have three coherent links on node 5 for 6p and above*/
1091 byte &= 3; /*bit [3,2] is count-2*/
1092 print_linkn("(5,7) link=", byte);
1093 setup_remote_row_direct(5, 7, byte);
1098 byte = ((val>>16) & 0xfe) - link_connection(4,5) - link_connection(4,2);
1099 byte = get_linkn_last_count(byte);
1101 if((byte>>2)==1) { /* We should have three coherent link on node 4 for 6p and above*/
1102 byte &= 3; /* bit [3,2] is count-2*/
1103 print_linkn("(4,6) link=", byte);
1104 setup_row_direct(4, 6, byte);
1109 //We need to set 5,0 here only, We need to set up 5, 7 to make 5,0
1110 /* Set indirect connection to 0, to 3 for indirect we will use clockwise routing */
1111 static const u8 conn6_3[] = {
1112 #if !CROSS_BAR_47_56
1119 setup_remote_row_indirect_group(conn6_3, sizeof(conn6_3)/sizeof(conn6_3[0]));
1121 /* ready to enable RT for 5 */
1122 rename_temp_node(5);
1123 enable_routing(5); /* enable routing on node 5 (temp.) */
1125 static const u8 conn6_4[] = {
1126 #if !CROSS_BAR_47_56
1145 setup_row_indirect_group(conn6_4, sizeof(conn6_4)/sizeof(conn6_4[0]));
1148 /* We need to do sth about reverse about setup_temp_row (0,1), (2,4), (1, 3), (3,5)
1149 * It will be done by clear_dead_links
1151 for(byte=0; byte<4; byte++) {
1152 clear_temp_row(byte);
1156 /* optimize physical connections - by LYH */
1157 static const uint8_t opt_conn6[] ={
1160 #if !CROSS_BAR_47_56
1164 result.needs_reset |= optimize_connection_group(opt_conn6, sizeof(opt_conn6)/sizeof(opt_conn6[0]));
1170 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 4 */
1172 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1174 static struct setup_smp_result setup_smp8(int needs_reset)
1176 struct setup_smp_result result;
1181 result.needs_reset = needs_reset;
1183 /* Setup and check temporary connection from Node 0 to Node 6 via 2 and 4 to 7 */
1186 byte = ((val>>16) & 0xfe) - link_connection(4,2);
1188 byte = ((val>>16) & 0xfe) - link_connection(4,5) - link_connection(4,2);
1189 byte = get_linkn_last_count(byte); /* Max link to 6*/
1190 if((byte>>2)==0) { /* We should have two or three coherent links on node 4 for 8p*/
1197 byte = get_linkn_last_count(byte); /* Max link to 6*/
1198 if((byte>>2)<2) { /* We should have two or three coherent links on node 4 for 8p*/
1202 #if TRY_HIGH_FIRST == 1
1203 byte = ((val>>16) & 0xfe) - link_connection(4,2);
1204 byte = get_linkn_first(byte); /*Min link to 6*/
1206 byte &= 3; /* bit [3,2] is count-1 or 2*/
1208 print_linkn("(4,6) link=", byte);
1209 setup_row_direct(4, 6, byte);
1212 #if !CROSS_BAR_47_56
1213 /* Setup and check temporary connection from Node 0 to Node 7 through 1, 3, 5*/
1215 byte = ((val>>16) & 0xfe) - link_connection(5,4) - link_connection(5,3);
1216 byte = get_linkn_last_count(byte);
1217 if((byte>>2)==0) { /* We should have three coherent links on node 5 for 6p and above*/
1223 /* We found 8 nodes so far. Now setup all nodes for 8p */
1224 static const u8 conn8_1[] = {
1225 #if !CROSS_BAR_47_56
1247 setup_row_indirect_group(conn8_1,sizeof(conn8_1)/sizeof(conn8_1[0]));
1249 for(byte=0; byte<6; byte+=2) {
1250 setup_temp_row(byte,byte+2);
1252 verify_connection(7);
1253 val = pci_read_config32(NODE_HT(7), 0x6c);
1254 byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
1255 print_linkn("(6,4) link=", byte);
1257 setup_row_local(7,6);
1258 setup_remote_row_direct(6, 4, byte);
1259 setup_remote_node(6); /* Setup the regs on the remote node */
1260 /* Set indirect connection to 0, to 3 */
1261 #warning "FIXME we need to find out the correct gateway for 8p"
1262 static const u8 conn8_2[] = {
1263 #if !CROSS_BAR_47_56
1270 setup_remote_row_indirect_group(conn8_2, sizeof(conn8_2)/sizeof(conn8_2[0]));
1274 /* here init 5, 6 */
1275 /* Setup and check temporary connection from Node 0 to Node 5 through 1, 3, 5*/
1277 byte = ((val>>16) & 0xfe) - link_connection(5,3);
1278 #if TRY_HIGH_FIRST == 1
1279 byte = get_linkn_first(byte);
1281 byte = get_linkn_last(byte);
1283 print_linkn("(5,6) link=", byte);
1284 setup_row_direct(5, 6, byte);
1286 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
1287 for(byte=0; byte<4; byte+=2) {
1288 setup_temp_row(byte+1,byte+3);
1290 setup_temp_row(5,6);
1292 verify_connection(7);
1294 val = get_row(7,6); // to chect it if it is node6 before renaming
1295 if( (val>>16) == 1) { // it is real node 7 so swap it
1296 /* We need to recompute link to 6 */
1298 byte = ((val>>16) & 0xfe) - link_connection(5,3);
1299 #if TRY_HIGH_FIRST == 1
1300 byte = get_linkn_first(byte);
1302 byte = get_linkn_last(byte);
1304 print_linkn("\t-->(5,6) link=", byte);
1305 setup_row_direct(5, 6, byte);
1307 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
1308 for(byte=0; byte<4; byte+=2) {
1309 setup_temp_row(byte+1,byte+3);
1312 setup_temp_row(5,6);
1314 verify_connection(7);
1316 val = pci_read_config32(NODE_HT(7), 0x6c);
1317 byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
1318 print_linkn("(6,5) link=", byte);
1319 setup_remote_row_direct(6, 5, byte);
1320 /*Till now 56, 65 done */
1323 rename_temp_node(6);
1326 #if !CROSS_BAR_47_56
1327 setup_temp_row(0,1);
1328 for(byte=0; byte<6; byte+=2) {
1329 setup_temp_row(byte+1,byte+3);
1332 verify_connection(7);
1334 val = pci_read_config32(NODE_HT(7), 0x6c);
1335 byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
1336 print_linkn("(7,5) link=", byte);
1337 setup_row_local(7,7);
1338 setup_remote_row_direct(7, 5, byte);
1342 byte = ((val>>16) & 0xfe) - link_connection(4,2) - link_connection(4,6);
1343 byte = get_linkn_first(byte);
1344 print_linkn("(4,7) link=", byte);
1345 setup_row_direct(4, 7, byte);
1347 /* Setup and check temporary connection from Node 0 to Node 7 through 2, and 4*/
1348 for(byte=0; byte<4; byte+=2) {
1349 setup_temp_row(byte,byte+2);
1352 verify_connection(7);
1354 val = pci_read_config32(NODE_HT(7), 0x6c);
1355 byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
1356 print_linkn("(7,4) link=", byte);
1357 setup_row_local(7,7);
1358 setup_remote_row_direct(7, 4, byte);
1359 /* till now 4-7, 7-4 done. */
1361 setup_remote_node(7); /* Setup the regs on the remote node */
1364 /* here init 5, 7 */
1365 /* Setup and check temporary connection from Node 0 to Node 5 through 1, 3, 5*/
1367 byte = ((val>>16) & 0xfe) - link_connection(5,3) - link_connection(5,6);
1368 byte = get_linkn_first(byte);
1369 print_linkn("(5,7) link=", byte);
1370 setup_row_direct(5, 7, byte);
1372 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
1373 for(byte=0; byte<4; byte+=2) {
1374 setup_temp_row(byte+1,byte+3);
1377 verify_connection(7);
1379 val = pci_read_config32(NODE_HT(7), 0x6c);
1380 byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
1381 print_linkn("(7,5) link=", byte);
1382 setup_remote_row_direct(7, 5, byte);
1383 /*Till now 57, 75 done */
1387 /* We need to init link between 6, and 7 direct link */
1389 #if !CROSS_BAR_47_56
1390 byte = ((val>>16) & 0xfe) - link_connection(6,4);
1392 byte = ((val>>16) & 0xfe) - link_connection(6,4) - link_connection(6,5);
1394 byte = get_linkn_first(byte);
1395 print_linkn("(6,7) link=", byte);
1396 setup_row_direct(6,7, byte);
1399 #if !CROSS_BAR_47_56
1400 byte = ((val>>16) & 0xfe) - link_connection(7,5);
1402 byte = ((val>>16) & 0xfe) - link_connection(7,5) - link_connection(7,4);
1404 byte = get_linkn_first(byte);
1405 print_linkn("(7,6) link=", byte);
1406 setup_row_direct(7,6, byte);
1408 /* Set indirect connection to 0, to 3 for indirect we will use clockwise routing */
1409 static const u8 conn8_3[] = {
1410 #if !CROSS_BAR_47_56
1411 0, 7, /* restore it*/
1433 6, 1, 5, 0, // or 4, 1
1435 6, 3, 5, 0, // or 4, 1
1437 7, 0, 4, 0, // or 5, 1
1439 7, 2, 4, 0, // or 5, 1
1442 0, 7, 2, 0, /* restore it*/
1447 2, 5, 4, 1, /* reset it */
1450 4, 1, 2, 1, /* reset it */
1453 5, 2, 3, 1, /* reset it */
1459 setup_row_indirect_group(conn8_3, sizeof(conn8_3)/sizeof(conn8_3[0]));
1462 /* for 47, 56, 57, 75, 46, 64 we need to substract another link to
1464 static const u8 conn8_4[] = {
1487 6, 1, 7, // needed for via 5
1490 6, 3, 7, // needed for via 5
1492 7, 0, 6, // needed for via 4
1495 7, 2, 6, // needed for via 4
1500 opt_broadcast_rt_group(conn8_4, sizeof(conn8_4)/sizeof(conn8_4[0]));
1502 static const u8 conn8_5[] = {
1508 opt_broadcast_rt_plus_group(conn8_5, sizeof(conn8_5)/sizeof(conn8_5[0]));
1513 /* ready to enable RT for Node 7 */
1514 enable_routing(7); /* enable routing on node 7 (temp.) */
1516 static const uint8_t opt_conn8[] ={
1525 /* optimize physical connections - by LYH */
1526 result.needs_reset |= optimize_connection_group(opt_conn8, sizeof(opt_conn8)/sizeof(opt_conn8[0]));
1531 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 6 */
1534 #if CONFIG_MAX_PHYSICAL_CPUS > 1
1536 static struct setup_smp_result setup_smp(void)
1538 struct setup_smp_result result;
1540 print_spew("Enabling SMP settings\r\n");
1542 result = setup_smp2();
1543 #if CONFIG_MAX_PHYSICAL_CPUS > 2
1544 if(result.nodes == 2)
1545 result = setup_smp4(result.needs_reset);
1548 #if CONFIG_MAX_PHYSICAL_CPUS > 4
1549 if(result.nodes == 4)
1550 result = setup_smp6(result.needs_reset);
1553 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1554 if(result.nodes == 6)
1555 result = setup_smp8(result.needs_reset);
1559 printk_debug("%02x nodes initialized.\r\n", result.nodes);
1561 print_debug_hex8(result.nodes);
1562 print_debug(" nodes initialized.\r\n");
1568 static unsigned verify_mp_capabilities(unsigned nodes)
1570 unsigned node, mask;
1572 mask = 0x06; /* BigMPCap */
1574 for (node=0; node<nodes; node++) {
1575 mask &= pci_read_config32(NODE_MC(node), 0xe8);
1579 #if CONFIG_MAX_PHYSICAL_CPUS > 2
1580 case 0x02: /* MPCap */
1582 print_err("Going back to DP\r\n");
1587 case 0x00: /* Non SMP */
1589 print_err("Going back to UP\r\n");
1600 static void clear_dead_routes(unsigned nodes)
1604 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1605 if(nodes==8) return;/* don't touch (7,7)*/
1611 for(node = 7; node >= 0; node--) {
1612 for(row = 7; row >= last_row; row--) {
1613 fill_row(node, row, DEFAULT);
1617 /* Update the local row */
1618 for( node=0; node<nodes; node++) {
1620 for(row =0; row<nodes; row++) {
1621 val |= get_row(node, row);
1623 fill_row(node, node, (((val & 0xff) | ((val >> 8) & 0xff)) << 16) | 0x0101);
1626 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 1 */
1628 #if CONFIG_LOGICAL_CPUS==1
1629 static unsigned verify_dualcore(unsigned nodes)
1631 unsigned node, totalcpus, tmp;
1634 for (node=0; node<nodes; node++) {
1635 tmp = (pci_read_config32(NODE_MC(node), 0xe8) >> 12) & 3 ;
1636 totalcpus += (tmp + 1);
1644 static void coherent_ht_finalize(unsigned nodes)
1648 #if CONFIG_LOGICAL_CPUS==1
1649 unsigned total_cpus;
1651 if(read_option(CMOS_VSTART_dual_core, CMOS_VLEN_dual_core, 0) == 0) { /* dual_core */
1652 total_cpus = verify_dualcore(nodes);
1659 /* set up cpu count and node count and enable Limit
1660 * Config Space Range for all available CPUs.
1661 * Also clear non coherent hypertransport bus range
1662 * registers on Hammer A0 revision.
1665 print_spew("coherent_ht_finalize\r\n");
1666 rev_a0 = is_cpu_rev_a0();
1667 for (node = 0; node < nodes; node++) {
1670 dev = NODE_HT(node);
1672 /* Set the Total CPU and Node count in the system */
1673 val = pci_read_config32(dev, 0x60);
1674 val &= (~0x000F0070);
1675 #if CONFIG_LOGICAL_CPUS==1
1676 val |= ((total_cpus-1)<<16)|((nodes-1)<<4);
1678 val |= ((nodes-1)<<16)|((nodes-1)<<4);
1680 pci_write_config32(dev, 0x60, val);
1682 /* Only respond to real cpu pci configuration cycles
1683 * and optimize the HT settings
1685 val=pci_read_config32(dev, HT_TRANSACTION_CONTROL);
1686 val &= ~((HTTC_BUF_REL_PRI_MASK << HTTC_BUF_REL_PRI_SHIFT) |
1687 (HTTC_MED_PRI_BYP_CNT_MASK << HTTC_MED_PRI_BYP_CNT_SHIFT) |
1688 (HTTC_HI_PRI_BYP_CNT_MASK << HTTC_HI_PRI_BYP_CNT_SHIFT));
1689 val |= HTTC_LIMIT_CLDT_CFG |
1690 (HTTC_BUF_REL_PRI_8 << HTTC_BUF_REL_PRI_SHIFT) |
1691 (3 << HTTC_MED_PRI_BYP_CNT_SHIFT) |
1692 (3 << HTTC_HI_PRI_BYP_CNT_SHIFT);
1693 pci_write_config32(dev, HT_TRANSACTION_CONTROL, val);
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 /* Only handle coherent links */
1774 if ((link_type & (LinkConnected | InitComplete|NonCoherent)) ==
1775 (LinkConnected|InitComplete))
1777 cmd &= ~(0xff << (link *8));
1778 cmd |= 0x25 << (link *8);
1781 if (cmd != cmd_ref) {
1782 pci_write_config32(f3_dev, 0xdc, cmd);
1789 static int setup_coherent_ht_domain(void)
1791 struct setup_smp_result result;
1793 result.needs_reset = 0;
1795 #if K8_HT_CHECK_PENDING_LINK == 1
1799 enable_bsp_routing();
1801 #if CONFIG_MAX_PHYSICAL_CPUS > 1
1802 result = setup_smp();
1803 result.nodes = verify_mp_capabilities(result.nodes);
1804 clear_dead_routes(result.nodes);
1807 if (result.nodes == 1) {
1808 setup_uniprocessor();
1810 coherent_ht_finalize(result.nodes);
1811 result.needs_reset = apply_cpu_errata_fixes(result.nodes, result.needs_reset);
1812 result.needs_reset = optimize_link_read_pointers(result.nodes, result.needs_reset);
1813 return result.needs_reset;