diff options
Diffstat (limited to 'arch/arm/mach-versatile/pci.c')
| -rw-r--r-- | arch/arm/mach-versatile/pci.c | 93 |
1 files changed, 48 insertions, 45 deletions
diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c index b80d57d51699..722fbabc9cfb 100644 --- a/arch/arm/mach-versatile/pci.c +++ b/arch/arm/mach-versatile/pci.c | |||
| @@ -240,6 +240,14 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys) | |||
| 240 | int i; | 240 | int i; |
| 241 | int myslot = -1; | 241 | int myslot = -1; |
| 242 | unsigned long val; | 242 | unsigned long val; |
| 243 | void __iomem *local_pci_cfg_base; | ||
| 244 | |||
| 245 | val = __raw_readl(SYS_PCICTL); | ||
| 246 | if (!(val & 1)) { | ||
| 247 | printk("Not plugged into PCI backplane!\n"); | ||
| 248 | ret = -EIO; | ||
| 249 | goto out; | ||
| 250 | } | ||
| 243 | 251 | ||
| 244 | if (nr == 0) { | 252 | if (nr == 0) { |
| 245 | sys->mem_offset = 0; | 253 | sys->mem_offset = 0; |
| @@ -253,48 +261,45 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys) | |||
| 253 | goto out; | 261 | goto out; |
| 254 | } | 262 | } |
| 255 | 263 | ||
| 256 | __raw_writel(VERSATILE_PCI_MEM_BASE0 >> 28,PCI_IMAP0); | ||
| 257 | __raw_writel(VERSATILE_PCI_MEM_BASE1 >> 28,PCI_IMAP1); | ||
| 258 | __raw_writel(VERSATILE_PCI_MEM_BASE2 >> 28,PCI_IMAP2); | ||
| 259 | |||
| 260 | __raw_writel(1, SYS_PCICTL); | ||
| 261 | |||
| 262 | val = __raw_readl(SYS_PCICTL); | ||
| 263 | if (!(val & 1)) { | ||
| 264 | printk("Not plugged into PCI backplane!\n"); | ||
| 265 | ret = -EIO; | ||
| 266 | goto out; | ||
| 267 | } | ||
| 268 | |||
| 269 | /* | 264 | /* |
| 270 | * We need to discover the PCI core first to configure itself | 265 | * We need to discover the PCI core first to configure itself |
| 271 | * before the main PCI probing is performed | 266 | * before the main PCI probing is performed |
| 272 | */ | 267 | */ |
| 273 | for (i=0; i<32; i++) { | 268 | for (i=0; i<32; i++) |
| 274 | if ((__raw_readl(VERSATILE_PCI_VIRT_BASE+(i<<11)+DEVICE_ID_OFFSET) == VP_PCI_DEVICE_ID) && | 269 | if ((__raw_readl(VERSATILE_PCI_VIRT_BASE+(i<<11)+DEVICE_ID_OFFSET) == VP_PCI_DEVICE_ID) && |
| 275 | (__raw_readl(VERSATILE_PCI_VIRT_BASE+(i<<11)+CLASS_ID_OFFSET) == VP_PCI_CLASS_ID)) { | 270 | (__raw_readl(VERSATILE_PCI_VIRT_BASE+(i<<11)+CLASS_ID_OFFSET) == VP_PCI_CLASS_ID)) { |
| 276 | myslot = i; | 271 | myslot = i; |
| 277 | |||
| 278 | __raw_writel(myslot, PCI_SELFID); | ||
| 279 | val = __raw_readl(VERSATILE_PCI_CFG_VIRT_BASE+(myslot<<11)+CSR_OFFSET); | ||
| 280 | val |= (1<<2); | ||
| 281 | __raw_writel(val, VERSATILE_PCI_CFG_VIRT_BASE+(myslot<<11)+CSR_OFFSET); | ||
| 282 | break; | 272 | break; |
| 283 | } | 273 | } |
| 284 | } | ||
| 285 | 274 | ||
| 286 | if (myslot == -1) { | 275 | if (myslot == -1) { |
| 287 | printk("Cannot find PCI core!\n"); | 276 | printk("Cannot find PCI core!\n"); |
| 288 | ret = -EIO; | 277 | ret = -EIO; |
| 289 | } else { | 278 | goto out; |
| 290 | printk("PCI core found (slot %d)\n",myslot); | ||
| 291 | /* Do not to map Versatile FPGA PCI device | ||
| 292 | into memory space as we are short of | ||
| 293 | mappable memory */ | ||
| 294 | pci_slot_ignore |= (1 << myslot); | ||
| 295 | ret = 1; | ||
| 296 | } | 279 | } |
| 297 | 280 | ||
| 281 | printk("PCI core found (slot %d)\n",myslot); | ||
| 282 | |||
| 283 | __raw_writel(myslot, PCI_SELFID); | ||
| 284 | local_pci_cfg_base = (void *) VERSATILE_PCI_CFG_VIRT_BASE + (myslot << 11); | ||
| 285 | |||
| 286 | val = __raw_readl(local_pci_cfg_base + CSR_OFFSET); | ||
| 287 | val |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE; | ||
| 288 | __raw_writel(val, local_pci_cfg_base + CSR_OFFSET); | ||
| 289 | |||
| 290 | /* | ||
| 291 | * Configure the PCI inbound memory windows to be 1:1 mapped to SDRAM | ||
| 292 | */ | ||
| 293 | __raw_writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_0); | ||
| 294 | __raw_writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_1); | ||
| 295 | __raw_writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_2); | ||
| 296 | |||
| 297 | /* | ||
| 298 | * Do not to map Versatile FPGA PCI device into memory space | ||
| 299 | */ | ||
| 300 | pci_slot_ignore |= (1 << myslot); | ||
| 301 | ret = 1; | ||
| 302 | |||
| 298 | out: | 303 | out: |
| 299 | return ret; | 304 | return ret; |
| 300 | } | 305 | } |
| @@ -305,18 +310,18 @@ struct pci_bus *pci_versatile_scan_bus(int nr, struct pci_sys_data *sys) | |||
| 305 | return pci_scan_bus(sys->busnr, &pci_versatile_ops, sys); | 310 | return pci_scan_bus(sys->busnr, &pci_versatile_ops, sys); |
| 306 | } | 311 | } |
| 307 | 312 | ||
| 308 | /* | ||
| 309 | * V3_LB_BASE? - local bus address | ||
| 310 | * V3_LB_MAP? - pci bus address | ||
| 311 | */ | ||
| 312 | void __init pci_versatile_preinit(void) | 313 | void __init pci_versatile_preinit(void) |
| 313 | { | 314 | { |
| 314 | } | 315 | __raw_writel(VERSATILE_PCI_MEM_BASE0 >> 28, PCI_IMAP0); |
| 316 | __raw_writel(VERSATILE_PCI_MEM_BASE1 >> 28, PCI_IMAP1); | ||
| 317 | __raw_writel(VERSATILE_PCI_MEM_BASE2 >> 28, PCI_IMAP2); | ||
| 315 | 318 | ||
| 316 | void __init pci_versatile_postinit(void) | 319 | __raw_writel(PHYS_OFFSET >> 28, PCI_SMAP0); |
| 317 | { | 320 | __raw_writel(PHYS_OFFSET >> 28, PCI_SMAP1); |
| 318 | } | 321 | __raw_writel(PHYS_OFFSET >> 28, PCI_SMAP2); |
| 319 | 322 | ||
| 323 | __raw_writel(1, SYS_PCICTL); | ||
| 324 | } | ||
| 320 | 325 | ||
| 321 | /* | 326 | /* |
| 322 | * map the specified device/slot/pin to an IRQ. Different backplanes may need to modify this. | 327 | * map the specified device/slot/pin to an IRQ. Different backplanes may need to modify this. |
| @@ -326,16 +331,15 @@ static int __init versatile_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | |||
| 326 | int irq; | 331 | int irq; |
| 327 | int devslot = PCI_SLOT(dev->devfn); | 332 | int devslot = PCI_SLOT(dev->devfn); |
| 328 | 333 | ||
| 329 | /* slot, pin, irq | 334 | /* slot, pin, irq |
| 330 | 24 1 27 | 335 | * 24 1 27 |
| 331 | 25 1 28 untested | 336 | * 25 1 28 |
| 332 | 26 1 29 | 337 | * 26 1 29 |
| 333 | 27 1 30 untested | 338 | * 27 1 30 |
| 334 | */ | 339 | */ |
| 335 | 340 | irq = 27 + ((slot + pin - 1) & 3); | |
| 336 | irq = 27 + ((slot + pin + 2) % 3); /* Fudged */ | ||
| 337 | 341 | ||
| 338 | printk("map irq: slot %d, pin %d, devslot %d, irq: %d\n",slot,pin,devslot,irq); | 342 | printk("PCI map irq: slot %d, pin %d, devslot %d, irq: %d\n",slot,pin,devslot,irq); |
| 339 | 343 | ||
| 340 | return irq; | 344 | return irq; |
| 341 | } | 345 | } |
| @@ -347,7 +351,6 @@ static struct hw_pci versatile_pci __initdata = { | |||
| 347 | .setup = pci_versatile_setup, | 351 | .setup = pci_versatile_setup, |
| 348 | .scan = pci_versatile_scan_bus, | 352 | .scan = pci_versatile_scan_bus, |
| 349 | .preinit = pci_versatile_preinit, | 353 | .preinit = pci_versatile_preinit, |
| 350 | .postinit = pci_versatile_postinit, | ||
| 351 | }; | 354 | }; |
| 352 | 355 | ||
| 353 | static int __init versatile_pci_init(void) | 356 | static int __init versatile_pci_init(void) |
