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 static void enable_routing(u8 node)
162 /* HT Initialization Control Register
164 * [ 0: 0] Routing Table Disable
165 * 0 = Packets are routed according to routing tables
166 * 1 = Packets are routed according to the default link field
167 * [ 1: 1] Request Disable (BSP should clear this)
168 * 0 = Request packets may be generated
169 * 1 = Request packets may not be generated.
170 * [ 3: 2] Default Link (Read-only)
174 * 11 = CPU on same node
176 * - Scratch bit cleared by a cold reset
177 * [ 5: 5] BIOS Reset Detect
178 * - Scratch bit cleared by a cold reset
179 * [ 6: 6] INIT Detect
180 * - Scratch bit cleared by a warm or cold reset not by an INIT
184 /* Enable routing table */
185 print_spew("Enabling routing table for node ");
186 print_spew_hex8(node);
188 val=pci_read_config32(NODE_HT(node), 0x6c);
189 val &= ~((1<<1)|(1<<0));
190 pci_write_config32(NODE_HT(node), 0x6c, val);
192 print_spew(" done.\r\n");
195 static void enable_apic_ext_id(u8 node)
200 val = pci_read_config32(NODE_HT(node), 0x68);
201 val |= (HTTC_APIC_EXT_SPUR | HTTC_APIC_EXT_ID | HTTC_APIC_EXT_BRD_CST);
202 pci_write_config32(NODE_HT(node), 0x68, val);
206 static void fill_row(u8 node, u8 row, u32 value)
208 pci_write_config32(NODE_HT(node), 0x40+(row<<2), value);
211 #if CONFIG_MAX_PHYSICAL_CPUS > 1
212 static u8 link_to_register(int ldt)
215 * [ 0: 3] Request Route
216 * [0] Route to this node
217 * [1] Route to Link 0
218 * [2] Route to Link 1
219 * [3] Route to Link 2
222 if (ldt&0x08) return 0x40;
223 if (ldt&0x04) return 0x20;
224 if (ldt&0x02) return 0x00;
226 /* we should never get here */
227 print_spew("Unknown Link\n");
231 static u32 get_row(u8 node, u8 row)
233 return pci_read_config32(NODE_HT(node), 0x40+(row<<2));
236 static int link_connection(u8 src, u8 dest)
238 return get_row(src, dest) & 0x0f;
241 static void rename_temp_node(u8 node)
245 print_spew("Renaming current temporary node to ");
246 print_spew_hex8(node);
248 val=pci_read_config32(NODE_HT(7), 0x60);
249 val &= (~7); /* clear low bits. */
250 val |= node; /* new node */
251 pci_write_config32(NODE_HT(7), 0x60, val);
253 print_spew(" done.\r\n");
255 #if K8_HT_CHECK_PENDING_LINK == 1
256 static void wait_ht_stable(uint8_t node)
259 for(linkn = 0; linkn<3; linkn++) {
263 regpos = 0x98 + 0x20 * linkn;
264 for(i = 0; i < 0xff; i++) { //wait to make sure it is done
265 reg = pci_read_config32(NODE_HT(node), regpos);
266 if ((reg & 0x10) == 0) break; // init complete
273 static int verify_connection(u8 dest)
275 /* See if we have a valid connection to dest */
278 /* Verify that the coherent hypertransport link is
279 * established and actually working by reading the
280 * remode node's vendor/device id
282 val = pci_read_config32(NODE_HT(dest),0);
283 if(val != 0x11001022)
289 static unsigned read_freq_cap(device_t dev, unsigned pos)
291 /* Handle bugs in valid hypertransport frequency reporting */
295 freq_cap = pci_read_config16(dev, pos);
296 freq_cap &= ~(1 << HT_FREQ_VENDOR); /* Ignore Vendor HT frequencies */
298 if (!is_cpu_pre_e0()) {
302 id = pci_read_config32(dev, 0);
304 /* AMD K8 Unsupported 1Ghz? */
305 if (id == (PCI_VENDOR_ID_AMD | (0x1100 << 16))) {
306 freq_cap &= ~(1 << HT_FREQ_1000Mhz);
312 static int optimize_connection(device_t node1, uint8_t link1, device_t node2, uint8_t link2)
314 static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
315 static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
316 uint16_t freq_cap1, freq_cap2, freq_cap, freq_mask;
317 uint8_t width_cap1, width_cap2, width_cap, width, old_width, ln_width1, ln_width2;
318 uint8_t freq, old_freq;
320 /* Set link width and frequency */
322 /* Initially assume everything is already optimized and I don't need a reset */
325 /* Get the frequency capabilities */
326 freq_cap1 = read_freq_cap(node1, link1 + PCI_HT_CAP_HOST_FREQ_CAP);
327 freq_cap2 = read_freq_cap(node2, link2 + PCI_HT_CAP_HOST_FREQ_CAP);
329 /* Calculate the highest possible frequency */
330 freq = log2(freq_cap1 & freq_cap2);
332 /* See if I am changing the link freqency */
333 old_freq = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_FREQ);
335 needs_reset |= old_freq != freq;
336 old_freq = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_FREQ);
338 needs_reset |= old_freq != freq;
340 /* Set the Calulcated link frequency */
341 pci_write_config8(node1, link1 + PCI_HT_CAP_HOST_FREQ, freq);
342 pci_write_config8(node2, link2 + PCI_HT_CAP_HOST_FREQ, freq);
344 /* Get the width capabilities */
345 width_cap1 = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH);
346 width_cap2 = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH);
348 /* Calculate node1's input width */
349 ln_width1 = link_width_to_pow2[width_cap1 & 7];
350 ln_width2 = link_width_to_pow2[(width_cap2 >> 4) & 7];
351 if (ln_width1 > ln_width2) {
352 ln_width1 = ln_width2;
354 width = pow2_to_link_width[ln_width1];
355 /* Calculate node1's output width */
356 ln_width1 = link_width_to_pow2[(width_cap1 >> 4) & 7];
357 ln_width2 = link_width_to_pow2[width_cap2 & 7];
358 if (ln_width1 > ln_width2) {
359 ln_width1 = ln_width2;
361 width |= pow2_to_link_width[ln_width1] << 4;
363 /* See if I am changing node1's width */
364 old_width = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH + 1);
365 needs_reset |= old_width != width;
367 /* Set node1's widths */
368 pci_write_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH + 1, width);
370 // * Calculate node2's width */
371 width = ((width & 0x70) >> 4) | ((width & 0x7) << 4);
373 /* See if I am changing node2's width */
374 old_width = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH + 1);
375 needs_reset |= old_width != width;
377 /* Set node2's widths */
378 pci_write_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH + 1, width);
382 static uint8_t get_linkn_first(uint8_t byte)
384 if(byte & 0x02) { byte = 0; }
385 else if(byte & 0x04) { byte = 1; }
386 else if(byte & 0x08) { byte = 2; }
390 static uint8_t get_linkn_last(uint8_t byte)
392 if(byte & 0x02) { byte &= 0x0f; byte |= 0x00; }
393 if(byte & 0x04) { byte &= 0x0f; byte |= 0x10; }
394 if(byte & 0x08) { byte &= 0x0f; byte |= 0x20; }
398 static uint8_t get_linkn_last_count(uint8_t byte)
401 if(byte & 0x02) { byte &= 0xcf; byte |= 0x00; byte+=0x40; }
402 if(byte & 0x04) { byte &= 0xcf; byte |= 0x10; byte+=0x40; }
403 if(byte & 0x08) { byte &= 0xcf; byte |= 0x20; byte+=0x40; }
407 static void setup_row_local(u8 source, u8 row) /* source will be 7 when it is for temp use*/
412 for(linkn = 0; linkn<3; linkn++) {
415 regpos = 0x98 + 0x20 * linkn;
416 reg = pci_read_config32(NODE_HT(source), regpos);
417 if ((reg & 0x17) != 3) continue; /* it is not conherent or not connected*/
422 fill_row(source,row, val);
425 static void setup_row_direct_x(u8 temp, u8 source, u8 dest, u8 linkn)
430 val |= 1<<(linkn+1+8); /*for direct connect response route should equal to request table*/
432 if(((source &1)!=(dest &1))
434 && ( (source<4)||(source>5) ) //(6,7) (7,6) should still be here
435 //(6,5) (7,4) should be here
440 /*for CROSS_BAR_47_56 47, 56, should be here too
441 and for 47, 56, 57, 75, 46, 64 we need to substract another link to
444 val_s = get_row(temp, source);
445 val |= ((val_s>>16) - (1<<(linkn+1)))<<16;
448 fill_row(temp,dest, val );
452 static void opt_broadcast_rt(u8 source, u8 dest, u8 kickout) {
454 val = get_row(source, dest);
455 val -= link_connection(source, kickout)<<16;
456 fill_row(source, dest, val);
459 static void opt_broadcast_rt_group(const u8 *conn, int num) {
462 for(i=0; i<num; i+=3) {
463 opt_broadcast_rt(conn[i], conn[i+1],conn[i+2]);
466 static void opt_broadcast_rt_plus(u8 source, u8 dest, u8 kickout) {
468 val = get_row(source, dest);
469 val += link_connection(source, kickout)<<16;
470 fill_row(source, dest, val);
473 static void opt_broadcast_rt_plus_group(const u8 *conn, int num) {
476 for(i=0; i<num; i+=3) {
477 opt_broadcast_rt_plus(conn[i], conn[i+1],conn[i+2]);
482 static void setup_row_direct(u8 source, u8 dest, u8 linkn){
483 setup_row_direct_x(source, source, dest, linkn);
486 static void setup_remote_row_direct(u8 source, u8 dest, u8 linkn){
487 setup_row_direct_x(7, source, dest, linkn);
490 static void setup_temp_row(u8 source, u8 dest)
492 /* copy val from (source, dest) to (source,7) */
493 fill_row(source,7,get_row(source,dest));
496 static void clear_temp_row(u8 source)
498 fill_row(source, 7, DEFAULT);
501 static void setup_remote_node(u8 node)
503 static const uint8_t pci_reg[] = {
504 0x44, 0x4c, 0x54, 0x5c, 0x64, 0x6c, 0x74, 0x7c,
505 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78,
506 0x84, 0x8c, 0x94, 0x9c, 0xa4, 0xac, 0xb4, 0xbc,
507 0x80, 0x88, 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8,
508 0xc4, 0xcc, 0xd4, 0xdc,
509 0xc0, 0xc8, 0xd0, 0xd8,
510 0xe0, 0xe4, 0xe8, 0xec,
514 print_spew("setup_remote_node: ");
516 /* copy the default resource map from node 0 */
517 for(i = 0; i < sizeof(pci_reg)/sizeof(pci_reg[0]); i++) {
521 value = pci_read_config32(NODE_MP(0), reg);
522 pci_write_config32(NODE_MP(7), reg, value);
525 print_spew("done\r\n");
528 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 1*/
531 #if CONFIG_MAX_PHYSICAL_CPUS > 2
533 static void setup_row_indirect_x(u8 temp, u8 source, u8 dest)
535 static void setup_row_indirect_x(u8 temp, u8 source, u8 dest, u8 gateway, u8 diff)
538 /*for indirect connection, we need to compute the val from val_s(source, source), and val_g(source, gateway) */
545 gateway = source + 2;
547 gateway = source - 2;
550 val_s = get_row(temp, source);
551 val = get_row(temp, gateway);
558 diff = ((source&1)!=(dest &1));
561 if(diff && (val_s!=(val&0xff)) ) { /* use another connect as response*/
563 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
565 /* Some node have two links left
566 * don't worry we only have (2, (3 as source need to handle
569 byte = get_linkn_last_count(byte);
570 if((byte>>2)>1) { /* make sure not the corner*/
572 val_s-=link_connection(temp, source-2); /* -down*/
577 val_s-=link_connection(temp, 6); // for 7,2 via 5
578 } else if (source==6){
579 val_s-=link_connection(temp, 7); // for 6,3 via 4
582 if (source < gateway) { // for 5, 4 via 7
583 val_s-=link_connection(temp, source-2);
586 val_s-=link_connection(temp, source+2); /* -up*/
594 if(diff) { /* cross rung?*/
598 val_s = get_row(temp, source);
599 val |= ((val_s>>16) - link_connection(temp, gateway))<<16;
602 fill_row(temp, dest, val);
607 static void setup_row_indirect(u8 source, u8 dest)
609 setup_row_indirect_x(source, source, dest);
612 static void setup_row_indirect(u8 source, u8 dest, u8 gateway, u8 diff)
614 setup_row_indirect_x(source, source, dest, gateway, diff);
618 static void setup_row_indirect_group(const u8 *conn, int num)
623 for(i=0; i<num; i+=2) {
624 setup_row_indirect(conn[i], conn[i+1]);
626 for(i=0; i<num; i+=4) {
627 setup_row_indirect(conn[i], conn[i+1],conn[i+2], conn[i+3]);
634 static void setup_remote_row_indirect(u8 source, u8 dest)
636 setup_row_indirect_x(7, source, dest);
639 static void setup_remote_row_indirect(u8 source, u8 dest, u8 gateway, u8 diff)
641 setup_row_indirect_x(7, source, dest, gateway, diff);
645 static void setup_remote_row_indirect_group(const u8 *conn, int num)
650 for(i=0; i<num; i+=2) {
651 setup_remote_row_indirect(conn[i], conn[i+1]);
653 for(i=0; i<num; i+=4) {
654 setup_remote_row_indirect(conn[i], conn[i+1],conn[i+2], conn[i+3]);
659 #endif /*CONFIG_MAX_PHYSICAL_CPUS > 2*/
662 static void setup_uniprocessor(void)
664 print_spew("Enabling UP settings\r\n");
665 #if CONFIG_LOGICAL_CPUS==1
666 unsigned tmp = (pci_read_config32(NODE_MC(0), 0xe8) >> 12) & 3;
672 struct setup_smp_result {
677 #if CONFIG_MAX_PHYSICAL_CPUS > 2
678 static int optimize_connection_group(const u8 *opt_conn, int num) {
681 for(i=0; i<num; i+=2) {
682 needs_reset = optimize_connection(
683 NODE_HT(opt_conn[i]), 0x80 + link_to_register(link_connection(opt_conn[i],opt_conn[i+1])),
684 NODE_HT(opt_conn[i+1]), 0x80 + link_to_register(link_connection(opt_conn[i+1],opt_conn[i])) );
690 #if CONFIG_MAX_PHYSICAL_CPUS > 1
691 static struct setup_smp_result setup_smp2(void)
693 struct setup_smp_result result;
697 result.needs_reset = 0;
699 setup_row_local(0, 0); /* it will update the broadcast RT*/
702 byte = (val>>16) & 0xfe;
703 if(byte<0x2) { /* no coherent connection so get out.*/
708 /* Setup and check a temporary connection to node 1 */
709 #if TRY_HIGH_FIRST == 1
710 byte = get_linkn_last(byte); /* Max Link to node1 */
712 byte = get_linkn_first(byte); /*Min Link to node1 --- according to AMD*/
714 print_linkn("(0,1) link=", byte);
715 setup_row_direct(0,1, byte);
716 setup_temp_row(0, 1);
718 verify_connection(7);
720 /* We found 2 nodes so far */
721 val = pci_read_config32(NODE_HT(7), 0x6c);
722 byte = (val>>2) & 0x3; /*get default link on node7 to node0*/
723 print_linkn("(1,0) link=", byte);
724 setup_row_local(7,1);
725 setup_remote_row_direct(1, 0, byte);
727 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
729 byte = (val>>16) & 0xfe;
730 byte = get_linkn_last_count(byte);
731 if((byte>>2)==3) { /* Oh! we need to treat it as node2. So use another link*/
733 byte = (val>>16) & 0xfe;
734 #if TRY_HIGH_FIRST == 1
735 byte = get_linkn_first(byte); /* Min link to Node1 */
737 byte = get_linkn_last(byte); /* Max link to Node1*/
739 print_linkn("\t-->(0,1) link=", byte);
740 setup_row_direct(0,1, byte);
741 setup_temp_row(0, 1);
743 verify_connection(7);
745 /* We found 2 nodes so far */
746 val = pci_read_config32(NODE_HT(7), 0x6c);
747 byte = (val>>2) & 0x3; /* get default link on node7 to node0*/
748 print_linkn("\t-->(1,0) link=", byte);
749 setup_row_local(7,1);
750 setup_remote_row_direct(1, 0, byte);
754 setup_remote_node(1); /* Setup the regs on the remote node */
755 rename_temp_node(1); /* Rename Node 7 to Node 1 */
756 enable_routing(1); /* Enable routing on Node 1 */
758 /*don't need and it is done by clear_dead_links */
762 result.needs_reset |= optimize_connection(
763 NODE_HT(0), 0x80 + link_to_register(link_connection(0,1)),
764 NODE_HT(1), 0x80 + link_to_register(link_connection(1,0)) );
768 #endif /*CONFIG_MAX_PHYSICAL_CPUS > 1 */
770 #if CONFIG_MAX_PHYSICAL_CPUS > 2
772 static struct setup_smp_result setup_smp4(int needs_reset)
774 struct setup_smp_result result;
779 result.needs_reset = needs_reset;
781 /* Setup and check temporary connection from Node 0 to Node 2 */
783 byte = ((val>>16) & 0xfe) - link_connection(0,1);
784 byte = get_linkn_last_count(byte);
786 if((byte>>2)==0) { /* We should have two coherent for 4p and above*/
791 byte &= 3; /* bit [3,2] is count-1*/
792 print_linkn("(0,2) link=", byte);
793 setup_row_direct(0, 2, byte); /*(0,2) direct link done*/
795 /* We found 3 nodes so far. Now setup a temporary
796 * connection from node 0 to node 3 via node 1
798 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
799 /* here should setup_row_direct(1,3) at first, before that we should find the link in node 1 to 3*/
801 byte = ((val>>16) & 0xfe) - link_connection(1,0);
802 byte = get_linkn_first(byte);
803 print_linkn("(1,3) link=", byte);
804 setup_row_direct(1,3,byte); /* (1, 3) direct link done*/
806 /* We found 4 nodes so far. Now setup all nodes for 4p */
807 // We need to make sure 0,2 and 1,3 link is set already
809 static const u8 conn4_1[] = {
814 static const u8 conn4_1[] = {
820 setup_row_indirect_group(conn4_1, sizeof(conn4_1)/sizeof(conn4_1[0]));
823 verify_connection(7);
824 val = pci_read_config32(NODE_HT(7), 0x6c);
825 byte = (val>>2) & 0x3; /* get default link on 7 to 0*/
826 print_linkn("(2,0) link=", byte);
828 setup_row_local(7,2);
829 setup_remote_row_direct(2, 0, byte); /* node 2 to node 0 direct link done */
830 setup_remote_node(2); /* Setup the regs on the remote node */
832 rename_temp_node(2); /* Rename Node 7 to Node 2 */
833 enable_routing(2); /* Enable routing on Node 2 */
837 verify_connection(7);
839 val = pci_read_config32(NODE_HT(7), 0x6c);
840 byte = (val>>2) & 0x3; /* get default link on 7 to 1*/
841 print_linkn("(3,1) link=", byte);
843 setup_row_local(7,3);
844 setup_remote_row_direct(3, 1, byte); /* node 3 to node 1 direct link done */
845 setup_remote_node(3); /* Setup the regs on the remote node */
847 /* We need to init link between 2, and 3 direct link */
849 byte = ((val>>16) & 0xfe) - link_connection(2,0);
850 byte = get_linkn_last_count(byte);
851 print_linkn("(2,3) link=", byte & 3);
853 setup_row_direct(2,3, byte & 0x3);
856 verify_connection(7); /* to 3*/
858 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
859 /* We need to find out which link is to node3 */
860 if((byte>>2)==2) { /* one to node3, one to node0, one to node4*/
862 if((val>>16) == 1) { /* that link is to node4, because via node1 it has been set, recompute it*/
864 byte = ((val>>16) & 0xfe) - link_connection(2,0);
865 byte = get_linkn_first(byte);
866 print_linkn("\t-->(2,3) link=", byte);
867 setup_row_direct(2,3,byte);
869 verify_connection(7); /* to 3*/
874 val = pci_read_config32(NODE_HT(7), 0x6c);
875 byte = (val>>2) & 0x3; /* get default link on 7 to 2*/
876 print_linkn("(3,2) link=", byte);
877 setup_remote_row_direct(3,2, byte);
879 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
880 /* set link from 3 to 5 before enable it*/
882 byte = ((val>>16) & 0xfe) - link_connection(7,2) - link_connection(7,1);
883 byte = get_linkn_last_count(byte);
884 if((byte>>2)==1) { /* We should have three coherent links on node 3 for 6p and above*/
885 byte &= 3; /*bit [3,2] is count-2*/
886 print_linkn("(3,5) link=", byte);
887 setup_remote_row_direct(3, 5, byte);
891 byte = ((val>>16) & 0xfe) - link_connection(2,3) - link_connection(2,0);
892 byte = get_linkn_last_count(byte);
894 if((byte>>2)==1) { /* We should have three coherent link on node 2 for 6p and above*/
895 byte &= 3; /* bit [3,2] is count-2*/
896 print_linkn("(2,4) link=", byte);
897 setup_row_direct(2, 4, byte);
901 //Beside 3, 1 is set, We need to make sure 3, 5 is set already in case has three link in 3
903 static const u8 conn4_3[] = {
907 static const u8 conn4_3[] = {
911 setup_remote_row_indirect_group(conn4_3, sizeof(conn4_3)/sizeof(conn4_3[0]));
913 /* ready to enable RT for Node 3 */
915 enable_routing(3); /* enable routing on node 3 (temp.) */
917 // beside 2, 0 is set, We need to make sure 2, 4 link is set already in case has three link in 2
919 static const u8 conn4_2[] = {
923 static const u8 conn4_2[] = {
927 setup_row_indirect_group(conn4_2, sizeof(conn4_2)/sizeof(conn4_2[0]));
930 /*We need to do sth to reverse work for setup_temp_row (0,1) (1,3) */
931 /* it will be done by clear_dead_links */
936 /* optimize physical connections - by LYH */
937 static const u8 opt_conn4[] = {
943 result.needs_reset |= optimize_connection_group(opt_conn4, sizeof(opt_conn4)/sizeof(opt_conn4[0]));
949 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 2 */
951 #if CONFIG_MAX_PHYSICAL_CPUS > 4
953 static struct setup_smp_result setup_smp6(int needs_reset)
955 struct setup_smp_result result;
960 result.needs_reset = needs_reset;
962 /* Setup and check temporary connection from Node 0 to Node 4 through 2*/
964 byte = ((val>>16) & 0xfe) - link_connection(2,3) - link_connection(2,0);
965 byte = get_linkn_last_count(byte);
967 if((byte>>2)==0) { /* We should have three coherent link on node 2 for 6p and above*/
972 /* Setup and check temporary connection from Node 0 to Node 5 through 1, 3*/
973 /* set link from 3 to 5 before enable it*/
975 byte = ((val>>16) & 0xfe) - link_connection(3,2) - link_connection(3,1);
976 byte = get_linkn_last_count(byte);
977 if((byte>>2)==0) { /* We should have three coherent links on node 3 for 6p and above*/
982 /* We found 6 nodes so far. Now setup all nodes for 6p */
983 #warning "FIXME we need to find out the correct gateway for 6p"
984 static const u8 conn6_1[] = {
1002 setup_row_indirect_group(conn6_1, sizeof(conn6_1)/sizeof(conn6_1[0]));
1004 for(byte=0; byte<4; byte+=2) {
1005 setup_temp_row(byte,byte+2);
1007 verify_connection(7);
1008 val = pci_read_config32(NODE_HT(7), 0x6c);
1009 byte = (val>>2) & 0x3; /*get default link on 7 to 2*/
1010 print_linkn("(4,2) link=", byte);
1012 setup_row_local(7,4);
1013 setup_remote_row_direct(4, 2, byte);
1014 setup_remote_node(4); /* Setup the regs on the remote node */
1016 /* Set indirect connection to 0, to 3 */
1017 //we only need to set 4,0 here
1018 static const u8 conn6_2[] = {
1019 #if !CROSS_BAR_47_56
1026 setup_remote_row_indirect_group(conn6_2, sizeof(conn6_2)/sizeof(conn6_2[0]));
1028 rename_temp_node(4);
1031 setup_temp_row(0,1);
1032 for(byte=0; byte<4; byte+=2) {
1033 setup_temp_row(byte+1,byte+3);
1035 verify_connection(7);
1037 val = pci_read_config32(NODE_HT(7), 0x6c);
1038 byte = (val>>2) & 0x3; /* get default link on 7 to 3*/
1039 print_linkn("(5,3) link=", byte);
1040 setup_row_local(7,5);
1041 setup_remote_row_direct(5, 3, byte);
1042 setup_remote_node(5); /* Setup the regs on the remote node */
1044 #if !CROSS_BAR_47_56
1045 /* We need to init link between 4, and 5 direct link */
1047 byte = ((val>>16) & 0xfe) - link_connection(4,2);
1048 byte = get_linkn_last_count(byte);
1049 print_linkn("(4,5) link=", byte & 3);
1051 setup_row_direct(4,5, byte & 0x3);
1052 setup_temp_row(0,2);
1053 setup_temp_row(2,4);
1054 setup_temp_row(4,5);
1055 verify_connection(7); /* to 5*/
1057 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1058 /* We need to find out which link is to node5 */
1060 if((byte>>2)==2) { /* one to node5, one to node2, one to node6*/
1062 if((val>>16) == 1) { /* that link is to node6, because via node 3 node 5 has been set*/
1064 byte = ((val>>16) & 0xfe) - link_connection(4,2);
1065 byte = get_linkn_first(byte);
1066 print_linkn("\t-->(4,5) link=", byte);
1067 setup_row_direct(4,5,byte);
1068 setup_temp_row(4,5);
1069 verify_connection(7); /* to 5*/
1074 val = pci_read_config32(NODE_HT(7), 0x6c);
1075 byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
1076 print_linkn("(5,4) link=", byte);
1077 setup_remote_row_direct(5,4, byte);
1081 byte = ((val>>16) & 0xfe) - link_connection(7,4) - link_connection(7,3);
1082 byte = get_linkn_last_count(byte);
1083 if((byte>>2)==1) { /* We should have three coherent links on node 5 for 6p and above*/
1084 byte &= 3; /*bit [3,2] is count-2*/
1085 print_linkn("(5,7) link=", byte);
1086 setup_remote_row_direct(5, 7, byte);
1091 byte = ((val>>16) & 0xfe) - link_connection(4,5) - link_connection(4,2);
1092 byte = get_linkn_last_count(byte);
1094 if((byte>>2)==1) { /* We should have three coherent link on node 4 for 6p and above*/
1095 byte &= 3; /* bit [3,2] is count-2*/
1096 print_linkn("(4,6) link=", byte);
1097 setup_row_direct(4, 6, byte);
1102 //We need to set 5,0 here only, We need to set up 5, 7 to make 5,0
1103 /* Set indirect connection to 0, to 3 for indirect we will use clockwise routing */
1104 static const u8 conn6_3[] = {
1105 #if !CROSS_BAR_47_56
1112 setup_remote_row_indirect_group(conn6_3, sizeof(conn6_3)/sizeof(conn6_3[0]));
1114 /* ready to enable RT for 5 */
1115 rename_temp_node(5);
1116 enable_routing(5); /* enable routing on node 5 (temp.) */
1118 static const u8 conn6_4[] = {
1119 #if !CROSS_BAR_47_56
1138 setup_row_indirect_group(conn6_4, sizeof(conn6_4)/sizeof(conn6_4[0]));
1141 /* We need to do sth about reverse about setup_temp_row (0,1), (2,4), (1, 3), (3,5)
1142 * It will be done by clear_dead_links
1144 for(byte=0; byte<4; byte++) {
1145 clear_temp_row(byte);
1149 /* optimize physical connections - by LYH */
1150 static const uint8_t opt_conn6[] ={
1153 #if !CROSS_BAR_47_56
1157 result.needs_reset |= optimize_connection_group(opt_conn6, sizeof(opt_conn6)/sizeof(opt_conn6[0]));
1163 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 4 */
1165 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1167 static struct setup_smp_result setup_smp8(int needs_reset)
1169 struct setup_smp_result result;
1174 result.needs_reset = needs_reset;
1176 /* Setup and check temporary connection from Node 0 to Node 6 via 2 and 4 to 7 */
1179 byte = ((val>>16) & 0xfe) - link_connection(4,2);
1181 byte = ((val>>16) & 0xfe) - link_connection(4,5) - link_connection(4,2);
1182 byte = get_linkn_last_count(byte); /* Max link to 6*/
1183 if((byte>>2)==0) { /* We should have two or three coherent links on node 4 for 8p*/
1190 byte = get_linkn_last_count(byte); /* Max link to 6*/
1191 if((byte>>2)<2) { /* We should have two or three coherent links on node 4 for 8p*/
1195 #if TRY_HIGH_FIRST == 1
1196 byte = ((val>>16) & 0xfe) - link_connection(4,2);
1197 byte = get_linkn_first(byte); /*Min link to 6*/
1199 byte &= 3; /* bit [3,2] is count-1 or 2*/
1201 print_linkn("(4,6) link=", byte);
1202 setup_row_direct(4, 6, byte);
1205 #if !CROSS_BAR_47_56
1206 /* Setup and check temporary connection from Node 0 to Node 7 through 1, 3, 5*/
1208 byte = ((val>>16) & 0xfe) - link_connection(5,4) - link_connection(5,3);
1209 byte = get_linkn_last_count(byte);
1210 if((byte>>2)==0) { /* We should have three coherent links on node 5 for 6p and above*/
1216 /* We found 8 nodes so far. Now setup all nodes for 8p */
1217 static const u8 conn8_1[] = {
1218 #if !CROSS_BAR_47_56
1240 setup_row_indirect_group(conn8_1,sizeof(conn8_1)/sizeof(conn8_1[0]));
1242 for(byte=0; byte<6; byte+=2) {
1243 setup_temp_row(byte,byte+2);
1245 verify_connection(7);
1246 val = pci_read_config32(NODE_HT(7), 0x6c);
1247 byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
1248 print_linkn("(6,4) link=", byte);
1250 setup_row_local(7,6);
1251 setup_remote_row_direct(6, 4, byte);
1252 setup_remote_node(6); /* Setup the regs on the remote node */
1253 /* Set indirect connection to 0, to 3 */
1254 #warning "FIXME we need to find out the correct gateway for 8p"
1255 static const u8 conn8_2[] = {
1256 #if !CROSS_BAR_47_56
1263 setup_remote_row_indirect_group(conn8_2, sizeof(conn8_2)/sizeof(conn8_2[0]));
1267 /* here init 5, 6 */
1268 /* Setup and check temporary connection from Node 0 to Node 5 through 1, 3, 5*/
1270 byte = ((val>>16) & 0xfe) - link_connection(5,3);
1271 #if TRY_HIGH_FIRST == 1
1272 byte = get_linkn_first(byte);
1274 byte = get_linkn_last(byte);
1276 print_linkn("(5,6) link=", byte);
1277 setup_row_direct(5, 6, byte);
1279 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
1280 for(byte=0; byte<4; byte+=2) {
1281 setup_temp_row(byte+1,byte+3);
1283 setup_temp_row(5,6);
1285 verify_connection(7);
1287 val = get_row(7,6); // to chect it if it is node6 before renaming
1288 if( (val>>16) == 1) { // it is real node 7 so swap it
1289 /* We need to recompute link to 6 */
1291 byte = ((val>>16) & 0xfe) - link_connection(5,3);
1292 #if TRY_HIGH_FIRST == 1
1293 byte = get_linkn_first(byte);
1295 byte = get_linkn_last(byte);
1297 print_linkn("\t-->(5,6) link=", byte);
1298 setup_row_direct(5, 6, byte);
1300 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
1301 for(byte=0; byte<4; byte+=2) {
1302 setup_temp_row(byte+1,byte+3);
1305 setup_temp_row(5,6);
1307 verify_connection(7);
1309 val = pci_read_config32(NODE_HT(7), 0x6c);
1310 byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
1311 print_linkn("(6,5) link=", byte);
1312 setup_remote_row_direct(6, 5, byte);
1313 /*Till now 56, 65 done */
1316 rename_temp_node(6);
1319 #if !CROSS_BAR_47_56
1320 setup_temp_row(0,1);
1321 for(byte=0; byte<6; byte+=2) {
1322 setup_temp_row(byte+1,byte+3);
1325 verify_connection(7);
1327 val = pci_read_config32(NODE_HT(7), 0x6c);
1328 byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
1329 print_linkn("(7,5) link=", byte);
1330 setup_row_local(7,7);
1331 setup_remote_row_direct(7, 5, byte);
1335 byte = ((val>>16) & 0xfe) - link_connection(4,2) - link_connection(4,6);
1336 byte = get_linkn_first(byte);
1337 print_linkn("(4,7) link=", byte);
1338 setup_row_direct(4, 7, byte);
1340 /* Setup and check temporary connection from Node 0 to Node 7 through 2, and 4*/
1341 for(byte=0; byte<4; byte+=2) {
1342 setup_temp_row(byte,byte+2);
1345 verify_connection(7);
1347 val = pci_read_config32(NODE_HT(7), 0x6c);
1348 byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
1349 print_linkn("(7,4) link=", byte);
1350 setup_row_local(7,7);
1351 setup_remote_row_direct(7, 4, byte);
1352 /* till now 4-7, 7-4 done. */
1354 setup_remote_node(7); /* Setup the regs on the remote node */
1357 /* here init 5, 7 */
1358 /* Setup and check temporary connection from Node 0 to Node 5 through 1, 3, 5*/
1360 byte = ((val>>16) & 0xfe) - link_connection(5,3) - link_connection(5,6);
1361 byte = get_linkn_first(byte);
1362 print_linkn("(5,7) link=", byte);
1363 setup_row_direct(5, 7, byte);
1365 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
1366 for(byte=0; byte<4; byte+=2) {
1367 setup_temp_row(byte+1,byte+3);
1370 verify_connection(7);
1372 val = pci_read_config32(NODE_HT(7), 0x6c);
1373 byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
1374 print_linkn("(7,5) link=", byte);
1375 setup_remote_row_direct(7, 5, byte);
1376 /*Till now 57, 75 done */
1380 /* We need to init link between 6, and 7 direct link */
1382 #if !CROSS_BAR_47_56
1383 byte = ((val>>16) & 0xfe) - link_connection(6,4);
1385 byte = ((val>>16) & 0xfe) - link_connection(6,4) - link_connection(6,5);
1387 byte = get_linkn_first(byte);
1388 print_linkn("(6,7) link=", byte);
1389 setup_row_direct(6,7, byte);
1392 #if !CROSS_BAR_47_56
1393 byte = ((val>>16) & 0xfe) - link_connection(7,5);
1395 byte = ((val>>16) & 0xfe) - link_connection(7,5) - link_connection(7,4);
1397 byte = get_linkn_first(byte);
1398 print_linkn("(7,6) link=", byte);
1399 setup_row_direct(7,6, byte);
1401 /* Set indirect connection to 0, to 3 for indirect we will use clockwise routing */
1402 static const u8 conn8_3[] = {
1403 #if !CROSS_BAR_47_56
1404 0, 7, /* restore it*/
1426 6, 1, 5, 0, // or 4, 1
1428 6, 3, 5, 0, // or 4, 1
1430 7, 0, 4, 0, // or 5, 1
1432 7, 2, 4, 0, // or 5, 1
1435 0, 7, 2, 0, /* restore it*/
1440 2, 5, 4, 1, /* reset it */
1443 4, 1, 2, 1, /* reset it */
1446 5, 2, 3, 1, /* reset it */
1452 setup_row_indirect_group(conn8_3, sizeof(conn8_3)/sizeof(conn8_3[0]));
1455 /* for 47, 56, 57, 75, 46, 64 we need to substract another link to
1457 static const u8 conn8_4[] = {
1480 6, 1, 7, // needed for via 5
1483 6, 3, 7, // needed for via 5
1485 7, 0, 6, // needed for via 4
1488 7, 2, 6, // needed for via 4
1493 opt_broadcast_rt_group(conn8_4, sizeof(conn8_4)/sizeof(conn8_4[0]));
1495 static const u8 conn8_5[] = {
1501 opt_broadcast_rt_plus_group(conn8_5, sizeof(conn8_5)/sizeof(conn8_5[0]));
1506 /* ready to enable RT for Node 7 */
1507 enable_routing(7); /* enable routing on node 7 (temp.) */
1509 static const uint8_t opt_conn8[] ={
1518 /* optimize physical connections - by LYH */
1519 result.needs_reset |= optimize_connection_group(opt_conn8, sizeof(opt_conn8)/sizeof(opt_conn8[0]));
1524 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 6 */
1527 #if CONFIG_MAX_PHYSICAL_CPUS > 1
1529 static struct setup_smp_result setup_smp(void)
1531 struct setup_smp_result result;
1533 print_spew("Enabling SMP settings\r\n");
1535 result = setup_smp2();
1536 #if CONFIG_MAX_PHYSICAL_CPUS > 2
1537 if(result.nodes == 2)
1538 result = setup_smp4(result.needs_reset);
1541 #if CONFIG_MAX_PHYSICAL_CPUS > 4
1542 if(result.nodes == 4)
1543 result = setup_smp6(result.needs_reset);
1546 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1547 if(result.nodes == 6)
1548 result = setup_smp8(result.needs_reset);
1552 printk_debug("%02x nodes initialized.\r\n", result.nodes);
1554 print_debug_hex8(result.nodes);
1555 print_debug(" nodes initialized.\r\n");
1561 static unsigned verify_mp_capabilities(unsigned nodes)
1563 unsigned node, mask;
1565 mask = 0x06; /* BigMPCap */
1567 for (node=0; node<nodes; node++) {
1568 mask &= pci_read_config32(NODE_MC(node), 0xe8);
1572 #if CONFIG_MAX_PHYSICAL_CPUS > 2
1573 case 0x02: /* MPCap */
1575 print_err("Going back to DP\r\n");
1580 case 0x00: /* Non SMP */
1582 print_err("Going back to UP\r\n");
1593 static void clear_dead_routes(unsigned nodes)
1597 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1598 if(nodes==8) return;/* don't touch (7,7)*/
1604 for(node = 7; node >= 0; node--) {
1605 for(row = 7; row >= last_row; row--) {
1606 fill_row(node, row, DEFAULT);
1610 /* Update the local row */
1611 for( node=0; node<nodes; node++) {
1613 for(row =0; row<nodes; row++) {
1614 val |= get_row(node, row);
1616 fill_row(node, node, (((val & 0xff) | ((val >> 8) & 0xff)) << 16) | 0x0101);
1619 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 1 */
1621 static unsigned count_cpus(unsigned nodes)
1623 #if CONFIG_LOGICAL_CPUS==1
1624 unsigned node, totalcpus, tmp;
1627 for (node=0; node<nodes; node++) {
1628 tmp = (pci_read_config32(NODE_MC(node), 0xe8) >> 12) & 3 ;
1629 totalcpus += (tmp + 1);
1639 static void coherent_ht_finalize(unsigned nodes)
1641 unsigned total_cpus;
1642 unsigned cpu_node_count;
1645 total_cpus = count_cpus(nodes);
1646 cpu_node_count = ((total_cpus -1)<<16)|((nodes - 1) << 4);
1648 /* set up cpu count and node count and enable Limit
1649 * Config Space Range for all available CPUs.
1650 * Also clear non coherent hypertransport bus range
1651 * registers on Hammer A0 revision.
1654 print_spew("coherent_ht_finalize\r\n");
1655 rev_a0 = is_cpu_rev_a0();
1656 for (node = 0; node < nodes; node++) {
1659 dev = NODE_HT(node);
1661 /* Set the Total CPU and Node count in the system */
1662 val = pci_read_config32(dev, 0x60);
1663 val &= (~0x000F0070);
1664 val |= cpu_node_count;
1665 pci_write_config32(dev, 0x60, val);
1667 /* Only respond to real cpu pci configuration cycles
1668 * and optimize the HT settings
1670 val=pci_read_config32(dev, HT_TRANSACTION_CONTROL);
1671 val &= ~((HTTC_BUF_REL_PRI_MASK << HTTC_BUF_REL_PRI_SHIFT) |
1672 (HTTC_MED_PRI_BYP_CNT_MASK << HTTC_MED_PRI_BYP_CNT_SHIFT) |
1673 (HTTC_HI_PRI_BYP_CNT_MASK << HTTC_HI_PRI_BYP_CNT_SHIFT));
1674 val |= HTTC_LIMIT_CLDT_CFG |
1675 (HTTC_BUF_REL_PRI_8 << HTTC_BUF_REL_PRI_SHIFT) |
1676 (3 << HTTC_MED_PRI_BYP_CNT_SHIFT) |
1677 (3 << HTTC_HI_PRI_BYP_CNT_SHIFT);
1678 pci_write_config32(dev, HT_TRANSACTION_CONTROL, val);
1681 pci_write_config32(dev, 0x94, 0);
1682 pci_write_config32(dev, 0xb4, 0);
1683 pci_write_config32(dev, 0xd4, 0);
1687 print_spew("done\r\n");
1690 static int apply_cpu_errata_fixes(unsigned nodes, int needs_reset)
1693 for(node = 0; node < nodes; node++) {
1696 dev = NODE_MC(node);
1697 if (is_cpu_pre_c0()) {
1700 * Limit the number of downstream posted requests to 1
1702 cmd = pci_read_config32(dev, 0x70);
1703 if ((cmd & (3 << 0)) != 2) {
1706 pci_write_config32(dev, 0x70, cmd );
1709 cmd = pci_read_config32(dev, 0x7c);
1710 if ((cmd & (3 << 4)) != 0) {
1713 pci_write_config32(dev, 0x7c, cmd );
1716 /* Clock Power/Timing Low */
1717 cmd = pci_read_config32(dev, 0xd4);
1718 if (cmd != 0x000D0001) {
1720 pci_write_config32(dev, 0xd4, cmd);
1721 needs_reset = 1; /* Needed? */
1725 else if (is_cpu_pre_d0()) { // d0 later don't need it
1728 * Set Clk Ramp Hystersis to 7
1729 * Clock Power/Timing Low
1731 cmd_ref = 0x04e20707; /* Registered */
1732 cmd = pci_read_config32(dev, 0xd4);
1733 if(cmd != cmd_ref) {
1734 pci_write_config32(dev, 0xd4, cmd_ref );
1735 needs_reset = 1; /* Needed? */
1742 static int optimize_link_read_pointers(unsigned nodes, int needs_reset)
1745 for(node = 0; node < nodes; node++) {
1746 device_t f0_dev, f3_dev;
1747 uint32_t cmd_ref, cmd;
1749 f0_dev = NODE_HT(node);
1750 f3_dev = NODE_MC(node);
1751 cmd_ref = cmd = pci_read_config32(f3_dev, 0xdc);
1752 for(link = 0; link < 3; link++) {
1755 /* This works on an Athlon64 because unimplemented links return 0 */
1756 reg = 0x98 + (link * 0x20);
1757 link_type = pci_read_config32(f0_dev, reg);
1758 /* Only handle coherent links */
1759 if ((link_type & (LinkConnected | InitComplete|NonCoherent)) ==
1760 (LinkConnected|InitComplete))
1762 cmd &= ~(0xff << (link *8));
1763 cmd |= 0x25 << (link *8);
1766 if (cmd != cmd_ref) {
1767 pci_write_config32(f3_dev, 0xdc, cmd);
1774 static void startup_other_cores(unsigned nodes)
1777 for(node = 0; node < nodes; node++) {
1780 dev = NODE_MC(node);
1781 siblings = (pci_read_config32(dev, 0xe8) >> 12) & 0x3;
1786 /* Redirect all MC4 accesses and error logging to core0 */
1787 val = pci_read_config32(dev, 0x44);
1788 val |= (1 << 27); //NbMcaToMstCpuEn bit
1789 pci_write_config32(dev, 0x44, val);
1791 /* Enable the second core */
1792 dev_f0 = NODE_HT(node);
1793 val = pci_read_config32(dev_f0, 0x68);
1795 pci_write_config32(dev_f0, 0x68, val);
1801 static int setup_coherent_ht_domain(void)
1803 struct setup_smp_result result;
1805 result.needs_reset = 0;
1807 #if K8_HT_CHECK_PENDING_LINK == 1
1811 enable_bsp_routing();
1813 #if CONFIG_MAX_PHYSICAL_CPUS > 1
1814 result = setup_smp();
1815 result.nodes = verify_mp_capabilities(result.nodes);
1816 clear_dead_routes(result.nodes);
1818 if (result.nodes == 1) {
1819 setup_uniprocessor();
1821 coherent_ht_finalize(result.nodes);
1822 startup_other_cores(result.nodes);
1823 result.needs_reset = apply_cpu_errata_fixes(result.nodes, result.needs_reset);
1824 result.needs_reset = optimize_link_read_pointers(result.nodes, result.needs_reset);
1825 return result.needs_reset;