| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * This file is subject to the terms and conditions of the GNU General Public | 
|  | 3 | * License.  See the file "COPYING" in the main directory of this archive | 
|  | 4 | * for more details. | 
|  | 5 | * | 
| Ralf Baechle | 3367fd5 | 2006-03-08 14:22:27 +0000 | [diff] [blame] | 6 | * Copyright (C) 2004, 06 by Ralf Baechle (ralf@linux-mips.org) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 7 | */ | 
|  | 8 |  | 
|  | 9 | #include <linux/types.h> | 
|  | 10 | #include <linux/pci.h> | 
| Ralf Baechle | 3367fd5 | 2006-03-08 14:22:27 +0000 | [diff] [blame] | 11 | #include <linux/mv643xx.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 12 |  | 
|  | 13 | #include <linux/init.h> | 
|  | 14 |  | 
| Ralf Baechle | 3367fd5 | 2006-03-08 14:22:27 +0000 | [diff] [blame] | 15 | #include <asm/marvell.h> | 
|  | 16 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 17 | /* | 
|  | 18 | * We assume the address ranges have already been setup appropriately by | 
|  | 19 | * the firmware.  PMON in case of the Ocelot C does that. | 
|  | 20 | */ | 
|  | 21 | static struct resource mv_pci_io_mem0_resource = { | 
|  | 22 | .name	= "MV64340 PCI0 IO MEM", | 
|  | 23 | .flags	= IORESOURCE_IO | 
|  | 24 | }; | 
|  | 25 |  | 
|  | 26 | static struct resource mv_pci_mem0_resource = { | 
|  | 27 | .name	= "MV64340 PCI0 MEM", | 
|  | 28 | .flags	= IORESOURCE_MEM | 
|  | 29 | }; | 
|  | 30 |  | 
|  | 31 | static struct mv_pci_controller mv_bus0_controller = { | 
|  | 32 | .pcic = { | 
|  | 33 | .pci_ops	= &mv_pci_ops, | 
|  | 34 | .mem_resource	= &mv_pci_mem0_resource, | 
|  | 35 | .io_resource	= &mv_pci_io_mem0_resource, | 
|  | 36 | }, | 
|  | 37 | .config_addr	= MV64340_PCI_0_CONFIG_ADDR, | 
|  | 38 | .config_vreg	= MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG, | 
|  | 39 | }; | 
|  | 40 |  | 
|  | 41 | static uint32_t mv_io_base, mv_io_size; | 
|  | 42 |  | 
|  | 43 | static void mv64340_pci0_init(void) | 
|  | 44 | { | 
|  | 45 | uint32_t mem0_base, mem0_size; | 
|  | 46 | uint32_t io_base, io_size; | 
|  | 47 |  | 
|  | 48 | io_base = MV_READ(MV64340_PCI_0_IO_BASE_ADDR) << 16; | 
|  | 49 | io_size = (MV_READ(MV64340_PCI_0_IO_SIZE) + 1) << 16; | 
|  | 50 | mem0_base = MV_READ(MV64340_PCI_0_MEMORY0_BASE_ADDR) << 16; | 
|  | 51 | mem0_size = (MV_READ(MV64340_PCI_0_MEMORY0_SIZE) + 1) << 16; | 
|  | 52 |  | 
|  | 53 | mv_pci_io_mem0_resource.start		= 0; | 
|  | 54 | mv_pci_io_mem0_resource.end		= io_size - 1; | 
|  | 55 | mv_pci_mem0_resource.start		= mem0_base; | 
|  | 56 | mv_pci_mem0_resource.end		= mem0_base + mem0_size - 1; | 
|  | 57 | mv_bus0_controller.pcic.mem_offset	= mem0_base; | 
|  | 58 | mv_bus0_controller.pcic.io_offset	= 0; | 
|  | 59 |  | 
|  | 60 | ioport_resource.end		= io_size - 1; | 
|  | 61 |  | 
|  | 62 | register_pci_controller(&mv_bus0_controller.pcic); | 
|  | 63 |  | 
|  | 64 | mv_io_base = io_base; | 
|  | 65 | mv_io_size = io_size; | 
|  | 66 | } | 
|  | 67 |  | 
|  | 68 | static struct resource mv_pci_io_mem1_resource = { | 
|  | 69 | .name	= "MV64340 PCI1 IO MEM", | 
|  | 70 | .flags	= IORESOURCE_IO | 
|  | 71 | }; | 
|  | 72 |  | 
|  | 73 | static struct resource mv_pci_mem1_resource = { | 
|  | 74 | .name	= "MV64340 PCI1 MEM", | 
|  | 75 | .flags	= IORESOURCE_MEM | 
|  | 76 | }; | 
|  | 77 |  | 
|  | 78 | static struct mv_pci_controller mv_bus1_controller = { | 
|  | 79 | .pcic = { | 
|  | 80 | .pci_ops	= &mv_pci_ops, | 
|  | 81 | .mem_resource	= &mv_pci_mem1_resource, | 
|  | 82 | .io_resource	= &mv_pci_io_mem1_resource, | 
|  | 83 | }, | 
|  | 84 | .config_addr	= MV64340_PCI_1_CONFIG_ADDR, | 
|  | 85 | .config_vreg	= MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG, | 
|  | 86 | }; | 
|  | 87 |  | 
|  | 88 | static __init void mv64340_pci1_init(void) | 
|  | 89 | { | 
|  | 90 | uint32_t mem0_base, mem0_size; | 
|  | 91 | uint32_t io_base, io_size; | 
|  | 92 |  | 
|  | 93 | io_base = MV_READ(MV64340_PCI_1_IO_BASE_ADDR) << 16; | 
|  | 94 | io_size = (MV_READ(MV64340_PCI_1_IO_SIZE) + 1) << 16; | 
|  | 95 | mem0_base = MV_READ(MV64340_PCI_1_MEMORY0_BASE_ADDR) << 16; | 
|  | 96 | mem0_size = (MV_READ(MV64340_PCI_1_MEMORY0_SIZE) + 1) << 16; | 
|  | 97 |  | 
|  | 98 | /* | 
|  | 99 | * Here we assume the I/O window of second bus to be contiguous with | 
|  | 100 | * the first.  A gap is no problem but would waste address space for | 
|  | 101 | * remapping the port space. | 
|  | 102 | */ | 
|  | 103 | mv_pci_io_mem1_resource.start		= mv_io_size; | 
|  | 104 | mv_pci_io_mem1_resource.end		= mv_io_size + io_size - 1; | 
|  | 105 | mv_pci_mem1_resource.start		= mem0_base; | 
|  | 106 | mv_pci_mem1_resource.end		= mem0_base + mem0_size - 1; | 
|  | 107 | mv_bus1_controller.pcic.mem_offset	= mem0_base; | 
|  | 108 | mv_bus1_controller.pcic.io_offset	= 0; | 
|  | 109 |  | 
|  | 110 | ioport_resource.end		= io_base + io_size -mv_io_base - 1; | 
|  | 111 |  | 
|  | 112 | register_pci_controller(&mv_bus1_controller.pcic); | 
|  | 113 |  | 
|  | 114 | mv_io_size = io_base + io_size - mv_io_base; | 
|  | 115 | } | 
|  | 116 |  | 
|  | 117 | static __init int __init ocelot_c_pci_init(void) | 
|  | 118 | { | 
|  | 119 | unsigned long io_v_base; | 
|  | 120 | uint32_t enable; | 
|  | 121 |  | 
|  | 122 | enable = ~MV_READ(MV64340_BASE_ADDR_ENABLE); | 
|  | 123 |  | 
|  | 124 | /* | 
|  | 125 | * We require at least one enabled I/O or PCI memory window or we | 
|  | 126 | * will ignore this PCI bus.  We ignore PCI windows 1, 2 and 3. | 
|  | 127 | */ | 
|  | 128 | if (enable & (0x01 <<  9) || enable & (0x01 << 10)) | 
|  | 129 | mv64340_pci0_init(); | 
|  | 130 |  | 
|  | 131 | if (enable & (0x01 << 14) || enable & (0x01 << 15)) | 
|  | 132 | mv64340_pci1_init(); | 
|  | 133 |  | 
|  | 134 | if (mv_io_size) { | 
|  | 135 | io_v_base = (unsigned long) ioremap(mv_io_base, mv_io_size); | 
|  | 136 | if (!io_v_base) | 
|  | 137 | panic("Could not ioremap I/O port range"); | 
|  | 138 |  | 
|  | 139 | set_io_port_base(io_v_base); | 
|  | 140 | } | 
|  | 141 |  | 
|  | 142 | return 0; | 
|  | 143 | } | 
|  | 144 |  | 
|  | 145 | arch_initcall(ocelot_c_pci_init); |