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
92 static inline void print_linkn (const char *strval, uint8_t byteval)
95 print_debug(strval); print_debug_hex8(byteval); print_debug("\r\n");
99 static void disable_probes(void)
101 /* disable read/write/fill probes for uniprocessor setup
102 * they don't make sense if only one cpu is available
105 /* Hypetransport Transaction Control Register
107 * [ 0: 0] Disable read byte probe
109 * 1 = Probes not issued
110 * [ 1: 1] Disable Read Doubleword probe
112 * 1 = Probes not issued
113 * [ 2: 2] Disable write byte probes
115 * 1 = Probes not issued
116 * [ 3: 3] Disable Write Doubleword Probes
118 * 1 = Probes not issued.
119 * [10:10] Disable Fill Probe
120 * 0 = Probes issued for cache fills
121 * 1 = Probes not issued for cache fills.
126 print_spew("Disabling read/write/fill probes for UP... ");
128 val=pci_read_config32(NODE_HT(0), 0x68);
129 val |= (1<<10)|(1<<9)|(1<<8)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|(1 << 0);
130 pci_write_config32(NODE_HT(0), 0x68, val);
132 print_spew("done.\r\n");
136 static void enable_routing(u8 node)
140 /* HT Initialization Control Register
142 * [ 0: 0] Routing Table Disable
143 * 0 = Packets are routed according to routing tables
144 * 1 = Packets are routed according to the default link field
145 * [ 1: 1] Request Disable (BSP should clear this)
146 * 0 = Request packets may be generated
147 * 1 = Request packets may not be generated.
148 * [ 3: 2] Default Link (Read-only)
152 * 11 = CPU on same node
154 * - Scratch bit cleared by a cold reset
155 * [ 5: 5] BIOS Reset Detect
156 * - Scratch bit cleared by a cold reset
157 * [ 6: 6] INIT Detect
158 * - Scratch bit cleared by a warm or cold reset not by an INIT
162 /* Enable routing table */
163 print_spew("Enabling routing table for node ");
164 print_spew_hex8(node);
166 val=pci_read_config32(NODE_HT(node), 0x6c);
167 val &= ~((1<<1)|(1<<0));
168 pci_write_config32(NODE_HT(node), 0x6c, val);
170 print_spew(" done.\r\n");
173 static void fill_row(u8 node, u8 row, u32 value)
175 pci_write_config32(NODE_HT(node), 0x40+(row<<2), value);
178 #if CONFIG_MAX_CPUS > 1
179 static u8 link_to_register(int ldt)
182 * [ 0: 3] Request Route
183 * [0] Route to this node
184 * [1] Route to Link 0
185 * [2] Route to Link 1
186 * [3] Route to Link 2
189 if (ldt&0x08) return 0x40;
190 if (ldt&0x04) return 0x20;
191 if (ldt&0x02) return 0x00;
193 /* we should never get here */
194 print_spew("Unknown Link\n");
198 static u32 get_row(u8 node, u8 row)
200 return pci_read_config32(NODE_HT(node), 0x40+(row<<2));
203 static int link_connection(u8 src, u8 dest)
205 return get_row(src, dest) & 0x0f;
208 static void rename_temp_node(u8 node)
212 print_spew("Renaming current temporary node to ");
213 print_spew_hex8(node);
215 val=pci_read_config32(NODE_HT(7), 0x60);
216 val &= (~7); /* clear low bits. */
217 val |= node; /* new node */
218 pci_write_config32(NODE_HT(7), 0x60, val);
220 print_spew(" done.\r\n");
223 static int check_connection(u8 dest)
225 /* See if we have a valid connection to dest */
228 /* Verify that the coherent hypertransport link is
229 * established and actually working by reading the
230 * remode node's vendor/device id
232 val = pci_read_config32(NODE_HT(dest),0);
233 if(val != 0x11001022)
239 static unsigned read_freq_cap(device_t dev, unsigned pos)
241 /* Handle bugs in valid hypertransport frequency reporting */
245 freq_cap = pci_read_config16(dev, pos);
246 freq_cap &= ~(1 << HT_FREQ_VENDOR); /* Ignore Vendor HT frequencies */
248 id = pci_read_config32(dev, 0);
250 /* AMD 8131 Errata 48 */
251 if (id == (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_AMD_8131_PCIX << 16))) {
252 freq_cap &= ~(1 << HT_FREQ_800Mhz);
254 /* AMD 8151 Errata 23 */
255 if (id == (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_AMD_8151_SYSCTRL << 16))) {
256 freq_cap &= ~(1 << HT_FREQ_800Mhz);
258 /* AMD K8 Unsupported 1Ghz? */
259 if (id == (PCI_VENDOR_ID_AMD | (0x1100 << 16))) {
260 freq_cap &= ~(1 << HT_FREQ_1000Mhz);
265 static int optimize_connection(device_t node1, uint8_t link1, device_t node2, uint8_t link2)
267 static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
268 static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
269 uint16_t freq_cap1, freq_cap2, freq_cap, freq_mask;
270 uint8_t width_cap1, width_cap2, width_cap, width, old_width, ln_width1, ln_width2;
271 uint8_t freq, old_freq;
273 /* Set link width and frequency */
275 /* Initially assume everything is already optimized and I don't need a reset */
278 /* Get the frequency capabilities */
279 freq_cap1 = read_freq_cap(node1, link1 + PCI_HT_CAP_HOST_FREQ_CAP);
280 freq_cap2 = read_freq_cap(node2, link2 + PCI_HT_CAP_HOST_FREQ_CAP);
282 /* Calculate the highest possible frequency */
283 freq = log2(freq_cap1 & freq_cap2);
285 /* See if I am changing the link freqency */
286 old_freq = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_FREQ);
287 needs_reset |= old_freq != freq;
288 old_freq = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_FREQ);
289 needs_reset |= old_freq != freq;
291 /* Set the Calulcated link frequency */
292 pci_write_config8(node1, link1 + PCI_HT_CAP_HOST_FREQ, freq);
293 pci_write_config8(node2, link2 + PCI_HT_CAP_HOST_FREQ, freq);
295 /* Get the width capabilities */
296 width_cap1 = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH);
297 width_cap2 = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH);
299 /* Calculate node1's input width */
300 ln_width1 = link_width_to_pow2[width_cap1 & 7];
301 ln_width2 = link_width_to_pow2[(width_cap2 >> 4) & 7];
302 if (ln_width1 > ln_width2) {
303 ln_width1 = ln_width2;
305 width = pow2_to_link_width[ln_width1];
306 /* Calculate node1's output width */
307 ln_width1 = link_width_to_pow2[(width_cap1 >> 4) & 7];
308 ln_width2 = link_width_to_pow2[width_cap2 & 7];
309 if (ln_width1 > ln_width2) {
310 ln_width1 = ln_width2;
312 width |= pow2_to_link_width[ln_width1] << 4;
314 /* See if I am changing node1's width */
315 old_width = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH + 1);
316 needs_reset |= old_width != width;
318 /* Set node1's widths */
319 pci_write_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH + 1, width);
321 /* Calculate node2's width */
322 width = ((width & 0x70) >> 4) | ((width & 0x7) << 4);
324 /* See if I am changing node2's width */
325 old_width = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH + 1);
326 needs_reset |= old_width != width;
328 /* Set node2's widths */
329 pci_write_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH + 1, width);
334 static void setup_row_local(u8 source, u8 row) /* source will be 7 when it is for temp use*/
339 for(linkn = 0; linkn<3; linkn++) {
342 regpos = 0x98 + 0x20 * linkn;
343 reg = pci_read_config32(NODE_HT(source), regpos);
344 if ((reg & 0x17) != 3) continue; /* it is not conherent or not connected*/
349 fill_row(source,row, val);
352 static void setup_row_direct_x(u8 temp, u8 source, u8 dest, u8 linkn)
357 val |= 1<<(linkn+1+8); /*for direct connect response route should equal to request table*/
359 if(((source &1)!=(dest &1))
361 && (source<4) && (dest<4)
366 /*for CROSS_BAR_47_56 47, 74, 56, 65 should be here too*/
367 val_s = get_row(temp, source);
368 val |= ((val_s>>16) - (1<<(linkn+1)))<<16;
371 fill_row(temp,dest, val );
374 static void setup_row_direct(u8 source, u8 dest, u8 linkn){
375 setup_row_direct_x(source, source, dest, linkn);
378 static void setup_remote_row_direct(u8 source, u8 dest, u8 linkn){
379 setup_row_direct_x(7, source, dest, linkn);
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_temp_row(u8 source, u8 dest)
409 /* copy val from (source, dest) to (source,7) */
410 fill_row(source,7,get_row(source,dest));
413 static void clear_temp_row(u8 source)
415 fill_row(source, 7, DEFAULT);
418 static void setup_remote_node(u8 node)
420 static const uint8_t pci_reg[] = {
421 0x44, 0x4c, 0x54, 0x5c, 0x64, 0x6c, 0x74, 0x7c,
422 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78,
423 0x84, 0x8c, 0x94, 0x9c, 0xa4, 0xac, 0xb4, 0xbc,
424 0x80, 0x88, 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8,
425 0xc4, 0xcc, 0xd4, 0xdc,
426 0xc0, 0xc8, 0xd0, 0xd8,
427 0xe0, 0xe4, 0xe8, 0xec,
431 print_spew("setup_remote_node: ");
433 /* copy the default resource map from node 0 */
434 for(i = 0; i < sizeof(pci_reg)/sizeof(pci_reg[0]); i++) {
438 value = pci_read_config32(NODE_MP(0), reg);
439 pci_write_config32(NODE_MP(7), reg, value);
442 print_spew("done\r\n");
445 #endif /* CONFIG_MAX_CPUS > 1*/
448 #if CONFIG_MAX_CPUS > 2
450 static void setup_row_indirect_x(u8 temp, u8 source, u8 dest, u8 gateway)
452 static void setup_row_indirect_x(u8 temp, u8 source, u8 dest, u8 gateway, u8 diff)
455 /*for indirect connection, we need to compute the val from val_s(source, source), and val_g(source, gateway) */
461 val_s = get_row(temp, source);
462 val = get_row(temp, gateway);
469 diff = ((source&1)!=(dest &1));
472 if(diff && (val_s!=(val&0xff)) ) { /* use another connect as response*/
474 #if CONFIG_MAX_CPUS > 4
476 /* Some node have two links left
477 * don't worry we only have (2, (3 as source need to handle
480 byte = get_linkn_last_count(byte);
481 if((byte>>2)>1) { /* make sure not the corner*/
483 val_s-=link_connection(temp, source-2); /* -down*/
485 val_s-=link_connection(temp, source+2); /* -up*/
493 if(diff) { /* cross rung?*/
497 val_s = get_row(temp, source);
498 val |= ((val_s>>16) - link_connection(temp, gateway))<<16;
501 fill_row(temp, dest, val);
506 static void setup_row_indirect(u8 source, u8 dest, u8 gateway)
508 setup_row_indirect_x(source, source, dest, gateway);
511 static void setup_row_indirect(u8 source, u8 dest, u8 gateway, u8 diff)
513 setup_row_indirect_x(source, source, dest, gateway, diff);
517 static void setup_row_indirect_group(const u8 *conn, int num)
522 for(i=0; i<num; i+=3) {
523 setup_row_indirect(conn[i], conn[i+1],conn[i+2]);
525 for(i=0; i<num; i+=4) {
526 setup_row_indirect(conn[i], conn[i+1],conn[i+2], conn[i+3]);
533 static void setup_remote_row_indirect(u8 source, u8 dest, u8 gateway)
535 setup_row_indirect_x(7, source, dest, gateway);
538 static void setup_remote_row_indirect(u8 source, u8 dest, u8 gateway, u8 diff)
540 setup_row_indirect_x(7, source, dest, gateway, diff);
544 static void setup_remote_row_indirect_group(const u8 *conn, int num)
549 for(i=0; i<num; i+=3) {
550 setup_remote_row_indirect(conn[i], conn[i+1],conn[i+2]);
552 for(i=0; i<num; i+=4) {
553 setup_remote_row_indirect(conn[i], conn[i+1],conn[i+2], conn[i+3]);
558 #endif /*CONFIG_MAX_CPUS > 2*/
561 static void setup_uniprocessor(void)
563 print_spew("Enabling UP settings\r\n");
567 struct setup_smp_result {
572 #if CONFIG_MAX_CPUS > 2
573 static int optimize_connection_group(const u8 *opt_conn, int num) {
576 for(i=0; i<num; i+=2) {
577 needs_reset = optimize_connection(
578 NODE_HT(opt_conn[i]), 0x80 + link_to_register(link_connection(opt_conn[i],opt_conn[i+1])),
579 NODE_HT(opt_conn[i+1]), 0x80 + link_to_register(link_connection(opt_conn[i+1],opt_conn[i])) );
585 #if CONFIG_MAX_CPUS > 1
586 static struct setup_smp_result setup_smp2(void)
588 struct setup_smp_result result;
592 result.needs_reset = 0;
594 setup_row_local(0, 0); /* it will update the broadcast RT*/
597 byte = (val>>16) & 0xfe;
598 if(byte<0x2) { /* no coherent connection so get out.*/
603 /* Setup and check a temporary connection to node 1 */
604 #if TRY_HIGH_FIRST == 1
605 byte = get_linkn_last(byte); /* Max Link to node1 */
607 byte = get_linkn_first(byte); /*Min Link to node1 --- according to AMD*/
609 print_linkn("(0,1) byte=", byte);
610 setup_row_direct(0,1, byte);
611 setup_temp_row(0, 1);
613 if (!check_connection(7)) {
614 print_spew("No connection to Node 1.\r\n");
619 /* We found 2 nodes so far */
620 val = pci_read_config32(NODE_HT(7), 0x6c);
621 byte = (val>>2) & 0x3; /*get default link on node7 to node0*/
622 print_linkn("(1,0) byte=", byte);
623 setup_row_local(7,1);
624 setup_remote_row_direct(1, 0, byte);
626 #if CONFIG_MAX_CPUS > 4
628 byte = (val>>16) & 0xfe;
629 byte = get_linkn_last_count(byte);
630 if((byte>>2)==3) { /* Oh! we need to treat it as node2. So use another link*/
632 byte = (val>>16) & 0xfe;
633 #if TRY_HIGH_FIRST == 1
634 byte = get_linkn_first(byte); /* Min link to Node1 */
636 byte = get_linkn_last(byte); /* Max link to Node1*/
638 print_linkn("-->(0,1) byte=", byte);
639 setup_row_direct(0,1, byte);
640 setup_temp_row(0, 1);
642 if (!check_connection(7)) {
643 print_spew("No connection to Node 1.\r\n");
648 /* We found 2 nodes so far */
649 val = pci_read_config32(NODE_HT(7), 0x6c);
650 byte = (val>>2) & 0x3; /* get default link on node7 to node0*/
651 print_linkn("-->(1,0) byte=", byte);
652 setup_row_local(7,1);
653 setup_remote_row_direct(1, 0, byte);
657 setup_remote_node(1); /* Setup the regs on the remote node */
658 rename_temp_node(1); /* Rename Node 7 to Node 1 */
659 enable_routing(1); /* Enable routing on Node 1 */
661 /*don't need and it is done by clear_dead_links */
665 result.needs_reset = optimize_connection(
666 NODE_HT(0), 0x80 + link_to_register(link_connection(0,1)),
667 NODE_HT(1), 0x80 + link_to_register(link_connection(1,0)) );
672 #endif /*CONFIG_MAX_CPUS > 1 */
674 #if CONFIG_MAX_CPUS > 2
676 static struct setup_smp_result setup_smp4(int needs_reset)
678 struct setup_smp_result result;
683 result.needs_reset = needs_reset;
685 /* Setup and check temporary connection from Node 0 to Node 2 */
687 byte = ((val>>16) & 0xfe) - link_connection(0,1);
688 byte = get_linkn_last_count(byte);
690 if((byte>>2)==0) { /* We should have two coherent for 4p and above*/
695 byte &= 3; /* bit [3,2] is count-1*/
696 print_linkn("(0,2) byte=", byte);
697 setup_row_direct(0, 2, byte); /*(0,2) direct link done*/
698 setup_temp_row(0, 2);
700 if (!check_connection(7) ) {
701 print_spew("No connection to Node 2.\r\n");
706 /* We found 3 nodes so far. Now setup a temporary
707 * connection from node 0 to node 3 via node 1
709 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
710 /* here should setup_row_direct(1,3) at first, before that we should find the link in node 1 to 3*/
712 byte = ((val>>16) & 0xfe) - link_connection(1,0);
713 byte = get_linkn_first(byte);
714 print_linkn("(1,3) byte=", byte);
715 setup_row_direct(1,3,byte); /* (1, 3) direct link done*/
716 setup_temp_row(1,3); /* temp. link between nodes 1 and 3 */
718 if (!check_connection(7)) {
719 print_spew("No connection to Node 3.\r\n");
724 /* We found 4 nodes so far. Now setup all nodes for 4p */
726 static const u8 conn4_1[] = {
731 static const u8 conn4_1[] = {
737 setup_row_indirect_group(conn4_1, sizeof(conn4_1)/sizeof(conn4_1[0]));
741 val = pci_read_config32(NODE_HT(7), 0x6c);
742 byte = (val>>2) & 0x3; /* get default link on 7 to 0*/
743 print_linkn("(2,0) byte=", byte);
745 setup_row_local(7,2);
746 setup_remote_row_direct(2, 0, byte);
747 setup_remote_node(2); /* Setup the regs on the remote node */
749 static const u8 conn4_2[] = {
753 static const u8 conn4_2[] = {
757 setup_remote_row_indirect_group(conn4_2, sizeof(conn4_2)/sizeof(conn4_2[0]));
759 rename_temp_node(2); /* Rename Node 7 to Node 2 */
760 enable_routing(2); /* Enable routing on Node 2 */
765 val = pci_read_config32(NODE_HT(7), 0x6c);
766 byte = (val>>2) & 0x3; /* get default link on 7 to 1*/
767 print_linkn("(3,1) byte=", byte);
769 setup_row_local(7,3);
770 setup_remote_row_direct(3, 1, byte);
771 setup_remote_node(3); /* Setup the regs on the remote node */
774 static const u8 conn4_3[] = {
778 static const u8 conn4_3[] = {
782 setup_remote_row_indirect_group(conn4_3, sizeof(conn4_3)/sizeof(conn4_3[0]));
784 /* We need to init link between 2, and 3 direct link */
786 byte = ((val>>16) & 0xfe) - link_connection(2,0);
787 byte = get_linkn_last_count(byte);
788 print_linkn("(2,3) byte=", byte & 3);
790 setup_row_direct(2,3, byte & 0x3);
793 check_connection(7); /* to 3*/
795 #if CONFIG_MAX_CPUS > 4
796 /* We need to find out which link is to node3 */
798 if((byte>>2)==2) { /* one to node3, one to node0, one to node4*/
800 if((val>>16) == 1) { /* that link is to node4, because via node3 it has been set, recompute it*/
802 byte = ((val>>16) & 0xfe) - link_connection(2,0);
803 byte = get_linkn_first(byte);
804 print_linkn("-->(2,3) byte=", byte);
805 setup_row_direct(2,3,byte);
807 check_connection(7); /* to 3*/
812 val = pci_read_config32(NODE_HT(7), 0x6c);
813 byte = (val>>2) & 0x3; /* get default link on 7 to 2*/
814 print_linkn("(3,2) byte=", byte);
815 setup_remote_row_direct(3,2, byte);
817 /* ready to enable RT for Node 3 */
819 enable_routing(3); /* enable routing on node 3 (temp.) */
822 /*We need to do sth to reverse work for setup_temp_row (0,1) (1,3) */
823 /* it will be done by clear_dead_links */
828 /* optimize physical connections - by LYH */
829 static const u8 opt_conn4[] = {
835 result.needs_reset = optimize_connection_group(opt_conn4, sizeof(opt_conn4)/sizeof(opt_conn4[0]));
841 #endif /* CONFIG_MAX_CPUS > 2 */
843 #if CONFIG_MAX_CPUS > 4
845 static struct setup_smp_result setup_smp6(int needs_reset)
847 struct setup_smp_result result;
852 result.needs_reset = needs_reset;
854 /* Setup and check temporary connection from Node 0 to Node 4 via 2 */
856 byte = ((val>>16) & 0xfe) - link_connection(2,3) - link_connection(2,0);
857 byte = get_linkn_last_count(byte);
859 if((byte>>2)==0) { /* We should have two coherent link on node 2 for 6p and above*/
863 byte &= 3; /* bit [3,2] is count-2*/
864 print_linkn("(2,4) byte=", byte);
865 setup_row_direct(2, 4, byte);
867 /* Setup and check temporary connection from Node 0 to Node 4 through 2*/
868 for(byte=0; byte<4; byte+=2) {
869 setup_temp_row(byte,byte+2);
872 if (!check_connection(7) ) {
873 print_spew("No connection to Node 4.\r\n");
878 /* Setup and check temporary connection from Node 0 to Node 5 through 1, 3*/
880 byte = ((val>>16) & 0xfe) - link_connection(3,2) - link_connection(3,1);
881 byte = get_linkn_last_count(byte);
882 if((byte>>2)==0) { /* We should have two coherent links on node 3 for 6p and above*/
887 byte &= 3; /*bit [3,2] is count-2*/
888 print_linkn("(3,5) byte=", byte);
889 setup_row_direct(3, 5, byte);
891 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
892 for(byte=0; byte<4; byte+=2) {
893 setup_temp_row(byte+1,byte+3);
896 if (!check_connection(7)) {
897 print_spew("No connection to Node 5.\r\n");
902 /* We found 6 nodes so far. Now setup all nodes for 6p */
903 #warning "FIXME we need to find out the correct gateway for 6p"
904 static const u8 conn6_1[] = {
922 setup_row_indirect_group(conn6_1, sizeof(conn6_1)/sizeof(conn6_1[0]));
924 for(byte=0; byte<4; byte+=2) {
925 setup_temp_row(byte,byte+2);
927 val = pci_read_config32(NODE_HT(7), 0x6c);
928 byte = (val>>2) & 0x3; /*get default link on 7 to 2*/
929 print_linkn("(4,2) byte=", byte);
931 setup_row_local(7,4);
932 setup_remote_row_direct(4, 2, byte);
933 setup_remote_node(4); /* Setup the regs on the remote node */
934 /* Set indirect connection to 0, to 3 */
935 static const u8 conn6_2[] = {
948 setup_remote_row_indirect_group(conn6_2, sizeof(conn6_2)/sizeof(conn6_2[0]));
954 for(byte=0; byte<4; byte+=2) {
955 setup_temp_row(byte+1,byte+3);
958 val = pci_read_config32(NODE_HT(7), 0x6c);
959 byte = (val>>2) & 0x3; /* get default link on 7 to 3*/
960 print_linkn("(5,3) byte=", byte);
961 setup_row_local(7,5);
962 setup_remote_row_direct(5, 3, byte);
963 setup_remote_node(5); /* Setup the regs on the remote node */
966 /* We need to init link between 4, and 5 direct link */
968 byte = ((val>>16) & 0xfe) - link_connection(4,2);
969 byte = get_linkn_last_count(byte);
970 print_linkn("(4,5) byte=", byte & 3);
972 setup_row_direct(4,5, byte & 0x3);
976 check_connection(7); /* to 5*/
978 #if CONFIG_MAX_CPUS > 6
979 /* We need to find out which link is to node5 */
981 if((byte>>2)==2) { /* one to node5, one to node2, one to node6*/
983 if((val>>16) == 1) { /* that link is to node6, because via node 3 node 5 has been set*/
985 byte = ((val>>16) & 0xfe) - link_connection(4,2);
986 byte = get_linkn_first(byte);
987 print_linkn("-->(4,5) byte=", byte);
988 setup_row_direct(4,5,byte);
990 check_connection(7); /* to 5*/
995 val = pci_read_config32(NODE_HT(7), 0x6c);
996 byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
997 print_linkn("(5,4) byte=", byte);
998 setup_remote_row_direct(5,4, byte);
1001 /* Set indirect connection to 0, to 3 for indirect we will use clockwise routing */
1002 static const u8 conn6_3[] = {
1003 #if !CROSS_BAR_47_56
1015 setup_remote_row_indirect_group(conn6_3, sizeof(conn6_3)/sizeof(conn6_3[0]));
1017 /* ready to enable RT for 5 */
1018 rename_temp_node(5);
1019 enable_routing(5); /* enable routing on node 5 (temp.) */
1022 /* We need to do sth about reverse about setup_temp_row (0,1), (2,4), (1, 3), (3,5)
1023 * It will be done by clear_dead_links
1025 for(byte=0; byte<4; byte++) {
1026 clear_temp_row(byte);
1030 /* optimize physical connections - by LYH */
1031 static const uint8_t opt_conn6[] ={
1034 #if !CROSS_BAR_47_56
1038 result.needs_reset = optimize_connection_group(opt_conn6, sizeof(opt_conn6)/sizeof(opt_conn6[0]));
1044 #endif /* CONFIG_MAX_CPUS > 4 */
1046 #if CONFIG_MAX_CPUS > 6
1048 static struct setup_smp_result setup_smp8(int needs_reset)
1050 struct setup_smp_result result;
1055 result.needs_reset = needs_reset;
1057 /* Setup and check temporary connection from Node 0 to Node 6 via 2 and 4 to 7 */
1059 #if !CROSS_BAR_47_56
1060 byte = ((val>>16) & 0xfe) - link_connection(4,5) - link_connection(4,2);
1062 byte = ((val>>16) & 0xfe) - link_connection(4,2);
1065 #if TRY_HIGH_FIRST == 1
1066 byte = get_linkn_last_count(byte); /* Max link to 6*/
1067 if((byte>>2)==0) { /* We should have two or three coherent links on node 4 for 8p*/
1071 byte &= 3; /* bit [3,2] is count-1 or 2*/
1073 byte = get_linkn_first(byte); /*Min link to 6*/
1075 print_linkn("(4,6) byte=", byte);
1076 setup_row_direct(4, 6, byte);
1078 /* Setup and check temporary connection from Node 0 to Node 6 through 2, and 4*/
1079 for(byte=0; byte<6; byte+=2) {
1080 setup_temp_row(byte,byte+2);
1083 if (!check_connection(7) ) {
1084 print_spew("No connection to Node 6.\r\n");
1088 #if !CROSS_BAR_47_56
1089 /* Setup and check temporary connection from Node 0 to Node 7 through 1, 3, 5*/
1091 byte = ((val>>16) & 0xfe) - link_connection(5,4) - link_connection(5,3);
1092 byte = get_linkn_first(byte);
1093 print_linkn("(5,7) byte=", byte);
1094 setup_row_direct(5, 7, byte);
1096 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
1097 for(byte=0; byte<6; byte+=2) {
1098 setup_temp_row(byte+1,byte+3);
1102 byte = ((val>>16) & 0xfe) - link_connection(4,2) - link_connection(4,6);
1103 byte = get_linkn_first(byte);
1104 print_linkn("(4,7) byte=", byte);
1105 setup_row_direct(4, 7, byte);
1107 /* Setup and check temporary connection from Node 0 to Node 7 through 2, and 4*/
1108 for(byte=0; byte<4; byte+=2) {
1109 setup_temp_row(byte,byte+2);
1111 setup_temp_row(4, 7);
1115 if (!check_connection(7)) {
1116 print_spew("No connection to Node 7.\r\n");
1122 /* We found 8 nodes so far. Now setup all nodes for 8p */
1123 static const u8 conn8_1[] = {
1124 #if !CROSS_BAR_47_56
1146 setup_row_indirect_group(conn8_1,sizeof(conn8_1)/sizeof(conn8_1[0]));
1148 for(byte=0; byte<6; byte+=2) {
1149 setup_temp_row(byte,byte+2);
1151 val = pci_read_config32(NODE_HT(7), 0x6c);
1152 byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
1153 print_linkn("(6,4) byte=", byte);
1155 setup_row_local(7,6);
1156 setup_remote_row_direct(6, 4, byte);
1157 setup_remote_node(6); /* Setup the regs on the remote node */
1158 /* Set indirect connection to 0, to 3 */
1159 #warning "FIXME we need to find out the correct gateway for 8p"
1160 static const u8 conn8_2[] = {
1161 #if !CROSS_BAR_47_56
1175 setup_remote_row_indirect_group(conn8_2, sizeof(conn8_2)/sizeof(conn8_2[0]));
1177 rename_temp_node(6);
1180 #if !CROSS_BAR_47_56
1181 setup_temp_row(0,1);
1182 for(byte=0; byte<6; byte+=2) {
1183 setup_temp_row(byte+1,byte+3);
1186 val = pci_read_config32(NODE_HT(7), 0x6c);
1187 byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
1188 print_linkn("(7,5) byte=", byte);
1189 setup_row_local(7,7);
1190 setup_remote_row_direct(7, 5, byte);
1193 for(byte=0; byte<4; byte+=2) {
1194 setup_temp_row(byte,byte+2);
1196 setup_temp_row(4,7);
1197 val = pci_read_config32(NODE_HT(7), 0x6c);
1198 byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
1199 print_linkn("(7,4) byte=", byte);
1200 setup_row_local(7,7);
1201 setup_remote_row_direct(7, 4, byte);
1202 /* till now 4-7, 7-4 done. */
1204 setup_remote_node(7); /* Setup the regs on the remote node */
1207 /* here init 5, 7 */
1208 /* Setup and check temporary connection from Node 0 to Node 5 through 1, 3, 5*/
1210 byte = ((val>>16) & 0xfe) - link_connection(5,3);
1211 byte = get_linkn_last(byte);
1212 print_linkn("(5,7) byte=", byte);
1213 setup_row_direct(5, 7, byte);
1215 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
1216 for(byte=0; byte<6; byte+=2) {
1217 setup_temp_row(byte+1,byte+3);
1220 if (!check_connection(7)) {
1221 /* We need to recompute link to 7 */
1223 byte = ((val>>16) & 0xfe) - link_connection(5,3);
1224 byte = get_linkn_first(byte);
1226 print_linkn("-->(5,7) byte=", byte);
1227 setup_row_direct(5, 7, byte);
1229 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
1230 for(byte=0; byte<6; byte+=2) {
1231 setup_temp_row(byte+1,byte+3);
1234 setup_temp_row(5,7);
1236 check_connection(7);
1238 val = pci_read_config32(NODE_HT(7), 0x6c);
1239 byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
1240 print_linkn("(7,5) byte=", byte);
1241 setup_remote_row_direct(7, 5, byte);
1242 /*Till now 57, 75 done */
1244 /* init init 5, 6 */
1246 byte = ((val>>16) & 0xfe) - link_connection(5,3) - link_connection(5,7);
1247 byte = get_linkn_first(byte);
1248 print_linkn("(5,6) byte=", byte);
1249 setup_row_direct(5, 6, byte);
1253 byte = ((val>>16) & 0xfe) - link_connection(6,4);
1254 byte = get_linkn_last(byte);
1255 print_linkn("(6,7) byte=", byte);
1256 setup_row_direct(6, 7, byte);
1258 for(byte=0; byte<6; byte+=2) {
1259 setup_temp_row(byte,byte+2);
1261 setup_temp_row(6,7);
1263 if (!check_connection(7)) {
1264 /* We need to recompute link to 7 */
1266 byte = ((val>>16) & 0xfe) - link_connection(6,4);
1267 byte = get_linkn_first(byte);
1268 print_linkn("-->(6,7) byte=", byte);
1270 setup_row_direct(6, 7, byte);
1272 for(byte=0; byte<6; byte+=2) {
1273 setup_temp_row(byte,byte+2); /* temp. link between nodes 0 and 2 */
1276 setup_temp_row(6,7);
1277 check_connection(7);
1279 val = pci_read_config32(NODE_HT(7), 0x6c);
1280 byte = (val>>2) & 0x3; /* get default link on 7 to 6*/
1281 print_linkn("(7,6) byte=", byte);
1283 setup_remote_row_direct(7, 6, byte);
1284 /* Till now 67, 76 done*/
1288 byte = ((val>>16) & 0xfe) - link_connection(6,4) - link_connection(6,7);
1289 byte = get_linkn_first(byte);
1290 print_linkn("(6,5) byte=", byte);
1291 setup_row_direct(6, 5, byte);
1295 #if !CROSS_BAR_47_56
1296 /* We need to init link between 6, and 7 direct link */
1298 byte = ((val>>16) & 0xfe) - link_connection(6,4);
1299 byte = get_linkn_first(byte);
1300 print_linkn("(6,7) byte=", byte);
1301 setup_row_direct(6,7, byte);
1304 byte = ((val>>16) & 0xfe) - link_connection(7,5);
1305 byte = get_linkn_first(byte);
1306 print_linkn("(7,6) byte=", byte);
1307 setup_row_direct(7,6, byte);
1310 /* Set indirect connection to 0, to 3 for indirect we will use clockwise routing */
1311 static const u8 conn8_3[] = {
1312 #if !CROSS_BAR_47_56
1313 0, 7, 1, /* restore it*/
1325 0, 7, 2, 0, /* restore it*/
1342 setup_row_indirect_group(conn8_3, sizeof(conn8_3)/sizeof(conn8_3[0]));
1344 /* ready to enable RT for Node 7 */
1345 enable_routing(7); /* enable routing on node 7 (temp.) */
1348 static const uint8_t opt_conn8[] ={
1357 /* optimize physical connections - by LYH */
1358 result.needs_reset = optimize_connection_group(opt_conn8, sizeof(opt_conn8)/sizeof(opt_conn8[0]));
1363 #endif /* CONFIG_MAX_CPUS > 6 */
1366 #if CONFIG_MAX_CPUS > 1
1368 static struct setup_smp_result setup_smp(void)
1370 struct setup_smp_result result;
1372 print_spew("Enabling SMP settings\r\n");
1374 result = setup_smp2();
1375 #if CONFIG_MAX_CPUS > 2
1376 result = setup_smp4(result.needs_reset);
1379 #if CONFIG_MAX_CPUS > 4
1380 result = setup_smp6(result.needs_reset);
1383 #if CONFIG_MAX_CPUS > 6
1384 result = setup_smp6(result.needs_reset);
1387 print_debug_hex8(result.nodes);
1388 print_debug(" nodes initialized.\r\n");
1394 static unsigned verify_mp_capabilities(unsigned nodes)
1396 unsigned node, mask;
1398 mask = 0x06; /* BigMPCap */
1400 for (node=0; node<nodes; node++) {
1401 mask &= pci_read_config32(NODE_MC(node), 0xe8);
1405 #if CONFIG_MAX_CPUS > 2
1406 case 0x02: /* MPCap */
1408 print_err("Going back to DP\r\n");
1413 case 0x00: /* Non SMP */
1415 print_err("Going back to UP\r\n");
1426 static void clear_dead_routes(unsigned nodes)
1430 #if CONFIG_MAX_CPUS > 6
1431 if(nodes==8) return;/* don't touch (7,7)*/
1437 for(node = 7; node >= 0; node--) {
1438 for(row = 7; row >= last_row; row--) {
1439 fill_row(node, row, DEFAULT);
1443 /* Update the local row */
1444 for( node=0; node<nodes; node++) {
1446 for(row =0; row<nodes; row++) {
1447 val |= get_row(node, row);
1449 fill_row(node, row, (((val & 0xff) | ((val >> 8) & 0xff)) << 16) | 0x0101);
1452 #endif /* CONFIG_MAX_CPUS > 1 */
1454 static void coherent_ht_finalize(unsigned nodes)
1459 /* set up cpu count and node count and enable Limit
1460 * Config Space Range for all available CPUs.
1461 * Also clear non coherent hypertransport bus range
1462 * registers on Hammer A0 revision.
1465 print_spew("coherent_ht_finalize\r\n");
1466 rev_a0 = is_cpu_rev_a0();
1467 for (node = 0; node < nodes; node++) {
1470 dev = NODE_HT(node);
1472 /* Set the Total CPU and Node count in the system */
1473 val = pci_read_config32(dev, 0x60);
1474 val &= (~0x000F0070);
1475 val |= ((nodes-1)<<16)|((nodes-1)<<4);
1476 pci_write_config32(dev, 0x60, val);
1478 /* Only respond to real cpu pci configuration cycles
1479 * and optimize the HT settings
1481 val=pci_read_config32(dev, 0x68);
1482 val &= ~((HTTC_BUF_REL_PRI_MASK << HTTC_BUF_REL_PRI_SHIFT) |
1483 (HTTC_MED_PRI_BYP_CNT_MASK << HTTC_MED_PRI_BYP_CNT_SHIFT) |
1484 (HTTC_HI_PRI_BYP_CNT_MASK << HTTC_HI_PRI_BYP_CNT_SHIFT));
1485 val |= HTTC_LIMIT_CLDT_CFG |
1486 (HTTC_BUF_REL_PRI_8 << HTTC_BUF_REL_PRI_SHIFT) |
1488 (3 << HTTC_MED_PRI_BYP_CNT_SHIFT) |
1489 (3 << HTTC_HI_PRI_BYP_CNT_SHIFT);
1490 pci_write_config32(dev, 0x68, val);
1493 print_spew("shit it is an old cup\n");
1494 pci_write_config32(dev, 0x94, 0);
1495 pci_write_config32(dev, 0xb4, 0);
1496 pci_write_config32(dev, 0xd4, 0);
1500 print_spew("done\r\n");
1503 static int apply_cpu_errata_fixes(unsigned nodes, int needs_reset)
1506 for(node = 0; node < nodes; node++) {
1509 dev = NODE_MC(node);
1510 if (is_cpu_pre_c0()) {
1513 * Limit the number of downstream posted requests to 1
1515 cmd = pci_read_config32(dev, 0x70);
1516 if ((cmd & (3 << 0)) != 2) {
1519 pci_write_config32(dev, 0x70, cmd );
1522 cmd = pci_read_config32(dev, 0x7c);
1523 if ((cmd & (3 << 4)) != 0) {
1526 pci_write_config32(dev, 0x7c, cmd );
1529 /* Clock Power/Timing Low */
1530 cmd = pci_read_config32(dev, 0xd4);
1531 if (cmd != 0x000D0001) {
1533 pci_write_config32(dev, 0xd4, cmd);
1534 needs_reset = 1; /* Needed? */
1541 * Set Clk Ramp Hystersis to 7
1542 * Clock Power/Timing Low
1544 cmd_ref = 0x04e20707; /* Registered */
1545 cmd = pci_read_config32(dev, 0xd4);
1546 if(cmd != cmd_ref) {
1547 pci_write_config32(dev, 0xd4, cmd_ref );
1548 needs_reset = 1; /* Needed? */
1555 static int optimize_link_read_pointers(unsigned nodes, int needs_reset)
1558 for(node = 0; node < nodes; node++) {
1559 device_t f0_dev, f3_dev;
1560 uint32_t cmd_ref, cmd;
1562 f0_dev = NODE_HT(node);
1563 f3_dev = NODE_MC(node);
1564 cmd_ref = cmd = pci_read_config32(f3_dev, 0xdc);
1565 for(link = 0; link < 3; link++) {
1568 /* This works on an Athlon64 because unimplemented links return 0 */
1569 reg = 0x98 + (link * 0x20);
1570 link_type = pci_read_config32(f0_dev, reg);
1571 if ((link_type & 3) == 3) {
1572 cmd &= ~(0xff << (link *8));
1573 cmd |= 0x25 << (link *8);
1576 if (cmd != cmd_ref) {
1577 pci_write_config32(f3_dev, 0xdc, cmd);
1584 static int setup_coherent_ht_domain(void)
1586 struct setup_smp_result result;
1588 enable_bsp_routing();
1590 #if CONFIG_MAX_CPUS > 1
1591 result = setup_smp();
1592 result.nodes = verify_mp_capabilities(result.nodes);
1593 clear_dead_routes(result.nodes);
1596 result.needs_reset = 0;
1599 if (result.nodes == 1) {
1600 setup_uniprocessor();
1602 coherent_ht_finalize(result.nodes);
1603 result.needs_reset = apply_cpu_errata_fixes(result.nodes, result.needs_reset);
1604 result.needs_reset = optimize_link_read_pointers(result.nodes, result.needs_reset);
1605 return result.needs_reset;