aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-ixp2000
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-ixp2000')
-rw-r--r--arch/arm/mach-ixp2000/ixdp2800.c147
1 files changed, 134 insertions, 13 deletions
diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c
index c4683aaff84a..aec13c7108a9 100644
--- a/arch/arm/mach-ixp2000/ixdp2800.c
+++ b/arch/arm/mach-ixp2000/ixdp2800.c
@@ -65,19 +65,102 @@ static struct sys_timer ixdp2800_timer = {
65/************************************************************************* 65/*************************************************************************
66 * IXDP2800 PCI 66 * IXDP2800 PCI
67 *************************************************************************/ 67 *************************************************************************/
68static void __init ixdp2800_slave_disable_pci_master(void)
69{
70 *IXP2000_PCI_CMDSTAT &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
71}
72
73static void __init ixdp2800_master_wait_for_slave(void)
74{
75 volatile u32 *addr;
76
77 printk(KERN_INFO "IXDP2800: waiting for slave NPU to configure "
78 "its BAR sizes\n");
79
80 addr = ixp2000_pci_config_addr(0, IXDP2X00_SLAVE_NPU_DEVFN,
81 PCI_BASE_ADDRESS_1);
82 do {
83 *addr = 0xffffffff;
84 cpu_relax();
85 } while (*addr != 0xfe000008);
86
87 addr = ixp2000_pci_config_addr(0, IXDP2X00_SLAVE_NPU_DEVFN,
88 PCI_BASE_ADDRESS_2);
89 do {
90 *addr = 0xffffffff;
91 cpu_relax();
92 } while (*addr != 0xc0000008);
93
94 /*
95 * Configure the slave's SDRAM BAR by hand.
96 */
97 *addr = 0x40000008;
98}
99
100static void __init ixdp2800_slave_wait_for_master_enable(void)
101{
102 printk(KERN_INFO "IXDP2800: waiting for master NPU to enable us\n");
103
104 while ((*IXP2000_PCI_CMDSTAT & PCI_COMMAND_MASTER) == 0)
105 cpu_relax();
106}
107
68void __init ixdp2800_pci_preinit(void) 108void __init ixdp2800_pci_preinit(void)
69{ 109{
70 printk("ixdp2x00_pci_preinit called\n"); 110 printk("ixdp2x00_pci_preinit called\n");
71 111
72 *IXP2000_PCI_ADDR_EXT = 0x0000e000; 112 *IXP2000_PCI_ADDR_EXT = 0x0001e000;
113
114 if (!ixdp2x00_master_npu())
115 ixdp2800_slave_disable_pci_master();
73 116
74 *IXP2000_PCI_DRAM_BASE_ADDR_MASK = (0x40000000 - 1) & ~0xfffff;
75 *IXP2000_PCI_SRAM_BASE_ADDR_MASK = (0x2000000 - 1) & ~0x3ffff; 117 *IXP2000_PCI_SRAM_BASE_ADDR_MASK = (0x2000000 - 1) & ~0x3ffff;
118 *IXP2000_PCI_DRAM_BASE_ADDR_MASK = (0x40000000 - 1) & ~0xfffff;
76 119
77 ixp2000_pci_preinit(); 120 ixp2000_pci_preinit();
121
122 if (ixdp2x00_master_npu()) {
123 /*
124 * Wait until the slave set its SRAM/SDRAM BAR sizes
125 * correctly before we proceed to scan and enumerate
126 * the bus.
127 */
128 ixdp2800_master_wait_for_slave();
129
130 /*
131 * We configure the SDRAM BARs by hand because they
132 * are 1G and fall outside of the regular allocated
133 * PCI address space.
134 */
135 *IXP2000_PCI_SDRAM_BAR = 0x00000008;
136 } else {
137 /*
138 * Wait for the master to complete scanning the bus
139 * and assigning resources before we proceed to scan
140 * the bus ourselves. Set pci=firmware to honor the
141 * master's resource assignment.
142 */
143 ixdp2800_slave_wait_for_master_enable();
144 pcibios_setup("firmware");
145 }
78} 146}
79 147
80int ixdp2800_pci_setup(int nr, struct pci_sys_data *sys) 148/*
149 * We assign the SDRAM BARs for the two IXP2800 CPUs by hand, outside
150 * of the regular PCI window, because there's only 512M of outbound PCI
151 * memory window on each IXP, while we need 1G for each of the BARs.
152 */
153static void __devinit ixp2800_pci_fixup(struct pci_dev *dev)
154{
155 if (machine_is_ixdp2800()) {
156 dev->resource[2].start = 0;
157 dev->resource[2].end = 0;
158 dev->resource[2].flags = 0;
159 }
160}
161DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IXP2800, ixp2800_pci_fixup);
162
163static int __init ixdp2800_pci_setup(int nr, struct pci_sys_data *sys)
81{ 164{
82 sys->mem_offset = 0x00000000; 165 sys->mem_offset = 0x00000000;
83 166
@@ -129,22 +212,47 @@ static int __init ixdp2800_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
129 } else return IRQ_IXP2000_PCIB; /* Slave NIC interrupt */ 212 } else return IRQ_IXP2000_PCIB; /* Slave NIC interrupt */
130} 213}
131 214
132static void ixdp2800_pci_postinit(void) 215static void __init ixdp2800_master_enable_slave(void)
133{ 216{
134 struct pci_dev *dev; 217 volatile u32 *addr;
135 218
136 if (ixdp2x00_master_npu()) { 219 printk(KERN_INFO "IXDP2800: enabling slave NPU\n");
137 dev = pci_find_slot(1, IXDP2800_SLAVE_ENET_DEVFN); 220
138 pci_remove_bus_device(dev); 221 addr = (volatile u32 *)ixp2000_pci_config_addr(0,
139 } else { 222 IXDP2X00_SLAVE_NPU_DEVFN,
140 dev = pci_find_slot(1, IXDP2800_MASTER_ENET_DEVFN); 223 PCI_COMMAND);
141 pci_remove_bus_device(dev); 224
225 *addr |= PCI_COMMAND_MASTER;
226}
142 227
228static void __init ixdp2800_master_wait_for_slave_bus_scan(void)
229{
230 volatile u32 *addr;
231
232 printk(KERN_INFO "IXDP2800: waiting for slave to finish bus scan\n");
233
234 addr = (volatile u32 *)ixp2000_pci_config_addr(0,
235 IXDP2X00_SLAVE_NPU_DEVFN,
236 PCI_COMMAND);
237 while ((*addr & PCI_COMMAND_MEMORY) == 0)
238 cpu_relax();
239}
240
241static void __init ixdp2800_slave_signal_bus_scan_completion(void)
242{
243 printk(KERN_INFO "IXDP2800: bus scan done, signaling master\n");
244 *IXP2000_PCI_CMDSTAT |= PCI_COMMAND_MEMORY;
245}
246
247static void __init ixdp2800_pci_postinit(void)
248{
249 if (!ixdp2x00_master_npu()) {
143 ixdp2x00_slave_pci_postinit(); 250 ixdp2x00_slave_pci_postinit();
251 ixdp2800_slave_signal_bus_scan_completion();
144 } 252 }
145} 253}
146 254
147struct hw_pci ixdp2800_pci __initdata = { 255struct __initdata hw_pci ixdp2800_pci __initdata = {
148 .nr_controllers = 1, 256 .nr_controllers = 1,
149 .setup = ixdp2800_pci_setup, 257 .setup = ixdp2800_pci_setup,
150 .preinit = ixdp2800_pci_preinit, 258 .preinit = ixdp2800_pci_preinit,
@@ -155,8 +263,21 @@ struct hw_pci ixdp2800_pci __initdata = {
155 263
156int __init ixdp2800_pci_init(void) 264int __init ixdp2800_pci_init(void)
157{ 265{
158 if (machine_is_ixdp2800()) 266 if (machine_is_ixdp2800()) {
267 struct pci_dev *dev;
268
159 pci_common_init(&ixdp2800_pci); 269 pci_common_init(&ixdp2800_pci);
270 if (ixdp2x00_master_npu()) {
271 dev = pci_find_slot(1, IXDP2800_SLAVE_ENET_DEVFN);
272 pci_remove_bus_device(dev);
273
274 ixdp2800_master_enable_slave();
275 ixdp2800_master_wait_for_slave_bus_scan();
276 } else {
277 dev = pci_find_slot(1, IXDP2800_MASTER_ENET_DEVFN);
278 pci_remove_bus_device(dev);
279 }
280 }
160 281
161 return 0; 282 return 0;
162} 283}