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 #if CONFIG_USE_PRINTK_IN_CAR == 0
28 #error This file needs CONFIG_USE_PRINTK_IN_CAR
31 static inline void print_linkn_in (const char *strval, uint8_t byteval)
33 printk_debug("%s%02x\r\n", strval, byteval);
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 printk_spew("pos=0x%x, unfiltered freq_cap=0x%x\r\n", pos, freq_cap);
135 freq_cap &= ~(1 << HT_FREQ_VENDOR); /* Ignore Vendor HT frequencies */
137 id = pci_read_config32(dev, 0);
139 /* AMD 8131 Errata 48 */
140 if (id == (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_AMD_8131_PCIX << 16))) {
141 freq_cap &= ~(1 << HT_FREQ_800Mhz);
145 /* AMD 8151 Errata 23 */
146 if (id == (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_AMD_8151_SYSCTRL << 16))) {
147 freq_cap &= ~(1 << HT_FREQ_800Mhz);
151 /* AMD K8 Unsupported 1Ghz? */
152 if (id == (PCI_VENDOR_ID_AMD | (0x1100 << 16))) {
153 #if K8_HT_FREQ_1G_SUPPORT == 1
154 #if K8_REV_F_SUPPORT == 0
155 if (is_cpu_pre_e0()) { // only E0 later support 1GHz
156 freq_cap &= ~(1 << HT_FREQ_1000Mhz);
160 freq_cap &= ~(1 << HT_FREQ_1000Mhz);
164 printk_spew("pos=0x%x, filtered freq_cap=0x%x\r\n", pos, freq_cap);
165 //printk_spew("capping to 800/600/400/200 MHz\r\n");
170 static uint8_t ht_read_width_cap(device_t dev, uint8_t pos)
172 uint8_t width_cap = pci_read_config8(dev, pos);
176 id = pci_read_config32(dev, 0);
178 /* netlogic micro cap doesn't support 16 bit yet */
179 if (id == (0x184e | (0x0001 << 16))) {
180 if((width_cap & 0x77) == 0x11) {
189 #define LINK_OFFS(CTRL, WIDTH,FREQ,FREQ_CAP) \
190 (((CTRL & 0xff) << 24) | ((WIDTH & 0xff) << 16) | ((FREQ & 0xff) << 8) | (FREQ_CAP & 0xFF))
192 #define LINK_CTRL(OFFS) ((OFFS >> 24) & 0xFF)
193 #define LINK_WIDTH(OFFS) ((OFFS >> 16) & 0xFF)
194 #define LINK_FREQ(OFFS) ((OFFS >> 8) & 0xFF)
195 #define LINK_FREQ_CAP(OFFS) ((OFFS) & 0xFF)
197 #define PCI_HT_HOST_OFFS LINK_OFFS( \
198 PCI_HT_CAP_HOST_CTRL, \
199 PCI_HT_CAP_HOST_WIDTH, \
200 PCI_HT_CAP_HOST_FREQ, \
201 PCI_HT_CAP_HOST_FREQ_CAP)
203 #define PCI_HT_SLAVE0_OFFS LINK_OFFS( \
204 PCI_HT_CAP_SLAVE_CTRL0, \
205 PCI_HT_CAP_SLAVE_WIDTH0, \
206 PCI_HT_CAP_SLAVE_FREQ0, \
207 PCI_HT_CAP_SLAVE_FREQ_CAP0)
209 #define PCI_HT_SLAVE1_OFFS LINK_OFFS( \
210 PCI_HT_CAP_SLAVE_CTRL1, \
211 PCI_HT_CAP_SLAVE_WIDTH1, \
212 PCI_HT_CAP_SLAVE_FREQ1, \
213 PCI_HT_CAP_SLAVE_FREQ_CAP1)
215 static int ht_optimize_link(
216 device_t dev1, uint8_t pos1, unsigned offs1,
217 device_t dev2, uint8_t pos2, unsigned offs2)
219 static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
220 static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
221 uint16_t freq_cap1, freq_cap2;
222 uint8_t width_cap1, width_cap2, width, old_width, ln_width1, ln_width2;
223 uint8_t freq, old_freq;
225 /* Set link width and frequency */
227 printk_spew("entering ht_optimize_link\r\n");
228 /* Initially assume everything is already optimized and I don't need a reset */
231 /* Get the frequency capabilities */
232 freq_cap1 = ht_read_freq_cap(dev1, pos1 + LINK_FREQ_CAP(offs1));
233 freq_cap2 = ht_read_freq_cap(dev2, pos2 + LINK_FREQ_CAP(offs2));
234 printk_spew("freq_cap1=0x%x, freq_cap2=0x%x\r\n", freq_cap1, freq_cap2);
236 /* Calculate the highest possible frequency */
237 freq = log2(freq_cap1 & freq_cap2);
239 /* See if I am changing the link freqency */
240 old_freq = pci_read_config8(dev1, pos1 + LINK_FREQ(offs1));
242 needs_reset |= old_freq != freq;
243 printk_spew("dev1 old_freq=0x%x, freq=0x%x, needs_reset=0x%0x\r\n", old_freq, freq, needs_reset);
244 old_freq = pci_read_config8(dev2, pos2 + LINK_FREQ(offs2));
246 needs_reset |= old_freq != freq;
247 printk_spew("dev2 old_freq=0x%x, freq=0x%x, needs_reset=0x%0x\r\n", old_freq, freq, needs_reset);
249 /* Set the Calculated link frequency */
250 pci_write_config8(dev1, pos1 + LINK_FREQ(offs1), freq);
251 pci_write_config8(dev2, pos2 + LINK_FREQ(offs2), freq);
253 /* Get the width capabilities */
254 width_cap1 = ht_read_width_cap(dev1, pos1 + LINK_WIDTH(offs1));
255 width_cap2 = ht_read_width_cap(dev2, pos2 + LINK_WIDTH(offs2));
256 printk_spew("width_cap1=0x%x, width_cap2=0x%x\r\n", width_cap1, width_cap2);
258 /* Calculate dev1's input width */
259 ln_width1 = link_width_to_pow2[width_cap1 & 7];
260 ln_width2 = link_width_to_pow2[(width_cap2 >> 4) & 7];
261 printk_spew("dev1 input ln_width1=0x%x, ln_width2=0x%x\r\n", ln_width1, ln_width2);
262 if (ln_width1 > ln_width2) {
263 ln_width1 = ln_width2;
265 width = pow2_to_link_width[ln_width1];
266 printk_spew("dev1 input width=0x%x\r\n", width);
267 /* Calculate dev1's output width */
268 ln_width1 = link_width_to_pow2[(width_cap1 >> 4) & 7];
269 ln_width2 = link_width_to_pow2[width_cap2 & 7];
270 printk_spew("dev1 output ln_width1=0x%x, ln_width2=0x%x\r\n", ln_width1, ln_width2);
271 if (ln_width1 > ln_width2) {
272 ln_width1 = ln_width2;
274 width |= pow2_to_link_width[ln_width1] << 4;
275 printk_spew("dev1 input|output width=0x%x\r\n", width);
277 /* See if I am changing dev1's width */
278 old_width = pci_read_config8(dev1, pos1 + LINK_WIDTH(offs1) + 1);
280 needs_reset |= old_width != width;
281 printk_spew("old dev1 input|output width=0x%x\r\n", width);
283 /* Set dev1's widths */
284 pci_write_config8(dev1, pos1 + LINK_WIDTH(offs1) + 1, width);
286 /* Calculate dev2's width */
287 width = ((width & 0x70) >> 4) | ((width & 0x7) << 4);
288 printk_spew("dev2 input|output width=0x%x\r\n", width);
290 /* See if I am changing dev2's width */
291 old_width = pci_read_config8(dev2, pos2 + LINK_WIDTH(offs2) + 1);
293 needs_reset |= old_width != width;
294 printk_spew("old dev2 input|output width=0x%x\r\n", width);
296 /* Set dev2's widths */
297 pci_write_config8(dev2, pos2 + LINK_WIDTH(offs2) + 1, width);
302 #if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1)
304 #if RAMINIT_SYSINFO == 1
305 static void ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned offset_unitid, struct sys_info *sysinfo);
306 static int scan_pci_bus( unsigned bus , struct sys_info *sysinfo)
308 static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned offset_unitid);
309 static int scan_pci_bus( unsigned bus)
313 here we already can access PCI_DEV(bus, 0, 0) to PCI_DEV(bus, 0x1f, 0x7)
314 So We can scan these devices to find out if they are bridge
315 If it is pci bridge, We need to set busn in bridge, and go on
316 For ht bridge, We need to set the busn in bridge and ht_setup_chainx, and the scan_pci_bus
322 new_bus = (bus & 0xff); // mask out the reset_needed
326 } else if (new_bus<0x80) {
328 } else if (new_bus<0xc0) {
336 for (devfn = 0; devfn <= 0xff; devfn++) {
342 dev = PCI_DEV((bus & 0xff), ((devfn>>3) & 0x1f), (devfn & 0x7));
343 hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
344 class = pci_read_config16(dev, PCI_CLASS_DEVICE);
346 switch(hdr_type & 0x7f) { /* header type */
347 case PCI_HEADER_TYPE_BRIDGE:
348 if (class != PCI_CLASS_BRIDGE_PCI) goto bad;
349 /* set the bus range dev */
351 /* Clear all status bits and turn off memory, I/O and master enables. */
352 cr = pci_read_config16(dev, PCI_COMMAND);
353 pci_write_config16(dev, PCI_COMMAND, 0x0000);
354 pci_write_config16(dev, PCI_STATUS, 0xffff);
356 buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
360 buses |= (((unsigned int) (bus & 0xff) << 0) |
361 ((unsigned int) (new_bus & 0xff) << 8) |
362 ((unsigned int) max_bus << 16));
363 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
365 /* here we need to figure out if dev is a ht bridge
366 if it is ht bridge, we need to call ht_setup_chainx at first
367 Not verified --- yhlu
370 upos = ht_lookup_host_capability(dev); // one func one ht sub
371 if (upos) { // sub ht chain
373 busn = (new_bus & 0xff);
374 /* Make certain the HT bus is not enumerated */
375 ht_collapse_previous_enumeration(busn, 0);
376 /* scan the ht chain */
377 #if RAMINIT_SYSINFO == 1
378 ht_setup_chainx(dev,upos,busn, 0, sysinfo); // don't need offset unitid
380 new_bus |= (ht_setup_chainx(dev, upos, busn, 0)<<16); // store reset_needed to upword
384 #if RAMINIT_SYSINFO == 1
385 new_bus = scan_pci_bus(new_bus, sysinfo);
387 new_bus = scan_pci_bus(new_bus);
389 /* set real max bus num in that */
391 buses = (buses & 0xff00ffff) |
392 ((unsigned int) (new_bus & 0xff) << 16);
393 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
395 pci_write_config16(dev, PCI_COMMAND, cr);
403 /* if this is not a multi function device,
404 * or the device is not present don't waste
405 * time probing another function.
406 * Skip to next device.
408 if ( ((devfn & 0x07) == 0x00) && ((hdr_type & 0x80) != 0x80))
418 #if RAMINIT_SYSINFO == 1
419 static void ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned offset_unitid, struct sys_info *sysinfo)
421 static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned offset_unitid)
424 //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
426 uint8_t next_unitid, last_unitid;
429 #if RAMINIT_SYSINFO == 0
430 int reset_needed = 0;
433 #if HT_CHAIN_END_UNITID_BASE != 0x20
434 //let't record the device of last ht device, So we can set the Unitid to HT_CHAIN_END_UNITID_BASE
435 unsigned real_last_unitid;
436 uint8_t real_last_pos;
438 uint8_t end_used = 0;
441 uoffs = PCI_HT_HOST_OFFS;
442 next_unitid = (offset_unitid) ? HT_CHAIN_UNITID_BASE:1;
447 uint16_t flags, ctrl;
451 /* Wait until the link initialization is complete */
453 ctrl = pci_read_config16(udev, upos + LINK_CTRL(uoffs));
454 /* Is this the end of the hypertransport chain? */
455 if (ctrl & (1 << 6)) {
459 if (ctrl & ((1 << 4) | (1 << 8))) {
461 * Either the link has failed, or we have
463 * Sometimes this can happen due to link
464 * retrain, so lets knock it down and see
467 ctrl |= ((1 << 4) | (1 <<8)); // Link fail + Crc
468 pci_write_config16(udev, upos + LINK_CTRL(uoffs), ctrl);
469 ctrl = pci_read_config16(udev, upos + LINK_CTRL(uoffs));
470 if (ctrl & ((1 << 4) | (1 << 8))) {
471 print_err("Detected error on Hypertransport Link\n");
475 } while((ctrl & (1 << 5)) == 0);
477 device_t dev = PCI_DEV(bus, 0, 0);
478 last_unitid = next_unitid;
480 id = pci_read_config32(dev, PCI_VENDOR_ID);
482 /* If the chain is enumerated quit */
483 if ((id == 0xffffffff) || (id == 0x00000000) ||
484 (id == 0x0000ffff) || (id == 0xffff0000))
489 pos = ht_lookup_slave_capability(dev);
491 print_err("udev="); print_err_hex32(udev);
492 print_err("\tupos="); print_err_hex32(upos);
493 print_err("\tuoffs="); print_err_hex32(uoffs);
494 print_err("\tHT link capability not found\r\n");
499 #if HT_CHAIN_END_UNITID_BASE != 0x20
501 if(next_unitid>= (bus ? 0x20:0x18) ) {
503 next_unitid = HT_CHAIN_END_UNITID_BASE;
511 real_last_unitid = next_unitid;
515 /* Update the Unitid of the current device */
516 flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
517 flags &= ~0x1f; /* mask out the base Unit ID */
518 flags |= next_unitid & 0x1f;
519 pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
521 /* Compute the number of unitids consumed */
522 count = (flags >> 5) & 0x1f;
524 /* Note the change in device number */
525 dev = PCI_DEV(bus, next_unitid, 0);
527 next_unitid += count;
529 /* Find which side of the ht link we are on,
530 * by reading which direction our last write to PCI_CAP_FLAGS
533 flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
534 offs = ((flags>>10) & 1) ? PCI_HT_SLAVE1_OFFS : PCI_HT_SLAVE0_OFFS;
536 #if RAMINIT_SYSINFO == 1
537 /* store the link pair here and we will Setup the Hypertransport link later, after we get final FID/VID */
539 struct link_pair_st *link_pair = &sysinfo->link_pair[sysinfo->link_pair_num];
540 link_pair->udev = udev;
541 link_pair->upos = upos;
542 link_pair->uoffs = uoffs;
543 link_pair->dev = dev;
544 link_pair->pos = pos;
545 link_pair->offs = offs;
546 sysinfo->link_pair_num++;
549 reset_needed |= ht_optimize_link(udev, upos, uoffs, dev, pos, offs);
552 /* Remeber the location of the last device */
555 uoffs = ( offs != PCI_HT_SLAVE0_OFFS ) ? PCI_HT_SLAVE0_OFFS : PCI_HT_SLAVE1_OFFS;
557 } while (last_unitid != next_unitid );
562 #if HT_CHAIN_END_UNITID_BASE != 0x20
563 if(offset_unitid && (ht_dev_num>1) && (real_last_unitid != HT_CHAIN_END_UNITID_BASE) && !end_used ) {
566 flags = pci_read_config16(PCI_DEV(bus,real_last_unitid,0), real_last_pos + PCI_CAP_FLAGS);
568 flags |= HT_CHAIN_END_UNITID_BASE & 0x1f;
569 pci_write_config16(PCI_DEV(bus, real_last_unitid, 0), real_last_pos + PCI_CAP_FLAGS, flags);
571 #if RAMINIT_SYSINFO == 1
572 // Here need to change the dev in the array
573 for(i=0;i<sysinfo->link_pair_num;i++)
575 struct link_pair_st *link_pair = &sysinfo->link_pair[i];
576 if(link_pair->udev == PCI_DEV(bus, real_last_unitid, 0)) {
577 link_pair->udev = PCI_DEV(bus, HT_CHAIN_END_UNITID_BASE, 0);
580 if(link_pair->dev == PCI_DEV(bus, real_last_unitid, 0)) {
581 link_pair->dev = PCI_DEV(bus, HT_CHAIN_END_UNITID_BASE, 0);
589 #if RAMINIT_SYSINFO == 0
595 #if RAMINIT_SYSINFO == 1
596 static void ht_setup_chain(device_t udev, unsigned upos, struct sys_info *sysinfo)
598 static int ht_setup_chain(device_t udev, unsigned upos)
601 unsigned offset_unitid = 0;
602 #if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20))
606 /* Assumption the HT chain that is bus 0 has the HT I/O Hub on it.
607 * On most boards this just happens. If a cpu has multiple
608 * non Coherent links the appropriate bus registers for the
609 * links needs to be programed to point at bus 0.
612 /* Make certain the HT bus is not enumerated */
613 ht_collapse_previous_enumeration(0, 0);
615 #if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20))
619 #if RAMINIT_SYSINFO == 1
620 ht_setup_chainx(udev, upos, 0, offset_unitid, sysinfo);
622 return ht_setup_chainx(udev, upos, 0, offset_unitid);
625 static int optimize_link_read_pointer(uint8_t node, uint8_t linkn, uint8_t linkt, uint8_t val)
627 uint32_t dword, dword_old;
630 /* This works on an Athlon64 because unimplemented links return 0 */
631 dword = pci_read_config32(PCI_DEV(0,0x18+node,0), 0x98 + (linkn * 0x20));
632 link_type = dword & 0xff;
635 if ( (link_type & 7) == linkt ) { /* Coherent Link only linkt = 3, ncoherent = 7*/
636 dword_old = dword = pci_read_config32(PCI_DEV(0,0x18+node,3), 0xdc);
637 dword &= ~( 0xff<<(linkn *8) );
638 dword |= val << (linkn *8);
640 if (dword != dword_old) {
641 pci_write_config32(PCI_DEV(0,0x18+node,3), 0xdc, dword);
649 static int optimize_link_read_pointers_chain(uint8_t ht_c_num)
656 for (i = 0; i < ht_c_num; i++) {
658 uint8_t nodeid, linkn;
663 #if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20))
664 #if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
665 if(i==0) // to check if it is sb ht chain
667 devn = HT_CHAIN_UNITID_BASE;
670 reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
672 nodeid = ((reg & 0xf0)>>4); // nodeid
673 linkn = ((reg & 0xf00)>>8); // link n
674 busn = (reg & 0xff0000)>>16; //busn
676 reg = pci_read_config32( PCI_DEV(busn, devn, 0), PCI_VENDOR_ID); // ? the chain dev maybe offseted
677 if ( (reg & 0xffff) == PCI_VENDOR_ID_AMD) {
679 } else if ( (reg & 0xffff) == PCI_VENDOR_ID_NVIDIA ) {
685 reset_needed |= optimize_link_read_pointer(nodeid, linkn, 0x07, val);
692 static int set_ht_link_buffer_count(uint8_t node, uint8_t linkn, uint8_t linkt, unsigned val)
699 /* This works on an Athlon64 because unimplemented links return 0 */
700 regpos = 0x98 + (linkn * 0x20);
701 dev = PCI_DEV(0,0x18+node,0);
702 dword = pci_read_config32(dev, regpos);
703 link_type = dword & 0xff;
705 if ( (link_type & 0x7) == linkt ) { /* Coherent Link only linkt = 3, ncoherent = 7*/
706 regpos = 0x90 + (linkn * 0x20);
707 dword = pci_read_config32(dev, regpos );
710 pci_write_config32(dev, regpos, val);
717 static int set_ht_link_buffer_counts_chain(uint8_t ht_c_num, unsigned vendorid, unsigned val)
724 for (i = 0; i < ht_c_num; i++) {
726 uint8_t nodeid, linkn;
730 reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
731 if((reg & 3) != 3) continue; // not enabled
733 nodeid = ((reg & 0xf0)>>4); // nodeid
734 linkn = ((reg & 0xf00)>>8); // link n
735 busn = (reg & 0xff0000)>>16; //busn
737 for(devn = 0; devn < 0x20; devn++) {
738 reg = pci_read_config32( PCI_DEV(busn, devn, 0), PCI_VENDOR_ID); //1?
739 if ( (reg & 0xffff) == vendorid ) {
740 reset_needed |= set_ht_link_buffer_count(nodeid, linkn, 0x07,val);
750 #if RAMINIT_SYSINFO == 1
751 static void ht_setup_chains(uint8_t ht_c_num, struct sys_info *sysinfo)
753 static int ht_setup_chains(uint8_t ht_c_num)
756 /* Assumption the HT chain that is bus 0 has the HT I/O Hub on it.
757 * On most boards this just happens. If a cpu has multiple
758 * non Coherent links the appropriate bus registers for the
759 * links needs to be programed to point at bus 0.
765 #if RAMINIT_SYSINFO == 0
766 int reset_needed = 0;
768 sysinfo->link_pair_num = 0;
771 // first one is SB Chain
772 for (i = 0; i < ht_c_num; i++) {
778 #if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1)
781 unsigned offset_unitid = 0;
783 reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
785 //We need setup 0x94, 0xb4, and 0xd4 according to the reg
786 devpos = ((reg & 0xf0)>>4)+0x18; // nodeid; it will decide 0x18 or 0x19
787 regpos = ((reg & 0xf00)>>8) * 0x20 + 0x94; // link n; it will decide 0x94 or 0xb4, 0x0xd4;
788 busn = (reg & 0xff0000)>>16;
790 dword = pci_read_config32( PCI_DEV(0, devpos, 0), regpos) ;
791 dword &= ~(0xffff<<8);
792 dword |= (reg & 0xffff0000)>>8;
793 pci_write_config32( PCI_DEV(0, devpos,0), regpos , dword);
796 #if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20))
797 #if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
798 if(i==0) // to check if it is sb ht chain
803 /* Make certain the HT bus is not enumerated */
804 ht_collapse_previous_enumeration(busn, offset_unitid);
806 upos = ((reg & 0xf00)>>8) * 0x20 + 0x80;
807 udev = PCI_DEV(0, devpos, 0);
809 #if RAMINIT_SYSINFO == 1
810 ht_setup_chainx(udev,upos,busn, offset_unitid, sysinfo); // all not
812 reset_needed |= ht_setup_chainx(udev,upos,busn, offset_unitid); //all not
815 #if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1)
816 /* You can use use this in romcc, because there is function call in romcc, recursive will kill you */
817 bus = busn; // we need 32 bit
818 #if RAMINIT_SYSINFO == 1
819 scan_pci_bus(bus, sysinfo);
821 reset_needed |= (scan_pci_bus(bus)>>16); // take out reset_needed that stored in upword
826 #if RAMINIT_SYSINFO == 0
827 reset_needed |= optimize_link_read_pointers_chain(ht_c_num);
834 #if defined (__GNUC__)
835 static inline unsigned get_nodes(void);
838 #if RAMINIT_SYSINFO == 1
839 static void ht_setup_chains_x(struct sys_info *sysinfo)
841 static int ht_setup_chains_x(void)
850 #if K8_ALLOCATE_IO_RANGE == 1
851 unsigned next_io_base;
856 /* read PCI_DEV(0,0x18,0) 0x64 bit [8:9] to find out SbLink m */
857 reg = pci_read_config32(PCI_DEV(0, 0x18, 0), 0x64);
858 /* update PCI_DEV(0, 0x18, 1) 0xe0 to 0x05000m03, and next_busn=0x3f+1 */
859 print_linkn_in("SBLink=", ((reg>>8) & 3) );
860 #if RAMINIT_SYSINFO == 1
861 sysinfo->sblk = (reg>>8) & 3;
863 sysinfo->nodes = nodes;
865 tempreg = 3 | ( 0<<4) | (((reg>>8) & 3)<<8) | (0<<16)| (0x3f<<24);
866 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0, tempreg);
868 next_busn=0x3f+1; /* 0 will be used ht chain with SB we need to keep SB in bus0 in auto stage*/
870 #if K8_ALLOCATE_IO_RANGE == 1
871 /* io range allocation */
872 tempreg = 0 | (((reg>>8) & 0x3) << 4 )| (0x3<<12); //limit
873 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC4, tempreg);
874 tempreg = 3 | ( 3<<4) | (0<<12); //base
875 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC0, tempreg);
876 next_io_base = 0x3+0x1;
880 for(ht_c_num=1;ht_c_num<4; ht_c_num++) {
881 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4, 0);
883 #if K8_ALLOCATE_IO_RANGE == 1
884 /* io range allocation */
885 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xc4 + ht_c_num * 8, 0);
886 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xc0 + ht_c_num * 8, 0);
890 for(nodeid=0; nodeid<nodes; nodeid++) {
893 dev = PCI_DEV(0, 0x18+nodeid,0);
894 for(linkn = 0; linkn<3; linkn++) {
896 regpos = 0x98 + 0x20 * linkn;
897 reg = pci_read_config32(dev, regpos);
898 if ((reg & 0x17) != 7) continue; /* it is not non conherent or not connected*/
899 print_linkn_in("NC node|link=", ((nodeid & 0xf)<<4)|(linkn & 0xf));
900 tempreg = 3 | (nodeid <<4) | (linkn<<8);
901 /*compare (temp & 0xffff), with (PCI(0, 0x18, 1) 0xe0 to 0xec & 0xfffff) */
902 for(ht_c_num=0;ht_c_num<4; ht_c_num++) {
903 reg = pci_read_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4);
904 if(((reg & 0xffff) == (tempreg & 0xffff)) || ((reg & 0xffff) == 0x0000)) { /*we got it*/
908 if(ht_c_num == 4) break; /*used up only 4 non conherent allowed*/
909 /*update to 0xe0...*/
910 if((reg & 0xf) == 3) continue; /*SbLink so don't touch it */
911 print_linkn_in("\tbusn=", next_busn);
912 tempreg |= (next_busn<<16)|((next_busn+0x3f)<<24);
913 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4, tempreg);
916 #if K8_ALLOCATE_IO_RANGE == 1
917 /* io range allocation */
918 tempreg = nodeid | (linkn<<4) | ((next_io_base+0x3)<<12); //limit
919 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC4 + ht_c_num * 8, tempreg);
920 tempreg = 3 /*| ( 3<<4)*/ | (next_io_base<<12); //base :ISA and VGA ?
921 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC0 + ht_c_num * 8, tempreg);
922 next_io_base += 0x3+0x1;
927 /*update 0xe0, 0xe4, 0xe8, 0xec from PCI_DEV(0, 0x18,1) to PCI_DEV(0, 0x19,1) to PCI_DEV(0, 0x1f,1);*/
929 for(nodeid = 1; nodeid<nodes; nodeid++) {
932 dev = PCI_DEV(0, 0x18+nodeid,1);
933 for(i = 0; i< 4; i++) {
935 regpos = 0xe0 + i * 4;
936 reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos);
937 pci_write_config32(dev, regpos, reg);
940 #if K8_ALLOCATE_IO_RANGE == 1
941 /* io range allocation */
942 for(i = 0; i< 4; i++) {
944 regpos = 0xc4 + i * 8;
945 reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos);
946 pci_write_config32(dev, regpos, reg);
948 for(i = 0; i< 4; i++) {
950 regpos = 0xc0 + i * 8;
951 reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos);
952 pci_write_config32(dev, regpos, reg);
957 /* recount ht_c_num*/
959 for(ht_c_num=0;ht_c_num<4; ht_c_num++) {
960 reg = pci_read_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4);
961 if(((reg & 0xf) != 0x0)) {
966 #if RAMINIT_SYSINFO == 1
967 sysinfo->ht_c_num = i;
968 ht_setup_chains(i, sysinfo);
969 sysinfo->sbdn = get_sbdn(sysinfo->sbbusn);
971 return ht_setup_chains(i);
976 #if RAMINIT_SYSINFO == 1
977 static int optimize_link_incoherent_ht(struct sys_info *sysinfo)
979 // We need to use recorded link pair info to optimize the link
981 int reset_needed = 0;
983 unsigned link_pair_num = sysinfo->link_pair_num;
985 printk_spew("entering optimize_link_incoherent_ht\r\n");
986 printk_spew("sysinfo->link_pair_num=0x%x\r\n", link_pair_num);
987 for(i=0; i< link_pair_num; i++) {
988 struct link_pair_st *link_pair= &sysinfo->link_pair[i];
989 reset_needed |= ht_optimize_link(link_pair->udev, link_pair->upos, link_pair->uoffs, link_pair->dev, link_pair->pos, link_pair->offs);
990 printk_spew("after ht_optimize_link for link pair %d, reset_needed=0x%x\r\n", i, reset_needed);
993 reset_needed |= optimize_link_read_pointers_chain(sysinfo->ht_c_num);
994 printk_spew("after optimize_link_read_pointers_chain, reset_needed=0x%x\r\n", reset_needed);