162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Support for PCI bridges found on Power Macintoshes. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2003-2005 Benjamin Herrenschmuidt (benh@kernel.crashing.org) 662306a36Sopenharmony_ci * Copyright (C) 1997 Paul Mackerras (paulus@samba.org) 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/kernel.h> 1062306a36Sopenharmony_ci#include <linux/pci.h> 1162306a36Sopenharmony_ci#include <linux/delay.h> 1262306a36Sopenharmony_ci#include <linux/string.h> 1362306a36Sopenharmony_ci#include <linux/init.h> 1462306a36Sopenharmony_ci#include <linux/irq.h> 1562306a36Sopenharmony_ci#include <linux/of_address.h> 1662306a36Sopenharmony_ci#include <linux/of_irq.h> 1762306a36Sopenharmony_ci#include <linux/of_pci.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#include <asm/sections.h> 2062306a36Sopenharmony_ci#include <asm/io.h> 2162306a36Sopenharmony_ci#include <asm/pci-bridge.h> 2262306a36Sopenharmony_ci#include <asm/machdep.h> 2362306a36Sopenharmony_ci#include <asm/pmac_feature.h> 2462306a36Sopenharmony_ci#include <asm/grackle.h> 2562306a36Sopenharmony_ci#include <asm/ppc-pci.h> 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#include "pmac.h" 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci#undef DEBUG 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci#ifdef DEBUG 3262306a36Sopenharmony_ci#define DBG(x...) printk(x) 3362306a36Sopenharmony_ci#else 3462306a36Sopenharmony_ci#define DBG(x...) 3562306a36Sopenharmony_ci#endif 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci/* XXX Could be per-controller, but I don't think we risk anything by 3862306a36Sopenharmony_ci * assuming we won't have both UniNorth and Bandit */ 3962306a36Sopenharmony_cistatic int has_uninorth; 4062306a36Sopenharmony_ci#ifdef CONFIG_PPC64 4162306a36Sopenharmony_cistatic struct pci_controller *u3_agp; 4262306a36Sopenharmony_ci#else 4362306a36Sopenharmony_cistatic int has_second_ohare; 4462306a36Sopenharmony_ci#endif /* CONFIG_PPC64 */ 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ciextern int pcibios_assign_bus_offset; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_cistruct device_node *k2_skiplist[2]; 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci/* 5162306a36Sopenharmony_ci * Magic constants for enabling cache coherency in the bandit/PSX bridge. 5262306a36Sopenharmony_ci */ 5362306a36Sopenharmony_ci#define BANDIT_DEVID_2 8 5462306a36Sopenharmony_ci#define BANDIT_REVID 3 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci#define BANDIT_DEVNUM 11 5762306a36Sopenharmony_ci#define BANDIT_MAGIC 0x50 5862306a36Sopenharmony_ci#define BANDIT_COHERENT 0x40 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_cistatic int __init fixup_one_level_bus_range(struct device_node *node, int higher) 6162306a36Sopenharmony_ci{ 6262306a36Sopenharmony_ci for (; node; node = node->sibling) { 6362306a36Sopenharmony_ci const int * bus_range; 6462306a36Sopenharmony_ci const unsigned int *class_code; 6562306a36Sopenharmony_ci int len; 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci /* For PCI<->PCI bridges or CardBus bridges, we go down */ 6862306a36Sopenharmony_ci class_code = of_get_property(node, "class-code", NULL); 6962306a36Sopenharmony_ci if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && 7062306a36Sopenharmony_ci (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) 7162306a36Sopenharmony_ci continue; 7262306a36Sopenharmony_ci bus_range = of_get_property(node, "bus-range", &len); 7362306a36Sopenharmony_ci if (bus_range != NULL && len > 2 * sizeof(int)) { 7462306a36Sopenharmony_ci if (bus_range[1] > higher) 7562306a36Sopenharmony_ci higher = bus_range[1]; 7662306a36Sopenharmony_ci } 7762306a36Sopenharmony_ci higher = fixup_one_level_bus_range(node->child, higher); 7862306a36Sopenharmony_ci } 7962306a36Sopenharmony_ci return higher; 8062306a36Sopenharmony_ci} 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci/* This routine fixes the "bus-range" property of all bridges in the 8362306a36Sopenharmony_ci * system since they tend to have their "last" member wrong on macs 8462306a36Sopenharmony_ci * 8562306a36Sopenharmony_ci * Note that the bus numbers manipulated here are OF bus numbers, they 8662306a36Sopenharmony_ci * are not Linux bus numbers. 8762306a36Sopenharmony_ci */ 8862306a36Sopenharmony_cistatic void __init fixup_bus_range(struct device_node *bridge) 8962306a36Sopenharmony_ci{ 9062306a36Sopenharmony_ci int *bus_range, len; 9162306a36Sopenharmony_ci struct property *prop; 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci /* Lookup the "bus-range" property for the hose */ 9462306a36Sopenharmony_ci prop = of_find_property(bridge, "bus-range", &len); 9562306a36Sopenharmony_ci if (prop == NULL || prop->length < 2 * sizeof(int)) 9662306a36Sopenharmony_ci return; 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci bus_range = prop->value; 9962306a36Sopenharmony_ci bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]); 10062306a36Sopenharmony_ci} 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci/* 10362306a36Sopenharmony_ci * Apple MacRISC (U3, UniNorth, Bandit, Chaos) PCI controllers. 10462306a36Sopenharmony_ci * 10562306a36Sopenharmony_ci * The "Bandit" version is present in all early PCI PowerMacs, 10662306a36Sopenharmony_ci * and up to the first ones using Grackle. Some machines may 10762306a36Sopenharmony_ci * have 2 bandit controllers (2 PCI busses). 10862306a36Sopenharmony_ci * 10962306a36Sopenharmony_ci * "Chaos" is used in some "Bandit"-type machines as a bridge 11062306a36Sopenharmony_ci * for the separate display bus. It is accessed the same 11162306a36Sopenharmony_ci * way as bandit, but cannot be probed for devices. It therefore 11262306a36Sopenharmony_ci * has its own config access functions. 11362306a36Sopenharmony_ci * 11462306a36Sopenharmony_ci * The "UniNorth" version is present in all Core99 machines 11562306a36Sopenharmony_ci * (iBook, G4, new IMacs, and all the recent Apple machines). 11662306a36Sopenharmony_ci * It contains 3 controllers in one ASIC. 11762306a36Sopenharmony_ci * 11862306a36Sopenharmony_ci * The U3 is the bridge used on G5 machines. It contains an 11962306a36Sopenharmony_ci * AGP bus which is dealt with the old UniNorth access routines 12062306a36Sopenharmony_ci * and a HyperTransport bus which uses its own set of access 12162306a36Sopenharmony_ci * functions. 12262306a36Sopenharmony_ci */ 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci#define MACRISC_CFA0(devfn, off) \ 12562306a36Sopenharmony_ci ((1 << (unsigned int)PCI_SLOT(dev_fn)) \ 12662306a36Sopenharmony_ci | (((unsigned int)PCI_FUNC(dev_fn)) << 8) \ 12762306a36Sopenharmony_ci | (((unsigned int)(off)) & 0xFCUL)) 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci#define MACRISC_CFA1(bus, devfn, off) \ 13062306a36Sopenharmony_ci ((((unsigned int)(bus)) << 16) \ 13162306a36Sopenharmony_ci |(((unsigned int)(devfn)) << 8) \ 13262306a36Sopenharmony_ci |(((unsigned int)(off)) & 0xFCUL) \ 13362306a36Sopenharmony_ci |1UL) 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_cistatic void __iomem *macrisc_cfg_map_bus(struct pci_bus *bus, 13662306a36Sopenharmony_ci unsigned int dev_fn, 13762306a36Sopenharmony_ci int offset) 13862306a36Sopenharmony_ci{ 13962306a36Sopenharmony_ci unsigned int caddr; 14062306a36Sopenharmony_ci struct pci_controller *hose; 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci hose = pci_bus_to_host(bus); 14362306a36Sopenharmony_ci if (hose == NULL) 14462306a36Sopenharmony_ci return NULL; 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci if (bus->number == hose->first_busno) { 14762306a36Sopenharmony_ci if (dev_fn < (11 << 3)) 14862306a36Sopenharmony_ci return NULL; 14962306a36Sopenharmony_ci caddr = MACRISC_CFA0(dev_fn, offset); 15062306a36Sopenharmony_ci } else 15162306a36Sopenharmony_ci caddr = MACRISC_CFA1(bus->number, dev_fn, offset); 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci /* Uninorth will return garbage if we don't read back the value ! */ 15462306a36Sopenharmony_ci do { 15562306a36Sopenharmony_ci out_le32(hose->cfg_addr, caddr); 15662306a36Sopenharmony_ci } while (in_le32(hose->cfg_addr) != caddr); 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci offset &= has_uninorth ? 0x07 : 0x03; 15962306a36Sopenharmony_ci return hose->cfg_data + offset; 16062306a36Sopenharmony_ci} 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_cistatic struct pci_ops macrisc_pci_ops = 16362306a36Sopenharmony_ci{ 16462306a36Sopenharmony_ci .map_bus = macrisc_cfg_map_bus, 16562306a36Sopenharmony_ci .read = pci_generic_config_read, 16662306a36Sopenharmony_ci .write = pci_generic_config_write, 16762306a36Sopenharmony_ci}; 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci#ifdef CONFIG_PPC32 17062306a36Sopenharmony_ci/* 17162306a36Sopenharmony_ci * Verify that a specific (bus, dev_fn) exists on chaos 17262306a36Sopenharmony_ci */ 17362306a36Sopenharmony_cistatic void __iomem *chaos_map_bus(struct pci_bus *bus, unsigned int devfn, 17462306a36Sopenharmony_ci int offset) 17562306a36Sopenharmony_ci{ 17662306a36Sopenharmony_ci struct device_node *np; 17762306a36Sopenharmony_ci const u32 *vendor, *device; 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci if (offset >= 0x100) 18062306a36Sopenharmony_ci return NULL; 18162306a36Sopenharmony_ci np = of_pci_find_child_device(bus->dev.of_node, devfn); 18262306a36Sopenharmony_ci if (np == NULL) 18362306a36Sopenharmony_ci return NULL; 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci vendor = of_get_property(np, "vendor-id", NULL); 18662306a36Sopenharmony_ci device = of_get_property(np, "device-id", NULL); 18762306a36Sopenharmony_ci if (vendor == NULL || device == NULL) 18862306a36Sopenharmony_ci return NULL; 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci if ((*vendor == 0x106b) && (*device == 3) && (offset >= 0x10) 19162306a36Sopenharmony_ci && (offset != 0x14) && (offset != 0x18) && (offset <= 0x24)) 19262306a36Sopenharmony_ci return NULL; 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci return macrisc_cfg_map_bus(bus, devfn, offset); 19562306a36Sopenharmony_ci} 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_cistatic struct pci_ops chaos_pci_ops = 19862306a36Sopenharmony_ci{ 19962306a36Sopenharmony_ci .map_bus = chaos_map_bus, 20062306a36Sopenharmony_ci .read = pci_generic_config_read, 20162306a36Sopenharmony_ci .write = pci_generic_config_write, 20262306a36Sopenharmony_ci}; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_cistatic void __init setup_chaos(struct pci_controller *hose, 20562306a36Sopenharmony_ci struct resource *addr) 20662306a36Sopenharmony_ci{ 20762306a36Sopenharmony_ci /* assume a `chaos' bridge */ 20862306a36Sopenharmony_ci hose->ops = &chaos_pci_ops; 20962306a36Sopenharmony_ci hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000); 21062306a36Sopenharmony_ci hose->cfg_data = ioremap(addr->start + 0xc00000, 0x1000); 21162306a36Sopenharmony_ci} 21262306a36Sopenharmony_ci#endif /* CONFIG_PPC32 */ 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci#ifdef CONFIG_PPC64 21562306a36Sopenharmony_ci/* 21662306a36Sopenharmony_ci * These versions of U3 HyperTransport config space access ops do not 21762306a36Sopenharmony_ci * implement self-view of the HT host yet 21862306a36Sopenharmony_ci */ 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci/* 22162306a36Sopenharmony_ci * This function deals with some "special cases" devices. 22262306a36Sopenharmony_ci * 22362306a36Sopenharmony_ci * 0 -> No special case 22462306a36Sopenharmony_ci * 1 -> Skip the device but act as if the access was successful 22562306a36Sopenharmony_ci * (return 0xff's on reads, eventually, cache config space 22662306a36Sopenharmony_ci * accesses in a later version) 22762306a36Sopenharmony_ci * -1 -> Hide the device (unsuccessful access) 22862306a36Sopenharmony_ci */ 22962306a36Sopenharmony_cistatic int u3_ht_skip_device(struct pci_controller *hose, 23062306a36Sopenharmony_ci struct pci_bus *bus, unsigned int devfn) 23162306a36Sopenharmony_ci{ 23262306a36Sopenharmony_ci struct device_node *busdn, *dn; 23362306a36Sopenharmony_ci int i; 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci /* We only allow config cycles to devices that are in OF device-tree 23662306a36Sopenharmony_ci * as we are apparently having some weird things going on with some 23762306a36Sopenharmony_ci * revs of K2 on recent G5s, except for the host bridge itself, which 23862306a36Sopenharmony_ci * is missing from the tree but we know we can probe. 23962306a36Sopenharmony_ci */ 24062306a36Sopenharmony_ci if (bus->self) 24162306a36Sopenharmony_ci busdn = pci_device_to_OF_node(bus->self); 24262306a36Sopenharmony_ci else if (devfn == 0) 24362306a36Sopenharmony_ci return 0; 24462306a36Sopenharmony_ci else 24562306a36Sopenharmony_ci busdn = hose->dn; 24662306a36Sopenharmony_ci for (dn = busdn->child; dn; dn = dn->sibling) 24762306a36Sopenharmony_ci if (PCI_DN(dn) && PCI_DN(dn)->devfn == devfn) 24862306a36Sopenharmony_ci break; 24962306a36Sopenharmony_ci if (dn == NULL) 25062306a36Sopenharmony_ci return -1; 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci /* 25362306a36Sopenharmony_ci * When a device in K2 is powered down, we die on config 25462306a36Sopenharmony_ci * cycle accesses. Fix that here. 25562306a36Sopenharmony_ci */ 25662306a36Sopenharmony_ci for (i=0; i<2; i++) 25762306a36Sopenharmony_ci if (k2_skiplist[i] == dn) 25862306a36Sopenharmony_ci return 1; 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci return 0; 26162306a36Sopenharmony_ci} 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci#define U3_HT_CFA0(devfn, off) \ 26462306a36Sopenharmony_ci ((((unsigned int)devfn) << 8) | offset) 26562306a36Sopenharmony_ci#define U3_HT_CFA1(bus, devfn, off) \ 26662306a36Sopenharmony_ci (U3_HT_CFA0(devfn, off) \ 26762306a36Sopenharmony_ci + (((unsigned int)bus) << 16) \ 26862306a36Sopenharmony_ci + 0x01000000UL) 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_cistatic void __iomem *u3_ht_cfg_access(struct pci_controller *hose, u8 bus, 27162306a36Sopenharmony_ci u8 devfn, u8 offset, int *swap) 27262306a36Sopenharmony_ci{ 27362306a36Sopenharmony_ci *swap = 1; 27462306a36Sopenharmony_ci if (bus == hose->first_busno) { 27562306a36Sopenharmony_ci if (devfn != 0) 27662306a36Sopenharmony_ci return hose->cfg_data + U3_HT_CFA0(devfn, offset); 27762306a36Sopenharmony_ci *swap = 0; 27862306a36Sopenharmony_ci return ((void __iomem *)hose->cfg_addr) + (offset << 2); 27962306a36Sopenharmony_ci } else 28062306a36Sopenharmony_ci return hose->cfg_data + U3_HT_CFA1(bus, devfn, offset); 28162306a36Sopenharmony_ci} 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_cistatic int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, 28462306a36Sopenharmony_ci int offset, int len, u32 *val) 28562306a36Sopenharmony_ci{ 28662306a36Sopenharmony_ci struct pci_controller *hose; 28762306a36Sopenharmony_ci void __iomem *addr; 28862306a36Sopenharmony_ci int swap; 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_ci hose = pci_bus_to_host(bus); 29162306a36Sopenharmony_ci if (hose == NULL) 29262306a36Sopenharmony_ci return PCIBIOS_DEVICE_NOT_FOUND; 29362306a36Sopenharmony_ci if (offset >= 0x100) 29462306a36Sopenharmony_ci return PCIBIOS_BAD_REGISTER_NUMBER; 29562306a36Sopenharmony_ci addr = u3_ht_cfg_access(hose, bus->number, devfn, offset, &swap); 29662306a36Sopenharmony_ci if (!addr) 29762306a36Sopenharmony_ci return PCIBIOS_DEVICE_NOT_FOUND; 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci switch (u3_ht_skip_device(hose, bus, devfn)) { 30062306a36Sopenharmony_ci case 0: 30162306a36Sopenharmony_ci break; 30262306a36Sopenharmony_ci case 1: 30362306a36Sopenharmony_ci switch (len) { 30462306a36Sopenharmony_ci case 1: 30562306a36Sopenharmony_ci *val = 0xff; break; 30662306a36Sopenharmony_ci case 2: 30762306a36Sopenharmony_ci *val = 0xffff; break; 30862306a36Sopenharmony_ci default: 30962306a36Sopenharmony_ci *val = 0xfffffffful; break; 31062306a36Sopenharmony_ci } 31162306a36Sopenharmony_ci return PCIBIOS_SUCCESSFUL; 31262306a36Sopenharmony_ci default: 31362306a36Sopenharmony_ci return PCIBIOS_DEVICE_NOT_FOUND; 31462306a36Sopenharmony_ci } 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ci /* 31762306a36Sopenharmony_ci * Note: the caller has already checked that offset is 31862306a36Sopenharmony_ci * suitably aligned and that len is 1, 2 or 4. 31962306a36Sopenharmony_ci */ 32062306a36Sopenharmony_ci switch (len) { 32162306a36Sopenharmony_ci case 1: 32262306a36Sopenharmony_ci *val = in_8(addr); 32362306a36Sopenharmony_ci break; 32462306a36Sopenharmony_ci case 2: 32562306a36Sopenharmony_ci *val = swap ? in_le16(addr) : in_be16(addr); 32662306a36Sopenharmony_ci break; 32762306a36Sopenharmony_ci default: 32862306a36Sopenharmony_ci *val = swap ? in_le32(addr) : in_be32(addr); 32962306a36Sopenharmony_ci break; 33062306a36Sopenharmony_ci } 33162306a36Sopenharmony_ci return PCIBIOS_SUCCESSFUL; 33262306a36Sopenharmony_ci} 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_cistatic int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, 33562306a36Sopenharmony_ci int offset, int len, u32 val) 33662306a36Sopenharmony_ci{ 33762306a36Sopenharmony_ci struct pci_controller *hose; 33862306a36Sopenharmony_ci void __iomem *addr; 33962306a36Sopenharmony_ci int swap; 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci hose = pci_bus_to_host(bus); 34262306a36Sopenharmony_ci if (hose == NULL) 34362306a36Sopenharmony_ci return PCIBIOS_DEVICE_NOT_FOUND; 34462306a36Sopenharmony_ci if (offset >= 0x100) 34562306a36Sopenharmony_ci return PCIBIOS_BAD_REGISTER_NUMBER; 34662306a36Sopenharmony_ci addr = u3_ht_cfg_access(hose, bus->number, devfn, offset, &swap); 34762306a36Sopenharmony_ci if (!addr) 34862306a36Sopenharmony_ci return PCIBIOS_DEVICE_NOT_FOUND; 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ci switch (u3_ht_skip_device(hose, bus, devfn)) { 35162306a36Sopenharmony_ci case 0: 35262306a36Sopenharmony_ci break; 35362306a36Sopenharmony_ci case 1: 35462306a36Sopenharmony_ci return PCIBIOS_SUCCESSFUL; 35562306a36Sopenharmony_ci default: 35662306a36Sopenharmony_ci return PCIBIOS_DEVICE_NOT_FOUND; 35762306a36Sopenharmony_ci } 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci /* 36062306a36Sopenharmony_ci * Note: the caller has already checked that offset is 36162306a36Sopenharmony_ci * suitably aligned and that len is 1, 2 or 4. 36262306a36Sopenharmony_ci */ 36362306a36Sopenharmony_ci switch (len) { 36462306a36Sopenharmony_ci case 1: 36562306a36Sopenharmony_ci out_8(addr, val); 36662306a36Sopenharmony_ci break; 36762306a36Sopenharmony_ci case 2: 36862306a36Sopenharmony_ci swap ? out_le16(addr, val) : out_be16(addr, val); 36962306a36Sopenharmony_ci break; 37062306a36Sopenharmony_ci default: 37162306a36Sopenharmony_ci swap ? out_le32(addr, val) : out_be32(addr, val); 37262306a36Sopenharmony_ci break; 37362306a36Sopenharmony_ci } 37462306a36Sopenharmony_ci return PCIBIOS_SUCCESSFUL; 37562306a36Sopenharmony_ci} 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_cistatic struct pci_ops u3_ht_pci_ops = 37862306a36Sopenharmony_ci{ 37962306a36Sopenharmony_ci .read = u3_ht_read_config, 38062306a36Sopenharmony_ci .write = u3_ht_write_config, 38162306a36Sopenharmony_ci}; 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci#define U4_PCIE_CFA0(devfn, off) \ 38462306a36Sopenharmony_ci ((1 << ((unsigned int)PCI_SLOT(dev_fn))) \ 38562306a36Sopenharmony_ci | (((unsigned int)PCI_FUNC(dev_fn)) << 8) \ 38662306a36Sopenharmony_ci | ((((unsigned int)(off)) >> 8) << 28) \ 38762306a36Sopenharmony_ci | (((unsigned int)(off)) & 0xfcU)) 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_ci#define U4_PCIE_CFA1(bus, devfn, off) \ 39062306a36Sopenharmony_ci ((((unsigned int)(bus)) << 16) \ 39162306a36Sopenharmony_ci |(((unsigned int)(devfn)) << 8) \ 39262306a36Sopenharmony_ci | ((((unsigned int)(off)) >> 8) << 28) \ 39362306a36Sopenharmony_ci |(((unsigned int)(off)) & 0xfcU) \ 39462306a36Sopenharmony_ci |1UL) 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_cistatic void __iomem *u4_pcie_cfg_map_bus(struct pci_bus *bus, 39762306a36Sopenharmony_ci unsigned int dev_fn, 39862306a36Sopenharmony_ci int offset) 39962306a36Sopenharmony_ci{ 40062306a36Sopenharmony_ci struct pci_controller *hose; 40162306a36Sopenharmony_ci unsigned int caddr; 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_ci if (offset >= 0x1000) 40462306a36Sopenharmony_ci return NULL; 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_ci hose = pci_bus_to_host(bus); 40762306a36Sopenharmony_ci if (!hose) 40862306a36Sopenharmony_ci return NULL; 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_ci if (bus->number == hose->first_busno) { 41162306a36Sopenharmony_ci caddr = U4_PCIE_CFA0(dev_fn, offset); 41262306a36Sopenharmony_ci } else 41362306a36Sopenharmony_ci caddr = U4_PCIE_CFA1(bus->number, dev_fn, offset); 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_ci /* Uninorth will return garbage if we don't read back the value ! */ 41662306a36Sopenharmony_ci do { 41762306a36Sopenharmony_ci out_le32(hose->cfg_addr, caddr); 41862306a36Sopenharmony_ci } while (in_le32(hose->cfg_addr) != caddr); 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ci offset &= 0x03; 42162306a36Sopenharmony_ci return hose->cfg_data + offset; 42262306a36Sopenharmony_ci} 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_cistatic struct pci_ops u4_pcie_pci_ops = 42562306a36Sopenharmony_ci{ 42662306a36Sopenharmony_ci .map_bus = u4_pcie_cfg_map_bus, 42762306a36Sopenharmony_ci .read = pci_generic_config_read, 42862306a36Sopenharmony_ci .write = pci_generic_config_write, 42962306a36Sopenharmony_ci}; 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_cistatic void pmac_pci_fixup_u4_of_node(struct pci_dev *dev) 43262306a36Sopenharmony_ci{ 43362306a36Sopenharmony_ci /* Apple's device-tree "hides" the root complex virtual P2P bridge 43462306a36Sopenharmony_ci * on U4. However, Linux sees it, causing the PCI <-> OF matching 43562306a36Sopenharmony_ci * code to fail to properly match devices below it. This works around 43662306a36Sopenharmony_ci * it by setting the node of the bridge to point to the PHB node, 43762306a36Sopenharmony_ci * which is not entirely correct but fixes the matching code and 43862306a36Sopenharmony_ci * doesn't break anything else. It's also the simplest possible fix. 43962306a36Sopenharmony_ci */ 44062306a36Sopenharmony_ci if (dev->dev.of_node == NULL) 44162306a36Sopenharmony_ci dev->dev.of_node = pcibios_get_phb_of_node(dev->bus); 44262306a36Sopenharmony_ci} 44362306a36Sopenharmony_ciDECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_APPLE, 0x5b, pmac_pci_fixup_u4_of_node); 44462306a36Sopenharmony_ci 44562306a36Sopenharmony_ci#endif /* CONFIG_PPC64 */ 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ci#ifdef CONFIG_PPC32 44862306a36Sopenharmony_ci/* 44962306a36Sopenharmony_ci * For a bandit bridge, turn on cache coherency if necessary. 45062306a36Sopenharmony_ci * N.B. we could clean this up using the hose ops directly. 45162306a36Sopenharmony_ci */ 45262306a36Sopenharmony_cistatic void __init init_bandit(struct pci_controller *bp) 45362306a36Sopenharmony_ci{ 45462306a36Sopenharmony_ci unsigned int vendev, magic; 45562306a36Sopenharmony_ci int rev; 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_ci /* read the word at offset 0 in config space for device 11 */ 45862306a36Sopenharmony_ci out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + PCI_VENDOR_ID); 45962306a36Sopenharmony_ci udelay(2); 46062306a36Sopenharmony_ci vendev = in_le32(bp->cfg_data); 46162306a36Sopenharmony_ci if (vendev == (PCI_DEVICE_ID_APPLE_BANDIT << 16) + 46262306a36Sopenharmony_ci PCI_VENDOR_ID_APPLE) { 46362306a36Sopenharmony_ci /* read the revision id */ 46462306a36Sopenharmony_ci out_le32(bp->cfg_addr, 46562306a36Sopenharmony_ci (1UL << BANDIT_DEVNUM) + PCI_REVISION_ID); 46662306a36Sopenharmony_ci udelay(2); 46762306a36Sopenharmony_ci rev = in_8(bp->cfg_data); 46862306a36Sopenharmony_ci if (rev != BANDIT_REVID) 46962306a36Sopenharmony_ci printk(KERN_WARNING 47062306a36Sopenharmony_ci "Unknown revision %d for bandit\n", rev); 47162306a36Sopenharmony_ci } else if (vendev != (BANDIT_DEVID_2 << 16) + PCI_VENDOR_ID_APPLE) { 47262306a36Sopenharmony_ci printk(KERN_WARNING "bandit isn't? (%x)\n", vendev); 47362306a36Sopenharmony_ci return; 47462306a36Sopenharmony_ci } 47562306a36Sopenharmony_ci 47662306a36Sopenharmony_ci /* read the word at offset 0x50 */ 47762306a36Sopenharmony_ci out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + BANDIT_MAGIC); 47862306a36Sopenharmony_ci udelay(2); 47962306a36Sopenharmony_ci magic = in_le32(bp->cfg_data); 48062306a36Sopenharmony_ci if ((magic & BANDIT_COHERENT) != 0) 48162306a36Sopenharmony_ci return; 48262306a36Sopenharmony_ci magic |= BANDIT_COHERENT; 48362306a36Sopenharmony_ci udelay(2); 48462306a36Sopenharmony_ci out_le32(bp->cfg_data, magic); 48562306a36Sopenharmony_ci printk(KERN_INFO "Cache coherency enabled for bandit/PSX\n"); 48662306a36Sopenharmony_ci} 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_ci/* 48962306a36Sopenharmony_ci * Tweak the PCI-PCI bridge chip on the blue & white G3s. 49062306a36Sopenharmony_ci */ 49162306a36Sopenharmony_cistatic void __init init_p2pbridge(void) 49262306a36Sopenharmony_ci{ 49362306a36Sopenharmony_ci struct device_node *p2pbridge; 49462306a36Sopenharmony_ci struct pci_controller* hose; 49562306a36Sopenharmony_ci u8 bus, devfn; 49662306a36Sopenharmony_ci u16 val; 49762306a36Sopenharmony_ci 49862306a36Sopenharmony_ci /* XXX it would be better here to identify the specific 49962306a36Sopenharmony_ci PCI-PCI bridge chip we have. */ 50062306a36Sopenharmony_ci p2pbridge = of_find_node_by_name(NULL, "pci-bridge"); 50162306a36Sopenharmony_ci if (p2pbridge == NULL || !of_node_name_eq(p2pbridge->parent, "pci")) 50262306a36Sopenharmony_ci goto done; 50362306a36Sopenharmony_ci if (pci_device_from_OF_node(p2pbridge, &bus, &devfn) < 0) { 50462306a36Sopenharmony_ci DBG("Can't find PCI infos for PCI<->PCI bridge\n"); 50562306a36Sopenharmony_ci goto done; 50662306a36Sopenharmony_ci } 50762306a36Sopenharmony_ci /* Warning: At this point, we have not yet renumbered all busses. 50862306a36Sopenharmony_ci * So we must use OF walking to find out hose 50962306a36Sopenharmony_ci */ 51062306a36Sopenharmony_ci hose = pci_find_hose_for_OF_device(p2pbridge); 51162306a36Sopenharmony_ci if (!hose) { 51262306a36Sopenharmony_ci DBG("Can't find hose for PCI<->PCI bridge\n"); 51362306a36Sopenharmony_ci goto done; 51462306a36Sopenharmony_ci } 51562306a36Sopenharmony_ci if (early_read_config_word(hose, bus, devfn, 51662306a36Sopenharmony_ci PCI_BRIDGE_CONTROL, &val) < 0) { 51762306a36Sopenharmony_ci printk(KERN_ERR "init_p2pbridge: couldn't read bridge" 51862306a36Sopenharmony_ci " control\n"); 51962306a36Sopenharmony_ci goto done; 52062306a36Sopenharmony_ci } 52162306a36Sopenharmony_ci val &= ~PCI_BRIDGE_CTL_MASTER_ABORT; 52262306a36Sopenharmony_ci early_write_config_word(hose, bus, devfn, PCI_BRIDGE_CONTROL, val); 52362306a36Sopenharmony_cidone: 52462306a36Sopenharmony_ci of_node_put(p2pbridge); 52562306a36Sopenharmony_ci} 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_cistatic void __init init_second_ohare(void) 52862306a36Sopenharmony_ci{ 52962306a36Sopenharmony_ci struct device_node *np = of_find_node_by_name(NULL, "pci106b,7"); 53062306a36Sopenharmony_ci unsigned char bus, devfn; 53162306a36Sopenharmony_ci unsigned short cmd; 53262306a36Sopenharmony_ci 53362306a36Sopenharmony_ci if (np == NULL) 53462306a36Sopenharmony_ci return; 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_ci /* This must run before we initialize the PICs since the second 53762306a36Sopenharmony_ci * ohare hosts a PIC that will be accessed there. 53862306a36Sopenharmony_ci */ 53962306a36Sopenharmony_ci if (pci_device_from_OF_node(np, &bus, &devfn) == 0) { 54062306a36Sopenharmony_ci struct pci_controller* hose = 54162306a36Sopenharmony_ci pci_find_hose_for_OF_device(np); 54262306a36Sopenharmony_ci if (!hose) { 54362306a36Sopenharmony_ci printk(KERN_ERR "Can't find PCI hose for OHare2 !\n"); 54462306a36Sopenharmony_ci of_node_put(np); 54562306a36Sopenharmony_ci return; 54662306a36Sopenharmony_ci } 54762306a36Sopenharmony_ci early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd); 54862306a36Sopenharmony_ci cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; 54962306a36Sopenharmony_ci cmd &= ~PCI_COMMAND_IO; 55062306a36Sopenharmony_ci early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd); 55162306a36Sopenharmony_ci } 55262306a36Sopenharmony_ci has_second_ohare = 1; 55362306a36Sopenharmony_ci of_node_put(np); 55462306a36Sopenharmony_ci} 55562306a36Sopenharmony_ci 55662306a36Sopenharmony_ci/* 55762306a36Sopenharmony_ci * Some Apple desktop machines have a NEC PD720100A USB2 controller 55862306a36Sopenharmony_ci * on the motherboard. Open Firmware, on these, will disable the 55962306a36Sopenharmony_ci * EHCI part of it so it behaves like a pair of OHCI's. This fixup 56062306a36Sopenharmony_ci * code re-enables it ;) 56162306a36Sopenharmony_ci */ 56262306a36Sopenharmony_cistatic void __init fixup_nec_usb2(void) 56362306a36Sopenharmony_ci{ 56462306a36Sopenharmony_ci struct device_node *nec; 56562306a36Sopenharmony_ci 56662306a36Sopenharmony_ci for_each_node_by_name(nec, "usb") { 56762306a36Sopenharmony_ci struct pci_controller *hose; 56862306a36Sopenharmony_ci u32 data; 56962306a36Sopenharmony_ci const u32 *prop; 57062306a36Sopenharmony_ci u8 bus, devfn; 57162306a36Sopenharmony_ci 57262306a36Sopenharmony_ci prop = of_get_property(nec, "vendor-id", NULL); 57362306a36Sopenharmony_ci if (prop == NULL) 57462306a36Sopenharmony_ci continue; 57562306a36Sopenharmony_ci if (0x1033 != *prop) 57662306a36Sopenharmony_ci continue; 57762306a36Sopenharmony_ci prop = of_get_property(nec, "device-id", NULL); 57862306a36Sopenharmony_ci if (prop == NULL) 57962306a36Sopenharmony_ci continue; 58062306a36Sopenharmony_ci if (0x0035 != *prop) 58162306a36Sopenharmony_ci continue; 58262306a36Sopenharmony_ci prop = of_get_property(nec, "reg", NULL); 58362306a36Sopenharmony_ci if (prop == NULL) 58462306a36Sopenharmony_ci continue; 58562306a36Sopenharmony_ci devfn = (prop[0] >> 8) & 0xff; 58662306a36Sopenharmony_ci bus = (prop[0] >> 16) & 0xff; 58762306a36Sopenharmony_ci if (PCI_FUNC(devfn) != 0) 58862306a36Sopenharmony_ci continue; 58962306a36Sopenharmony_ci hose = pci_find_hose_for_OF_device(nec); 59062306a36Sopenharmony_ci if (!hose) 59162306a36Sopenharmony_ci continue; 59262306a36Sopenharmony_ci early_read_config_dword(hose, bus, devfn, 0xe4, &data); 59362306a36Sopenharmony_ci if (data & 1UL) { 59462306a36Sopenharmony_ci printk("Found NEC PD720100A USB2 chip with disabled" 59562306a36Sopenharmony_ci " EHCI, fixing up...\n"); 59662306a36Sopenharmony_ci data &= ~1UL; 59762306a36Sopenharmony_ci early_write_config_dword(hose, bus, devfn, 0xe4, data); 59862306a36Sopenharmony_ci } 59962306a36Sopenharmony_ci } 60062306a36Sopenharmony_ci} 60162306a36Sopenharmony_ci 60262306a36Sopenharmony_cistatic void __init setup_bandit(struct pci_controller *hose, 60362306a36Sopenharmony_ci struct resource *addr) 60462306a36Sopenharmony_ci{ 60562306a36Sopenharmony_ci hose->ops = ¯isc_pci_ops; 60662306a36Sopenharmony_ci hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000); 60762306a36Sopenharmony_ci hose->cfg_data = ioremap(addr->start + 0xc00000, 0x1000); 60862306a36Sopenharmony_ci init_bandit(hose); 60962306a36Sopenharmony_ci} 61062306a36Sopenharmony_ci 61162306a36Sopenharmony_cistatic int __init setup_uninorth(struct pci_controller *hose, 61262306a36Sopenharmony_ci struct resource *addr) 61362306a36Sopenharmony_ci{ 61462306a36Sopenharmony_ci pci_add_flags(PCI_REASSIGN_ALL_BUS); 61562306a36Sopenharmony_ci has_uninorth = 1; 61662306a36Sopenharmony_ci hose->ops = ¯isc_pci_ops; 61762306a36Sopenharmony_ci hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000); 61862306a36Sopenharmony_ci hose->cfg_data = ioremap(addr->start + 0xc00000, 0x1000); 61962306a36Sopenharmony_ci /* We "know" that the bridge at f2000000 has the PCI slots. */ 62062306a36Sopenharmony_ci return addr->start == 0xf2000000; 62162306a36Sopenharmony_ci} 62262306a36Sopenharmony_ci#endif /* CONFIG_PPC32 */ 62362306a36Sopenharmony_ci 62462306a36Sopenharmony_ci#ifdef CONFIG_PPC64 62562306a36Sopenharmony_cistatic void __init setup_u3_agp(struct pci_controller* hose) 62662306a36Sopenharmony_ci{ 62762306a36Sopenharmony_ci /* On G5, we move AGP up to high bus number so we don't need 62862306a36Sopenharmony_ci * to reassign bus numbers for HT. If we ever have P2P bridges 62962306a36Sopenharmony_ci * on AGP, we'll have to move pci_assign_all_busses to the 63062306a36Sopenharmony_ci * pci_controller structure so we enable it for AGP and not for 63162306a36Sopenharmony_ci * HT childs. 63262306a36Sopenharmony_ci * We hard code the address because of the different size of 63362306a36Sopenharmony_ci * the reg address cell, we shall fix that by killing struct 63462306a36Sopenharmony_ci * reg_property and using some accessor functions instead 63562306a36Sopenharmony_ci */ 63662306a36Sopenharmony_ci hose->first_busno = 0xf0; 63762306a36Sopenharmony_ci hose->last_busno = 0xff; 63862306a36Sopenharmony_ci has_uninorth = 1; 63962306a36Sopenharmony_ci hose->ops = ¯isc_pci_ops; 64062306a36Sopenharmony_ci hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000); 64162306a36Sopenharmony_ci hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000); 64262306a36Sopenharmony_ci u3_agp = hose; 64362306a36Sopenharmony_ci} 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_cistatic void __init setup_u4_pcie(struct pci_controller* hose) 64662306a36Sopenharmony_ci{ 64762306a36Sopenharmony_ci /* We currently only implement the "non-atomic" config space, to 64862306a36Sopenharmony_ci * be optimised later. 64962306a36Sopenharmony_ci */ 65062306a36Sopenharmony_ci hose->ops = &u4_pcie_pci_ops; 65162306a36Sopenharmony_ci hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000); 65262306a36Sopenharmony_ci hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000); 65362306a36Sopenharmony_ci 65462306a36Sopenharmony_ci /* The bus contains a bridge from root -> device, we need to 65562306a36Sopenharmony_ci * make it visible on bus 0 so that we pick the right type 65662306a36Sopenharmony_ci * of config cycles. If we didn't, we would have to force all 65762306a36Sopenharmony_ci * config cycles to be type 1. So we override the "bus-range" 65862306a36Sopenharmony_ci * property here 65962306a36Sopenharmony_ci */ 66062306a36Sopenharmony_ci hose->first_busno = 0x00; 66162306a36Sopenharmony_ci hose->last_busno = 0xff; 66262306a36Sopenharmony_ci} 66362306a36Sopenharmony_ci 66462306a36Sopenharmony_cistatic void __init parse_region_decode(struct pci_controller *hose, 66562306a36Sopenharmony_ci u32 decode) 66662306a36Sopenharmony_ci{ 66762306a36Sopenharmony_ci unsigned long base, end, next = -1; 66862306a36Sopenharmony_ci int i, cur = -1; 66962306a36Sopenharmony_ci 67062306a36Sopenharmony_ci /* Iterate through all bits. We ignore the last bit as this region is 67162306a36Sopenharmony_ci * reserved for the ROM among other niceties 67262306a36Sopenharmony_ci */ 67362306a36Sopenharmony_ci for (i = 0; i < 31; i++) { 67462306a36Sopenharmony_ci if ((decode & (0x80000000 >> i)) == 0) 67562306a36Sopenharmony_ci continue; 67662306a36Sopenharmony_ci if (i < 16) { 67762306a36Sopenharmony_ci base = 0xf0000000 | (((u32)i) << 24); 67862306a36Sopenharmony_ci end = base + 0x00ffffff; 67962306a36Sopenharmony_ci } else { 68062306a36Sopenharmony_ci base = ((u32)i-16) << 28; 68162306a36Sopenharmony_ci end = base + 0x0fffffff; 68262306a36Sopenharmony_ci } 68362306a36Sopenharmony_ci if (base != next) { 68462306a36Sopenharmony_ci if (++cur >= 3) { 68562306a36Sopenharmony_ci printk(KERN_WARNING "PCI: Too many ranges !\n"); 68662306a36Sopenharmony_ci break; 68762306a36Sopenharmony_ci } 68862306a36Sopenharmony_ci hose->mem_resources[cur].flags = IORESOURCE_MEM; 68962306a36Sopenharmony_ci hose->mem_resources[cur].name = hose->dn->full_name; 69062306a36Sopenharmony_ci hose->mem_resources[cur].start = base; 69162306a36Sopenharmony_ci hose->mem_resources[cur].end = end; 69262306a36Sopenharmony_ci hose->mem_offset[cur] = 0; 69362306a36Sopenharmony_ci DBG(" %d: 0x%08lx-0x%08lx\n", cur, base, end); 69462306a36Sopenharmony_ci } else { 69562306a36Sopenharmony_ci DBG(" : -0x%08lx\n", end); 69662306a36Sopenharmony_ci hose->mem_resources[cur].end = end; 69762306a36Sopenharmony_ci } 69862306a36Sopenharmony_ci next = end + 1; 69962306a36Sopenharmony_ci } 70062306a36Sopenharmony_ci} 70162306a36Sopenharmony_ci 70262306a36Sopenharmony_cistatic void __init setup_u3_ht(struct pci_controller* hose) 70362306a36Sopenharmony_ci{ 70462306a36Sopenharmony_ci struct device_node *np = hose->dn; 70562306a36Sopenharmony_ci struct resource cfg_res, self_res; 70662306a36Sopenharmony_ci u32 decode; 70762306a36Sopenharmony_ci 70862306a36Sopenharmony_ci hose->ops = &u3_ht_pci_ops; 70962306a36Sopenharmony_ci 71062306a36Sopenharmony_ci /* Get base addresses from OF tree 71162306a36Sopenharmony_ci */ 71262306a36Sopenharmony_ci if (of_address_to_resource(np, 0, &cfg_res) || 71362306a36Sopenharmony_ci of_address_to_resource(np, 1, &self_res)) { 71462306a36Sopenharmony_ci printk(KERN_ERR "PCI: Failed to get U3/U4 HT resources !\n"); 71562306a36Sopenharmony_ci return; 71662306a36Sopenharmony_ci } 71762306a36Sopenharmony_ci 71862306a36Sopenharmony_ci /* Map external cfg space access into cfg_data and self registers 71962306a36Sopenharmony_ci * into cfg_addr 72062306a36Sopenharmony_ci */ 72162306a36Sopenharmony_ci hose->cfg_data = ioremap(cfg_res.start, 0x02000000); 72262306a36Sopenharmony_ci hose->cfg_addr = ioremap(self_res.start, resource_size(&self_res)); 72362306a36Sopenharmony_ci 72462306a36Sopenharmony_ci /* 72562306a36Sopenharmony_ci * /ht node doesn't expose a "ranges" property, we read the register 72662306a36Sopenharmony_ci * that controls the decoding logic and use that for memory regions. 72762306a36Sopenharmony_ci * The IO region is hard coded since it is fixed in HW as well. 72862306a36Sopenharmony_ci */ 72962306a36Sopenharmony_ci hose->io_base_phys = 0xf4000000; 73062306a36Sopenharmony_ci hose->pci_io_size = 0x00400000; 73162306a36Sopenharmony_ci hose->io_resource.name = np->full_name; 73262306a36Sopenharmony_ci hose->io_resource.start = 0; 73362306a36Sopenharmony_ci hose->io_resource.end = 0x003fffff; 73462306a36Sopenharmony_ci hose->io_resource.flags = IORESOURCE_IO; 73562306a36Sopenharmony_ci hose->first_busno = 0; 73662306a36Sopenharmony_ci hose->last_busno = 0xef; 73762306a36Sopenharmony_ci 73862306a36Sopenharmony_ci /* Note: fix offset when cfg_addr becomes a void * */ 73962306a36Sopenharmony_ci decode = in_be32(hose->cfg_addr + 0x80); 74062306a36Sopenharmony_ci 74162306a36Sopenharmony_ci DBG("PCI: Apple HT bridge decode register: 0x%08x\n", decode); 74262306a36Sopenharmony_ci 74362306a36Sopenharmony_ci /* NOTE: The decode register setup is a bit weird... region 74462306a36Sopenharmony_ci * 0xf8000000 for example is marked as enabled in there while it's 74562306a36Sopenharmony_ci & actually the memory controller registers. 74662306a36Sopenharmony_ci * That means that we are incorrectly attributing it to HT. 74762306a36Sopenharmony_ci * 74862306a36Sopenharmony_ci * In a similar vein, region 0xf4000000 is actually the HT IO space but 74962306a36Sopenharmony_ci * also marked as enabled in here and 0xf9000000 is used by some other 75062306a36Sopenharmony_ci * internal bits of the northbridge. 75162306a36Sopenharmony_ci * 75262306a36Sopenharmony_ci * Unfortunately, we can't just mask out those bit as we would end 75362306a36Sopenharmony_ci * up with more regions than we can cope (linux can only cope with 75462306a36Sopenharmony_ci * 3 memory regions for a PHB at this stage). 75562306a36Sopenharmony_ci * 75662306a36Sopenharmony_ci * So for now, we just do a little hack. We happen to -know- that 75762306a36Sopenharmony_ci * Apple firmware doesn't assign things below 0xfa000000 for that 75862306a36Sopenharmony_ci * bridge anyway so we mask out all bits we don't want. 75962306a36Sopenharmony_ci */ 76062306a36Sopenharmony_ci decode &= 0x003fffff; 76162306a36Sopenharmony_ci 76262306a36Sopenharmony_ci /* Now parse the resulting bits and build resources */ 76362306a36Sopenharmony_ci parse_region_decode(hose, decode); 76462306a36Sopenharmony_ci} 76562306a36Sopenharmony_ci#endif /* CONFIG_PPC64 */ 76662306a36Sopenharmony_ci 76762306a36Sopenharmony_ci/* 76862306a36Sopenharmony_ci * We assume that if we have a G3 powermac, we have one bridge called 76962306a36Sopenharmony_ci * "pci" (a MPC106) and no bandit or chaos bridges, and contrariwise, 77062306a36Sopenharmony_ci * if we have one or more bandit or chaos bridges, we don't have a MPC106. 77162306a36Sopenharmony_ci */ 77262306a36Sopenharmony_cistatic int __init pmac_add_bridge(struct device_node *dev) 77362306a36Sopenharmony_ci{ 77462306a36Sopenharmony_ci int len; 77562306a36Sopenharmony_ci struct pci_controller *hose; 77662306a36Sopenharmony_ci struct resource rsrc; 77762306a36Sopenharmony_ci char *disp_name; 77862306a36Sopenharmony_ci const int *bus_range; 77962306a36Sopenharmony_ci int primary = 1; 78062306a36Sopenharmony_ci 78162306a36Sopenharmony_ci DBG("Adding PCI host bridge %pOF\n", dev); 78262306a36Sopenharmony_ci 78362306a36Sopenharmony_ci /* Fetch host bridge registers address */ 78462306a36Sopenharmony_ci of_address_to_resource(dev, 0, &rsrc); 78562306a36Sopenharmony_ci 78662306a36Sopenharmony_ci /* Get bus range if any */ 78762306a36Sopenharmony_ci bus_range = of_get_property(dev, "bus-range", &len); 78862306a36Sopenharmony_ci if (bus_range == NULL || len < 2 * sizeof(int)) { 78962306a36Sopenharmony_ci printk(KERN_WARNING "Can't get bus-range for %pOF, assume" 79062306a36Sopenharmony_ci " bus 0\n", dev); 79162306a36Sopenharmony_ci } 79262306a36Sopenharmony_ci 79362306a36Sopenharmony_ci hose = pcibios_alloc_controller(dev); 79462306a36Sopenharmony_ci if (!hose) 79562306a36Sopenharmony_ci return -ENOMEM; 79662306a36Sopenharmony_ci hose->first_busno = bus_range ? bus_range[0] : 0; 79762306a36Sopenharmony_ci hose->last_busno = bus_range ? bus_range[1] : 0xff; 79862306a36Sopenharmony_ci hose->controller_ops = pmac_pci_controller_ops; 79962306a36Sopenharmony_ci 80062306a36Sopenharmony_ci disp_name = NULL; 80162306a36Sopenharmony_ci 80262306a36Sopenharmony_ci /* 64 bits only bridges */ 80362306a36Sopenharmony_ci#ifdef CONFIG_PPC64 80462306a36Sopenharmony_ci if (of_device_is_compatible(dev, "u3-agp")) { 80562306a36Sopenharmony_ci setup_u3_agp(hose); 80662306a36Sopenharmony_ci disp_name = "U3-AGP"; 80762306a36Sopenharmony_ci primary = 0; 80862306a36Sopenharmony_ci } else if (of_device_is_compatible(dev, "u3-ht")) { 80962306a36Sopenharmony_ci setup_u3_ht(hose); 81062306a36Sopenharmony_ci disp_name = "U3-HT"; 81162306a36Sopenharmony_ci primary = 1; 81262306a36Sopenharmony_ci } else if (of_device_is_compatible(dev, "u4-pcie")) { 81362306a36Sopenharmony_ci setup_u4_pcie(hose); 81462306a36Sopenharmony_ci disp_name = "U4-PCIE"; 81562306a36Sopenharmony_ci primary = 0; 81662306a36Sopenharmony_ci } 81762306a36Sopenharmony_ci printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number:" 81862306a36Sopenharmony_ci " %d->%d\n", disp_name, hose->first_busno, hose->last_busno); 81962306a36Sopenharmony_ci#endif /* CONFIG_PPC64 */ 82062306a36Sopenharmony_ci 82162306a36Sopenharmony_ci /* 32 bits only bridges */ 82262306a36Sopenharmony_ci#ifdef CONFIG_PPC32 82362306a36Sopenharmony_ci if (of_device_is_compatible(dev, "uni-north")) { 82462306a36Sopenharmony_ci primary = setup_uninorth(hose, &rsrc); 82562306a36Sopenharmony_ci disp_name = "UniNorth"; 82662306a36Sopenharmony_ci } else if (of_node_name_eq(dev, "pci")) { 82762306a36Sopenharmony_ci /* XXX assume this is a mpc106 (grackle) */ 82862306a36Sopenharmony_ci setup_grackle(hose); 82962306a36Sopenharmony_ci disp_name = "Grackle (MPC106)"; 83062306a36Sopenharmony_ci } else if (of_node_name_eq(dev, "bandit")) { 83162306a36Sopenharmony_ci setup_bandit(hose, &rsrc); 83262306a36Sopenharmony_ci disp_name = "Bandit"; 83362306a36Sopenharmony_ci } else if (of_node_name_eq(dev, "chaos")) { 83462306a36Sopenharmony_ci setup_chaos(hose, &rsrc); 83562306a36Sopenharmony_ci disp_name = "Chaos"; 83662306a36Sopenharmony_ci primary = 0; 83762306a36Sopenharmony_ci } 83862306a36Sopenharmony_ci printk(KERN_INFO "Found %s PCI host bridge at 0x%016llx. " 83962306a36Sopenharmony_ci "Firmware bus number: %d->%d\n", 84062306a36Sopenharmony_ci disp_name, (unsigned long long)rsrc.start, hose->first_busno, 84162306a36Sopenharmony_ci hose->last_busno); 84262306a36Sopenharmony_ci#endif /* CONFIG_PPC32 */ 84362306a36Sopenharmony_ci 84462306a36Sopenharmony_ci DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", 84562306a36Sopenharmony_ci hose, hose->cfg_addr, hose->cfg_data); 84662306a36Sopenharmony_ci 84762306a36Sopenharmony_ci /* Interpret the "ranges" property */ 84862306a36Sopenharmony_ci /* This also maps the I/O region and sets isa_io/mem_base */ 84962306a36Sopenharmony_ci pci_process_bridge_OF_ranges(hose, dev, primary); 85062306a36Sopenharmony_ci 85162306a36Sopenharmony_ci /* Fixup "bus-range" OF property */ 85262306a36Sopenharmony_ci fixup_bus_range(dev); 85362306a36Sopenharmony_ci 85462306a36Sopenharmony_ci /* create pci_dn's for DT nodes under this PHB */ 85562306a36Sopenharmony_ci if (IS_ENABLED(CONFIG_PPC64)) 85662306a36Sopenharmony_ci pci_devs_phb_init_dynamic(hose); 85762306a36Sopenharmony_ci 85862306a36Sopenharmony_ci return 0; 85962306a36Sopenharmony_ci} 86062306a36Sopenharmony_ci 86162306a36Sopenharmony_civoid pmac_pci_irq_fixup(struct pci_dev *dev) 86262306a36Sopenharmony_ci{ 86362306a36Sopenharmony_ci#ifdef CONFIG_PPC32 86462306a36Sopenharmony_ci /* Fixup interrupt for the modem/ethernet combo controller. 86562306a36Sopenharmony_ci * on machines with a second ohare chip. 86662306a36Sopenharmony_ci * The number in the device tree (27) is bogus (correct for 86762306a36Sopenharmony_ci * the ethernet-only board but not the combo ethernet/modem 86862306a36Sopenharmony_ci * board). The real interrupt is 28 on the second controller 86962306a36Sopenharmony_ci * -> 28+32 = 60. 87062306a36Sopenharmony_ci */ 87162306a36Sopenharmony_ci if (has_second_ohare && 87262306a36Sopenharmony_ci dev->vendor == PCI_VENDOR_ID_DEC && 87362306a36Sopenharmony_ci dev->device == PCI_DEVICE_ID_DEC_TULIP_PLUS) { 87462306a36Sopenharmony_ci dev->irq = irq_create_mapping(NULL, 60); 87562306a36Sopenharmony_ci irq_set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW); 87662306a36Sopenharmony_ci } 87762306a36Sopenharmony_ci#endif /* CONFIG_PPC32 */ 87862306a36Sopenharmony_ci} 87962306a36Sopenharmony_ci 88062306a36Sopenharmony_ci#ifdef CONFIG_PPC64 88162306a36Sopenharmony_cistatic int pmac_pci_root_bridge_prepare(struct pci_host_bridge *bridge) 88262306a36Sopenharmony_ci{ 88362306a36Sopenharmony_ci struct pci_controller *hose = pci_bus_to_host(bridge->bus); 88462306a36Sopenharmony_ci struct device_node *np, *child; 88562306a36Sopenharmony_ci 88662306a36Sopenharmony_ci if (hose != u3_agp) 88762306a36Sopenharmony_ci return 0; 88862306a36Sopenharmony_ci 88962306a36Sopenharmony_ci /* Fixup the PCI<->OF mapping for U3 AGP due to bus renumbering. We 89062306a36Sopenharmony_ci * assume there is no P2P bridge on the AGP bus, which should be a 89162306a36Sopenharmony_ci * safe assumptions for now. We should do something better in the 89262306a36Sopenharmony_ci * future though 89362306a36Sopenharmony_ci */ 89462306a36Sopenharmony_ci np = hose->dn; 89562306a36Sopenharmony_ci PCI_DN(np)->busno = 0xf0; 89662306a36Sopenharmony_ci for_each_child_of_node(np, child) 89762306a36Sopenharmony_ci PCI_DN(child)->busno = 0xf0; 89862306a36Sopenharmony_ci 89962306a36Sopenharmony_ci return 0; 90062306a36Sopenharmony_ci} 90162306a36Sopenharmony_ci#endif /* CONFIG_PPC64 */ 90262306a36Sopenharmony_ci 90362306a36Sopenharmony_civoid __init pmac_pci_init(void) 90462306a36Sopenharmony_ci{ 90562306a36Sopenharmony_ci struct device_node *np, *root; 90662306a36Sopenharmony_ci struct device_node *ht __maybe_unused = NULL; 90762306a36Sopenharmony_ci 90862306a36Sopenharmony_ci pci_set_flags(PCI_CAN_SKIP_ISA_ALIGN); 90962306a36Sopenharmony_ci 91062306a36Sopenharmony_ci root = of_find_node_by_path("/"); 91162306a36Sopenharmony_ci if (root == NULL) { 91262306a36Sopenharmony_ci printk(KERN_CRIT "pmac_pci_init: can't find root " 91362306a36Sopenharmony_ci "of device tree\n"); 91462306a36Sopenharmony_ci return; 91562306a36Sopenharmony_ci } 91662306a36Sopenharmony_ci for_each_child_of_node(root, np) { 91762306a36Sopenharmony_ci if (of_node_name_eq(np, "bandit") 91862306a36Sopenharmony_ci || of_node_name_eq(np, "chaos") 91962306a36Sopenharmony_ci || of_node_name_eq(np, "pci")) { 92062306a36Sopenharmony_ci if (pmac_add_bridge(np) == 0) 92162306a36Sopenharmony_ci of_node_get(np); 92262306a36Sopenharmony_ci } 92362306a36Sopenharmony_ci if (of_node_name_eq(np, "ht")) { 92462306a36Sopenharmony_ci of_node_get(np); 92562306a36Sopenharmony_ci ht = np; 92662306a36Sopenharmony_ci } 92762306a36Sopenharmony_ci } 92862306a36Sopenharmony_ci of_node_put(root); 92962306a36Sopenharmony_ci 93062306a36Sopenharmony_ci#ifdef CONFIG_PPC64 93162306a36Sopenharmony_ci /* Probe HT last as it relies on the agp resources to be already 93262306a36Sopenharmony_ci * setup 93362306a36Sopenharmony_ci */ 93462306a36Sopenharmony_ci if (ht && pmac_add_bridge(ht) != 0) 93562306a36Sopenharmony_ci of_node_put(ht); 93662306a36Sopenharmony_ci 93762306a36Sopenharmony_ci ppc_md.pcibios_root_bridge_prepare = pmac_pci_root_bridge_prepare; 93862306a36Sopenharmony_ci /* pmac_check_ht_link(); */ 93962306a36Sopenharmony_ci 94062306a36Sopenharmony_ci#else /* CONFIG_PPC64 */ 94162306a36Sopenharmony_ci init_p2pbridge(); 94262306a36Sopenharmony_ci init_second_ohare(); 94362306a36Sopenharmony_ci fixup_nec_usb2(); 94462306a36Sopenharmony_ci 94562306a36Sopenharmony_ci /* We are still having some issues with the Xserve G4, enabling 94662306a36Sopenharmony_ci * some offset between bus number and domains for now when we 94762306a36Sopenharmony_ci * assign all busses should help for now 94862306a36Sopenharmony_ci */ 94962306a36Sopenharmony_ci if (pci_has_flag(PCI_REASSIGN_ALL_BUS)) 95062306a36Sopenharmony_ci pcibios_assign_bus_offset = 0x10; 95162306a36Sopenharmony_ci#endif 95262306a36Sopenharmony_ci} 95362306a36Sopenharmony_ci 95462306a36Sopenharmony_ci#ifdef CONFIG_PPC32 95562306a36Sopenharmony_cistatic bool pmac_pci_enable_device_hook(struct pci_dev *dev) 95662306a36Sopenharmony_ci{ 95762306a36Sopenharmony_ci struct device_node* node; 95862306a36Sopenharmony_ci int updatecfg = 0; 95962306a36Sopenharmony_ci int uninorth_child; 96062306a36Sopenharmony_ci 96162306a36Sopenharmony_ci node = pci_device_to_OF_node(dev); 96262306a36Sopenharmony_ci 96362306a36Sopenharmony_ci /* We don't want to enable USB controllers absent from the OF tree 96462306a36Sopenharmony_ci * (iBook second controller) 96562306a36Sopenharmony_ci */ 96662306a36Sopenharmony_ci if (dev->vendor == PCI_VENDOR_ID_APPLE 96762306a36Sopenharmony_ci && dev->class == PCI_CLASS_SERIAL_USB_OHCI 96862306a36Sopenharmony_ci && !node) { 96962306a36Sopenharmony_ci printk(KERN_INFO "Apple USB OHCI %s disabled by firmware\n", 97062306a36Sopenharmony_ci pci_name(dev)); 97162306a36Sopenharmony_ci return false; 97262306a36Sopenharmony_ci } 97362306a36Sopenharmony_ci 97462306a36Sopenharmony_ci if (!node) 97562306a36Sopenharmony_ci return true; 97662306a36Sopenharmony_ci 97762306a36Sopenharmony_ci uninorth_child = node->parent && 97862306a36Sopenharmony_ci of_device_is_compatible(node->parent, "uni-north"); 97962306a36Sopenharmony_ci 98062306a36Sopenharmony_ci /* Firewire & GMAC were disabled after PCI probe, the driver is 98162306a36Sopenharmony_ci * claiming them, we must re-enable them now. 98262306a36Sopenharmony_ci */ 98362306a36Sopenharmony_ci if (uninorth_child && of_node_name_eq(node, "firewire") && 98462306a36Sopenharmony_ci (of_device_is_compatible(node, "pci106b,18") || 98562306a36Sopenharmony_ci of_device_is_compatible(node, "pci106b,30") || 98662306a36Sopenharmony_ci of_device_is_compatible(node, "pci11c1,5811"))) { 98762306a36Sopenharmony_ci pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, node, 0, 1); 98862306a36Sopenharmony_ci pmac_call_feature(PMAC_FTR_1394_ENABLE, node, 0, 1); 98962306a36Sopenharmony_ci updatecfg = 1; 99062306a36Sopenharmony_ci } 99162306a36Sopenharmony_ci if (uninorth_child && of_node_name_eq(node, "ethernet") && 99262306a36Sopenharmony_ci of_device_is_compatible(node, "gmac")) { 99362306a36Sopenharmony_ci pmac_call_feature(PMAC_FTR_GMAC_ENABLE, node, 0, 1); 99462306a36Sopenharmony_ci updatecfg = 1; 99562306a36Sopenharmony_ci } 99662306a36Sopenharmony_ci 99762306a36Sopenharmony_ci /* 99862306a36Sopenharmony_ci * Fixup various header fields on 32 bits. We don't do that on 99962306a36Sopenharmony_ci * 64 bits as some of these have strange values behind the HT 100062306a36Sopenharmony_ci * bridge and we must not, for example, enable MWI or set the 100162306a36Sopenharmony_ci * cache line size on them. 100262306a36Sopenharmony_ci */ 100362306a36Sopenharmony_ci if (updatecfg) { 100462306a36Sopenharmony_ci u16 cmd; 100562306a36Sopenharmony_ci 100662306a36Sopenharmony_ci pci_read_config_word(dev, PCI_COMMAND, &cmd); 100762306a36Sopenharmony_ci cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER 100862306a36Sopenharmony_ci | PCI_COMMAND_INVALIDATE; 100962306a36Sopenharmony_ci pci_write_config_word(dev, PCI_COMMAND, cmd); 101062306a36Sopenharmony_ci pci_write_config_byte(dev, PCI_LATENCY_TIMER, 16); 101162306a36Sopenharmony_ci 101262306a36Sopenharmony_ci pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 101362306a36Sopenharmony_ci L1_CACHE_BYTES >> 2); 101462306a36Sopenharmony_ci } 101562306a36Sopenharmony_ci 101662306a36Sopenharmony_ci return true; 101762306a36Sopenharmony_ci} 101862306a36Sopenharmony_ci 101962306a36Sopenharmony_cistatic void pmac_pci_fixup_ohci(struct pci_dev *dev) 102062306a36Sopenharmony_ci{ 102162306a36Sopenharmony_ci struct device_node *node = pci_device_to_OF_node(dev); 102262306a36Sopenharmony_ci 102362306a36Sopenharmony_ci /* We don't want to assign resources to USB controllers 102462306a36Sopenharmony_ci * absent from the OF tree (iBook second controller) 102562306a36Sopenharmony_ci */ 102662306a36Sopenharmony_ci if (dev->class == PCI_CLASS_SERIAL_USB_OHCI && !node) 102762306a36Sopenharmony_ci dev->resource[0].flags = 0; 102862306a36Sopenharmony_ci} 102962306a36Sopenharmony_ciDECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_APPLE, PCI_ANY_ID, pmac_pci_fixup_ohci); 103062306a36Sopenharmony_ci 103162306a36Sopenharmony_ci/* We power down some devices after they have been probed. They'll 103262306a36Sopenharmony_ci * be powered back on later on 103362306a36Sopenharmony_ci */ 103462306a36Sopenharmony_civoid __init pmac_pcibios_after_init(void) 103562306a36Sopenharmony_ci{ 103662306a36Sopenharmony_ci struct device_node* nd; 103762306a36Sopenharmony_ci 103862306a36Sopenharmony_ci for_each_node_by_name(nd, "firewire") { 103962306a36Sopenharmony_ci if (nd->parent && (of_device_is_compatible(nd, "pci106b,18") || 104062306a36Sopenharmony_ci of_device_is_compatible(nd, "pci106b,30") || 104162306a36Sopenharmony_ci of_device_is_compatible(nd, "pci11c1,5811")) 104262306a36Sopenharmony_ci && of_device_is_compatible(nd->parent, "uni-north")) { 104362306a36Sopenharmony_ci pmac_call_feature(PMAC_FTR_1394_ENABLE, nd, 0, 0); 104462306a36Sopenharmony_ci pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, nd, 0, 0); 104562306a36Sopenharmony_ci } 104662306a36Sopenharmony_ci } 104762306a36Sopenharmony_ci for_each_node_by_name(nd, "ethernet") { 104862306a36Sopenharmony_ci if (nd->parent && of_device_is_compatible(nd, "gmac") 104962306a36Sopenharmony_ci && of_device_is_compatible(nd->parent, "uni-north")) 105062306a36Sopenharmony_ci pmac_call_feature(PMAC_FTR_GMAC_ENABLE, nd, 0, 0); 105162306a36Sopenharmony_ci } 105262306a36Sopenharmony_ci} 105362306a36Sopenharmony_ci 105462306a36Sopenharmony_cistatic void pmac_pci_fixup_cardbus(struct pci_dev *dev) 105562306a36Sopenharmony_ci{ 105662306a36Sopenharmony_ci if (!machine_is(powermac)) 105762306a36Sopenharmony_ci return; 105862306a36Sopenharmony_ci /* 105962306a36Sopenharmony_ci * Fix the interrupt routing on the various cardbus bridges 106062306a36Sopenharmony_ci * used on powerbooks 106162306a36Sopenharmony_ci */ 106262306a36Sopenharmony_ci if (dev->vendor != PCI_VENDOR_ID_TI) 106362306a36Sopenharmony_ci return; 106462306a36Sopenharmony_ci if (dev->device == PCI_DEVICE_ID_TI_1130 || 106562306a36Sopenharmony_ci dev->device == PCI_DEVICE_ID_TI_1131) { 106662306a36Sopenharmony_ci u8 val; 106762306a36Sopenharmony_ci /* Enable PCI interrupt */ 106862306a36Sopenharmony_ci if (pci_read_config_byte(dev, 0x91, &val) == 0) 106962306a36Sopenharmony_ci pci_write_config_byte(dev, 0x91, val | 0x30); 107062306a36Sopenharmony_ci /* Disable ISA interrupt mode */ 107162306a36Sopenharmony_ci if (pci_read_config_byte(dev, 0x92, &val) == 0) 107262306a36Sopenharmony_ci pci_write_config_byte(dev, 0x92, val & ~0x06); 107362306a36Sopenharmony_ci } 107462306a36Sopenharmony_ci if (dev->device == PCI_DEVICE_ID_TI_1210 || 107562306a36Sopenharmony_ci dev->device == PCI_DEVICE_ID_TI_1211 || 107662306a36Sopenharmony_ci dev->device == PCI_DEVICE_ID_TI_1410 || 107762306a36Sopenharmony_ci dev->device == PCI_DEVICE_ID_TI_1510) { 107862306a36Sopenharmony_ci u8 val; 107962306a36Sopenharmony_ci /* 0x8c == TI122X_IRQMUX, 2 says to route the INTA 108062306a36Sopenharmony_ci signal out the MFUNC0 pin */ 108162306a36Sopenharmony_ci if (pci_read_config_byte(dev, 0x8c, &val) == 0) 108262306a36Sopenharmony_ci pci_write_config_byte(dev, 0x8c, (val & ~0x0f) | 2); 108362306a36Sopenharmony_ci /* Disable ISA interrupt mode */ 108462306a36Sopenharmony_ci if (pci_read_config_byte(dev, 0x92, &val) == 0) 108562306a36Sopenharmony_ci pci_write_config_byte(dev, 0x92, val & ~0x06); 108662306a36Sopenharmony_ci } 108762306a36Sopenharmony_ci} 108862306a36Sopenharmony_ci 108962306a36Sopenharmony_ciDECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TI, PCI_ANY_ID, pmac_pci_fixup_cardbus); 109062306a36Sopenharmony_ci 109162306a36Sopenharmony_cistatic void pmac_pci_fixup_pciata(struct pci_dev *dev) 109262306a36Sopenharmony_ci{ 109362306a36Sopenharmony_ci u8 progif = 0; 109462306a36Sopenharmony_ci 109562306a36Sopenharmony_ci /* 109662306a36Sopenharmony_ci * On PowerMacs, we try to switch any PCI ATA controller to 109762306a36Sopenharmony_ci * fully native mode 109862306a36Sopenharmony_ci */ 109962306a36Sopenharmony_ci if (!machine_is(powermac)) 110062306a36Sopenharmony_ci return; 110162306a36Sopenharmony_ci 110262306a36Sopenharmony_ci /* Some controllers don't have the class IDE */ 110362306a36Sopenharmony_ci if (dev->vendor == PCI_VENDOR_ID_PROMISE) 110462306a36Sopenharmony_ci switch(dev->device) { 110562306a36Sopenharmony_ci case PCI_DEVICE_ID_PROMISE_20246: 110662306a36Sopenharmony_ci case PCI_DEVICE_ID_PROMISE_20262: 110762306a36Sopenharmony_ci case PCI_DEVICE_ID_PROMISE_20263: 110862306a36Sopenharmony_ci case PCI_DEVICE_ID_PROMISE_20265: 110962306a36Sopenharmony_ci case PCI_DEVICE_ID_PROMISE_20267: 111062306a36Sopenharmony_ci case PCI_DEVICE_ID_PROMISE_20268: 111162306a36Sopenharmony_ci case PCI_DEVICE_ID_PROMISE_20269: 111262306a36Sopenharmony_ci case PCI_DEVICE_ID_PROMISE_20270: 111362306a36Sopenharmony_ci case PCI_DEVICE_ID_PROMISE_20271: 111462306a36Sopenharmony_ci case PCI_DEVICE_ID_PROMISE_20275: 111562306a36Sopenharmony_ci case PCI_DEVICE_ID_PROMISE_20276: 111662306a36Sopenharmony_ci case PCI_DEVICE_ID_PROMISE_20277: 111762306a36Sopenharmony_ci goto good; 111862306a36Sopenharmony_ci } 111962306a36Sopenharmony_ci /* Others, check PCI class */ 112062306a36Sopenharmony_ci if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) 112162306a36Sopenharmony_ci return; 112262306a36Sopenharmony_ci good: 112362306a36Sopenharmony_ci pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); 112462306a36Sopenharmony_ci if ((progif & 5) != 5) { 112562306a36Sopenharmony_ci printk(KERN_INFO "PCI: %s Forcing PCI IDE into native mode\n", 112662306a36Sopenharmony_ci pci_name(dev)); 112762306a36Sopenharmony_ci (void) pci_write_config_byte(dev, PCI_CLASS_PROG, progif|5); 112862306a36Sopenharmony_ci if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif) || 112962306a36Sopenharmony_ci (progif & 5) != 5) 113062306a36Sopenharmony_ci printk(KERN_ERR "Rewrite of PROGIF failed !\n"); 113162306a36Sopenharmony_ci else { 113262306a36Sopenharmony_ci /* Clear IO BARs, they will be reassigned */ 113362306a36Sopenharmony_ci pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0); 113462306a36Sopenharmony_ci pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0); 113562306a36Sopenharmony_ci pci_write_config_dword(dev, PCI_BASE_ADDRESS_2, 0); 113662306a36Sopenharmony_ci pci_write_config_dword(dev, PCI_BASE_ADDRESS_3, 0); 113762306a36Sopenharmony_ci } 113862306a36Sopenharmony_ci } 113962306a36Sopenharmony_ci} 114062306a36Sopenharmony_ciDECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, pmac_pci_fixup_pciata); 114162306a36Sopenharmony_ci#endif /* CONFIG_PPC32 */ 114262306a36Sopenharmony_ci 114362306a36Sopenharmony_ci/* 114462306a36Sopenharmony_ci * Disable second function on K2-SATA, it's broken 114562306a36Sopenharmony_ci * and disable IO BARs on first one 114662306a36Sopenharmony_ci */ 114762306a36Sopenharmony_cistatic void fixup_k2_sata(struct pci_dev* dev) 114862306a36Sopenharmony_ci{ 114962306a36Sopenharmony_ci int i; 115062306a36Sopenharmony_ci u16 cmd; 115162306a36Sopenharmony_ci 115262306a36Sopenharmony_ci if (PCI_FUNC(dev->devfn) > 0) { 115362306a36Sopenharmony_ci pci_read_config_word(dev, PCI_COMMAND, &cmd); 115462306a36Sopenharmony_ci cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY); 115562306a36Sopenharmony_ci pci_write_config_word(dev, PCI_COMMAND, cmd); 115662306a36Sopenharmony_ci for (i = 0; i < 6; i++) { 115762306a36Sopenharmony_ci dev->resource[i].start = dev->resource[i].end = 0; 115862306a36Sopenharmony_ci dev->resource[i].flags = 0; 115962306a36Sopenharmony_ci pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 116062306a36Sopenharmony_ci 0); 116162306a36Sopenharmony_ci } 116262306a36Sopenharmony_ci } else { 116362306a36Sopenharmony_ci pci_read_config_word(dev, PCI_COMMAND, &cmd); 116462306a36Sopenharmony_ci cmd &= ~PCI_COMMAND_IO; 116562306a36Sopenharmony_ci pci_write_config_word(dev, PCI_COMMAND, cmd); 116662306a36Sopenharmony_ci for (i = 0; i < 5; i++) { 116762306a36Sopenharmony_ci dev->resource[i].start = dev->resource[i].end = 0; 116862306a36Sopenharmony_ci dev->resource[i].flags = 0; 116962306a36Sopenharmony_ci pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 117062306a36Sopenharmony_ci 0); 117162306a36Sopenharmony_ci } 117262306a36Sopenharmony_ci } 117362306a36Sopenharmony_ci} 117462306a36Sopenharmony_ciDECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, 0x0240, fixup_k2_sata); 117562306a36Sopenharmony_ci 117662306a36Sopenharmony_ci/* 117762306a36Sopenharmony_ci * On U4 (aka CPC945) the PCIe root complex "P2P" bridge resource ranges aren't 117862306a36Sopenharmony_ci * configured by the firmware. The bridge itself seems to ignore them but it 117962306a36Sopenharmony_ci * causes problems with Linux which then re-assigns devices below the bridge, 118062306a36Sopenharmony_ci * thus changing addresses of those devices from what was in the device-tree, 118162306a36Sopenharmony_ci * which sucks when those are video cards using offb 118262306a36Sopenharmony_ci * 118362306a36Sopenharmony_ci * We could just mark it transparent but I prefer fixing up the resources to 118462306a36Sopenharmony_ci * properly show what's going on here, as I have some doubts about having them 118562306a36Sopenharmony_ci * badly configured potentially being an issue for DMA. 118662306a36Sopenharmony_ci * 118762306a36Sopenharmony_ci * We leave PIO alone, it seems to be fine 118862306a36Sopenharmony_ci * 118962306a36Sopenharmony_ci * Oh and there's another funny bug. The OF properties advertize the region 119062306a36Sopenharmony_ci * 0xf1000000..0xf1ffffff as being forwarded as memory space. But that's 119162306a36Sopenharmony_ci * actually not true, this region is the memory mapped config space. So we 119262306a36Sopenharmony_ci * also need to filter it out or we'll map things in the wrong place. 119362306a36Sopenharmony_ci */ 119462306a36Sopenharmony_cistatic void fixup_u4_pcie(struct pci_dev* dev) 119562306a36Sopenharmony_ci{ 119662306a36Sopenharmony_ci struct pci_controller *host = pci_bus_to_host(dev->bus); 119762306a36Sopenharmony_ci struct resource *region = NULL; 119862306a36Sopenharmony_ci u32 reg; 119962306a36Sopenharmony_ci int i; 120062306a36Sopenharmony_ci 120162306a36Sopenharmony_ci /* Only do that on PowerMac */ 120262306a36Sopenharmony_ci if (!machine_is(powermac)) 120362306a36Sopenharmony_ci return; 120462306a36Sopenharmony_ci 120562306a36Sopenharmony_ci /* Find the largest MMIO region */ 120662306a36Sopenharmony_ci for (i = 0; i < 3; i++) { 120762306a36Sopenharmony_ci struct resource *r = &host->mem_resources[i]; 120862306a36Sopenharmony_ci if (!(r->flags & IORESOURCE_MEM)) 120962306a36Sopenharmony_ci continue; 121062306a36Sopenharmony_ci /* Skip the 0xf0xxxxxx..f2xxxxxx regions, we know they 121162306a36Sopenharmony_ci * are reserved by HW for other things 121262306a36Sopenharmony_ci */ 121362306a36Sopenharmony_ci if (r->start >= 0xf0000000 && r->start < 0xf3000000) 121462306a36Sopenharmony_ci continue; 121562306a36Sopenharmony_ci if (!region || resource_size(r) > resource_size(region)) 121662306a36Sopenharmony_ci region = r; 121762306a36Sopenharmony_ci } 121862306a36Sopenharmony_ci /* Nothing found, bail */ 121962306a36Sopenharmony_ci if (!region) 122062306a36Sopenharmony_ci return; 122162306a36Sopenharmony_ci 122262306a36Sopenharmony_ci /* Print things out */ 122362306a36Sopenharmony_ci printk(KERN_INFO "PCI: Fixup U4 PCIe bridge range: %pR\n", region); 122462306a36Sopenharmony_ci 122562306a36Sopenharmony_ci /* Fixup bridge config space. We know it's a Mac, resource aren't 122662306a36Sopenharmony_ci * offset so let's just blast them as-is. We also know that they 122762306a36Sopenharmony_ci * fit in 32 bits 122862306a36Sopenharmony_ci */ 122962306a36Sopenharmony_ci reg = ((region->start >> 16) & 0xfff0) | (region->end & 0xfff00000); 123062306a36Sopenharmony_ci pci_write_config_dword(dev, PCI_MEMORY_BASE, reg); 123162306a36Sopenharmony_ci pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0); 123262306a36Sopenharmony_ci pci_write_config_dword(dev, PCI_PREF_LIMIT_UPPER32, 0); 123362306a36Sopenharmony_ci pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0); 123462306a36Sopenharmony_ci} 123562306a36Sopenharmony_ciDECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_U4_PCIE, fixup_u4_pcie); 123662306a36Sopenharmony_ci 123762306a36Sopenharmony_ci#ifdef CONFIG_PPC64 123862306a36Sopenharmony_cistatic int pmac_pci_probe_mode(struct pci_bus *bus) 123962306a36Sopenharmony_ci{ 124062306a36Sopenharmony_ci struct device_node *node = pci_bus_to_OF_node(bus); 124162306a36Sopenharmony_ci 124262306a36Sopenharmony_ci /* We need to use normal PCI probing for the AGP bus, 124362306a36Sopenharmony_ci * since the device for the AGP bridge isn't in the tree. 124462306a36Sopenharmony_ci * Same for the PCIe host on U4 and the HT host bridge. 124562306a36Sopenharmony_ci */ 124662306a36Sopenharmony_ci if (bus->self == NULL && (of_device_is_compatible(node, "u3-agp") || 124762306a36Sopenharmony_ci of_device_is_compatible(node, "u4-pcie") || 124862306a36Sopenharmony_ci of_device_is_compatible(node, "u3-ht"))) 124962306a36Sopenharmony_ci return PCI_PROBE_NORMAL; 125062306a36Sopenharmony_ci return PCI_PROBE_DEVTREE; 125162306a36Sopenharmony_ci} 125262306a36Sopenharmony_ci#endif /* CONFIG_PPC64 */ 125362306a36Sopenharmony_ci 125462306a36Sopenharmony_cistruct pci_controller_ops pmac_pci_controller_ops = { 125562306a36Sopenharmony_ci#ifdef CONFIG_PPC64 125662306a36Sopenharmony_ci .probe_mode = pmac_pci_probe_mode, 125762306a36Sopenharmony_ci#endif 125862306a36Sopenharmony_ci#ifdef CONFIG_PPC32 125962306a36Sopenharmony_ci .enable_device_hook = pmac_pci_enable_device_hook, 126062306a36Sopenharmony_ci#endif 126162306a36Sopenharmony_ci}; 1262