3 #include "coherent_ht_car.c"
8 /* coherent hypertransport initialization for AMD64
10 * written by Stefan Reinauer <stepan@openbios.org>
11 * (c) 2003-2004 by SuSE Linux AG
13 * (c) 2004 Tyan Computer
14 * 2004.12 yhlu added support to create routing table dynamically.
15 * it also support 8 ways too. (8 ways ladder or 8 ways crossbar)
17 * This code is licensed under GPL.
21 * This algorithm assumes a grid configuration as follows:
24 * org. : 1x1 2x1 2x2 2x3 2x4
73 #include <device/pci_def.h>
74 #include <device/pci_ids.h>
75 #include <device/hypertransport_def.h>
76 #include "arch/romcc_io.h"
79 #define enable_bsp_routing() enable_routing(0)
81 #define NODE_HT(x) PCI_DEV(0,24+x,0)
82 #define NODE_MP(x) PCI_DEV(0,24+x,1)
83 #define NODE_MC(x) PCI_DEV(0,24+x,3)
85 #define DEFAULT 0x00010101 /* default row entry */
90 #ifndef CROSS_BAR_47_56
91 #define CROSS_BAR_47_56 0
94 #ifndef TRY_HIGH_FIRST
95 #define TRY_HIGH_FIRST 0
98 #ifndef K8_HT_FREQ_1G_SUPPORT
99 #define K8_HT_FREQ_1G_SUPPORT 0
102 #ifndef K8_HT_CHECK_PENDING_LINK
103 #if CONFIG_MAX_PHYSICAL_CPUS >= 4
104 #define K8_HT_CHECK_PENDING_LINK 1
106 #define K8_HT_CHECK_PENDING_LINK 0
110 #ifndef CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED
111 #define CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED 0
115 static inline void print_linkn (const char *strval, uint8_t byteval)
119 printk_debug("%s%02x\r\n", strval, byteval);
121 print_debug(strval); print_debug_hex8(byteval); print_debug("\r\n");
126 static void disable_probes(void)
128 /* disable read/write/fill probes for uniprocessor setup
129 * they don't make sense if only one cpu is available
132 /* Hypetransport Transaction Control Register
134 * [ 0: 0] Disable read byte probe
136 * 1 = Probes not issued
137 * [ 1: 1] Disable Read Doubleword probe
139 * 1 = Probes not issued
140 * [ 2: 2] Disable write byte probes
142 * 1 = Probes not issued
143 * [ 3: 3] Disable Write Doubleword Probes
145 * 1 = Probes not issued.
146 * [10:10] Disable Fill Probe
147 * 0 = Probes issued for cache fills
148 * 1 = Probes not issued for cache fills.
153 print_spew("Disabling read/write/fill probes for UP... ");
155 val=pci_read_config32(NODE_HT(0), HT_TRANSACTION_CONTROL);
156 val |= HTTC_DIS_FILL_P | HTTC_DIS_RMT_MEM_C | HTTC_DIS_P_MEM_C |
157 HTTC_DIS_MTS | HTTC_DIS_WR_DW_P | HTTC_DIS_WR_B_P |
158 HTTC_DIS_RD_DW_P | HTTC_DIS_RD_B_P;
159 pci_write_config32(NODE_HT(0), HT_TRANSACTION_CONTROL, val);
161 print_spew("done.\r\n");
165 static void enable_routing(u8 node)
169 /* HT Initialization Control Register
171 * [ 0: 0] Routing Table Disable
172 * 0 = Packets are routed according to routing tables
173 * 1 = Packets are routed according to the default link field
174 * [ 1: 1] Request Disable (BSP should clear this)
175 * 0 = Request packets may be generated
176 * 1 = Request packets may not be generated.
177 * [ 3: 2] Default Link (Read-only)
181 * 11 = CPU on same node
183 * - Scratch bit cleared by a cold reset
184 * [ 5: 5] BIOS Reset Detect
185 * - Scratch bit cleared by a cold reset
186 * [ 6: 6] INIT Detect
187 * - Scratch bit cleared by a warm or cold reset not by an INIT
191 /* Enable routing table */
192 print_spew("Enabling routing table for node ");
193 print_spew_hex8(node);
195 val=pci_read_config32(NODE_HT(node), 0x6c);
196 val &= ~((1<<1)|(1<<0));
197 pci_write_config32(NODE_HT(node), 0x6c, val);
199 print_spew(" done.\r\n");
202 static void enable_apic_ext_id(u8 node)
207 val = pci_read_config32(NODE_HT(node), 0x68);
208 val |= (HTTC_APIC_EXT_SPUR | HTTC_APIC_EXT_ID | HTTC_APIC_EXT_BRD_CST);
209 pci_write_config32(NODE_HT(node), 0x68, val);
213 static void fill_row(u8 node, u8 row, u32 value)
215 pci_write_config32(NODE_HT(node), 0x40+(row<<2), value);
218 #if CONFIG_MAX_PHYSICAL_CPUS > 1
219 static u8 link_to_register(int ldt)
222 * [ 0: 3] Request Route
223 * [0] Route to this node
224 * [1] Route to Link 0
225 * [2] Route to Link 1
226 * [3] Route to Link 2
229 if (ldt&0x08) return 0x40;
230 if (ldt&0x04) return 0x20;
231 if (ldt&0x02) return 0x00;
233 /* we should never get here */
234 print_spew("Unknown Link\n");
238 static u32 get_row(u8 node, u8 row)
240 return pci_read_config32(NODE_HT(node), 0x40+(row<<2));
243 static int link_connection(u8 src, u8 dest)
245 return get_row(src, dest) & 0x0f;
248 static void rename_temp_node(u8 node)
252 print_spew("Renaming current temporary node to ");
253 print_spew_hex8(node);
255 val=pci_read_config32(NODE_HT(7), 0x60);
256 val &= (~7); /* clear low bits. */
257 val |= node; /* new node */
258 pci_write_config32(NODE_HT(7), 0x60, val);
260 print_spew(" done.\r\n");
262 #if K8_HT_CHECK_PENDING_LINK == 1
263 static void wait_ht_stable(uint8_t node)
266 for(linkn = 0; linkn<3; linkn++) {
270 regpos = 0x98 + 0x20 * linkn;
271 for(i = 0; i < 0xff; i++) { //wait to make sure it is done
272 reg = pci_read_config32(NODE_HT(node), regpos);
273 if ((reg & 0x10) == 0) break; // init complete
280 static int verify_connection(u8 dest)
282 /* See if we have a valid connection to dest */
285 /* Verify that the coherent hypertransport link is
286 * established and actually working by reading the
287 * remode node's vendor/device id
289 val = pci_read_config32(NODE_HT(dest),0);
290 if(val != 0x11001022)
296 static unsigned read_freq_cap(device_t dev, unsigned 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 */
305 if (!is_cpu_pre_e0()) {
309 id = pci_read_config32(dev, 0);
311 /* AMD K8 Unsupported 1Ghz? */
312 if (id == (PCI_VENDOR_ID_AMD | (0x1100 << 16))) {
313 freq_cap &= ~(1 << HT_FREQ_1000Mhz);
319 static int optimize_connection(device_t node1, uint8_t link1, device_t node2, uint8_t link2)
321 static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
322 static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
323 uint16_t freq_cap1, freq_cap2, freq_cap, freq_mask;
324 uint8_t width_cap1, width_cap2, width_cap, width, old_width, ln_width1, ln_width2;
325 uint8_t freq, old_freq;
327 /* Set link width and frequency */
329 /* Initially assume everything is already optimized and I don't need a reset */
332 /* Get the frequency capabilities */
333 freq_cap1 = read_freq_cap(node1, link1 + PCI_HT_CAP_HOST_FREQ_CAP);
334 freq_cap2 = read_freq_cap(node2, link2 + PCI_HT_CAP_HOST_FREQ_CAP);
336 /* Calculate the highest possible frequency */
337 freq = log2(freq_cap1 & freq_cap2);
339 /* See if I am changing the link freqency */
340 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);
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);
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 static unsigned count_cpus(unsigned nodes)
1630 #if CONFIG_LOGICAL_CPUS==1
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);
1646 static void coherent_ht_finalize(unsigned nodes)
1648 unsigned total_cpus;
1649 unsigned cpu_node_count;
1652 total_cpus = count_cpus(nodes);
1653 cpu_node_count = ((total_cpus -1)<<16)|((nodes - 1) << 4);
1655 /* set up cpu count and node count and enable Limit
1656 * Config Space Range for all available CPUs.
1657 * Also clear non coherent hypertransport bus range
1658 * registers on Hammer A0 revision.
1661 print_spew("coherent_ht_finalize\r\n");
1662 rev_a0 = is_cpu_rev_a0();
1663 for (node = 0; node < nodes; node++) {
1666 dev = NODE_HT(node);
1668 /* Set the Total CPU and Node count in the system */
1669 val = pci_read_config32(dev, 0x60);
1670 val &= (~0x000F0070);
1671 val |= cpu_node_count;
1672 pci_write_config32(dev, 0x60, val);
1674 /* Only respond to real cpu pci configuration cycles
1675 * and optimize the HT settings
1677 val=pci_read_config32(dev, HT_TRANSACTION_CONTROL);
1678 val &= ~((HTTC_BUF_REL_PRI_MASK << HTTC_BUF_REL_PRI_SHIFT) |
1679 (HTTC_MED_PRI_BYP_CNT_MASK << HTTC_MED_PRI_BYP_CNT_SHIFT) |
1680 (HTTC_HI_PRI_BYP_CNT_MASK << HTTC_HI_PRI_BYP_CNT_SHIFT));
1681 val |= HTTC_LIMIT_CLDT_CFG |
1682 (HTTC_BUF_REL_PRI_8 << HTTC_BUF_REL_PRI_SHIFT) |
1683 (3 << HTTC_MED_PRI_BYP_CNT_SHIFT) |
1684 (3 << HTTC_HI_PRI_BYP_CNT_SHIFT);
1685 pci_write_config32(dev, HT_TRANSACTION_CONTROL, val);
1688 pci_write_config32(dev, 0x94, 0);
1689 pci_write_config32(dev, 0xb4, 0);
1690 pci_write_config32(dev, 0xd4, 0);
1694 print_spew("done\r\n");
1697 static int apply_cpu_errata_fixes(unsigned nodes, int needs_reset)
1700 for(node = 0; node < nodes; node++) {
1703 dev = NODE_MC(node);
1704 if (is_cpu_pre_c0()) {
1707 * Limit the number of downstream posted requests to 1
1709 cmd = pci_read_config32(dev, 0x70);
1710 if ((cmd & (3 << 0)) != 2) {
1713 pci_write_config32(dev, 0x70, cmd );
1716 cmd = pci_read_config32(dev, 0x7c);
1717 if ((cmd & (3 << 4)) != 0) {
1720 pci_write_config32(dev, 0x7c, cmd );
1723 /* Clock Power/Timing Low */
1724 cmd = pci_read_config32(dev, 0xd4);
1725 if (cmd != 0x000D0001) {
1727 pci_write_config32(dev, 0xd4, cmd);
1728 needs_reset = 1; /* Needed? */
1732 else if (is_cpu_pre_d0()) { // d0 later don't need it
1735 * Set Clk Ramp Hystersis to 7
1736 * Clock Power/Timing Low
1738 cmd_ref = 0x04e20707; /* Registered */
1739 cmd = pci_read_config32(dev, 0xd4);
1740 if(cmd != cmd_ref) {
1741 pci_write_config32(dev, 0xd4, cmd_ref );
1742 needs_reset = 1; /* Needed? */
1749 static int optimize_link_read_pointers(unsigned nodes, int needs_reset)
1752 for(node = 0; node < nodes; node++) {
1753 device_t f0_dev, f3_dev;
1754 uint32_t cmd_ref, cmd;
1756 f0_dev = NODE_HT(node);
1757 f3_dev = NODE_MC(node);
1758 cmd_ref = cmd = pci_read_config32(f3_dev, 0xdc);
1759 for(link = 0; link < 3; link++) {
1762 /* This works on an Athlon64 because unimplemented links return 0 */
1763 reg = 0x98 + (link * 0x20);
1764 link_type = pci_read_config32(f0_dev, reg);
1765 /* Only handle coherent links */
1766 if ((link_type & (LinkConnected | InitComplete|NonCoherent)) ==
1767 (LinkConnected|InitComplete))
1769 cmd &= ~(0xff << (link *8));
1770 cmd |= 0x25 << (link *8);
1773 if (cmd != cmd_ref) {
1774 pci_write_config32(f3_dev, 0xdc, cmd);
1781 static void startup_other_cores(unsigned nodes)
1784 for(node = 0; node < nodes; node++) {
1787 dev = NODE_MC(node);
1788 siblings = (pci_read_config32(dev, 0xe8) >> 12) & 0x3;
1793 /* Redirect all MC4 accesses and error logging to core0 */
1794 val = pci_read_config32(dev, 0x44);
1795 val |= (1 << 27); //NbMcaToMstCpuEn bit
1796 pci_write_config32(dev, 0x44, val);
1798 /* Enable the second core */
1799 dev_f0 = NODE_HT(node);
1800 val = pci_read_config32(dev_f0, 0x68);
1802 pci_write_config32(dev_f0, 0x68, val);
1808 static int setup_coherent_ht_domain(void)
1810 struct setup_smp_result result;
1812 result.needs_reset = 0;
1814 #if K8_HT_CHECK_PENDING_LINK == 1
1818 enable_bsp_routing();
1820 #if CONFIG_MAX_PHYSICAL_CPUS > 1
1821 result = setup_smp();
1822 result.nodes = verify_mp_capabilities(result.nodes);
1823 clear_dead_routes(result.nodes);
1825 if (result.nodes == 1) {
1826 setup_uniprocessor();
1828 coherent_ht_finalize(result.nodes);
1829 startup_other_cores(result.nodes);
1830 result.needs_reset = apply_cpu_errata_fixes(result.nodes, result.needs_reset);
1831 result.needs_reset = optimize_link_read_pointers(result.nodes, result.needs_reset);
1832 return result.needs_reset;