1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2006 PA Semi, Inc 4 * 5 * Authors: Kip Walker, PA Semi 6 * Olof Johansson, PA Semi 7 * 8 * Maintained by: Olof Johansson <olof@lixom.net> 9 * 10 * Based on arch/powerpc/platforms/maple/pci.c 11 */ 12 13 14 #include <linux/kernel.h> 15 #include <linux/pci.h> 16 17 #include <asm/pci-bridge.h> 18 #include <asm/isa-bridge.h> 19 #include <asm/machdep.h> 20 21 #include <asm/ppc-pci.h> 22 23 #include "pasemi.h" 24 25 #define PA_PXP_CFA(bus, devfn, off) (((bus) << 20) | ((devfn) << 12) | (off)) 26 27 static inline int pa_pxp_offset_valid(u8 bus, u8 devfn, int offset) 28 { 29 /* Device 0 Function 0 is special: It's config space spans function 1 as 30 * well, so allow larger offset. It's really a two-function device but the 31 * second function does not probe. 32 */ 33 if (bus == 0 && devfn == 0) 34 return offset < 8192; 35 else 36 return offset < 4096; 37 } 38 39 static void volatile __iomem *pa_pxp_cfg_addr(struct pci_controller *hose, 40 u8 bus, u8 devfn, int offset) 41 { 42 return hose->cfg_data + PA_PXP_CFA(bus, devfn, offset); 43 } 44 45 static inline int is_root_port(int busno, int devfn) 46 { 47 return ((busno == 0) && (PCI_FUNC(devfn) < 4) && 48 ((PCI_SLOT(devfn) == 16) || (PCI_SLOT(devfn) == 17))); 49 } 50 51 static inline int is_5945_reg(int reg) 52 { 53 return (((reg >= 0x18) && (reg < 0x34)) || 54 ((reg >= 0x158) && (reg < 0x178))); 55 } 56 57 static int workaround_5945(struct pci_bus *bus, unsigned int devfn, 58 int offset, int len, u32 *val) 59 { 60 struct pci_controller *hose; 61 void volatile __iomem *addr, *dummy; 62 int byte; 63 u32 tmp; 64 65 if (!is_root_port(bus->number, devfn) || !is_5945_reg(offset)) 66 return 0; 67 68 hose = pci_bus_to_host(bus); 69 70 addr = pa_pxp_cfg_addr(hose, bus->number, devfn, offset & ~0x3); 71 byte = offset & 0x3; 72 73 /* Workaround bug 5945: write 0 to a dummy register before reading, 74 * and write back what we read. We must read/write the full 32-bit 75 * contents so we need to shift and mask by hand. 76 */ 77 dummy = pa_pxp_cfg_addr(hose, bus->number, devfn, 0x10); 78 out_le32(dummy, 0); 79 tmp = in_le32(addr); 80 out_le32(addr, tmp); 81 82 switch (len) { 83 case 1: 84 *val = (tmp >> (8*byte)) & 0xff; 85 break; 86 case 2: 87 if (byte == 0) 88 *val = tmp & 0xffff; 89 else 90 *val = (tmp >> 16) & 0xffff; 91 break; 92 default: 93 *val = tmp; 94 break; 95 } 96 97 return 1; 98 } 99 100 #ifdef CONFIG_PPC_PASEMI_NEMO 101 #define PXP_ERR_CFG_REG 0x4 102 #define PXP_IGNORE_PCIE_ERRORS 0x800 103 #define SB600_BUS 5 104 105 static void sb600_set_flag(int bus) 106 { 107 static void __iomem *iob_mapbase = NULL; 108 struct resource res; 109 struct device_node *dn; 110 int err; 111 112 if (iob_mapbase == NULL) { 113 dn = of_find_compatible_node(NULL, "isa", "pasemi,1682m-iob"); 114 if (!dn) { 115 pr_crit("NEMO SB600 missing iob node\n"); 116 return; 117 } 118 119 err = of_address_to_resource(dn, 0, &res); 120 of_node_put(dn); 121 122 if (err) { 123 pr_crit("NEMO SB600 missing resource\n"); 124 return; 125 } 126 127 pr_info("NEMO SB600 IOB base %08llx\n",res.start); 128 129 iob_mapbase = ioremap(res.start + 0x100, 0x94); 130 } 131 132 if (iob_mapbase != NULL) { 133 if (bus == SB600_BUS) { 134 /* 135 * This is the SB600's bus, tell the PCI-e root port 136 * to allow non-zero devices to enumerate. 137 */ 138 out_le32(iob_mapbase + PXP_ERR_CFG_REG, in_le32(iob_mapbase + PXP_ERR_CFG_REG) | PXP_IGNORE_PCIE_ERRORS); 139 } else { 140 /* 141 * Only scan device 0 on other busses 142 */ 143 out_le32(iob_mapbase + PXP_ERR_CFG_REG, in_le32(iob_mapbase + PXP_ERR_CFG_REG) & ~PXP_IGNORE_PCIE_ERRORS); 144 } 145 } 146 } 147 148 #else 149 150 static void sb600_set_flag(int bus) 151 { 152 } 153 #endif 154 155 static int pa_pxp_read_config(struct pci_bus *bus, unsigned int devfn, 156 int offset, int len, u32 *val) 157 { 158 struct pci_controller *hose; 159 void volatile __iomem *addr; 160 161 hose = pci_bus_to_host(bus); 162 if (!hose) 163 return PCIBIOS_DEVICE_NOT_FOUND; 164 165 if (!pa_pxp_offset_valid(bus->number, devfn, offset)) 166 return PCIBIOS_BAD_REGISTER_NUMBER; 167 168 if (workaround_5945(bus, devfn, offset, len, val)) 169 return PCIBIOS_SUCCESSFUL; 170 171 addr = pa_pxp_cfg_addr(hose, bus->number, devfn, offset); 172 173 sb600_set_flag(bus->number); 174 175 /* 176 * Note: the caller has already checked that offset is 177 * suitably aligned and that len is 1, 2 or 4. 178 */ 179 switch (len) { 180 case 1: 181 *val = in_8(addr); 182 break; 183 case 2: 184 *val = in_le16(addr); 185 break; 186 default: 187 *val = in_le32(addr); 188 break; 189 } 190 191 return PCIBIOS_SUCCESSFUL; 192 } 193 194 static int pa_pxp_write_config(struct pci_bus *bus, unsigned int devfn, 195 int offset, int len, u32 val) 196 { 197 struct pci_controller *hose; 198 void volatile __iomem *addr; 199 200 hose = pci_bus_to_host(bus); 201 if (!hose) 202 return PCIBIOS_DEVICE_NOT_FOUND; 203 204 if (!pa_pxp_offset_valid(bus->number, devfn, offset)) 205 return PCIBIOS_BAD_REGISTER_NUMBER; 206 207 addr = pa_pxp_cfg_addr(hose, bus->number, devfn, offset); 208 209 sb600_set_flag(bus->number); 210 211 /* 212 * Note: the caller has already checked that offset is 213 * suitably aligned and that len is 1, 2 or 4. 214 */ 215 switch (len) { 216 case 1: 217 out_8(addr, val); 218 break; 219 case 2: 220 out_le16(addr, val); 221 break; 222 default: 223 out_le32(addr, val); 224 break; 225 } 226 return PCIBIOS_SUCCESSFUL; 227 } 228 229 static struct pci_ops pa_pxp_ops = { 230 .read = pa_pxp_read_config, 231 .write = pa_pxp_write_config, 232 }; 233 234 static void __init setup_pa_pxp(struct pci_controller *hose) 235 { 236 hose->ops = &pa_pxp_ops; 237 hose->cfg_data = ioremap(0xe0000000, 0x10000000); 238 } 239 240 static int __init pas_add_bridge(struct device_node *dev) 241 { 242 struct pci_controller *hose; 243 244 pr_debug("Adding PCI host bridge %pOF\n", dev); 245 246 hose = pcibios_alloc_controller(dev); 247 if (!hose) 248 return -ENOMEM; 249 250 hose->first_busno = 0; 251 hose->last_busno = 0xff; 252 hose->controller_ops = pasemi_pci_controller_ops; 253 254 setup_pa_pxp(hose); 255 256 pr_info("Found PA-PXP PCI host bridge.\n"); 257 258 /* Interpret the "ranges" property */ 259 pci_process_bridge_OF_ranges(hose, dev, 1); 260 261 /* 262 * Scan for an isa bridge. This is needed to find the SB600 on the nemo 263 * and does nothing on machines without one. 264 */ 265 isa_bridge_find_early(hose); 266 267 return 0; 268 } 269 270 void __init pas_pci_init(void) 271 { 272 struct device_node *np, *root; 273 int res; 274 275 root = of_find_node_by_path("/"); 276 if (!root) { 277 pr_crit("pas_pci_init: can't find root of device tree\n"); 278 return; 279 } 280 281 pci_set_flags(PCI_SCAN_ALL_PCIE_DEVS); 282 283 np = of_find_compatible_node(root, NULL, "pasemi,rootbus"); 284 if (np) { 285 res = pas_add_bridge(np); 286 of_node_put(np); 287 } 288 } 289 290 void __iomem *pasemi_pci_getcfgaddr(struct pci_dev *dev, int offset) 291 { 292 struct pci_controller *hose; 293 294 hose = pci_bus_to_host(dev->bus); 295 296 return (void __iomem *)pa_pxp_cfg_addr(hose, dev->bus->number, dev->devfn, offset); 297 } 298 299 struct pci_controller_ops pasemi_pci_controller_ops; 300