aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sh/drivers/pci/ops-sh7786.c35
-rw-r--r--arch/sh/drivers/pci/pcie-sh7786.c29
2 files changed, 55 insertions, 9 deletions
diff --git a/arch/sh/drivers/pci/ops-sh7786.c b/arch/sh/drivers/pci/ops-sh7786.c
index 4728199f71a6..01cb70fbd803 100644
--- a/arch/sh/drivers/pci/ops-sh7786.c
+++ b/arch/sh/drivers/pci/ops-sh7786.c
@@ -25,23 +25,49 @@ static int sh7786_pcie_config_access(unsigned char access_type,
25 struct pci_bus *bus, unsigned int devfn, int where, u32 *data) 25 struct pci_bus *bus, unsigned int devfn, int where, u32 *data)
26{ 26{
27 struct pci_channel *chan = bus->sysdata; 27 struct pci_channel *chan = bus->sysdata;
28 int dev, func, type; 28 int dev, func, type, reg;
29 29
30 dev = PCI_SLOT(devfn); 30 dev = PCI_SLOT(devfn);
31 func = PCI_FUNC(devfn); 31 func = PCI_FUNC(devfn);
32 type = !!bus->parent; 32 type = !!bus->parent;
33 reg = where & ~3;
33 34
34 if (bus->number > 255 || dev > 31 || func > 7) 35 if (bus->number > 255 || dev > 31 || func > 7)
35 return PCIBIOS_FUNC_NOT_SUPPORTED; 36 return PCIBIOS_FUNC_NOT_SUPPORTED;
36 if (bus->parent == NULL && dev) 37
37 return PCIBIOS_DEVICE_NOT_FOUND; 38 /*
39 * While each channel has its own memory-mapped extended config
40 * space, it's generally only accessible when in endpoint mode.
41 * When in root complex mode, the controller is unable to target
42 * itself with either type 0 or type 1 accesses, and indeed, any
43 * controller initiated target transfer to its own config space
44 * result in a completer abort.
45 *
46 * Each channel effectively only supports a single device, but as
47 * the same channel <-> device access works for any PCI_SLOT()
48 * value, we cheat a bit here and bind the controller's config
49 * space to devfn 0 in order to enable self-enumeration. In this
50 * case the regular PAR/PDR path is sidelined and the mangled
51 * config access itself is initiated as a SuperHyway transaction.
52 */
53 if (pci_is_root_bus(bus)) {
54 if (dev == 0) {
55 if (access_type == PCI_ACCESS_READ)
56 *data = pci_read_reg(chan, PCI_REG(reg));
57 else
58 pci_write_reg(chan, *data, PCI_REG(reg));
59
60 return PCIBIOS_SUCCESSFUL;
61 } else if (dev > 1)
62 return PCIBIOS_DEVICE_NOT_FOUND;
63 }
38 64
39 /* Clear errors */ 65 /* Clear errors */
40 pci_write_reg(chan, pci_read_reg(chan, SH4A_PCIEERRFR), SH4A_PCIEERRFR); 66 pci_write_reg(chan, pci_read_reg(chan, SH4A_PCIEERRFR), SH4A_PCIEERRFR);
41 67
42 /* Set the PIO address */ 68 /* Set the PIO address */
43 pci_write_reg(chan, (bus->number << 24) | (dev << 19) | 69 pci_write_reg(chan, (bus->number << 24) | (dev << 19) |
44 (func << 16) | (where & ~3), SH4A_PCIEPAR); 70 (func << 16) | reg, SH4A_PCIEPAR);
45 71
46 /* Enable the configuration access */ 72 /* Enable the configuration access */
47 pci_write_reg(chan, (1 << 31) | (type << 8), SH4A_PCIEPCTLR); 73 pci_write_reg(chan, (1 << 31) | (type << 8), SH4A_PCIEPCTLR);
@@ -49,6 +75,7 @@ static int sh7786_pcie_config_access(unsigned char access_type,
49 /* Check for errors */ 75 /* Check for errors */
50 if (pci_read_reg(chan, SH4A_PCIEERRFR) & 0x10) 76 if (pci_read_reg(chan, SH4A_PCIEERRFR) & 0x10)
51 return PCIBIOS_DEVICE_NOT_FOUND; 77 return PCIBIOS_DEVICE_NOT_FOUND;
78
52 /* Check for master and target aborts */ 79 /* Check for master and target aborts */
53 if (pci_read_reg(chan, SH4A_PCIEPCICONF1) & ((1 << 29) | (1 << 28))) 80 if (pci_read_reg(chan, SH4A_PCIEPCICONF1) & ((1 << 29) | (1 << 28)))
54 return PCIBIOS_DEVICE_NOT_FOUND; 81 return PCIBIOS_DEVICE_NOT_FOUND;
diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c
index 4e6cf8804979..3dfc250b897a 100644
--- a/arch/sh/drivers/pci/pcie-sh7786.c
+++ b/arch/sh/drivers/pci/pcie-sh7786.c
@@ -121,6 +121,24 @@ static struct pci_channel sh7786_pci_channels[] = {
121 DEFINE_CONTROLLER(0xfcc00000, 2), 121 DEFINE_CONTROLLER(0xfcc00000, 2),
122}; 122};
123 123
124static void __devinit sh7786_pci_fixup(struct pci_dev *dev)
125{
126 /*
127 * Prevent enumeration of root complex resources.
128 */
129 if (pci_is_root_bus(dev->bus) && dev->devfn == 0) {
130 int i;
131
132 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
133 dev->resource[i].start = 0;
134 dev->resource[i].end = 0;
135 dev->resource[i].flags = 0;
136 }
137 }
138}
139DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_SH7786,
140 sh7786_pci_fixup);
141
124static int phy_wait_for_ack(struct pci_channel *chan) 142static int phy_wait_for_ack(struct pci_channel *chan)
125{ 143{
126 unsigned int timeout = 100; 144 unsigned int timeout = 100;
@@ -229,11 +247,12 @@ static int pcie_init(struct sh7786_pcie_port *port)
229 /* Begin initialization */ 247 /* Begin initialization */
230 pcie_reset(port); 248 pcie_reset(port);
231 249
232 /* Initialize as type1. */ 250 /*
233 data = pci_read_reg(chan, SH4A_PCIEPCICONF3); 251 * Initial header for port config space is type 1, set the device
234 data &= ~(0x7f << 16); 252 * class to match. Hardware takes care of propagating the IDSETR
235 data |= PCI_HEADER_TYPE_BRIDGE << 16; 253 * settings, so there is no need to bother with a quirk.
236 pci_write_reg(chan, data, SH4A_PCIEPCICONF3); 254 */
255 pci_write_reg(chan, PCI_CLASS_BRIDGE_PCI << 16, SH4A_PCIEIDSETR1);
237 256
238 /* Initialize default capabilities. */ 257 /* Initialize default capabilities. */
239 data = pci_read_reg(chan, SH4A_PCIEEXPCAP0); 258 data = pci_read_reg(chan, SH4A_PCIEEXPCAP0);