0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #undef DEBUG
0014
0015 #include <linux/pci.h>
0016 #include <linux/of_address.h>
0017 #include <asm/mpc52xx.h>
0018 #include <asm/delay.h>
0019 #include <asm/machdep.h>
0020 #include <linux/kernel.h>
0021
0022
0023
0024
0025
0026
0027 #define MPC52xx_PCI_GSCR_BM 0x40000000
0028 #define MPC52xx_PCI_GSCR_PE 0x20000000
0029 #define MPC52xx_PCI_GSCR_SE 0x10000000
0030 #define MPC52xx_PCI_GSCR_XLB2PCI_MASK 0x07000000
0031 #define MPC52xx_PCI_GSCR_XLB2PCI_SHIFT 24
0032 #define MPC52xx_PCI_GSCR_IPG2PCI_MASK 0x00070000
0033 #define MPC52xx_PCI_GSCR_IPG2PCI_SHIFT 16
0034 #define MPC52xx_PCI_GSCR_BME 0x00004000
0035 #define MPC52xx_PCI_GSCR_PEE 0x00002000
0036 #define MPC52xx_PCI_GSCR_SEE 0x00001000
0037 #define MPC52xx_PCI_GSCR_PR 0x00000001
0038
0039
0040 #define MPC52xx_PCI_IWBTAR_TRANSLATION(proc_ad,pci_ad,size) \
0041 ( ( (proc_ad) & 0xff000000 ) | \
0042 ( (((size) - 1) >> 8) & 0x00ff0000 ) | \
0043 ( ((pci_ad) >> 16) & 0x0000ff00 ) )
0044
0045 #define MPC52xx_PCI_IWCR_PACK(win0,win1,win2) (((win0) << 24) | \
0046 ((win1) << 16) | \
0047 ((win2) << 8))
0048
0049 #define MPC52xx_PCI_IWCR_DISABLE 0x0
0050 #define MPC52xx_PCI_IWCR_ENABLE 0x1
0051 #define MPC52xx_PCI_IWCR_READ 0x0
0052 #define MPC52xx_PCI_IWCR_READ_LINE 0x2
0053 #define MPC52xx_PCI_IWCR_READ_MULTI 0x4
0054 #define MPC52xx_PCI_IWCR_MEM 0x0
0055 #define MPC52xx_PCI_IWCR_IO 0x8
0056
0057 #define MPC52xx_PCI_TCR_P 0x01000000
0058 #define MPC52xx_PCI_TCR_LD 0x00010000
0059 #define MPC52xx_PCI_TCR_WCT8 0x00000008
0060
0061 #define MPC52xx_PCI_TBATR_DISABLE 0x0
0062 #define MPC52xx_PCI_TBATR_ENABLE 0x1
0063
0064 struct mpc52xx_pci {
0065 u32 idr;
0066 u32 scr;
0067 u32 ccrir;
0068 u32 cr1;
0069 u32 bar0;
0070 u32 bar1;
0071 u8 reserved1[16];
0072 u32 ccpr;
0073 u32 sid;
0074 u32 erbar;
0075 u32 cpr;
0076 u8 reserved2[4];
0077 u32 cr2;
0078 u8 reserved3[32];
0079 u32 gscr;
0080 u32 tbatr0;
0081 u32 tbatr1;
0082 u32 tcr;
0083 u32 iw0btar;
0084 u32 iw1btar;
0085 u32 iw2btar;
0086 u8 reserved4[4];
0087 u32 iwcr;
0088 u32 icr;
0089 u32 isr;
0090 u32 arb;
0091 u8 reserved5[104];
0092 u32 car;
0093 u8 reserved6[4];
0094 };
0095
0096
0097 const struct of_device_id mpc52xx_pci_ids[] __initconst = {
0098 { .type = "pci", .compatible = "fsl,mpc5200-pci", },
0099 { .type = "pci", .compatible = "mpc5200-pci", },
0100 {}
0101 };
0102
0103
0104
0105
0106
0107 static int
0108 mpc52xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
0109 int offset, int len, u32 *val)
0110 {
0111 struct pci_controller *hose = pci_bus_to_host(bus);
0112 u32 value;
0113
0114 if (ppc_md.pci_exclude_device)
0115 if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
0116 return PCIBIOS_DEVICE_NOT_FOUND;
0117
0118 out_be32(hose->cfg_addr,
0119 (1 << 31) |
0120 (bus->number << 16) |
0121 (devfn << 8) |
0122 (offset & 0xfc));
0123 mb();
0124
0125 #if defined(CONFIG_PPC_MPC5200_BUGFIX)
0126 if (bus->number) {
0127
0128
0129 switch (len) {
0130 case 1:
0131 value = in_8(((u8 __iomem *)hose->cfg_data) +
0132 (offset & 3));
0133 break;
0134 case 2:
0135 value = in_le16(((u16 __iomem *)hose->cfg_data) +
0136 ((offset>>1) & 1));
0137 break;
0138
0139 default:
0140 value = in_le16((u16 __iomem *)hose->cfg_data) |
0141 (in_le16(((u16 __iomem *)hose->cfg_data) + 1) << 16);
0142 break;
0143 }
0144 }
0145 else
0146 #endif
0147 {
0148 value = in_le32(hose->cfg_data);
0149
0150 if (len != 4) {
0151 value >>= ((offset & 0x3) << 3);
0152 value &= 0xffffffff >> (32 - (len << 3));
0153 }
0154 }
0155
0156 *val = value;
0157
0158 out_be32(hose->cfg_addr, 0);
0159 mb();
0160
0161 return PCIBIOS_SUCCESSFUL;
0162 }
0163
0164 static int
0165 mpc52xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
0166 int offset, int len, u32 val)
0167 {
0168 struct pci_controller *hose = pci_bus_to_host(bus);
0169 u32 value, mask;
0170
0171 if (ppc_md.pci_exclude_device)
0172 if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
0173 return PCIBIOS_DEVICE_NOT_FOUND;
0174
0175 out_be32(hose->cfg_addr,
0176 (1 << 31) |
0177 (bus->number << 16) |
0178 (devfn << 8) |
0179 (offset & 0xfc));
0180 mb();
0181
0182 #if defined(CONFIG_PPC_MPC5200_BUGFIX)
0183 if (bus->number) {
0184
0185
0186 switch (len) {
0187 case 1:
0188 out_8(((u8 __iomem *)hose->cfg_data) +
0189 (offset & 3), val);
0190 break;
0191 case 2:
0192 out_le16(((u16 __iomem *)hose->cfg_data) +
0193 ((offset>>1) & 1), val);
0194 break;
0195
0196 default:
0197 out_le16((u16 __iomem *)hose->cfg_data,
0198 (u16)val);
0199 out_le16(((u16 __iomem *)hose->cfg_data) + 1,
0200 (u16)(val>>16));
0201 break;
0202 }
0203 }
0204 else
0205 #endif
0206 {
0207 if (len != 4) {
0208 value = in_le32(hose->cfg_data);
0209
0210 offset = (offset & 0x3) << 3;
0211 mask = (0xffffffff >> (32 - (len << 3)));
0212 mask <<= offset;
0213
0214 value &= ~mask;
0215 val = value | ((val << offset) & mask);
0216 }
0217
0218 out_le32(hose->cfg_data, val);
0219 }
0220 mb();
0221
0222 out_be32(hose->cfg_addr, 0);
0223 mb();
0224
0225 return PCIBIOS_SUCCESSFUL;
0226 }
0227
0228 static struct pci_ops mpc52xx_pci_ops = {
0229 .read = mpc52xx_pci_read_config,
0230 .write = mpc52xx_pci_write_config
0231 };
0232
0233
0234
0235
0236
0237
0238 static void __init
0239 mpc52xx_pci_setup(struct pci_controller *hose,
0240 struct mpc52xx_pci __iomem *pci_regs, phys_addr_t pci_phys)
0241 {
0242 struct resource *res;
0243 u32 tmp;
0244 int iwcr0 = 0, iwcr1 = 0, iwcr2 = 0;
0245
0246 pr_debug("%s(hose=%p, pci_regs=%p)\n", __func__, hose, pci_regs);
0247
0248
0249
0250 hose->cfg_addr = &pci_regs->car;
0251 hose->cfg_data = hose->io_base_virt;
0252
0253
0254 tmp = in_be32(&pci_regs->scr);
0255 tmp |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
0256 out_be32(&pci_regs->scr, tmp);
0257
0258
0259 res = &hose->mem_resources[0];
0260 if (res->flags) {
0261 pr_debug("mem_resource[0] = %pr\n", res);
0262 out_be32(&pci_regs->iw0btar,
0263 MPC52xx_PCI_IWBTAR_TRANSLATION(res->start, res->start,
0264 resource_size(res)));
0265 iwcr0 = MPC52xx_PCI_IWCR_ENABLE | MPC52xx_PCI_IWCR_MEM;
0266 if (res->flags & IORESOURCE_PREFETCH)
0267 iwcr0 |= MPC52xx_PCI_IWCR_READ_MULTI;
0268 else
0269 iwcr0 |= MPC52xx_PCI_IWCR_READ;
0270 }
0271
0272 res = &hose->mem_resources[1];
0273 if (res->flags) {
0274 pr_debug("mem_resource[1] = %pr\n", res);
0275 out_be32(&pci_regs->iw1btar,
0276 MPC52xx_PCI_IWBTAR_TRANSLATION(res->start, res->start,
0277 resource_size(res)));
0278 iwcr1 = MPC52xx_PCI_IWCR_ENABLE | MPC52xx_PCI_IWCR_MEM;
0279 if (res->flags & IORESOURCE_PREFETCH)
0280 iwcr1 |= MPC52xx_PCI_IWCR_READ_MULTI;
0281 else
0282 iwcr1 |= MPC52xx_PCI_IWCR_READ;
0283 }
0284
0285
0286 res = &hose->io_resource;
0287 if (!res) {
0288 printk(KERN_ERR "%s: Didn't find IO resources\n", __FILE__);
0289 return;
0290 }
0291 pr_debug(".io_resource = %pr .io_base_phys=0x%pa\n",
0292 res, &hose->io_base_phys);
0293 out_be32(&pci_regs->iw2btar,
0294 MPC52xx_PCI_IWBTAR_TRANSLATION(hose->io_base_phys,
0295 res->start,
0296 resource_size(res)));
0297 iwcr2 = MPC52xx_PCI_IWCR_ENABLE | MPC52xx_PCI_IWCR_IO;
0298
0299
0300 out_be32(&pci_regs->iwcr, MPC52xx_PCI_IWCR_PACK(iwcr0, iwcr1, iwcr2));
0301
0302
0303 pci_phys &= 0xfffc0000;
0304 out_be32(&pci_regs->tbatr0, MPC52xx_PCI_TBATR_ENABLE | pci_phys);
0305 out_be32(&pci_regs->bar0, PCI_BASE_ADDRESS_MEM_PREFETCH | pci_phys);
0306
0307
0308 out_be32(&pci_regs->tbatr1, MPC52xx_PCI_TBATR_ENABLE);
0309 out_be32(&pci_regs->bar1, PCI_BASE_ADDRESS_MEM_PREFETCH);
0310
0311 out_be32(&pci_regs->tcr, MPC52xx_PCI_TCR_LD | MPC52xx_PCI_TCR_WCT8);
0312
0313 tmp = in_be32(&pci_regs->gscr);
0314 #if 0
0315
0316
0317
0318
0319 out_be32(&pci_regs->gscr, tmp | MPC52xx_PCI_GSCR_PR);
0320 udelay(50);
0321 #endif
0322
0323
0324 out_be32(&pci_regs->gscr, tmp & ~MPC52xx_PCI_GSCR_PR);
0325 }
0326
0327 static void
0328 mpc52xx_pci_fixup_resources(struct pci_dev *dev)
0329 {
0330 int i;
0331
0332 pr_debug("%s() %.4x:%.4x\n", __func__, dev->vendor, dev->device);
0333
0334
0335
0336 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
0337 struct resource *res = &dev->resource[i];
0338 if (res->end > res->start) {
0339 res->end -= res->start;
0340 res->start = 0;
0341 res->flags |= IORESOURCE_UNSET;
0342 }
0343 }
0344
0345
0346
0347 if ( (dev->vendor == PCI_VENDOR_ID_MOTOROLA) &&
0348 ( dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200
0349 || dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200B) ) {
0350 struct resource *res = &dev->resource[1];
0351 res->start = res->end = res->flags = 0;
0352 }
0353 }
0354
0355 int __init
0356 mpc52xx_add_bridge(struct device_node *node)
0357 {
0358 int len;
0359 struct mpc52xx_pci __iomem *pci_regs;
0360 struct pci_controller *hose;
0361 const int *bus_range;
0362 struct resource rsrc;
0363
0364 pr_debug("Adding MPC52xx PCI host bridge %pOF\n", node);
0365
0366 pci_add_flags(PCI_REASSIGN_ALL_BUS);
0367
0368 if (of_address_to_resource(node, 0, &rsrc) != 0) {
0369 printk(KERN_ERR "Can't get %pOF resources\n", node);
0370 return -EINVAL;
0371 }
0372
0373 bus_range = of_get_property(node, "bus-range", &len);
0374 if (bus_range == NULL || len < 2 * sizeof(int)) {
0375 printk(KERN_WARNING "Can't get %pOF bus-range, assume bus 0\n",
0376 node);
0377 bus_range = NULL;
0378 }
0379
0380
0381
0382 ppc_md.pcibios_fixup_resources = mpc52xx_pci_fixup_resources;
0383
0384
0385
0386
0387
0388 hose = pcibios_alloc_controller(node);
0389 if (!hose)
0390 return -ENOMEM;
0391
0392 hose->first_busno = bus_range ? bus_range[0] : 0;
0393 hose->last_busno = bus_range ? bus_range[1] : 0xff;
0394
0395 hose->ops = &mpc52xx_pci_ops;
0396
0397 pci_regs = ioremap(rsrc.start, resource_size(&rsrc));
0398 if (!pci_regs)
0399 return -ENOMEM;
0400
0401 pci_process_bridge_OF_ranges(hose, node, 1);
0402
0403
0404
0405 mpc52xx_pci_setup(hose, pci_regs, rsrc.start);
0406
0407 return 0;
0408 }
0409
0410 void __init mpc52xx_setup_pci(void)
0411 {
0412 struct device_node *pci;
0413
0414 pci = of_find_matching_node(NULL, mpc52xx_pci_ids);
0415 if (!pci)
0416 return;
0417
0418 mpc52xx_add_bridge(pci);
0419 of_node_put(pci);
0420 }