2 This should be done by Eric
3 2004.12 yhlu add multi ht chain dynamically support
4 2005.11 yhlu add let real sb to use small unitid
6 #include <device/pci_def.h>
7 #include <device/pci_ids.h>
8 #include <device/hypertransport_def.h>
10 #ifndef K8_HT_FREQ_1G_SUPPORT
11 #define K8_HT_FREQ_1G_SUPPORT 0
14 #ifndef K8_SCAN_PCI_BUS
15 #define K8_SCAN_PCI_BUS 0
18 #ifndef K8_ALLOCATE_IO_RANGE
19 #define K8_ALLOCATE_IO_RANGE 0
22 // Do we need allocate MMIO? Current We direct last 64M to sblink only, We can not lose access to last 4M range to ROM
23 #ifndef K8_ALLOCATE_MMIO_RANGE
24 #define K8_ALLOCATE_MMIO_RANGE 0
27 static inline void print_linkn_in (const char *strval, uint8_t byteval)
29 #if CONFIG_USE_PRINTK_IN_CAR
30 printk_debug("%s%02x\r\n", strval, byteval);
32 print_debug(strval); print_debug_hex8(byteval); print_debug("\r\n");
36 static uint8_t ht_lookup_capability(device_t dev, uint16_t val)
41 hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
45 if ((hdr_type == PCI_HEADER_TYPE_NORMAL) ||
46 (hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
47 pos = PCI_CAPABILITY_LIST;
49 if (pos > PCI_CAP_LIST_NEXT) {
50 pos = pci_read_config8(dev, pos);
52 while(pos != 0) { /* loop through the linked list */
54 cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID);
55 if (cap == PCI_CAP_ID_HT) {
58 flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
59 if ((flags >> 13) == val) {
60 /* Entry is a slave or host , success... */
64 pos = pci_read_config8(dev, pos + PCI_CAP_LIST_NEXT);
69 static uint8_t ht_lookup_slave_capability(device_t dev)
71 return ht_lookup_capability(dev, 0); // Slave/Primary Interface Block Format
74 static uint8_t ht_lookup_host_capability(device_t dev)
76 return ht_lookup_capability(dev, 1); // Host/Secondary Interface Block Format
79 static void ht_collapse_previous_enumeration(uint8_t bus, unsigned offset_unitid)
84 //actually, only for one HT device HT chain, and unitid is 0
85 #if HT_CHAIN_UNITID_BASE == 0
91 /* Check if is already collapsed */
92 if((!offset_unitid) || (offset_unitid && (!((HT_CHAIN_END_UNITID_BASE == 0) && (HT_CHAIN_END_UNITID_BASE <HT_CHAIN_UNITID_BASE))))) {
93 dev = PCI_DEV(bus, 0, 0);
94 id = pci_read_config32(dev, PCI_VENDOR_ID);
95 if (!((id == 0xffffffff) || (id == 0x00000000) ||
96 (id == 0x0000ffff) || (id == 0xffff0000))) {
101 /* Spin through the devices and collapse any previous
102 * hypertransport enumeration.
104 for(dev = PCI_DEV(bus, 1, 0); dev <= PCI_DEV(bus, 0x1f, 0x7); dev += PCI_DEV(0, 1, 0)) {
109 id = pci_read_config32(dev, PCI_VENDOR_ID);
110 if ((id == 0xffffffff) || (id == 0x00000000) ||
111 (id == 0x0000ffff) || (id == 0xffff0000)) {
115 pos = ht_lookup_slave_capability(dev);
120 /* Clear the unitid */
121 flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
123 pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
127 static uint16_t ht_read_freq_cap(device_t dev, uint8_t pos)
129 /* Handle bugs in valid hypertransport frequency reporting */
133 freq_cap = pci_read_config16(dev, pos);
134 freq_cap &= ~(1 << HT_FREQ_VENDOR); /* Ignore Vendor HT frequencies */
136 id = pci_read_config32(dev, 0);
138 /* AMD 8131 Errata 48 */
139 if (id == (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_AMD_8131_PCIX << 16))) {
140 freq_cap &= ~(1 << HT_FREQ_800Mhz);
144 /* AMD 8151 Errata 23 */
145 if (id == (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_AMD_8151_SYSCTRL << 16))) {
146 freq_cap &= ~(1 << HT_FREQ_800Mhz);
150 /* AMD K8 Unsupported 1Ghz? */
151 if (id == (PCI_VENDOR_ID_AMD | (0x1100 << 16))) {
152 #if K8_HT_FREQ_1G_SUPPORT == 1
153 #if K8_REV_F_SUPPORT == 0
154 if (is_cpu_pre_e0()) { // only E0 later support 1GHz
155 freq_cap &= ~(1 << HT_FREQ_1000Mhz);
159 freq_cap &= ~(1 << HT_FREQ_1000Mhz);
166 static uint8_t ht_read_width_cap(device_t dev, uint8_t pos)
168 uint8_t width_cap = pci_read_config8(dev, pos);
172 id = pci_read_config32(dev, 0);
174 /* netlogic micro cap doesn't support 16 bit yet */
175 if (id == (0x184e | (0x0001 << 16))) {
176 if((width_cap & 0x77) == 0x11) {
185 #define LINK_OFFS(CTRL, WIDTH,FREQ,FREQ_CAP) \
186 (((CTRL & 0xff) << 24) | ((WIDTH & 0xff) << 16) | ((FREQ & 0xff) << 8) | (FREQ_CAP & 0xFF))
188 #define LINK_CTRL(OFFS) ((OFFS >> 24) & 0xFF)
189 #define LINK_WIDTH(OFFS) ((OFFS >> 16) & 0xFF)
190 #define LINK_FREQ(OFFS) ((OFFS >> 8) & 0xFF)
191 #define LINK_FREQ_CAP(OFFS) ((OFFS) & 0xFF)
193 #define PCI_HT_HOST_OFFS LINK_OFFS( \
194 PCI_HT_CAP_HOST_CTRL, \
195 PCI_HT_CAP_HOST_WIDTH, \
196 PCI_HT_CAP_HOST_FREQ, \
197 PCI_HT_CAP_HOST_FREQ_CAP)
199 #define PCI_HT_SLAVE0_OFFS LINK_OFFS( \
200 PCI_HT_CAP_SLAVE_CTRL0, \
201 PCI_HT_CAP_SLAVE_WIDTH0, \
202 PCI_HT_CAP_SLAVE_FREQ0, \
203 PCI_HT_CAP_SLAVE_FREQ_CAP0)
205 #define PCI_HT_SLAVE1_OFFS LINK_OFFS( \
206 PCI_HT_CAP_SLAVE_CTRL1, \
207 PCI_HT_CAP_SLAVE_WIDTH1, \
208 PCI_HT_CAP_SLAVE_FREQ1, \
209 PCI_HT_CAP_SLAVE_FREQ_CAP1)
211 static int ht_optimize_link(
212 device_t dev1, uint8_t pos1, unsigned offs1,
213 device_t dev2, uint8_t pos2, unsigned offs2)
215 static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
216 static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
217 uint16_t freq_cap1, freq_cap2;
218 uint8_t width_cap1, width_cap2, width, old_width, ln_width1, ln_width2;
219 uint8_t freq, old_freq;
221 /* Set link width and frequency */
223 /* Initially assume everything is already optimized and I don't need a reset */
226 /* Get the frequency capabilities */
227 freq_cap1 = ht_read_freq_cap(dev1, pos1 + LINK_FREQ_CAP(offs1));
228 freq_cap2 = ht_read_freq_cap(dev2, pos2 + LINK_FREQ_CAP(offs2));
230 /* Calculate the highest possible frequency */
231 freq = log2(freq_cap1 & freq_cap2);
233 /* See if I am changing the link freqency */
234 old_freq = pci_read_config8(dev1, pos1 + LINK_FREQ(offs1));
236 needs_reset |= old_freq != freq;
237 old_freq = pci_read_config8(dev2, pos2 + LINK_FREQ(offs2));
239 needs_reset |= old_freq != freq;
241 /* Set the Calulcated link frequency */
242 pci_write_config8(dev1, pos1 + LINK_FREQ(offs1), freq);
243 pci_write_config8(dev2, pos2 + LINK_FREQ(offs2), freq);
245 /* Get the width capabilities */
246 width_cap1 = ht_read_width_cap(dev1, pos1 + LINK_WIDTH(offs1));
247 width_cap2 = ht_read_width_cap(dev2, pos2 + LINK_WIDTH(offs2));
249 /* Calculate dev1's input width */
250 ln_width1 = link_width_to_pow2[width_cap1 & 7];
251 ln_width2 = link_width_to_pow2[(width_cap2 >> 4) & 7];
252 if (ln_width1 > ln_width2) {
253 ln_width1 = ln_width2;
255 width = pow2_to_link_width[ln_width1];
256 /* Calculate dev1's output width */
257 ln_width1 = link_width_to_pow2[(width_cap1 >> 4) & 7];
258 ln_width2 = link_width_to_pow2[width_cap2 & 7];
259 if (ln_width1 > ln_width2) {
260 ln_width1 = ln_width2;
262 width |= pow2_to_link_width[ln_width1] << 4;
264 /* See if I am changing dev1's width */
265 old_width = pci_read_config8(dev1, pos1 + LINK_WIDTH(offs1) + 1);
267 needs_reset |= old_width != width;
269 /* Set dev1's widths */
270 pci_write_config8(dev1, pos1 + LINK_WIDTH(offs1) + 1, width);
272 /* Calculate dev2's width */
273 width = ((width & 0x70) >> 4) | ((width & 0x7) << 4);
275 /* See if I am changing dev2's width */
276 old_width = pci_read_config8(dev2, pos2 + LINK_WIDTH(offs2) + 1);
278 needs_reset |= old_width != width;
280 /* Set dev2's widths */
281 pci_write_config8(dev2, pos2 + LINK_WIDTH(offs2) + 1, width);
286 #if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1)
288 #if RAMINIT_SYSINFO == 1
289 static void ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned offset_unitid, struct sys_info *sysinfo);
290 static int scan_pci_bus( unsigned bus , struct sys_info *sysinfo)
292 static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned offset_unitid);
293 static int scan_pci_bus( unsigned bus)
297 here we already can access PCI_DEV(bus, 0, 0) to PCI_DEV(bus, 0x1f, 0x7)
298 So We can scan these devices to find out if they are bridge
299 If it is pci bridge, We need to set busn in bridge, and go on
300 For ht bridge, We need to set the busn in bridge and ht_setup_chainx, and the scan_pci_bus
306 new_bus = (bus & 0xff); // mask out the reset_needed
310 } else if (new_bus<0x80) {
312 } else if (new_bus<0xc0) {
320 for (devfn = 0; devfn <= 0xff; devfn++) {
326 dev = PCI_DEV((bus & 0xff), ((devfn>>3) & 0x1f), (devfn & 0x7));
327 hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
328 class = pci_read_config16(dev, PCI_CLASS_DEVICE);
330 switch(hdr_type & 0x7f) { /* header type */
331 case PCI_HEADER_TYPE_BRIDGE:
332 if (class != PCI_CLASS_BRIDGE_PCI) goto bad;
333 /* set the bus range dev */
335 /* Clear all status bits and turn off memory, I/O and master enables. */
336 cr = pci_read_config16(dev, PCI_COMMAND);
337 pci_write_config16(dev, PCI_COMMAND, 0x0000);
338 pci_write_config16(dev, PCI_STATUS, 0xffff);
340 buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
344 buses |= (((unsigned int) (bus & 0xff) << 0) |
345 ((unsigned int) (new_bus & 0xff) << 8) |
346 ((unsigned int) max_bus << 16));
347 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
349 /* here we need to figure out if dev is a ht bridge
350 if it is ht bridge, we need to call ht_setup_chainx at first
351 Not verified --- yhlu
354 upos = ht_lookup_host_capability(dev); // one func one ht sub
355 if (upos) { // sub ht chain
357 busn = (new_bus & 0xff);
358 /* Make certain the HT bus is not enumerated */
359 ht_collapse_previous_enumeration(busn, 0);
360 /* scan the ht chain */
361 #if RAMINIT_SYSINFO == 1
362 ht_setup_chainx(dev,upos,busn, 0, sysinfo); // don't need offset unitid
364 new_bus |= (ht_setup_chainx(dev, upos, busn, 0)<<16); // store reset_needed to upword
368 #if RAMINIT_SYSINFO == 1
369 new_bus = scan_pci_bus(new_bus, sysinfo);
371 new_bus = scan_pci_bus(new_bus);
373 /* set real max bus num in that */
375 buses = (buses & 0xff00ffff) |
376 ((unsigned int) (new_bus & 0xff) << 16);
377 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
379 pci_write_config16(dev, PCI_COMMAND, cr);
387 /* if this is not a multi function device,
388 * or the device is not present don't waste
389 * time probing another function.
390 * Skip to next device.
392 if ( ((devfn & 0x07) == 0x00) && ((hdr_type & 0x80) != 0x80))
402 #if RAMINIT_SYSINFO == 1
403 static void ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned offset_unitid, struct sys_info *sysinfo)
405 static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned offset_unitid)
408 //even HT_CHAIN_UNITID_BASE == 0, we still can go through this function, because of end_of_chain check, also We need it to optimize link
410 uint8_t next_unitid, last_unitid;
413 #if RAMINIT_SYSINFO == 0
414 int reset_needed = 0;
417 #if HT_CHAIN_END_UNITID_BASE != 0x20
418 //let't record the device of last ht device, So we can set the Unitid to HT_CHAIN_END_UNITID_BASE
419 unsigned real_last_unitid;
420 uint8_t real_last_pos;
422 uint8_t end_used = 0;
425 uoffs = PCI_HT_HOST_OFFS;
426 next_unitid = (offset_unitid) ? HT_CHAIN_UNITID_BASE:1;
431 uint16_t flags, ctrl;
435 /* Wait until the link initialization is complete */
437 ctrl = pci_read_config16(udev, upos + LINK_CTRL(uoffs));
438 /* Is this the end of the hypertransport chain? */
439 if (ctrl & (1 << 6)) {
443 if (ctrl & ((1 << 4) | (1 << 8))) {
445 * Either the link has failed, or we have
447 * Sometimes this can happen due to link
448 * retrain, so lets knock it down and see
451 ctrl |= ((1 << 4) | (1 <<8)); // Link fail + Crc
452 pci_write_config16(udev, upos + LINK_CTRL(uoffs), ctrl);
453 ctrl = pci_read_config16(udev, upos + LINK_CTRL(uoffs));
454 if (ctrl & ((1 << 4) | (1 << 8))) {
455 print_err("Detected error on Hypertransport Link\n");
459 } while((ctrl & (1 << 5)) == 0);
461 device_t dev = PCI_DEV(bus, 0, 0);
462 last_unitid = next_unitid;
464 id = pci_read_config32(dev, PCI_VENDOR_ID);
466 /* If the chain is enumerated quit */
467 if ((id == 0xffffffff) || (id == 0x00000000) ||
468 (id == 0x0000ffff) || (id == 0xffff0000))
473 pos = ht_lookup_slave_capability(dev);
475 print_err("udev="); print_err_hex32(udev);
476 print_err("\tupos="); print_err_hex32(upos);
477 print_err("\tuoffs="); print_err_hex32(uoffs);
478 print_err("\tHT link capability not found\r\n");
483 #if HT_CHAIN_END_UNITID_BASE != 0x20
485 if(next_unitid>= (bus ? 0x20:0x18) ) {
487 next_unitid = HT_CHAIN_END_UNITID_BASE;
495 real_last_unitid = next_unitid;
499 /* Update the Unitid of the current device */
500 flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
501 flags &= ~0x1f; /* mask out the base Unit ID */
502 flags |= next_unitid & 0x1f;
503 pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
505 /* Compute the number of unitids consumed */
506 count = (flags >> 5) & 0x1f;
508 /* Note the change in device number */
509 dev = PCI_DEV(bus, next_unitid, 0);
511 next_unitid += count;
513 /* Find which side of the ht link we are on,
514 * by reading which direction our last write to PCI_CAP_FLAGS
517 flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
518 offs = ((flags>>10) & 1) ? PCI_HT_SLAVE1_OFFS : PCI_HT_SLAVE0_OFFS;
520 #if RAMINIT_SYSINFO == 1
521 /* store the link pair here and we will Setup the Hypertransport link later, after we get final FID/VID */
523 struct link_pair_st *link_pair = &sysinfo->link_pair[sysinfo->link_pair_num];
524 link_pair->udev = udev;
525 link_pair->upos = upos;
526 link_pair->uoffs = uoffs;
527 link_pair->dev = dev;
528 link_pair->pos = pos;
529 link_pair->offs = offs;
530 sysinfo->link_pair_num++;
533 reset_needed |= ht_optimize_link(udev, upos, uoffs, dev, pos, offs);
536 /* Remeber the location of the last device */
539 uoffs = ( offs != PCI_HT_SLAVE0_OFFS ) ? PCI_HT_SLAVE0_OFFS : PCI_HT_SLAVE1_OFFS;
541 } while (last_unitid != next_unitid );
546 #if HT_CHAIN_END_UNITID_BASE != 0x20
547 if(offset_unitid && (ht_dev_num>1) && (real_last_unitid != HT_CHAIN_END_UNITID_BASE) && !end_used ) {
550 flags = pci_read_config16(PCI_DEV(bus,real_last_unitid,0), real_last_pos + PCI_CAP_FLAGS);
552 flags |= HT_CHAIN_END_UNITID_BASE & 0x1f;
553 pci_write_config16(PCI_DEV(bus, real_last_unitid, 0), real_last_pos + PCI_CAP_FLAGS, flags);
555 #if RAMINIT_SYSINFO == 1
556 // Here need to change the dev in the array
557 for(i=0;i<sysinfo->link_pair_num;i++)
559 struct link_pair_st *link_pair = &sysinfo->link_pair[i];
560 if(link_pair->udev == PCI_DEV(bus, real_last_unitid, 0)) {
561 link_pair->udev = PCI_DEV(bus, HT_CHAIN_END_UNITID_BASE, 0);
564 if(link_pair->dev == PCI_DEV(bus, real_last_unitid, 0)) {
565 link_pair->dev = PCI_DEV(bus, HT_CHAIN_END_UNITID_BASE, 0);
573 #if RAMINIT_SYSINFO == 0
579 #if RAMINIT_SYSINFO == 1
580 static void ht_setup_chain(device_t udev, unsigned upos, struct sys_info *sysinfo)
582 static int ht_setup_chain(device_t udev, unsigned upos)
585 unsigned offset_unitid = 0;
586 #if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20))
590 /* Assumption the HT chain that is bus 0 has the HT I/O Hub on it.
591 * On most boards this just happens. If a cpu has multiple
592 * non Coherent links the appropriate bus registers for the
593 * links needs to be programed to point at bus 0.
596 /* Make certain the HT bus is not enumerated */
597 ht_collapse_previous_enumeration(0, 0);
599 #if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20))
603 #if RAMINIT_SYSINFO == 1
604 ht_setup_chainx(udev, upos, 0, offset_unitid, sysinfo);
606 return ht_setup_chainx(udev, upos, 0, offset_unitid);
609 static int optimize_link_read_pointer(uint8_t node, uint8_t linkn, uint8_t linkt, uint8_t val)
611 uint32_t dword, dword_old;
614 /* This works on an Athlon64 because unimplemented links return 0 */
615 dword = pci_read_config32(PCI_DEV(0,0x18+node,0), 0x98 + (linkn * 0x20));
616 link_type = dword & 0xff;
619 if ( (link_type & 7) == linkt ) { /* Coherent Link only linkt = 3, ncoherent = 7*/
620 dword_old = dword = pci_read_config32(PCI_DEV(0,0x18+node,3), 0xdc);
621 dword &= ~( 0xff<<(linkn *8) );
622 dword |= val << (linkn *8);
624 if (dword != dword_old) {
625 pci_write_config32(PCI_DEV(0,0x18+node,3), 0xdc, dword);
633 static int optimize_link_read_pointers_chain(uint8_t ht_c_num)
640 for (i = 0; i < ht_c_num; i++) {
642 uint8_t nodeid, linkn;
647 #if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20))
648 #if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
649 if(i==0) // to check if it is sb ht chain
651 devn = HT_CHAIN_UNITID_BASE;
654 reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
656 nodeid = ((reg & 0xf0)>>4); // nodeid
657 linkn = ((reg & 0xf00)>>8); // link n
658 busn = (reg & 0xff0000)>>16; //busn
660 reg = pci_read_config32( PCI_DEV(busn, devn, 0), PCI_VENDOR_ID); // ? the chain dev maybe offseted
661 if ( (reg & 0xffff) == PCI_VENDOR_ID_AMD) {
663 } else if ( (reg & 0xffff) == PCI_VENDOR_ID_NVIDIA ) {
669 reset_needed |= optimize_link_read_pointer(nodeid, linkn, 0x07, val);
676 static int set_ht_link_buffer_count(uint8_t node, uint8_t linkn, uint8_t linkt, unsigned val)
683 /* This works on an Athlon64 because unimplemented links return 0 */
684 regpos = 0x98 + (linkn * 0x20);
685 dev = PCI_DEV(0,0x18+node,0);
686 dword = pci_read_config32(dev, regpos);
687 link_type = dword & 0xff;
689 if ( (link_type & 0x7) == linkt ) { /* Coherent Link only linkt = 3, ncoherent = 7*/
690 regpos = 0x90 + (linkn * 0x20);
691 dword = pci_read_config32(dev, regpos );
694 pci_write_config32(dev, regpos, val);
701 static int set_ht_link_buffer_counts_chain(uint8_t ht_c_num, unsigned vendorid, unsigned val)
708 for (i = 0; i < ht_c_num; i++) {
710 uint8_t nodeid, linkn;
714 reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
715 if((reg & 3) != 3) continue; // not enabled
717 nodeid = ((reg & 0xf0)>>4); // nodeid
718 linkn = ((reg & 0xf00)>>8); // link n
719 busn = (reg & 0xff0000)>>16; //busn
721 for(devn = 0; devn < 0x20; devn++) {
722 reg = pci_read_config32( PCI_DEV(busn, devn, 0), PCI_VENDOR_ID); //1?
723 if ( (reg & 0xffff) == vendorid ) {
724 reset_needed |= set_ht_link_buffer_count(nodeid, linkn, 0x07,val);
734 #if RAMINIT_SYSINFO == 1
735 static void ht_setup_chains(uint8_t ht_c_num, struct sys_info *sysinfo)
737 static int ht_setup_chains(uint8_t ht_c_num)
740 /* Assumption the HT chain that is bus 0 has the HT I/O Hub on it.
741 * On most boards this just happens. If a cpu has multiple
742 * non Coherent links the appropriate bus registers for the
743 * links needs to be programed to point at bus 0.
749 #if RAMINIT_SYSINFO == 0
750 int reset_needed = 0;
752 sysinfo->link_pair_num = 0;
755 // first one is SB Chain
756 for (i = 0; i < ht_c_num; i++) {
762 #if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1)
765 unsigned offset_unitid = 0;
767 reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
769 //We need setup 0x94, 0xb4, and 0xd4 according to the reg
770 devpos = ((reg & 0xf0)>>4)+0x18; // nodeid; it will decide 0x18 or 0x19
771 regpos = ((reg & 0xf00)>>8) * 0x20 + 0x94; // link n; it will decide 0x94 or 0xb4, 0x0xd4;
772 busn = (reg & 0xff0000)>>16;
774 dword = pci_read_config32( PCI_DEV(0, devpos, 0), regpos) ;
775 dword &= ~(0xffff<<8);
776 dword |= (reg & 0xffff0000)>>8;
777 pci_write_config32( PCI_DEV(0, devpos,0), regpos , dword);
780 #if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20))
781 #if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
782 if(i==0) // to check if it is sb ht chain
787 /* Make certain the HT bus is not enumerated */
788 ht_collapse_previous_enumeration(busn, offset_unitid);
790 upos = ((reg & 0xf00)>>8) * 0x20 + 0x80;
791 udev = PCI_DEV(0, devpos, 0);
793 #if RAMINIT_SYSINFO == 1
794 ht_setup_chainx(udev,upos,busn, offset_unitid, sysinfo); // all not
796 reset_needed |= ht_setup_chainx(udev,upos,busn, offset_unitid); //all not
799 #if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1)
800 /* You can use use this in romcc, because there is function call in romcc, recursive will kill you */
801 bus = busn; // we need 32 bit
802 #if RAMINIT_SYSINFO == 1
803 scan_pci_bus(bus, sysinfo);
805 reset_needed |= (scan_pci_bus(bus)>>16); // take out reset_needed that stored in upword
810 #if RAMINIT_SYSINFO == 0
811 reset_needed |= optimize_link_read_pointers_chain(ht_c_num);
818 #if defined (__GNUC__)
819 static inline unsigned get_nodes(void);
822 #if RAMINIT_SYSINFO == 1
823 static void ht_setup_chains_x(struct sys_info *sysinfo)
825 static int ht_setup_chains_x(void)
834 #if K8_ALLOCATE_IO_RANGE == 1
835 unsigned next_io_base;
840 /* read PCI_DEV(0,0x18,0) 0x64 bit [8:9] to find out SbLink m */
841 reg = pci_read_config32(PCI_DEV(0, 0x18, 0), 0x64);
842 /* update PCI_DEV(0, 0x18, 1) 0xe0 to 0x05000m03, and next_busn=0x3f+1 */
843 print_linkn_in("SBLink=", ((reg>>8) & 3) );
844 #if RAMINIT_SYSINFO == 1
845 sysinfo->sblk = (reg>>8) & 3;
847 sysinfo->nodes = nodes;
849 tempreg = 3 | ( 0<<4) | (((reg>>8) & 3)<<8) | (0<<16)| (0x3f<<24);
850 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0, tempreg);
852 next_busn=0x3f+1; /* 0 will be used ht chain with SB we need to keep SB in bus0 in auto stage*/
854 #if K8_ALLOCATE_IO_RANGE == 1
855 /* io range allocation */
856 tempreg = 0 | (((reg>>8) & 0x3) << 4 )| (0x3<<12); //limit
857 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC4, tempreg);
858 tempreg = 3 | ( 3<<4) | (0<<12); //base
859 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC0, tempreg);
860 next_io_base = 0x3+0x1;
864 for(ht_c_num=1;ht_c_num<4; ht_c_num++) {
865 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4, 0);
867 #if K8_ALLOCATE_IO_RANGE == 1
868 /* io range allocation */
869 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xc4 + ht_c_num * 8, 0);
870 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xc0 + ht_c_num * 8, 0);
874 for(nodeid=0; nodeid<nodes; nodeid++) {
877 dev = PCI_DEV(0, 0x18+nodeid,0);
878 for(linkn = 0; linkn<3; linkn++) {
880 regpos = 0x98 + 0x20 * linkn;
881 reg = pci_read_config32(dev, regpos);
882 if ((reg & 0x17) != 7) continue; /* it is not non conherent or not connected*/
883 print_linkn_in("NC node|link=", ((nodeid & 0xf)<<4)|(linkn & 0xf));
884 tempreg = 3 | (nodeid <<4) | (linkn<<8);
885 /*compare (temp & 0xffff), with (PCI(0, 0x18, 1) 0xe0 to 0xec & 0xfffff) */
886 for(ht_c_num=0;ht_c_num<4; ht_c_num++) {
887 reg = pci_read_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4);
888 if(((reg & 0xffff) == (tempreg & 0xffff)) || ((reg & 0xffff) == 0x0000)) { /*we got it*/
892 if(ht_c_num == 4) break; /*used up only 4 non conherent allowed*/
893 /*update to 0xe0...*/
894 if((reg & 0xf) == 3) continue; /*SbLink so don't touch it */
895 print_linkn_in("\tbusn=", next_busn);
896 tempreg |= (next_busn<<16)|((next_busn+0x3f)<<24);
897 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4, tempreg);
900 #if K8_ALLOCATE_IO_RANGE == 1
901 /* io range allocation */
902 tempreg = nodeid | (linkn<<4) | ((next_io_base+0x3)<<12); //limit
903 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC4 + ht_c_num * 8, tempreg);
904 tempreg = 3 /*| ( 3<<4)*/ | (next_io_base<<12); //base :ISA and VGA ?
905 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC0 + ht_c_num * 8, tempreg);
906 next_io_base += 0x3+0x1;
911 /*update 0xe0, 0xe4, 0xe8, 0xec from PCI_DEV(0, 0x18,1) to PCI_DEV(0, 0x19,1) to PCI_DEV(0, 0x1f,1);*/
913 for(nodeid = 1; nodeid<nodes; nodeid++) {
916 dev = PCI_DEV(0, 0x18+nodeid,1);
917 for(i = 0; i< 4; i++) {
919 regpos = 0xe0 + i * 4;
920 reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos);
921 pci_write_config32(dev, regpos, reg);
924 #if K8_ALLOCATE_IO_RANGE == 1
925 /* io range allocation */
926 for(i = 0; i< 4; i++) {
928 regpos = 0xc4 + i * 8;
929 reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos);
930 pci_write_config32(dev, regpos, reg);
932 for(i = 0; i< 4; i++) {
934 regpos = 0xc0 + i * 8;
935 reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos);
936 pci_write_config32(dev, regpos, reg);
941 /* recount ht_c_num*/
943 for(ht_c_num=0;ht_c_num<4; ht_c_num++) {
944 reg = pci_read_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4);
945 if(((reg & 0xf) != 0x0)) {
950 #if RAMINIT_SYSINFO == 1
951 sysinfo->ht_c_num = i;
952 ht_setup_chains(i, sysinfo);
953 sysinfo->sbdn = get_sbdn(sysinfo->sbbusn);
955 return ht_setup_chains(i);
960 #if RAMINIT_SYSINFO == 1
961 static int optimize_link_incoherent_ht(struct sys_info *sysinfo)
963 // We need to use recorded link pair info to optimize the link
965 int reset_needed = 0;
967 unsigned link_pair_num = sysinfo->link_pair_num;
969 for(i=0; i< link_pair_num; i++) {
970 struct link_pair_st *link_pair= &sysinfo->link_pair[i];
971 reset_needed |= ht_optimize_link(link_pair->udev, link_pair->upos, link_pair->uoffs, link_pair->dev, link_pair->pos, link_pair->offs);
974 reset_needed |= optimize_link_read_pointers_chain(sysinfo->ht_c_num);