123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380 |
- /*
- * CHRP pci routines.
- */
- #include <linux/kernel.h>
- #include <linux/pci.h>
- #include <linux/delay.h>
- #include <linux/string.h>
- #include <linux/init.h>
- #include <asm/io.h>
- #include <asm/pgtable.h>
- #include <asm/irq.h>
- #include <asm/hydra.h>
- #include <asm/prom.h>
- #include <asm/machdep.h>
- #include <asm/sections.h>
- #include <asm/pci-bridge.h>
- #include <asm/grackle.h>
- #include <asm/rtas.h>
- #include "chrp.h"
- #include "gg2.h"
- /* LongTrail */
- void __iomem *gg2_pci_config_base;
- /*
- * The VLSI Golden Gate II has only 512K of PCI configuration space, so we
- * limit the bus number to 3 bits
- */
- int gg2_read_config(struct pci_bus *bus, unsigned int devfn, int off,
- int len, u32 *val)
- {
- volatile void __iomem *cfg_data;
- struct pci_controller *hose = pci_bus_to_host(bus);
- if (bus->number > 7)
- return PCIBIOS_DEVICE_NOT_FOUND;
- /*
- * Note: the caller has already checked that off is
- * suitably aligned and that len is 1, 2 or 4.
- */
- cfg_data = hose->cfg_data + ((bus->number<<16) | (devfn<<8) | off);
- switch (len) {
- case 1:
- *val = in_8(cfg_data);
- break;
- case 2:
- *val = in_le16(cfg_data);
- break;
- default:
- *val = in_le32(cfg_data);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
- }
- int gg2_write_config(struct pci_bus *bus, unsigned int devfn, int off,
- int len, u32 val)
- {
- volatile void __iomem *cfg_data;
- struct pci_controller *hose = pci_bus_to_host(bus);
- if (bus->number > 7)
- return PCIBIOS_DEVICE_NOT_FOUND;
- /*
- * Note: the caller has already checked that off is
- * suitably aligned and that len is 1, 2 or 4.
- */
- cfg_data = hose->cfg_data + ((bus->number<<16) | (devfn<<8) | off);
- switch (len) {
- case 1:
- out_8(cfg_data, val);
- break;
- case 2:
- out_le16(cfg_data, val);
- break;
- default:
- out_le32(cfg_data, val);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
- }
- static struct pci_ops gg2_pci_ops =
- {
- .read = gg2_read_config,
- .write = gg2_write_config,
- };
- /*
- * Access functions for PCI config space using RTAS calls.
- */
- int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
- int len, u32 *val)
- {
- struct pci_controller *hose = pci_bus_to_host(bus);
- unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
- | (((bus->number - hose->first_busno) & 0xff) << 16)
- | (hose->global_number << 24);
- int ret = -1;
- int rval;
- rval = rtas_call(rtas_token("read-pci-config"), 2, 2, &ret, addr, len);
- *val = ret;
- return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL;
- }
- int rtas_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
- int len, u32 val)
- {
- struct pci_controller *hose = pci_bus_to_host(bus);
- unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
- | (((bus->number - hose->first_busno) & 0xff) << 16)
- | (hose->global_number << 24);
- int rval;
- rval = rtas_call(rtas_token("write-pci-config"), 3, 1, NULL,
- addr, len, val);
- return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL;
- }
- static struct pci_ops rtas_pci_ops =
- {
- .read = rtas_read_config,
- .write = rtas_write_config,
- };
- volatile struct Hydra __iomem *Hydra = NULL;
- int __init
- hydra_init(void)
- {
- struct device_node *np;
- struct resource r;
- np = of_find_node_by_name(NULL, "mac-io");
- if (np == NULL || of_address_to_resource(np, 0, &r)) {
- of_node_put(np);
- return 0;
- }
- of_node_put(np);
- Hydra = ioremap(r.start, resource_size(&r));
- printk("Hydra Mac I/O at %llx\n", (unsigned long long)r.start);
- printk("Hydra Feature_Control was %x",
- in_le32(&Hydra->Feature_Control));
- 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));
- printk(", now %x\n", in_le32(&Hydra->Feature_Control));
- return 1;
- }
- #define PRG_CL_RESET_VALID 0x00010000
- static void __init
- setup_python(struct pci_controller *hose, struct device_node *dev)
- {
- u32 __iomem *reg;
- u32 val;
- struct resource r;
- if (of_address_to_resource(dev, 0, &r)) {
- printk(KERN_ERR "No address for Python PCI controller\n");
- return;
- }
- /* Clear the magic go-slow bit */
- reg = ioremap(r.start + 0xf6000, 0x40);
- BUG_ON(!reg);
- val = in_be32(®[12]);
- if (val & PRG_CL_RESET_VALID) {
- out_be32(®[12], val & ~PRG_CL_RESET_VALID);
- in_be32(®[12]);
- }
- iounmap(reg);
- setup_indirect_pci(hose, r.start + 0xf8000, r.start + 0xf8010, 0);
- }
- /* Marvell Discovery II based Pegasos 2 */
- static void __init setup_peg2(struct pci_controller *hose, struct device_node *dev)
- {
- struct device_node *root = of_find_node_by_path("/");
- struct device_node *rtas;
- rtas = of_find_node_by_name (root, "rtas");
- if (rtas) {
- hose->ops = &rtas_pci_ops;
- of_node_put(rtas);
- } else {
- printk ("RTAS supporting Pegasos OF not found, please upgrade"
- " your firmware\n");
- }
- pci_add_flags(PCI_REASSIGN_ALL_BUS);
- /* keep the reference to the root node */
- }
- void __init
- chrp_find_bridges(void)
- {
- struct device_node *dev;
- const int *bus_range;
- int len, index = -1;
- struct pci_controller *hose;
- const unsigned int *dma;
- const char *model, *machine;
- int is_longtrail = 0, is_mot = 0, is_pegasos = 0;
- struct device_node *root = of_find_node_by_path("/");
- struct resource r;
- /*
- * The PCI host bridge nodes on some machines don't have
- * properties to adequately identify them, so we have to
- * look at what sort of machine this is as well.
- */
- machine = of_get_property(root, "model", NULL);
- if (machine != NULL) {
- is_longtrail = strncmp(machine, "IBM,LongTrail", 13) == 0;
- is_mot = strncmp(machine, "MOT", 3) == 0;
- if (strncmp(machine, "Pegasos2", 8) == 0)
- is_pegasos = 2;
- else if (strncmp(machine, "Pegasos", 7) == 0)
- is_pegasos = 1;
- }
- for (dev = root->child; dev != NULL; dev = dev->sibling) {
- if (dev->type == NULL || strcmp(dev->type, "pci") != 0)
- continue;
- ++index;
- /* The GG2 bridge on the LongTrail doesn't have an address */
- if (of_address_to_resource(dev, 0, &r) && !is_longtrail) {
- printk(KERN_WARNING "Can't use %s: no address\n",
- dev->full_name);
- continue;
- }
- bus_range = of_get_property(dev, "bus-range", &len);
- if (bus_range == NULL || len < 2 * sizeof(int)) {
- printk(KERN_WARNING "Can't get bus-range for %s\n",
- dev->full_name);
- continue;
- }
- if (bus_range[1] == bus_range[0])
- printk(KERN_INFO "PCI bus %d", bus_range[0]);
- else
- printk(KERN_INFO "PCI buses %d..%d",
- bus_range[0], bus_range[1]);
- printk(" controlled by %s", dev->full_name);
- if (!is_longtrail)
- printk(" at %llx", (unsigned long long)r.start);
- printk("\n");
- hose = pcibios_alloc_controller(dev);
- if (!hose) {
- printk("Can't allocate PCI controller structure for %s\n",
- dev->full_name);
- continue;
- }
- hose->first_busno = hose->self_busno = bus_range[0];
- hose->last_busno = bus_range[1];
- model = of_get_property(dev, "model", NULL);
- if (model == NULL)
- model = "<none>";
- if (strncmp(model, "IBM, Python", 11) == 0) {
- setup_python(hose, dev);
- } else if (is_mot
- || strncmp(model, "Motorola, Grackle", 17) == 0) {
- setup_grackle(hose);
- } else if (is_longtrail) {
- void __iomem *p = ioremap(GG2_PCI_CONFIG_BASE, 0x80000);
- hose->ops = &gg2_pci_ops;
- hose->cfg_data = p;
- gg2_pci_config_base = p;
- } else if (is_pegasos == 1) {
- setup_indirect_pci(hose, 0xfec00cf8, 0xfee00cfc, 0);
- } else if (is_pegasos == 2) {
- setup_peg2(hose, dev);
- } else if (!strncmp(model, "IBM,CPC710", 10)) {
- setup_indirect_pci(hose,
- r.start + 0x000f8000,
- r.start + 0x000f8010,
- 0);
- if (index == 0) {
- dma = of_get_property(dev, "system-dma-base",
- &len);
- if (dma && len >= sizeof(*dma)) {
- dma = (unsigned int *)
- (((unsigned long)dma) +
- len - sizeof(*dma));
- pci_dram_offset = *dma;
- }
- }
- } else {
- printk("No methods for %s (model %s), using RTAS\n",
- dev->full_name, model);
- hose->ops = &rtas_pci_ops;
- }
- pci_process_bridge_OF_ranges(hose, dev, index == 0);
- /* check the first bridge for a property that we can
- use to set pci_dram_offset */
- dma = of_get_property(dev, "ibm,dma-ranges", &len);
- if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) {
- pci_dram_offset = dma[2] - dma[3];
- printk("pci_dram_offset = %lx\n", pci_dram_offset);
- }
- }
- of_node_put(root);
- }
- /* SL82C105 IDE Control/Status Register */
- #define SL82C105_IDECSR 0x40
- /* Fixup for Winbond ATA quirk, required for briq mostly because the
- * 8259 is configured for level sensitive IRQ 14 and so wants the
- * ATA controller to be set to fully native mode or bad things
- * will happen.
- */
- static void chrp_pci_fixup_winbond_ata(struct pci_dev *sl82c105)
- {
- u8 progif;
- /* If non-briq machines need that fixup too, please speak up */
- if (!machine_is(chrp) || _chrp_type != _CHRP_briq)
- return;
- if ((sl82c105->class & 5) != 5) {
- printk("W83C553: Switching SL82C105 IDE to PCI native mode\n");
- /* Enable SL82C105 PCI native IDE mode */
- pci_read_config_byte(sl82c105, PCI_CLASS_PROG, &progif);
- pci_write_config_byte(sl82c105, PCI_CLASS_PROG, progif | 0x05);
- sl82c105->class |= 0x05;
- /* Disable SL82C105 second port */
- pci_write_config_word(sl82c105, SL82C105_IDECSR, 0x0003);
- /* Clear IO BARs, they will be reassigned */
- pci_write_config_dword(sl82c105, PCI_BASE_ADDRESS_0, 0);
- pci_write_config_dword(sl82c105, PCI_BASE_ADDRESS_1, 0);
- pci_write_config_dword(sl82c105, PCI_BASE_ADDRESS_2, 0);
- pci_write_config_dword(sl82c105, PCI_BASE_ADDRESS_3, 0);
- }
- }
- DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105,
- chrp_pci_fixup_winbond_ata);
- /* Pegasos2 firmware version 20040810 configures the built-in IDE controller
- * in legacy mode, but sets the PCI registers to PCI native mode.
- * The chip can only operate in legacy mode, so force the PCI class into legacy
- * mode as well. The same fixup must be done to the class-code property in
- * the IDE node /pci@80000000/ide@C,1
- */
- static void chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide)
- {
- u8 progif;
- struct pci_dev *viaisa;
- if (!machine_is(chrp) || _chrp_type != _CHRP_Pegasos)
- return;
- if (viaide->irq != 14)
- return;
- viaisa = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, NULL);
- if (!viaisa)
- return;
- dev_info(&viaide->dev, "Fixing VIA IDE, force legacy mode on\n");
- pci_read_config_byte(viaide, PCI_CLASS_PROG, &progif);
- pci_write_config_byte(viaide, PCI_CLASS_PROG, progif & ~0x5);
- viaide->class &= ~0x5;
- pci_dev_put(viaisa);
- }
- DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata);
|