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), 0x68);
149 val |= (1<<10)|(1<<9)|(1<<8)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|(1 << 0);
150 pci_write_config32(NODE_HT(0), 0x68, val);
152 print_spew("done.\r\n");
157 #ifndef ENABLE_APIC_EXT_ID
158 #define ENABLE_APIC_EXT_ID 0
161 static void enable_apic_ext_id(u8 node)
163 #if ENABLE_APIC_EXT_ID==1
164 #warning "FIXME Is the right place to enable apic ext id here?"
168 val = pci_read_config32(NODE_HT(node), 0x68);
169 val |= (HTTC_APIC_EXT_SPUR | HTTC_APIC_EXT_ID | HTTC_APIC_EXT_BRD_CST);
170 pci_write_config32(NODE_HT(node), 0x68, val);
176 static void enable_routing(u8 node)
180 /* HT Initialization Control Register
182 * [ 0: 0] Routing Table Disable
183 * 0 = Packets are routed according to routing tables
184 * 1 = Packets are routed according to the default link field
185 * [ 1: 1] Request Disable (BSP should clear this)
186 * 0 = Request packets may be generated
187 * 1 = Request packets may not be generated.
188 * [ 3: 2] Default Link (Read-only)
192 * 11 = CPU on same node
194 * - Scratch bit cleared by a cold reset
195 * [ 5: 5] BIOS Reset Detect
196 * - Scratch bit cleared by a cold reset
197 * [ 6: 6] INIT Detect
198 * - Scratch bit cleared by a warm or cold reset not by an INIT
202 /* Enable routing table */
203 print_spew("Enabling routing table for node ");
204 print_spew_hex8(node);
206 val=pci_read_config32(NODE_HT(node), 0x6c);
207 val &= ~((1<<1)|(1<<0));
208 pci_write_config32(NODE_HT(node), 0x6c, val);
210 print_spew(" done.\r\n");
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 check_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)
293 #if K8_HT_CHECK_PENDING_LINK == 1
294 wait_ht_stable(dest);
300 static uint16_t read_freq_cap(device_t dev, uint8_t pos)
302 /* Handle bugs in valid hypertransport frequency reporting */
306 freq_cap = pci_read_config16(dev, pos);
307 freq_cap &= ~(1 << HT_FREQ_VENDOR); /* Ignore Vendor HT frequencies */
310 #if K8_HT_FREQ_1G_SUPPORT == 1
311 if (!is_cpu_pre_e0())
315 id = pci_read_config32(dev, 0);
317 /* AMD K8 Unsupported 1Ghz? */
318 if (id == (PCI_VENDOR_ID_AMD | (0x1100 << 16))) {
319 freq_cap &= ~(1 << HT_FREQ_1000Mhz);
325 static int optimize_connection(device_t node1, uint8_t link1, device_t node2, uint8_t link2)
327 static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
328 static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
329 uint16_t freq_cap1, freq_cap2, freq_cap, freq_mask;
330 uint8_t width_cap1, width_cap2, width_cap, width, old_width, ln_width1, ln_width2;
331 uint8_t freq, old_freq;
333 /* Set link width and frequency */
335 /* Initially assume everything is already optimized and I don't need a reset */
338 /* Get the frequency capabilities */
339 freq_cap1 = read_freq_cap(node1, link1 + PCI_HT_CAP_HOST_FREQ_CAP);
340 freq_cap2 = read_freq_cap(node2, link2 + PCI_HT_CAP_HOST_FREQ_CAP);
342 /* Calculate the highest possible frequency */
343 freq = log2(freq_cap1 & freq_cap2);
345 /* See if I am changing the link freqency */
346 old_freq = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_FREQ);
347 needs_reset |= old_freq != freq;
348 old_freq = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_FREQ);
349 needs_reset |= old_freq != freq;
351 /* Set the Calulcated link frequency */
352 pci_write_config8(node1, link1 + PCI_HT_CAP_HOST_FREQ, freq);
353 pci_write_config8(node2, link2 + PCI_HT_CAP_HOST_FREQ, freq);
355 /* Get the width capabilities */
356 width_cap1 = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH);
357 width_cap2 = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH);
359 /* Calculate node1's input width */
360 ln_width1 = link_width_to_pow2[width_cap1 & 7];
361 ln_width2 = link_width_to_pow2[(width_cap2 >> 4) & 7];
362 if (ln_width1 > ln_width2) {
363 ln_width1 = ln_width2;
365 width = pow2_to_link_width[ln_width1];
366 /* Calculate node1's output width */
367 ln_width1 = link_width_to_pow2[(width_cap1 >> 4) & 7];
368 ln_width2 = link_width_to_pow2[width_cap2 & 7];
369 if (ln_width1 > ln_width2) {
370 ln_width1 = ln_width2;
372 width |= pow2_to_link_width[ln_width1] << 4;
374 /* See if I am changing node1's width */
375 old_width = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH + 1);
376 needs_reset |= old_width != width;
378 /* Set node1's widths */
379 pci_write_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH + 1, width);
381 // * Calculate node2's width */
382 width = ((width & 0x70) >> 4) | ((width & 0x7) << 4);
384 /* See if I am changing node2's width */
385 old_width = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH + 1);
386 needs_reset |= old_width != width;
388 /* Set node2's widths */
389 pci_write_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH + 1, width);
394 static uint8_t get_linkn_first(uint8_t byte)
396 if(byte & 0x02) { byte = 0; }
397 else if(byte & 0x04) { byte = 1; }
398 else if(byte & 0x08) { byte = 2; }
402 static uint8_t get_linkn_last(uint8_t byte)
404 if(byte & 0x02) { byte &= 0x0f; byte |= 0x00; }
405 if(byte & 0x04) { byte &= 0x0f; byte |= 0x10; }
406 if(byte & 0x08) { byte &= 0x0f; byte |= 0x20; }
410 static uint8_t get_linkn_last_count(uint8_t byte)
413 if(byte & 0x02) { byte &= 0xcf; byte |= 0x00; byte+=0x40; }
414 if(byte & 0x04) { byte &= 0xcf; byte |= 0x10; byte+=0x40; }
415 if(byte & 0x08) { byte &= 0xcf; byte |= 0x20; byte+=0x40; }
419 static void setup_row_local(u8 source, u8 row) /* source will be 7 when it is for temp use*/
424 for(linkn = 0; linkn<3; linkn++) {
427 regpos = 0x98 + 0x20 * linkn;
428 reg = pci_read_config32(NODE_HT(source), regpos);
429 if ((reg & 0x17) != 3) continue; /* it is not conherent or not connected*/
434 fill_row(source,row, val);
437 static void setup_row_direct_x(u8 temp, u8 source, u8 dest, u8 linkn)
442 val |= 1<<(linkn+1+8); /*for direct connect response route should equal to request table*/
444 if(((source &1)!=(dest &1))
446 && ( (source<4)||(source>5) ) //(6,7) (7,6) should still be here
447 //(6,5) (7,4) should be here
452 /*for CROSS_BAR_47_56 47, 56, should be here too
453 and for 47, 56, 57, 75, 46, 64 we need to substract another link to
456 val_s = get_row(temp, source);
457 val |= ((val_s>>16) - (1<<(linkn+1)))<<16;
460 fill_row(temp,dest, val );
464 static void opt_broadcast_rt(u8 source, u8 dest, u8 kickout) {
466 val = get_row(source, dest);
467 val -= link_connection(source, kickout)<<16;
468 fill_row(source, dest, val);
471 static void opt_broadcast_rt_group(const u8 *conn, int num) {
474 for(i=0; i<num; i+=3) {
475 opt_broadcast_rt(conn[i], conn[i+1],conn[i+2]);
478 static void opt_broadcast_rt_plus(u8 source, u8 dest, u8 kickout) {
480 val = get_row(source, dest);
481 val += link_connection(source, kickout)<<16;
482 fill_row(source, dest, val);
485 static void opt_broadcast_rt_plus_group(const u8 *conn, int num) {
488 for(i=0; i<num; i+=3) {
489 opt_broadcast_rt_plus(conn[i], conn[i+1],conn[i+2]);
494 static void setup_row_direct(u8 source, u8 dest, u8 linkn){
495 setup_row_direct_x(source, source, dest, linkn);
498 static void setup_remote_row_direct(u8 source, u8 dest, u8 linkn){
499 setup_row_direct_x(7, source, dest, linkn);
502 static void setup_temp_row(u8 source, u8 dest)
504 /* copy val from (source, dest) to (source,7) */
505 fill_row(source,7,get_row(source,dest));
508 static void clear_temp_row(u8 source)
510 fill_row(source, 7, DEFAULT);
513 static void setup_remote_node(u8 node)
515 static const uint8_t pci_reg[] = {
516 0x44, 0x4c, 0x54, 0x5c, 0x64, 0x6c, 0x74, 0x7c,
517 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78,
518 0x84, 0x8c, 0x94, 0x9c, 0xa4, 0xac, 0xb4, 0xbc,
519 0x80, 0x88, 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8,
520 0xc4, 0xcc, 0xd4, 0xdc,
521 0xc0, 0xc8, 0xd0, 0xd8,
522 0xe0, 0xe4, 0xe8, 0xec,
526 print_spew("setup_remote_node: ");
528 /* copy the default resource map from node 0 */
529 for(i = 0; i < sizeof(pci_reg)/sizeof(pci_reg[0]); i++) {
533 value = pci_read_config32(NODE_MP(0), reg);
534 pci_write_config32(NODE_MP(7), reg, value);
537 print_spew("done\r\n");
540 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 1*/
543 #if CONFIG_MAX_PHYSICAL_CPUS > 2
545 static void setup_row_indirect_x(u8 temp, u8 source, u8 dest)
547 static void setup_row_indirect_x(u8 temp, u8 source, u8 dest, u8 gateway, u8 diff)
550 /*for indirect connection, we need to compute the val from val_s(source, source), and val_g(source, gateway) */
557 gateway = source + 2;
559 gateway = source - 2;
562 val_s = get_row(temp, source);
563 val = get_row(temp, gateway);
570 diff = ((source&1)!=(dest &1));
573 if(diff && (val_s!=(val&0xff)) ) { /* use another connect as response*/
575 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
577 /* Some node have two links left
578 * don't worry we only have (2, (3 as source need to handle
581 byte = get_linkn_last_count(byte);
582 if((byte>>2)>1) { /* make sure not the corner*/
584 val_s-=link_connection(temp, source-2); /* -down*/
589 val_s-=link_connection(temp, 6); // for 7,2 via 5
590 } else if (source==6){
591 val_s-=link_connection(temp, 7); // for 6,3 via 4
594 if (source < gateway) { // for 5, 4 via 7
595 val_s-=link_connection(temp, source-2);
598 val_s-=link_connection(temp, source+2); /* -up*/
606 if(diff) { /* cross rung?*/
610 val_s = get_row(temp, source);
611 val |= ((val_s>>16) - link_connection(temp, gateway))<<16;
614 fill_row(temp, dest, val);
619 static void setup_row_indirect(u8 source, u8 dest)
621 setup_row_indirect_x(source, source, dest);
624 static void setup_row_indirect(u8 source, u8 dest, u8 gateway, u8 diff)
626 setup_row_indirect_x(source, source, dest, gateway, diff);
630 static void setup_row_indirect_group(const u8 *conn, int num)
635 for(i=0; i<num; i+=2) {
636 setup_row_indirect(conn[i], conn[i+1]);
638 for(i=0; i<num; i+=4) {
639 setup_row_indirect(conn[i], conn[i+1],conn[i+2], conn[i+3]);
646 static void setup_remote_row_indirect(u8 source, u8 dest)
648 setup_row_indirect_x(7, source, dest);
651 static void setup_remote_row_indirect(u8 source, u8 dest, u8 gateway, u8 diff)
653 setup_row_indirect_x(7, source, dest, gateway, diff);
657 static void setup_remote_row_indirect_group(const u8 *conn, int num)
662 for(i=0; i<num; i+=2) {
663 setup_remote_row_indirect(conn[i], conn[i+1]);
665 for(i=0; i<num; i+=4) {
666 setup_remote_row_indirect(conn[i], conn[i+1],conn[i+2], conn[i+3]);
671 #endif /*CONFIG_MAX_PHYSICAL_CPUS > 2*/
674 static void setup_uniprocessor(void)
676 print_spew("Enabling UP settings\r\n");
677 #if CONFIG_LOGICAL_CPUS==1
678 unsigned tmp = (pci_read_config32(NODE_MC(0), 0xe8) >> 12) & 3;
684 struct setup_smp_result {
689 #if CONFIG_MAX_PHYSICAL_CPUS > 2
690 static int optimize_connection_group(const u8 *opt_conn, int num) {
693 for(i=0; i<num; i+=2) {
694 needs_reset = optimize_connection(
695 NODE_HT(opt_conn[i]), 0x80 + link_to_register(link_connection(opt_conn[i],opt_conn[i+1])),
696 NODE_HT(opt_conn[i+1]), 0x80 + link_to_register(link_connection(opt_conn[i+1],opt_conn[i])) );
702 #if CONFIG_MAX_PHYSICAL_CPUS > 1
703 static struct setup_smp_result setup_smp2(void)
705 struct setup_smp_result result;
709 result.needs_reset = 0;
711 setup_row_local(0, 0); /* it will update the broadcast RT*/
714 byte = (val>>16) & 0xfe;
715 if(byte<0x2) { /* no coherent connection so get out.*/
720 /* Setup and check a temporary connection to node 1 */
721 #if TRY_HIGH_FIRST == 1
722 byte = get_linkn_last(byte); /* Max Link to node1 */
724 byte = get_linkn_first(byte); /*Min Link to node1 --- according to AMD*/
726 print_linkn("(0,1) link=", byte);
727 setup_row_direct(0,1, byte);
728 setup_temp_row(0, 1);
732 /* We found 2 nodes so far */
733 val = pci_read_config32(NODE_HT(7), 0x6c);
734 byte = (val>>2) & 0x3; /*get default link on node7 to node0*/
735 print_linkn("(1,0) link=", byte);
736 setup_row_local(7,1);
737 setup_remote_row_direct(1, 0, byte);
739 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
741 byte = (val>>16) & 0xfe;
742 byte = get_linkn_last_count(byte);
743 if((byte>>2)==3) { /* Oh! we need to treat it as node2. So use another link*/
745 byte = (val>>16) & 0xfe;
746 #if TRY_HIGH_FIRST == 1
747 byte = get_linkn_first(byte); /* Min link to Node1 */
749 byte = get_linkn_last(byte); /* Max link to Node1*/
751 print_linkn("\t-->(0,1) link=", byte);
752 setup_row_direct(0,1, byte);
753 setup_temp_row(0, 1);
757 /* We found 2 nodes so far */
758 val = pci_read_config32(NODE_HT(7), 0x6c);
759 byte = (val>>2) & 0x3; /* get default link on node7 to node0*/
760 print_linkn("\t-->(1,0) link=", byte);
761 setup_row_local(7,1);
762 setup_remote_row_direct(1, 0, byte);
766 setup_remote_node(1); /* Setup the regs on the remote node */
767 rename_temp_node(1); /* Rename Node 7 to Node 1 */
768 enable_routing(1); /* Enable routing on Node 1 */
770 /*don't need and it is done by clear_dead_links */
774 result.needs_reset |= optimize_connection(
775 NODE_HT(0), 0x80 + link_to_register(link_connection(0,1)),
776 NODE_HT(1), 0x80 + link_to_register(link_connection(1,0)) );
780 #endif /*CONFIG_MAX_PHYSICAL_CPUS > 1 */
782 #if CONFIG_MAX_PHYSICAL_CPUS > 2
784 static struct setup_smp_result setup_smp4(int needs_reset)
786 struct setup_smp_result result;
791 result.needs_reset = needs_reset;
793 /* Setup and check temporary connection from Node 0 to Node 2 */
795 byte = ((val>>16) & 0xfe) - link_connection(0,1);
796 byte = get_linkn_last_count(byte);
798 if((byte>>2)==0) { /* We should have two coherent for 4p and above*/
803 byte &= 3; /* bit [3,2] is count-1*/
804 print_linkn("(0,2) link=", byte);
805 setup_row_direct(0, 2, byte); /*(0,2) direct link done*/
807 /* We found 3 nodes so far. Now setup a temporary
808 * connection from node 0 to node 3 via node 1
810 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
811 /* here should setup_row_direct(1,3) at first, before that we should find the link in node 1 to 3*/
813 byte = ((val>>16) & 0xfe) - link_connection(1,0);
814 byte = get_linkn_first(byte);
815 print_linkn("(1,3) link=", byte);
816 setup_row_direct(1,3,byte); /* (1, 3) direct link done*/
818 /* We found 4 nodes so far. Now setup all nodes for 4p */
819 // We need to make sure 0,2 and 1,3 link is set already
821 static const u8 conn4_1[] = {
826 static const u8 conn4_1[] = {
832 setup_row_indirect_group(conn4_1, sizeof(conn4_1)/sizeof(conn4_1[0]));
836 val = pci_read_config32(NODE_HT(7), 0x6c);
837 byte = (val>>2) & 0x3; /* get default link on 7 to 0*/
838 print_linkn("(2,0) link=", byte);
840 setup_row_local(7,2);
841 setup_remote_row_direct(2, 0, byte); /* node 2 to node 0 direct link done */
842 setup_remote_node(2); /* Setup the regs on the remote node */
844 rename_temp_node(2); /* Rename Node 7 to Node 2 */
845 enable_routing(2); /* Enable routing on Node 2 */
851 val = pci_read_config32(NODE_HT(7), 0x6c);
852 byte = (val>>2) & 0x3; /* get default link on 7 to 1*/
853 print_linkn("(3,1) link=", byte);
855 setup_row_local(7,3);
856 setup_remote_row_direct(3, 1, byte); /* node 3 to node 1 direct link done */
857 setup_remote_node(3); /* Setup the regs on the remote node */
859 /* We need to init link between 2, and 3 direct link */
861 byte = ((val>>16) & 0xfe) - link_connection(2,0);
862 byte = get_linkn_last_count(byte);
863 print_linkn("(2,3) link=", byte & 3);
865 setup_row_direct(2,3, byte & 0x3);
868 check_connection(7); /* to 3*/
870 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
871 /* We need to find out which link is to node3 */
872 if((byte>>2)==2) { /* one to node3, one to node0, one to node4*/
874 if((val>>16) == 1) { /* that link is to node4, because via node1 it has been set, recompute it*/
876 byte = ((val>>16) & 0xfe) - link_connection(2,0);
877 byte = get_linkn_first(byte);
878 print_linkn("\t-->(2,3) link=", byte);
879 setup_row_direct(2,3,byte);
881 check_connection(7); /* to 3*/
886 val = pci_read_config32(NODE_HT(7), 0x6c);
887 byte = (val>>2) & 0x3; /* get default link on 7 to 2*/
888 print_linkn("(3,2) link=", byte);
889 setup_remote_row_direct(3,2, byte);
891 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
892 /* set link from 3 to 5 before enable it*/
894 byte = ((val>>16) & 0xfe) - link_connection(7,2) - link_connection(7,1);
895 byte = get_linkn_last_count(byte);
896 if((byte>>2)==1) { /* We should have three coherent links on node 3 for 6p and above*/
897 byte &= 3; /*bit [3,2] is count-2*/
898 print_linkn("(3,5) link=", byte);
899 setup_remote_row_direct(3, 5, byte);
903 byte = ((val>>16) & 0xfe) - link_connection(2,3) - link_connection(2,0);
904 byte = get_linkn_last_count(byte);
906 if((byte>>2)==1) { /* We should have three coherent link on node 2 for 6p and above*/
907 byte &= 3; /* bit [3,2] is count-2*/
908 print_linkn("(2,4) link=", byte);
909 setup_row_direct(2, 4, byte);
913 //Beside 3, 1 is set, We need to make sure 3, 5 is set already in case has three link in 3
915 static const u8 conn4_3[] = {
919 static const u8 conn4_3[] = {
923 setup_remote_row_indirect_group(conn4_3, sizeof(conn4_3)/sizeof(conn4_3[0]));
925 /* ready to enable RT for Node 3 */
927 enable_routing(3); /* enable routing on node 3 (temp.) */
929 // beside 2, 0 is set, We need to make sure 2, 4 link is set already in case has three link in 2
931 static const u8 conn4_2[] = {
935 static const u8 conn4_2[] = {
939 setup_row_indirect_group(conn4_2, sizeof(conn4_2)/sizeof(conn4_2[0]));
942 /*We need to do sth to reverse work for setup_temp_row (0,1) (1,3) */
943 /* it will be done by clear_dead_links */
948 /* optimize physical connections - by LYH */
949 static const u8 opt_conn4[] = {
955 result.needs_reset |= optimize_connection_group(opt_conn4, sizeof(opt_conn4)/sizeof(opt_conn4[0]));
961 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 2 */
963 #if CONFIG_MAX_PHYSICAL_CPUS > 4
965 static struct setup_smp_result setup_smp6(int needs_reset)
967 struct setup_smp_result result;
972 result.needs_reset = needs_reset;
974 /* Setup and check temporary connection from Node 0 to Node 4 through 2*/
976 byte = ((val>>16) & 0xfe) - link_connection(2,3) - link_connection(2,0);
977 byte = get_linkn_last_count(byte);
979 if((byte>>2)==0) { /* We should have three coherent link on node 2 for 6p and above*/
984 /* Setup and check temporary connection from Node 0 to Node 5 through 1, 3*/
985 /* set link from 3 to 5 before enable it*/
987 byte = ((val>>16) & 0xfe) - link_connection(3,2) - link_connection(3,1);
988 byte = get_linkn_last_count(byte);
989 if((byte>>2)==0) { /* We should have three coherent links on node 3 for 6p and above*/
994 /* We found 6 nodes so far. Now setup all nodes for 6p */
995 #warning "FIXME we need to find out the correct gateway for 6p"
996 static const u8 conn6_1[] = {
1014 setup_row_indirect_group(conn6_1, sizeof(conn6_1)/sizeof(conn6_1[0]));
1016 for(byte=0; byte<4; byte+=2) {
1017 setup_temp_row(byte,byte+2);
1019 check_connection(7);
1020 val = pci_read_config32(NODE_HT(7), 0x6c);
1021 byte = (val>>2) & 0x3; /*get default link on 7 to 2*/
1022 print_linkn("(4,2) link=", byte);
1024 setup_row_local(7,4);
1025 setup_remote_row_direct(4, 2, byte);
1026 setup_remote_node(4); /* Setup the regs on the remote node */
1028 /* Set indirect connection to 0, to 3 */
1029 //we only need to set 4,0 here
1030 static const u8 conn6_2[] = {
1031 #if !CROSS_BAR_47_56
1038 setup_remote_row_indirect_group(conn6_2, sizeof(conn6_2)/sizeof(conn6_2[0]));
1040 rename_temp_node(4);
1043 setup_temp_row(0,1);
1044 for(byte=0; byte<4; byte+=2) {
1045 setup_temp_row(byte+1,byte+3);
1047 check_connection(7);
1049 val = pci_read_config32(NODE_HT(7), 0x6c);
1050 byte = (val>>2) & 0x3; /* get default link on 7 to 3*/
1051 print_linkn("(5,3) link=", byte);
1052 setup_row_local(7,5);
1053 setup_remote_row_direct(5, 3, byte);
1054 setup_remote_node(5); /* Setup the regs on the remote node */
1056 #if !CROSS_BAR_47_56
1057 /* We need to init link between 4, and 5 direct link */
1059 byte = ((val>>16) & 0xfe) - link_connection(4,2);
1060 byte = get_linkn_last_count(byte);
1061 print_linkn("(4,5) link=", byte & 3);
1063 setup_row_direct(4,5, byte & 0x3);
1064 setup_temp_row(0,2);
1065 setup_temp_row(2,4);
1066 setup_temp_row(4,5);
1067 check_connection(7); /* to 5*/
1069 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1070 /* We need to find out which link is to node5 */
1072 if((byte>>2)==2) { /* one to node5, one to node2, one to node6*/
1074 if((val>>16) == 1) { /* that link is to node6, because via node 3 node 5 has been set*/
1076 byte = ((val>>16) & 0xfe) - link_connection(4,2);
1077 byte = get_linkn_first(byte);
1078 print_linkn("\t-->(4,5) link=", byte);
1079 setup_row_direct(4,5,byte);
1080 setup_temp_row(4,5);
1081 check_connection(7); /* to 5*/
1086 val = pci_read_config32(NODE_HT(7), 0x6c);
1087 byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
1088 print_linkn("(5,4) link=", byte);
1089 setup_remote_row_direct(5,4, byte);
1093 byte = ((val>>16) & 0xfe) - link_connection(7,4) - link_connection(7,3);
1094 byte = get_linkn_last_count(byte);
1095 if((byte>>2)==1) { /* We should have three coherent links on node 5 for 6p and above*/
1096 byte &= 3; /*bit [3,2] is count-2*/
1097 print_linkn("(5,7) link=", byte);
1098 setup_remote_row_direct(5, 7, byte);
1103 byte = ((val>>16) & 0xfe) - link_connection(4,5) - link_connection(4,2);
1104 byte = get_linkn_last_count(byte);
1106 if((byte>>2)==1) { /* We should have three coherent link on node 4 for 6p and above*/
1107 byte &= 3; /* bit [3,2] is count-2*/
1108 print_linkn("(4,6) link=", byte);
1109 setup_row_direct(4, 6, byte);
1114 //We need to set 5,0 here only, We need to set up 5, 7 to make 5,0
1115 /* Set indirect connection to 0, to 3 for indirect we will use clockwise routing */
1116 static const u8 conn6_3[] = {
1117 #if !CROSS_BAR_47_56
1124 setup_remote_row_indirect_group(conn6_3, sizeof(conn6_3)/sizeof(conn6_3[0]));
1126 /* ready to enable RT for 5 */
1127 rename_temp_node(5);
1128 enable_routing(5); /* enable routing on node 5 (temp.) */
1130 static const u8 conn6_4[] = {
1131 #if !CROSS_BAR_47_56
1150 setup_row_indirect_group(conn6_4, sizeof(conn6_4)/sizeof(conn6_4[0]));
1153 /* We need to do sth about reverse about setup_temp_row (0,1), (2,4), (1, 3), (3,5)
1154 * It will be done by clear_dead_links
1156 for(byte=0; byte<4; byte++) {
1157 clear_temp_row(byte);
1161 /* optimize physical connections - by LYH */
1162 static const uint8_t opt_conn6[] ={
1165 #if !CROSS_BAR_47_56
1169 result.needs_reset |= optimize_connection_group(opt_conn6, sizeof(opt_conn6)/sizeof(opt_conn6[0]));
1175 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 4 */
1177 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1179 static struct setup_smp_result setup_smp8(int needs_reset)
1181 struct setup_smp_result result;
1186 result.needs_reset = needs_reset;
1188 /* Setup and check temporary connection from Node 0 to Node 6 via 2 and 4 to 7 */
1191 byte = ((val>>16) & 0xfe) - link_connection(4,2);
1193 byte = ((val>>16) & 0xfe) - link_connection(4,5) - link_connection(4,2);
1194 byte = get_linkn_last_count(byte); /* Max link to 6*/
1195 if((byte>>2)==0) { /* We should have two or three coherent links on node 4 for 8p*/
1202 byte = get_linkn_last_count(byte); /* Max link to 6*/
1203 if((byte>>2)<2) { /* We should have two or three coherent links on node 4 for 8p*/
1207 #if TRY_HIGH_FIRST == 1
1208 byte = ((val>>16) & 0xfe) - link_connection(4,2);
1209 byte = get_linkn_first(byte); /*Min link to 6*/
1211 byte &= 3; /* bit [3,2] is count-1 or 2*/
1213 print_linkn("(4,6) link=", byte);
1214 setup_row_direct(4, 6, byte);
1217 #if !CROSS_BAR_47_56
1218 /* Setup and check temporary connection from Node 0 to Node 7 through 1, 3, 5*/
1220 byte = ((val>>16) & 0xfe) - link_connection(5,4) - link_connection(5,3);
1221 byte = get_linkn_last_count(byte);
1222 if((byte>>2)==0) { /* We should have three coherent links on node 5 for 6p and above*/
1228 /* We found 8 nodes so far. Now setup all nodes for 8p */
1229 static const u8 conn8_1[] = {
1230 #if !CROSS_BAR_47_56
1252 setup_row_indirect_group(conn8_1,sizeof(conn8_1)/sizeof(conn8_1[0]));
1254 for(byte=0; byte<6; byte+=2) {
1255 setup_temp_row(byte,byte+2);
1257 check_connection(7);
1258 val = pci_read_config32(NODE_HT(7), 0x6c);
1259 byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
1260 print_linkn("(6,4) link=", byte);
1262 setup_row_local(7,6);
1263 setup_remote_row_direct(6, 4, byte);
1264 setup_remote_node(6); /* Setup the regs on the remote node */
1265 /* Set indirect connection to 0, to 3 */
1266 #warning "FIXME we need to find out the correct gateway for 8p"
1267 static const u8 conn8_2[] = {
1268 #if !CROSS_BAR_47_56
1275 setup_remote_row_indirect_group(conn8_2, sizeof(conn8_2)/sizeof(conn8_2[0]));
1279 /* here init 5, 6 */
1280 /* Setup and check temporary connection from Node 0 to Node 5 through 1, 3, 5*/
1282 byte = ((val>>16) & 0xfe) - link_connection(5,3);
1283 #if TRY_HIGH_FIRST == 1
1284 byte = get_linkn_first(byte);
1286 byte = get_linkn_last(byte);
1288 print_linkn("(5,6) link=", byte);
1289 setup_row_direct(5, 6, byte);
1291 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
1292 for(byte=0; byte<4; byte+=2) {
1293 setup_temp_row(byte+1,byte+3);
1295 setup_temp_row(5,6);
1297 check_connection(7);
1299 val = get_row(7,6); // to chect it if it is node6 before renaming
1300 if( (val>>16) == 1) { // it is real node 7 so swap it
1301 /* We need to recompute link to 6 */
1303 byte = ((val>>16) & 0xfe) - link_connection(5,3);
1304 #if TRY_HIGH_FIRST == 1
1305 byte = get_linkn_first(byte);
1307 byte = get_linkn_last(byte);
1309 print_linkn("\t-->(5,6) link=", byte);
1310 setup_row_direct(5, 6, byte);
1312 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
1313 for(byte=0; byte<4; byte+=2) {
1314 setup_temp_row(byte+1,byte+3);
1317 setup_temp_row(5,6);
1319 check_connection(7);
1321 val = pci_read_config32(NODE_HT(7), 0x6c);
1322 byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
1323 print_linkn("(6,5) link=", byte);
1324 setup_remote_row_direct(6, 5, byte);
1325 /*Till now 56, 65 done */
1328 rename_temp_node(6);
1331 #if !CROSS_BAR_47_56
1332 setup_temp_row(0,1);
1333 for(byte=0; byte<6; byte+=2) {
1334 setup_temp_row(byte+1,byte+3);
1337 check_connection(7);
1339 val = pci_read_config32(NODE_HT(7), 0x6c);
1340 byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
1341 print_linkn("(7,5) link=", byte);
1342 setup_row_local(7,7);
1343 setup_remote_row_direct(7, 5, byte);
1347 byte = ((val>>16) & 0xfe) - link_connection(4,2) - link_connection(4,6);
1348 byte = get_linkn_first(byte);
1349 print_linkn("(4,7) link=", byte);
1350 setup_row_direct(4, 7, byte);
1352 /* Setup and check temporary connection from Node 0 to Node 7 through 2, and 4*/
1353 for(byte=0; byte<4; byte+=2) {
1354 setup_temp_row(byte,byte+2);
1357 check_connection(7);
1359 val = pci_read_config32(NODE_HT(7), 0x6c);
1360 byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
1361 print_linkn("(7,4) link=", byte);
1362 setup_row_local(7,7);
1363 setup_remote_row_direct(7, 4, byte);
1364 /* till now 4-7, 7-4 done. */
1366 setup_remote_node(7); /* Setup the regs on the remote node */
1369 /* here init 5, 7 */
1370 /* Setup and check temporary connection from Node 0 to Node 5 through 1, 3, 5*/
1372 byte = ((val>>16) & 0xfe) - link_connection(5,3) - link_connection(5,6);
1373 byte = get_linkn_first(byte);
1374 print_linkn("(5,7) link=", byte);
1375 setup_row_direct(5, 7, byte);
1377 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
1378 for(byte=0; byte<4; byte+=2) {
1379 setup_temp_row(byte+1,byte+3);
1382 check_connection(7);
1384 val = pci_read_config32(NODE_HT(7), 0x6c);
1385 byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
1386 print_linkn("(7,5) link=", byte);
1387 setup_remote_row_direct(7, 5, byte);
1388 /*Till now 57, 75 done */
1392 /* We need to init link between 6, and 7 direct link */
1394 #if !CROSS_BAR_47_56
1395 byte = ((val>>16) & 0xfe) - link_connection(6,4);
1397 byte = ((val>>16) & 0xfe) - link_connection(6,4) - link_connection(6,5);
1399 byte = get_linkn_first(byte);
1400 print_linkn("(6,7) link=", byte);
1401 setup_row_direct(6,7, byte);
1404 #if !CROSS_BAR_47_56
1405 byte = ((val>>16) & 0xfe) - link_connection(7,5);
1407 byte = ((val>>16) & 0xfe) - link_connection(7,5) - link_connection(7,4);
1409 byte = get_linkn_first(byte);
1410 print_linkn("(7,6) link=", byte);
1411 setup_row_direct(7,6, byte);
1413 /* Set indirect connection to 0, to 3 for indirect we will use clockwise routing */
1414 static const u8 conn8_3[] = {
1415 #if !CROSS_BAR_47_56
1416 0, 7, /* restore it*/
1438 6, 1, 5, 0, // or 4, 1
1440 6, 3, 5, 0, // or 4, 1
1442 7, 0, 4, 0, // or 5, 1
1444 7, 2, 4, 0, // or 5, 1
1447 0, 7, 2, 0, /* restore it*/
1452 2, 5, 4, 1, /* reset it */
1455 4, 1, 2, 1, /* reset it */
1458 5, 2, 3, 1, /* reset it */
1464 setup_row_indirect_group(conn8_3, sizeof(conn8_3)/sizeof(conn8_3[0]));
1467 /* for 47, 56, 57, 75, 46, 64 we need to substract another link to
1469 static const u8 conn8_4[] = {
1492 6, 1, 7, // needed for via 5
1495 6, 3, 7, // needed for via 5
1497 7, 0, 6, // needed for via 4
1500 7, 2, 6, // needed for via 4
1505 opt_broadcast_rt_group(conn8_4, sizeof(conn8_4)/sizeof(conn8_4[0]));
1507 static const u8 conn8_5[] = {
1513 opt_broadcast_rt_plus_group(conn8_5, sizeof(conn8_5)/sizeof(conn8_5[0]));
1518 /* ready to enable RT for Node 7 */
1519 enable_routing(7); /* enable routing on node 7 (temp.) */
1521 static const uint8_t opt_conn8[] ={
1530 /* optimize physical connections - by LYH */
1531 result.needs_reset |= optimize_connection_group(opt_conn8, sizeof(opt_conn8)/sizeof(opt_conn8[0]));
1536 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 6 */
1539 #if CONFIG_MAX_PHYSICAL_CPUS > 1
1541 static struct setup_smp_result setup_smp(void)
1543 struct setup_smp_result result;
1545 print_spew("Enabling SMP settings\r\n");
1547 result = setup_smp2();
1548 #if CONFIG_MAX_PHYSICAL_CPUS > 2
1549 if(result.nodes == 2)
1550 result = setup_smp4(result.needs_reset);
1553 #if CONFIG_MAX_PHYSICAL_CPUS > 4
1554 if(result.nodes == 4)
1555 result = setup_smp6(result.needs_reset);
1558 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1559 if(result.nodes == 6)
1560 result = setup_smp8(result.needs_reset);
1564 printk_debug("%02x nodes initialized.\r\n", result.nodes);
1566 print_debug_hex8(result.nodes);
1567 print_debug(" nodes initialized.\r\n");
1574 static unsigned verify_mp_capabilities(unsigned nodes)
1576 unsigned node, mask;
1578 mask = 0x06; /* BigMPCap */
1580 for (node=0; node<nodes; node++) {
1581 mask &= pci_read_config32(NODE_MC(node), 0xe8);
1585 #if CONFIG_MAX_PHYSICAL_CPUS > 2
1586 case 0x02: /* MPCap */
1588 print_err("Going back to DP\r\n");
1593 case 0x00: /* Non SMP */
1595 print_err("Going back to UP\r\n");
1606 static void clear_dead_routes(unsigned nodes)
1610 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1611 if(nodes==8) return;/* don't touch (7,7)*/
1617 for(node = 7; node >= 0; node--) {
1618 for(row = 7; row >= last_row; row--) {
1619 fill_row(node, row, DEFAULT);
1623 /* Update the local row */
1624 for( node=0; node<nodes; node++) {
1626 for(row =0; row<nodes; row++) {
1627 val |= get_row(node, row);
1629 fill_row(node, node, (((val & 0xff) | ((val >> 8) & 0xff)) << 16) | 0x0101);
1632 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 1 */
1634 #if CONFIG_LOGICAL_CPUS==1
1635 static unsigned verify_dualcore(unsigned nodes)
1637 unsigned node, totalcpus, tmp;
1640 for (node=0; node<nodes; node++) {
1641 tmp = (pci_read_config32(NODE_MC(node), 0xe8) >> 12) & 3 ;
1642 totalcpus += (tmp + 1);
1650 static void coherent_ht_finalize(unsigned nodes)
1654 #if CONFIG_LOGICAL_CPUS==1
1655 unsigned total_cpus;
1657 if(read_option(CMOS_VSTART_dual_core, CMOS_VLEN_dual_core, 0) == 0) { /* dual_core */
1658 total_cpus = verify_dualcore(nodes);
1665 /* set up cpu count and node count and enable Limit
1666 * Config Space Range for all available CPUs.
1667 * Also clear non coherent hypertransport bus range
1668 * registers on Hammer A0 revision.
1671 print_spew("coherent_ht_finalize\r\n");
1672 rev_a0 = is_cpu_rev_a0();
1673 for (node = 0; node < nodes; node++) {
1676 dev = NODE_HT(node);
1678 /* Set the Total CPU and Node count in the system */
1679 val = pci_read_config32(dev, 0x60);
1680 val &= (~0x000F0070);
1681 #if CONFIG_LOGICAL_CPUS==1
1682 val |= ((total_cpus-1)<<16)|((nodes-1)<<4);
1684 val |= ((nodes-1)<<16)|((nodes-1)<<4);
1686 pci_write_config32(dev, 0x60, val);
1688 /* Only respond to real cpu pci configuration cycles
1689 * and optimize the HT settings
1691 val=pci_read_config32(dev, 0x68);
1692 val &= ~((HTTC_BUF_REL_PRI_MASK << HTTC_BUF_REL_PRI_SHIFT) |
1693 (HTTC_MED_PRI_BYP_CNT_MASK << HTTC_MED_PRI_BYP_CNT_SHIFT) |
1694 (HTTC_HI_PRI_BYP_CNT_MASK << HTTC_HI_PRI_BYP_CNT_SHIFT));
1695 val |= HTTC_LIMIT_CLDT_CFG |
1696 (HTTC_BUF_REL_PRI_8 << HTTC_BUF_REL_PRI_SHIFT) |
1698 (3 << HTTC_MED_PRI_BYP_CNT_SHIFT) |
1699 (3 << HTTC_HI_PRI_BYP_CNT_SHIFT);
1700 pci_write_config32(dev, 0x68, val);
1703 print_spew("shit it is an old cup\n");
1704 pci_write_config32(dev, 0x94, 0);
1705 pci_write_config32(dev, 0xb4, 0);
1706 pci_write_config32(dev, 0xd4, 0);
1710 print_spew("done\r\n");
1713 static int apply_cpu_errata_fixes(unsigned nodes, int needs_reset)
1716 for(node = 0; node < nodes; node++) {
1719 dev = NODE_MC(node);
1720 if (is_cpu_pre_c0()) {
1723 * Limit the number of downstream posted requests to 1
1725 cmd = pci_read_config32(dev, 0x70);
1726 if ((cmd & (3 << 0)) != 2) {
1729 pci_write_config32(dev, 0x70, cmd );
1732 cmd = pci_read_config32(dev, 0x7c);
1733 if ((cmd & (3 << 4)) != 0) {
1736 pci_write_config32(dev, 0x7c, cmd );
1739 /* Clock Power/Timing Low */
1740 cmd = pci_read_config32(dev, 0xd4);
1741 if (cmd != 0x000D0001) {
1743 pci_write_config32(dev, 0xd4, cmd);
1744 needs_reset = 1; /* Needed? */
1748 else if(is_cpu_pre_d0()) { // d0 later don't need it
1751 * Set Clk Ramp Hystersis to 7
1752 * Clock Power/Timing Low
1754 cmd_ref = 0x04e20707; /* Registered */
1755 cmd = pci_read_config32(dev, 0xd4);
1756 if(cmd != cmd_ref) {
1757 pci_write_config32(dev, 0xd4, cmd_ref );
1758 needs_reset = 1; /* Needed? */
1765 static int optimize_link_read_pointers(unsigned nodes, int needs_reset)
1768 for(node = 0; node < nodes; node++) {
1769 device_t f0_dev, f3_dev;
1770 uint32_t cmd_ref, cmd;
1772 f0_dev = NODE_HT(node);
1773 f3_dev = NODE_MC(node);
1774 cmd_ref = cmd = pci_read_config32(f3_dev, 0xdc);
1775 for(link = 0; link < 3; link++) {
1778 /* This works on an Athlon64 because unimplemented links return 0 */
1779 reg = 0x98 + (link * 0x20);
1780 link_type = pci_read_config32(f0_dev, reg);
1781 if ((link_type & 7) == 3) { /* only handle coherent link here*/
1782 cmd &= ~(0xff << (link *8));
1783 cmd |= 0x25 << (link *8);
1786 if (cmd != cmd_ref) {
1787 pci_write_config32(f3_dev, 0xdc, cmd);
1794 static int setup_coherent_ht_domain(void)
1796 struct setup_smp_result result;
1798 #if K8_HT_CHECK_PENDING_LINK == 1
1802 enable_bsp_routing();
1804 #if CONFIG_MAX_PHYSICAL_CPUS > 1
1805 result = setup_smp();
1806 result.nodes = verify_mp_capabilities(result.nodes);
1807 clear_dead_routes(result.nodes);
1810 result.needs_reset = 0;
1813 if (result.nodes == 1) {
1814 setup_uniprocessor();
1816 coherent_ht_finalize(result.nodes);
1817 result.needs_reset = apply_cpu_errata_fixes(result.nodes, result.needs_reset);
1818 result.needs_reset = optimize_link_read_pointers(result.nodes, result.needs_reset);
1819 return result.needs_reset;