📄 chrp_pci.c
字号:
printk("Hydra Mac I/O at %x\n", np->addrs[0].address); out_le32(&Hydra->Feature_Control, (HYDRA_FC_SCC_CELL_EN | HYDRA_FC_SCSI_CELL_EN | HYDRA_FC_SCCA_ENABLE | HYDRA_FC_SCCB_ENABLE | HYDRA_FC_ARB_BYPASS | HYDRA_FC_MPIC_ENABLE | HYDRA_FC_SLOW_SCC_PCLK | HYDRA_FC_MPIC_IS_MASTER)); OpenPIC = (volatile struct OpenPIC *)&Hydra->OpenPIC; OpenPIC_InitSenses = hydra_openpic_initsenses; OpenPIC_NumInitSenses = sizeof(hydra_openpic_initsenses); return 1;}#ifdef CONFIG_POWER4static voidpower4_fixup_dev(struct pci_dev *dev){ int i; unsigned long offset; for (i = 0; i < 6; ++i) { if (dev->resource[i].start == 0) continue; offset = pci_address_offset(dev->bus->number, dev->resource[i].flags); if (offset) { dev->resource[i].start += offset; dev->resource[i].end += offset; printk("device %x.%x[%d] now [%lx..%lx]\n", dev->bus->number, dev->devfn, i, dev->resource[i].start, dev->resource[i].end); } /* zap the 2nd function of the winbond chip */ if (dev->resource[i].flags & IORESOURCE_IO && dev->bus->number == 0 && dev->devfn == 0x81) dev->resource[i].flags &= ~IORESOURCE_IO; }}#endif /* CONFIG_POWER4 */void __initchrp_pcibios_fixup(void){ struct pci_dev *dev; int *brp; struct device_node *np; extern struct pci_ops generic_pci_ops;#ifndef CONFIG_POWER4 np = find_devices("device-tree"); if (np != 0) { for (np = np->child; np != NULL; np = np->sibling) { if (np->type == NULL || strcmp(np->type, "pci") != 0) continue; if ((brp = (int *) get_property(np, "bus-range", NULL)) == 0) continue; if (brp[0] != 0) /* bus 0 is already done */ pci_scan_bus(brp[0], &generic_pci_ops, NULL); } }#else /* XXX kludge for now because we can't properly handle physical addresses > 4GB. -- paulus */ pci_scan_bus(0x1e, &generic_pci_ops, NULL);#endif /* CONFIG_POWER4 */ /* PCI interrupts are controlled by the OpenPIC */ pci_for_each_dev(dev) { np = find_pci_device_OFnode(dev->bus->number, dev->devfn); if ((np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0)) dev->irq = np->intrs[0].line; /* these need to be absolute addrs for OF and Matrox FB -- Cort */ if ( dev->vendor == PCI_VENDOR_ID_MATROX ) { if ( dev->resource[0].start < isa_mem_base ) dev->resource[0].start += isa_mem_base; if ( dev->resource[1].start < isa_mem_base ) dev->resource[1].start += isa_mem_base; } /* the F50 identifies the amd as a trident */ if ( (dev->vendor == PCI_VENDOR_ID_TRIDENT) && (dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET) ) { dev->vendor = PCI_VENDOR_ID_AMD; pcibios_write_config_word(dev->bus->number, dev->devfn, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD); }#ifdef CONFIG_POWER4 power4_fixup_dev(dev);#else if (dev->bus->number > 0 && python_busnr > 0) dev->resource[0].start += dev->bus->number*0x01000000;#endif }}static struct { /* parent is iomem */ struct resource ram, pci_mem, isa_mem, pci_io, pci_cfg, rom_exp, flash; /* parent is isa_mem */ struct resource nvram;} gg2_resources = { ram: { "RAM", 0x00000000, 0xbfffffff, IORESOURCE_MEM }, pci_mem: { "GG2 PCI mem", 0xc0000000, 0xf6ffffff, IORESOURCE_MEM }, isa_mem: { "GG2 ISA mem", 0xf7000000, 0xf7ffffff }, pci_io: { "GG2 PCI I/O", 0xf8000000, 0xf8ffffff }, pci_cfg: { "GG2 PCI cfg", 0xfec00000, 0xfec7ffff }, rom_exp: { "ROM exp", 0xff000000, 0xff7fffff, }, flash: { "Flash ROM", 0xfff80000, 0xffffffff }, nvram: { "NVRAM", 0xf70e0000, 0xf70e7fff },};static void __init gg2_pcibios_fixup(void){ int i; extern unsigned long *end_of_DRAM; chrp_pcibios_fixup(); gg2_resources.ram.end = (unsigned long)end_of_DRAM-PAGE_OFFSET; for (i = 0; i < 7; i++) request_resource(&iomem_resource, &((struct resource *)&gg2_resources)[i]); request_resource(&gg2_resources.isa_mem, &gg2_resources.nvram);}static void __init gg2_pcibios_fixup_bus(struct pci_bus *bus){ bus->resource[1] = &gg2_resources.pci_mem;}decl_config_access_method(grackle);decl_config_access_method(indirect);decl_config_access_method(rtas);void __initchrp_setup_pci_ptrs(void){ struct device_node *py; ppc_md.pcibios_fixup = chrp_pcibios_fixup;#ifdef CONFIG_POWER4 set_config_access_method(rtas); pci_dram_offset = 0;#else /* CONFIG_POWER4 */ if ( !strncmp("MOT", get_property(find_path_device("/"), "model", NULL),3) ) { pci_dram_offset = 0; isa_mem_base = 0xf7000000; isa_io_base = 0xfe000000; set_config_access_method(grackle); } else { if ((py = find_compatible_devices("pci", "IBM,python")) != 0 || (py = find_compatible_devices("pci", "IBM,python3.0")) != 0) { char *name = get_property(find_path_device("/"), "name", NULL); /* find out how many pythons */ while ( (py = py->next) ) python_busnr++; set_config_access_method(python); /* * We base these values on the machine type but should * try to read them from the python controller itself. * -- Cort */ if ( !strncmp("IBM,7025-F50", name, 12) ) { pci_dram_offset = 0x80000000; isa_mem_base = 0xa0000000; isa_io_base = 0x88000000; } else if ( !strncmp("IBM,7043-260", name, 12) || !strncmp("IBM,7044-270", name, 12)) { pci_dram_offset = 0x0; isa_mem_base = 0xc0000000; isa_io_base = 0xf8000000; } } else { if ( !strncmp("IBM,7043-150", get_property(find_path_device("/"), "name", NULL),12) || !strncmp("IBM,7046-155", get_property(find_path_device("/"), "name", NULL),12) || !strncmp("IBM,7046-B50", get_property(find_path_device("/"), "name", NULL),12) ) { pci_dram_offset = 0; isa_mem_base = 0x80000000; isa_io_base = 0xfe000000; pci_config_address = (unsigned int *)0xfec00000; pci_config_data = (unsigned char *)0xfee00000; set_config_access_method(indirect); } else { /* LongTrail */ pci_dram_offset = 0; isa_mem_base = 0xf7000000; isa_io_base = 0xf8000000; set_config_access_method(gg2); ppc_md.pcibios_fixup = gg2_pcibios_fixup; ppc_md.pcibios_fixup_bus = gg2_pcibios_fixup_bus; } } }#endif /* CONFIG_POWER4 */}#ifdef CONFIG_PPC64BRIDGE/* * Hack alert!!! * 64-bit machines like POWER3 and POWER4 have > 32 bit * physical addresses. For now we remap particular parts * of the 32-bit physical address space that the Linux * page table gives us into parts of the physical address * space above 4GB so we can access the I/O devices. */#ifdef CONFIG_POWER4static unsigned long pci_address_offset(int busnr, unsigned int flags){ unsigned long offset = 0; if (busnr >= 0x1e) { if (flags & IORESOURCE_IO) offset = -0x100000; else if (flags & IORESOURCE_MEM) offset = 0x38000000; } else if (busnr <= 0xf) { if (flags & IORESOURCE_MEM) offset = -0x40000000; else } return offset;}unsigned long phys_to_bus(unsigned long pa){ if (pa >= 0xf8000000) pa -= 0x38000000; else if (pa >= 0x80000000 && pa < 0xc0000000) pa += 0x40000000; return pa;}unsigned long bus_to_phys(unsigned int ba, int busnr){ return ba + pci_address_offset(busnr, IORESOURCE_MEM);}#else /* CONFIG_POWER4 *//* * For now assume I/O addresses are < 4GB and PCI bridges don't * remap addresses on POWER3 machines. */unsigned long phys_to_bus(unsigned long pa){ return pa;}unsigned long bus_to_phys(unsigned int ba, int busnr){ return ba;}#endif /* CONFIG_POWER4 */#endif /* CONFIG_PPC64BRIDGE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -