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);
165 static uint8_t ht_read_width_cap(device_t dev, uint8_t pos)
167 uint8_t width_cap = pci_read_config8(dev, pos);
171 id = pci_read_config32(dev, 0);
173 /* netlogic micro cap doesn't support 16 bit yet */
174 if (id == (0x184e | (0x0001 << 16))) {
175 if((width_cap & 0x77) == 0x11) {
183 #define LINK_OFFS(CTRL, WIDTH,FREQ,FREQ_CAP) \
184 (((CTRL & 0xff) << 24) | ((WIDTH & 0xff) << 16) | ((FREQ & 0xff) << 8) | (FREQ_CAP & 0xFF))
186 #define LINK_CTRL(OFFS) ((OFFS >> 24) & 0xFF)
187 #define LINK_WIDTH(OFFS) ((OFFS >> 16) & 0xFF)
188 #define LINK_FREQ(OFFS) ((OFFS >> 8) & 0xFF)
189 #define LINK_FREQ_CAP(OFFS) ((OFFS) & 0xFF)
191 #define PCI_HT_HOST_OFFS LINK_OFFS( \
192 PCI_HT_CAP_HOST_CTRL, \
193 PCI_HT_CAP_HOST_WIDTH, \
194 PCI_HT_CAP_HOST_FREQ, \
195 PCI_HT_CAP_HOST_FREQ_CAP)
197 #define PCI_HT_SLAVE0_OFFS LINK_OFFS( \
198 PCI_HT_CAP_SLAVE_CTRL0, \
199 PCI_HT_CAP_SLAVE_WIDTH0, \
200 PCI_HT_CAP_SLAVE_FREQ0, \
201 PCI_HT_CAP_SLAVE_FREQ_CAP0)
203 #define PCI_HT_SLAVE1_OFFS LINK_OFFS( \
204 PCI_HT_CAP_SLAVE_CTRL1, \
205 PCI_HT_CAP_SLAVE_WIDTH1, \
206 PCI_HT_CAP_SLAVE_FREQ1, \
207 PCI_HT_CAP_SLAVE_FREQ_CAP1)
209 static int ht_optimize_link(
210 device_t dev1, uint8_t pos1, unsigned offs1,
211 device_t dev2, uint8_t pos2, unsigned offs2)
213 static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
214 static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
215 uint16_t freq_cap1, freq_cap2;
216 uint8_t width_cap1, width_cap2, width, old_width, ln_width1, ln_width2;
217 uint8_t freq, old_freq;
219 /* Set link width and frequency */
221 /* Initially assume everything is already optimized and I don't need a reset */
224 /* Get the frequency capabilities */
225 freq_cap1 = ht_read_freq_cap(dev1, pos1 + LINK_FREQ_CAP(offs1));
226 freq_cap2 = ht_read_freq_cap(dev2, pos2 + LINK_FREQ_CAP(offs2));
228 /* Calculate the highest possible frequency */
229 freq = log2(freq_cap1 & freq_cap2);
231 /* See if I am changing the link freqency */
232 old_freq = pci_read_config8(dev1, pos1 + LINK_FREQ(offs1));
234 needs_reset |= old_freq != freq;
235 old_freq = pci_read_config8(dev2, pos2 + LINK_FREQ(offs2));
237 needs_reset |= old_freq != freq;
239 /* Set the Calulcated link frequency */
240 pci_write_config8(dev1, pos1 + LINK_FREQ(offs1), freq);
241 pci_write_config8(dev2, pos2 + LINK_FREQ(offs2), freq);
243 /* Get the width capabilities */
244 width_cap1 = ht_read_width_cap(dev1, pos1 + LINK_WIDTH(offs1));
245 width_cap2 = ht_read_width_cap(dev2, pos2 + LINK_WIDTH(offs2));
247 /* Calculate dev1's input width */
248 ln_width1 = link_width_to_pow2[width_cap1 & 7];
249 ln_width2 = link_width_to_pow2[(width_cap2 >> 4) & 7];
250 if (ln_width1 > ln_width2) {
251 ln_width1 = ln_width2;
253 width = pow2_to_link_width[ln_width1];
254 /* Calculate dev1's output width */
255 ln_width1 = link_width_to_pow2[(width_cap1 >> 4) & 7];
256 ln_width2 = link_width_to_pow2[width_cap2 & 7];
257 if (ln_width1 > ln_width2) {
258 ln_width1 = ln_width2;
260 width |= pow2_to_link_width[ln_width1] << 4;
262 /* See if I am changing dev1's width */
263 old_width = pci_read_config8(dev1, pos1 + LINK_WIDTH(offs1) + 1);
265 needs_reset |= old_width != width;
267 /* Set dev1's widths */
268 pci_write_config8(dev1, pos1 + LINK_WIDTH(offs1) + 1, width);
270 /* Calculate dev2's width */
271 width = ((width & 0x70) >> 4) | ((width & 0x7) << 4);
273 /* See if I am changing dev2's width */
274 old_width = pci_read_config8(dev2, pos2 + LINK_WIDTH(offs2) + 1);
276 needs_reset |= old_width != width;
278 /* Set dev2's widths */
279 pci_write_config8(dev2, pos2 + LINK_WIDTH(offs2) + 1, width);
283 #if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1)
285 #if RAMINIT_SYSINFO == 1
286 static void ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned offset_unitid, struct sys_info *sysinfo);
287 static int scan_pci_bus( unsigned bus , struct sys_info *sysinfo)
289 static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned offset_unitid);
290 static int scan_pci_bus( unsigned bus)
294 here we already can access PCI_DEV(bus, 0, 0) to PCI_DEV(bus, 0x1f, 0x7)
295 So We can scan these devices to find out if they are bridge
296 If it is pci bridge, We need to set busn in bridge, and go on
297 For ht bridge, We need to set the busn in bridge and ht_setup_chainx, and the scan_pci_bus
303 new_bus = (bus & 0xff); // mask out the reset_needed
307 } else if (new_bus<0x80) {
309 } else if (new_bus<0xc0) {
317 for (devfn = 0; devfn <= 0xff; devfn++) {
323 dev = PCI_DEV((bus & 0xff), ((devfn>>3) & 0x1f), (devfn & 0x7));
324 hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
325 class = pci_read_config16(dev, PCI_CLASS_DEVICE);
327 switch(hdr_type & 0x7f) { /* header type */
328 case PCI_HEADER_TYPE_BRIDGE:
329 if (class != PCI_CLASS_BRIDGE_PCI) goto bad;
330 /* set the bus range dev */
332 /* Clear all status bits and turn off memory, I/O and master enables. */
333 cr = pci_read_config16(dev, PCI_COMMAND);
334 pci_write_config16(dev, PCI_COMMAND, 0x0000);
335 pci_write_config16(dev, PCI_STATUS, 0xffff);
337 buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
341 buses |= (((unsigned int) (bus & 0xff) << 0) |
342 ((unsigned int) (new_bus & 0xff) << 8) |
343 ((unsigned int) max_bus << 16));
344 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
346 /* here we need to figure out if dev is a ht bridge
347 if it is ht bridge, we need to call ht_setup_chainx at first
348 Not verified --- yhlu
351 upos = ht_lookup_host_capability(dev); // one func one ht sub
352 if (upos) { // sub ht chain
354 busn = (new_bus & 0xff);
355 /* Make certain the HT bus is not enumerated */
356 ht_collapse_previous_enumeration(busn, 0);
357 /* scan the ht chain */
358 #if RAMINIT_SYSINFO == 1
359 ht_setup_chainx(dev,upos,busn, 0, sysinfo); // don't need offset unitid
361 new_bus |= (ht_setup_chainx(dev, upos, busn, 0)<<16); // store reset_needed to upword
365 #if RAMINIT_SYSINFO == 1
366 new_bus = scan_pci_bus(new_bus, sysinfo);
368 new_bus = scan_pci_bus(new_bus);
370 /* set real max bus num in that */
372 buses = (buses & 0xff00ffff) |
373 ((unsigned int) (new_bus & 0xff) << 16);
374 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
376 pci_write_config16(dev, PCI_COMMAND, cr);
384 /* if this is not a multi function device,
385 * or the device is not present don't waste
386 * time probing another function.
387 * Skip to next device.
389 if ( ((devfn & 0x07) == 0x00) && ((hdr_type & 0x80) != 0x80))
399 #if RAMINIT_SYSINFO == 1
400 static void ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned offset_unitid, struct sys_info *sysinfo)
402 static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned offset_unitid)
405 //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
407 uint8_t next_unitid, last_unitid;
410 #if RAMINIT_SYSINFO == 0
411 int reset_needed = 0;
414 #if HT_CHAIN_END_UNITID_BASE != 0x20
415 //let't record the device of last ht device, So we can set the Unitid to HT_CHAIN_END_UNITID_BASE
416 unsigned real_last_unitid;
417 uint8_t real_last_pos;
419 uint8_t end_used = 0;
422 uoffs = PCI_HT_HOST_OFFS;
423 next_unitid = (offset_unitid) ? HT_CHAIN_UNITID_BASE:1;
428 uint16_t flags, ctrl;
432 /* Wait until the link initialization is complete */
434 ctrl = pci_read_config16(udev, upos + LINK_CTRL(uoffs));
435 /* Is this the end of the hypertransport chain? */
436 if (ctrl & (1 << 6)) {
440 if (ctrl & ((1 << 4) | (1 << 8))) {
442 * Either the link has failed, or we have
444 * Sometimes this can happen due to link
445 * retrain, so lets knock it down and see
448 ctrl |= ((1 << 4) | (1 <<8)); // Link fail + Crc
449 pci_write_config16(udev, upos + LINK_CTRL(uoffs), ctrl);
450 ctrl = pci_read_config16(udev, upos + LINK_CTRL(uoffs));
451 if (ctrl & ((1 << 4) | (1 << 8))) {
452 print_err("Detected error on Hypertransport Link\n");
456 } while((ctrl & (1 << 5)) == 0);
458 device_t dev = PCI_DEV(bus, 0, 0);
459 last_unitid = next_unitid;
461 id = pci_read_config32(dev, PCI_VENDOR_ID);
463 /* If the chain is enumerated quit */
464 if ( (id == 0xffffffff) || (id == 0x00000000) ||
465 (id == 0x0000ffff) || (id == 0xffff0000))
470 pos = ht_lookup_slave_capability(dev);
472 print_err("udev="); print_err_hex32(udev);
473 print_err("\tupos="); print_err_hex32(upos);
474 print_err("\tuoffs="); print_err_hex32(uoffs);
475 print_err("\tHT link capability not found\r\n");
480 #if HT_CHAIN_END_UNITID_BASE != 0x20
482 if(next_unitid>= (bus ? 0x20:0x18) ) {
484 next_unitid = HT_CHAIN_END_UNITID_BASE;
492 real_last_unitid = next_unitid;
496 /* Update the Unitid of the current device */
497 flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
498 flags &= ~0x1f; /* mask out the base Unit ID */
499 flags |= next_unitid & 0x1f;
500 pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
502 /* Compute the number of unitids consumed */
503 count = (flags >> 5) & 0x1f;
505 /* Note the change in device number */
506 dev = PCI_DEV(bus, next_unitid, 0);
508 next_unitid += count;
510 /* Find which side of the ht link we are on,
511 * by reading which direction our last write to PCI_CAP_FLAGS
514 flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
515 offs = ((flags>>10) & 1) ? PCI_HT_SLAVE1_OFFS : PCI_HT_SLAVE0_OFFS;
517 #if RAMINIT_SYSINFO == 1
518 /* store the link pair here and we will Setup the Hypertransport link later, after we get final FID/VID */
520 struct link_pair_st *link_pair = &sysinfo->link_pair[sysinfo->link_pair_num];
521 link_pair->udev = udev;
522 link_pair->upos = upos;
523 link_pair->uoffs = uoffs;
524 link_pair->dev = dev;
525 link_pair->pos = pos;
526 link_pair->offs = offs;
527 sysinfo->link_pair_num++;
530 reset_needed |= ht_optimize_link(udev, upos, uoffs, dev, pos, offs);
533 /* Remeber the location of the last device */
536 uoffs = ( offs != PCI_HT_SLAVE0_OFFS ) ? PCI_HT_SLAVE0_OFFS : PCI_HT_SLAVE1_OFFS;
538 } while (last_unitid != next_unitid );
543 #if HT_CHAIN_END_UNITID_BASE != 0x20
544 if(offset_unitid && (ht_dev_num>1) && (real_last_unitid != HT_CHAIN_END_UNITID_BASE) && !end_used ) {
547 flags = pci_read_config16(PCI_DEV(bus,real_last_unitid,0), real_last_pos + PCI_CAP_FLAGS);
549 flags |= HT_CHAIN_END_UNITID_BASE & 0x1f;
550 pci_write_config16(PCI_DEV(bus, real_last_unitid, 0), real_last_pos + PCI_CAP_FLAGS, flags);
552 #if RAMINIT_SYSINFO == 1
553 // Here need to change the dev in the array
554 for(i=0;i<sysinfo->link_pair_num;i++)
556 struct link_pair_st *link_pair = &sysinfo->link_pair[i];
557 if(link_pair->udev == PCI_DEV(bus, real_last_unitid, 0)) {
558 link_pair->udev = PCI_DEV(bus, HT_CHAIN_END_UNITID_BASE, 0);
561 if(link_pair->dev == PCI_DEV(bus, real_last_unitid, 0)) {
562 link_pair->dev = PCI_DEV(bus, HT_CHAIN_END_UNITID_BASE, 0);
570 #if RAMINIT_SYSINFO == 0
576 #if RAMINIT_SYSINFO == 1
577 static void ht_setup_chain(device_t udev, unsigned upos, struct sys_info *sysinfo)
579 static int ht_setup_chain(device_t udev, unsigned upos)
582 unsigned offset_unitid = 0;
583 #if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20))
587 /* Assumption the HT chain that is bus 0 has the HT I/O Hub on it.
588 * On most boards this just happens. If a cpu has multiple
589 * non Coherent links the appropriate bus registers for the
590 * links needs to be programed to point at bus 0.
593 /* Make certain the HT bus is not enumerated */
594 ht_collapse_previous_enumeration(0, 0);
596 #if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20))
600 #if RAMINIT_SYSINFO == 1
601 ht_setup_chainx(udev, upos, 0, offset_unitid, sysinfo);
603 return ht_setup_chainx(udev, upos, 0, offset_unitid);
606 static int optimize_link_read_pointer(uint8_t node, uint8_t linkn, uint8_t linkt, uint8_t val)
608 uint32_t dword, dword_old;
611 /* This works on an Athlon64 because unimplemented links return 0 */
612 dword = pci_read_config32(PCI_DEV(0,0x18+node,0), 0x98 + (linkn * 0x20));
613 link_type = dword & 0xff;
616 if ( (link_type & 7) == linkt ) { /* Coherent Link only linkt = 3, ncoherent = 7*/
617 dword_old = dword = pci_read_config32(PCI_DEV(0,0x18+node,3), 0xdc);
618 dword &= ~( 0xff<<(linkn *8) );
619 dword |= val << (linkn *8);
621 if (dword != dword_old) {
622 pci_write_config32(PCI_DEV(0,0x18+node,3), 0xdc, dword);
630 static int optimize_link_read_pointers_chain(uint8_t ht_c_num)
637 for (i = 0; i < ht_c_num; i++) {
639 uint8_t nodeid, linkn;
644 #if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20))
645 #if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
646 if(i==0) // to check if it is sb ht chain
648 devn = HT_CHAIN_UNITID_BASE;
651 reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
653 nodeid = ((reg & 0xf0)>>4); // nodeid
654 linkn = ((reg & 0xf00)>>8); // link n
655 busn = (reg & 0xff0000)>>16; //busn
657 reg = pci_read_config32( PCI_DEV(busn, devn, 0), PCI_VENDOR_ID); // ? the chain dev maybe offseted
658 if ( (reg & 0xffff) == PCI_VENDOR_ID_AMD) {
660 } else if ( (reg & 0xffff) == PCI_VENDOR_ID_NVIDIA ) {
666 reset_needed |= optimize_link_read_pointer(nodeid, linkn, 0x07, val);
673 static int set_ht_link_buffer_count(uint8_t node, uint8_t linkn, uint8_t linkt, unsigned val)
680 /* This works on an Athlon64 because unimplemented links return 0 */
681 regpos = 0x98 + (linkn * 0x20);
682 dev = PCI_DEV(0,0x18+node,0);
683 dword = pci_read_config32(dev, regpos);
684 link_type = dword & 0xff;
686 if ( (link_type & 0x7) == linkt ) { /* Coherent Link only linkt = 3, ncoherent = 7*/
687 regpos = 0x90 + (linkn * 0x20);
688 dword = pci_read_config32(dev, regpos );
691 pci_write_config32(dev, regpos, val);
698 static int set_ht_link_buffer_counts_chain(uint8_t ht_c_num, unsigned vendorid, unsigned val)
705 for (i = 0; i < ht_c_num; i++) {
707 uint8_t nodeid, linkn;
711 reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
712 if((reg & 3) != 3) continue; // not enabled
714 nodeid = ((reg & 0xf0)>>4); // nodeid
715 linkn = ((reg & 0xf00)>>8); // link n
716 busn = (reg & 0xff0000)>>16; //busn
718 for(devn = 0; devn < 0x20; devn++) {
719 reg = pci_read_config32( PCI_DEV(busn, devn, 0), PCI_VENDOR_ID); //1?
720 if ( (reg & 0xffff) == vendorid ) {
721 reset_needed |= set_ht_link_buffer_count(nodeid, linkn, 0x07,val);
731 #if RAMINIT_SYSINFO == 1
732 static void ht_setup_chains(uint8_t ht_c_num, struct sys_info *sysinfo)
734 static int ht_setup_chains(uint8_t ht_c_num)
737 /* Assumption the HT chain that is bus 0 has the HT I/O Hub on it.
738 * On most boards this just happens. If a cpu has multiple
739 * non Coherent links the appropriate bus registers for the
740 * links needs to be programed to point at bus 0.
746 #if RAMINIT_SYSINFO == 0
747 int reset_needed = 0;
749 sysinfo->link_pair_num = 0;
752 // first one is SB Chain
753 for (i = 0; i < ht_c_num; i++) {
759 #if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1)
762 unsigned offset_unitid = 0;
764 reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
766 //We need setup 0x94, 0xb4, and 0xd4 according to the reg
767 devpos = ((reg & 0xf0)>>4)+0x18; // nodeid; it will decide 0x18 or 0x19
768 regpos = ((reg & 0xf00)>>8) * 0x20 + 0x94; // link n; it will decide 0x94 or 0xb4, 0x0xd4;
769 busn = (reg & 0xff0000)>>16;
771 dword = pci_read_config32( PCI_DEV(0, devpos, 0), regpos) ;
772 dword &= ~(0xffff<<8);
773 dword |= (reg & 0xffff0000)>>8;
774 pci_write_config32( PCI_DEV(0, devpos,0), regpos , dword);
777 #if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20))
778 #if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
779 if(i==0) // to check if it is sb ht chain
784 /* Make certain the HT bus is not enumerated */
785 ht_collapse_previous_enumeration(busn, offset_unitid);
787 upos = ((reg & 0xf00)>>8) * 0x20 + 0x80;
788 udev = PCI_DEV(0, devpos, 0);
790 #if RAMINIT_SYSINFO == 1
791 ht_setup_chainx(udev,upos,busn, offset_unitid, sysinfo); // all not
793 reset_needed |= ht_setup_chainx(udev,upos,busn, offset_unitid); //all not
796 #if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1)
797 /* You can use use this in romcc, because there is function call in romcc, recursive will kill you */
798 bus = busn; // we need 32 bit
799 #if RAMINIT_SYSINFO == 1
800 scan_pci_bus(bus, sysinfo);
802 reset_needed |= (scan_pci_bus(bus)>>16); // take out reset_needed that stored in upword
807 #if RAMINIT_SYSINFO == 0
808 reset_needed |= optimize_link_read_pointers_chain(ht_c_num);
815 #if defined (__GNUC__)
816 static inline unsigned get_nodes(void);
819 #if RAMINIT_SYSINFO == 1
820 static void ht_setup_chains_x(struct sys_info *sysinfo)
822 static int ht_setup_chains_x(void)
831 #if K8_ALLOCATE_IO_RANGE == 1
832 unsigned next_io_base;
837 /* read PCI_DEV(0,0x18,0) 0x64 bit [8:9] to find out SbLink m */
838 reg = pci_read_config32(PCI_DEV(0, 0x18, 0), 0x64);
839 /* update PCI_DEV(0, 0x18, 1) 0xe0 to 0x05000m03, and next_busn=0x3f+1 */
840 print_linkn_in("SBLink=", ((reg>>8) & 3) );
841 #if RAMINIT_SYSINFO == 1
842 sysinfo->sblk = (reg>>8) & 3;
844 sysinfo->nodes = nodes;
846 tempreg = 3 | ( 0<<4) | (((reg>>8) & 3)<<8) | (0<<16)| (0x3f<<24);
847 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0, tempreg);
849 next_busn=0x3f+1; /* 0 will be used ht chain with SB we need to keep SB in bus0 in auto stage*/
851 #if K8_ALLOCATE_IO_RANGE == 1
852 /* io range allocation */
853 tempreg = 0 | (((reg>>8) & 0x3) << 4 )| (0x3<<12); //limit
854 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC4, tempreg);
855 tempreg = 3 | ( 3<<4) | (0<<12); //base
856 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC0, tempreg);
857 next_io_base = 0x3+0x1;
861 for(ht_c_num=1;ht_c_num<4; ht_c_num++) {
862 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4, 0);
864 #if K8_ALLOCATE_IO_RANGE == 1
865 /* io range allocation */
866 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xc4 + ht_c_num * 8, 0);
867 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xc0 + ht_c_num * 8, 0);
871 for(nodeid=0; nodeid<nodes; nodeid++) {
874 dev = PCI_DEV(0, 0x18+nodeid,0);
875 for(linkn = 0; linkn<3; linkn++) {
877 regpos = 0x98 + 0x20 * linkn;
878 reg = pci_read_config32(dev, regpos);
879 if ((reg & 0x17) != 7) continue; /* it is not non conherent or not connected*/
880 print_linkn_in("NC node|link=", ((nodeid & 0xf)<<4)|(linkn & 0xf));
881 tempreg = 3 | (nodeid <<4) | (linkn<<8);
882 /*compare (temp & 0xffff), with (PCI(0, 0x18, 1) 0xe0 to 0xec & 0xfffff) */
883 for(ht_c_num=0;ht_c_num<4; ht_c_num++) {
884 reg = pci_read_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4);
885 if(((reg & 0xffff) == (tempreg & 0xffff)) || ((reg & 0xffff) == 0x0000)) { /*we got it*/
889 if(ht_c_num == 4) break; /*used up only 4 non conherent allowed*/
890 /*update to 0xe0...*/
891 if((reg & 0xf) == 3) continue; /*SbLink so don't touch it */
892 print_linkn_in("\tbusn=", next_busn);
893 tempreg |= (next_busn<<16)|((next_busn+0x3f)<<24);
894 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4, tempreg);
897 #if K8_ALLOCATE_IO_RANGE == 1
898 /* io range allocation */
899 tempreg = nodeid | (linkn<<4) | ((next_io_base+0x3)<<12); //limit
900 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC4 + ht_c_num * 8, tempreg);
901 tempreg = 3 /*| ( 3<<4)*/ | (next_io_base<<12); //base :ISA and VGA ?
902 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC0 + ht_c_num * 8, tempreg);
903 next_io_base += 0x3+0x1;
908 /*update 0xe0, 0xe4, 0xe8, 0xec from PCI_DEV(0, 0x18,1) to PCI_DEV(0, 0x19,1) to PCI_DEV(0, 0x1f,1);*/
910 for(nodeid = 1; nodeid<nodes; nodeid++) {
913 dev = PCI_DEV(0, 0x18+nodeid,1);
914 for(i = 0; i< 4; i++) {
916 regpos = 0xe0 + i * 4;
917 reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos);
918 pci_write_config32(dev, regpos, reg);
921 #if K8_ALLOCATE_IO_RANGE == 1
922 /* io range allocation */
923 for(i = 0; i< 4; i++) {
925 regpos = 0xc4 + i * 8;
926 reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos);
927 pci_write_config32(dev, regpos, reg);
929 for(i = 0; i< 4; i++) {
931 regpos = 0xc0 + i * 8;
932 reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos);
933 pci_write_config32(dev, regpos, reg);
938 /* recount ht_c_num*/
940 for(ht_c_num=0;ht_c_num<4; ht_c_num++) {
941 reg = pci_read_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4);
942 if(((reg & 0xf) != 0x0)) {
947 #if RAMINIT_SYSINFO == 1
948 sysinfo->ht_c_num = i;
949 ht_setup_chains(i, sysinfo);
950 sysinfo->sbdn = get_sbdn(sysinfo->sbbusn);
952 return ht_setup_chains(i);
957 #if RAMINIT_SYSINFO == 1
958 static int optimize_link_incoherent_ht(struct sys_info *sysinfo)
960 // We need to use recorded link pair info to optimize the link
962 int reset_needed = 0;
964 unsigned link_pair_num = sysinfo->link_pair_num;
966 for(i=0; i< link_pair_num; i++) {
967 struct link_pair_st *link_pair= &sysinfo->link_pair[i];
968 reset_needed |= ht_optimize_link(link_pair->udev, link_pair->upos, link_pair->uoffs, link_pair->dev, link_pair->pos, link_pair->offs);
971 reset_needed |= optimize_link_read_pointers_chain(sysinfo->ht_c_num);