2 * Broadcom specific AMBA
5 * Licensed under the GNU/GPL. See COPYING for details.
8 #include "bcma_private.h"
9 #include <linux/slab.h>
10 #include <linux/bcma/bcma.h>
11 #include <linux/pci.h>
12 #include <linux/module.h>
14 static void bcma_host_pci_switch_core(struct bcma_device
*core
)
16 int win2
= core
->bus
->host_is_pcie2
?
17 BCMA_PCIE2_BAR0_WIN2
: BCMA_PCI_BAR0_WIN2
;
19 pci_write_config_dword(core
->bus
->host_pci
, BCMA_PCI_BAR0_WIN
,
21 pci_write_config_dword(core
->bus
->host_pci
, win2
, core
->wrap
);
22 core
->bus
->mapped_core
= core
;
23 bcma_debug(core
->bus
, "Switched to core: 0x%X\n", core
->id
.id
);
26 /* Provides access to the requested core. Returns base offset that has to be
27 * used. It makes use of fixed windows when possible. */
28 static u16
bcma_host_pci_provide_access_to_core(struct bcma_device
*core
)
30 switch (core
->id
.id
) {
31 case BCMA_CORE_CHIPCOMMON
:
32 return 3 * BCMA_CORE_SIZE
;
34 return 2 * BCMA_CORE_SIZE
;
37 if (core
->bus
->mapped_core
!= core
)
38 bcma_host_pci_switch_core(core
);
42 static u8
bcma_host_pci_read8(struct bcma_device
*core
, u16 offset
)
44 offset
+= bcma_host_pci_provide_access_to_core(core
);
45 return ioread8(core
->bus
->mmio
+ offset
);
48 static u16
bcma_host_pci_read16(struct bcma_device
*core
, u16 offset
)
50 offset
+= bcma_host_pci_provide_access_to_core(core
);
51 return ioread16(core
->bus
->mmio
+ offset
);
54 static u32
bcma_host_pci_read32(struct bcma_device
*core
, u16 offset
)
56 offset
+= bcma_host_pci_provide_access_to_core(core
);
57 return ioread32(core
->bus
->mmio
+ offset
);
60 static void bcma_host_pci_write8(struct bcma_device
*core
, u16 offset
,
63 offset
+= bcma_host_pci_provide_access_to_core(core
);
64 iowrite8(value
, core
->bus
->mmio
+ offset
);
67 static void bcma_host_pci_write16(struct bcma_device
*core
, u16 offset
,
70 offset
+= bcma_host_pci_provide_access_to_core(core
);
71 iowrite16(value
, core
->bus
->mmio
+ offset
);
74 static void bcma_host_pci_write32(struct bcma_device
*core
, u16 offset
,
77 offset
+= bcma_host_pci_provide_access_to_core(core
);
78 iowrite32(value
, core
->bus
->mmio
+ offset
);
81 #ifdef CONFIG_BCMA_BLOCKIO
82 static void bcma_host_pci_block_read(struct bcma_device
*core
, void *buffer
,
83 size_t count
, u16 offset
, u8 reg_width
)
85 void __iomem
*addr
= core
->bus
->mmio
+ offset
;
86 if (core
->bus
->mapped_core
!= core
)
87 bcma_host_pci_switch_core(core
);
90 ioread8_rep(addr
, buffer
, count
);
94 ioread16_rep(addr
, buffer
, count
>> 1);
98 ioread32_rep(addr
, buffer
, count
>> 2);
105 static void bcma_host_pci_block_write(struct bcma_device
*core
,
106 const void *buffer
, size_t count
,
107 u16 offset
, u8 reg_width
)
109 void __iomem
*addr
= core
->bus
->mmio
+ offset
;
110 if (core
->bus
->mapped_core
!= core
)
111 bcma_host_pci_switch_core(core
);
114 iowrite8_rep(addr
, buffer
, count
);
118 iowrite16_rep(addr
, buffer
, count
>> 1);
122 iowrite32_rep(addr
, buffer
, count
>> 2);
130 static u32
bcma_host_pci_aread32(struct bcma_device
*core
, u16 offset
)
132 if (core
->bus
->mapped_core
!= core
)
133 bcma_host_pci_switch_core(core
);
134 return ioread32(core
->bus
->mmio
+ (1 * BCMA_CORE_SIZE
) + offset
);
137 static void bcma_host_pci_awrite32(struct bcma_device
*core
, u16 offset
,
140 if (core
->bus
->mapped_core
!= core
)
141 bcma_host_pci_switch_core(core
);
142 iowrite32(value
, core
->bus
->mmio
+ (1 * BCMA_CORE_SIZE
) + offset
);
145 static const struct bcma_host_ops bcma_host_pci_ops
= {
146 .read8
= bcma_host_pci_read8
,
147 .read16
= bcma_host_pci_read16
,
148 .read32
= bcma_host_pci_read32
,
149 .write8
= bcma_host_pci_write8
,
150 .write16
= bcma_host_pci_write16
,
151 .write32
= bcma_host_pci_write32
,
152 #ifdef CONFIG_BCMA_BLOCKIO
153 .block_read
= bcma_host_pci_block_read
,
154 .block_write
= bcma_host_pci_block_write
,
156 .aread32
= bcma_host_pci_aread32
,
157 .awrite32
= bcma_host_pci_awrite32
,
160 static int bcma_host_pci_probe(struct pci_dev
*dev
,
161 const struct pci_device_id
*id
)
163 struct bcma_bus
*bus
;
169 bus
= kzalloc(sizeof(*bus
), GFP_KERNEL
);
173 /* Basic PCI configuration */
174 err
= pci_enable_device(dev
);
178 name
= dev_name(&dev
->dev
);
179 if (dev
->driver
&& dev
->driver
->name
)
180 name
= dev
->driver
->name
;
181 err
= pci_request_regions(dev
, name
);
183 goto err_pci_disable
;
186 /* Disable the RETRY_TIMEOUT register (0x41) to keep
187 * PCI Tx retries from interfering with C3 CPU state */
188 pci_read_config_dword(dev
, 0x40, &val
);
189 if ((val
& 0x0000ff00) != 0)
190 pci_write_config_dword(dev
, 0x40, val
& 0xffff00ff);
192 /* SSB needed additional powering up, do we have any AMBA PCI cards? */
193 if (!pci_is_pcie(dev
)) {
194 bcma_err(bus
, "PCI card detected, they are not supported.\n");
196 goto err_pci_release_regions
;
201 bus
->mmio
= pci_iomap(dev
, 0, ~0UL);
203 goto err_pci_release_regions
;
207 bus
->hosttype
= BCMA_HOSTTYPE_PCI
;
208 bus
->ops
= &bcma_host_pci_ops
;
210 bus
->boardinfo
.vendor
= bus
->host_pci
->subsystem_vendor
;
211 bus
->boardinfo
.type
= bus
->host_pci
->subsystem_device
;
213 /* Initialize struct, detect chip */
216 /* Scan bus to find out generation of PCIe core */
217 err
= bcma_bus_scan(bus
);
219 goto err_pci_unmap_mmio
;
221 if (bcma_find_core(bus
, BCMA_CORE_PCIE2
))
222 bus
->host_is_pcie2
= true;
225 err
= bcma_bus_register(bus
);
227 goto err_unregister_cores
;
229 pci_set_drvdata(dev
, bus
);
234 err_unregister_cores
:
235 bcma_unregister_cores(bus
);
237 pci_iounmap(dev
, bus
->mmio
);
238 err_pci_release_regions
:
239 pci_release_regions(dev
);
241 pci_disable_device(dev
);
247 static void bcma_host_pci_remove(struct pci_dev
*dev
)
249 struct bcma_bus
*bus
= pci_get_drvdata(dev
);
251 bcma_bus_unregister(bus
);
252 pci_iounmap(dev
, bus
->mmio
);
253 pci_release_regions(dev
);
254 pci_disable_device(dev
);
258 #ifdef CONFIG_PM_SLEEP
259 static int bcma_host_pci_suspend(struct device
*dev
)
261 struct pci_dev
*pdev
= to_pci_dev(dev
);
262 struct bcma_bus
*bus
= pci_get_drvdata(pdev
);
264 bus
->mapped_core
= NULL
;
266 return bcma_bus_suspend(bus
);
269 static int bcma_host_pci_resume(struct device
*dev
)
271 struct pci_dev
*pdev
= to_pci_dev(dev
);
272 struct bcma_bus
*bus
= pci_get_drvdata(pdev
);
274 return bcma_bus_resume(bus
);
277 static SIMPLE_DEV_PM_OPS(bcma_pm_ops
, bcma_host_pci_suspend
,
278 bcma_host_pci_resume
);
279 #define BCMA_PM_OPS (&bcma_pm_ops)
281 #else /* CONFIG_PM_SLEEP */
283 #define BCMA_PM_OPS NULL
285 #endif /* CONFIG_PM_SLEEP */
287 static const struct pci_device_id bcma_pci_bridge_tbl
[] = {
288 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM
, 0x0576) },
289 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM
, 0x4313) },
290 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM
, 43224) }, /* 0xa8d8 */
291 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM
, 0x4331) },
292 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM
, 0x4353) },
293 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM
, 0x4357) },
294 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM
, 0x4358) },
295 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM
, 0x4359) },
296 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM
, 0x4360) },
297 { PCI_DEVICE_SUB(PCI_VENDOR_ID_BROADCOM
, 0x4365, PCI_VENDOR_ID_DELL
, 0x0016) },
298 { PCI_DEVICE_SUB(PCI_VENDOR_ID_BROADCOM
, 0x4365, PCI_VENDOR_ID_DELL
, 0x0018) },
299 { PCI_DEVICE_SUB(PCI_VENDOR_ID_BROADCOM
, 0x4365, PCI_VENDOR_ID_FOXCONN
, 0xe092) },
300 { PCI_DEVICE_SUB(PCI_VENDOR_ID_BROADCOM
, 0x4365, PCI_VENDOR_ID_HP
, 0x804a) },
301 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM
, 0x43a0) },
302 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM
, 0x43a9) },
303 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM
, 0x43aa) },
304 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM
, 0x43b1) },
305 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM
, 0x4727) },
306 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM
, 43227) }, /* 0xa8db, BCM43217 (sic!) */
307 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM
, 43228) }, /* 0xa8dc */
310 MODULE_DEVICE_TABLE(pci
, bcma_pci_bridge_tbl
);
312 static struct pci_driver bcma_pci_bridge_driver
= {
313 .name
= "bcma-pci-bridge",
314 .id_table
= bcma_pci_bridge_tbl
,
315 .probe
= bcma_host_pci_probe
,
316 .remove
= bcma_host_pci_remove
,
317 .driver
.pm
= BCMA_PM_OPS
,
320 int __init
bcma_host_pci_init(void)
322 return pci_register_driver(&bcma_pci_bridge_driver
);
325 void __exit
bcma_host_pci_exit(void)
327 pci_unregister_driver(&bcma_pci_bridge_driver
);
330 /**************************************************
331 * Runtime ops for drivers.
332 **************************************************/
334 /* See also pcicore_up */
335 void bcma_host_pci_up(struct bcma_bus
*bus
)
337 if (bus
->hosttype
!= BCMA_HOSTTYPE_PCI
)
340 if (bus
->host_is_pcie2
)
341 bcma_core_pcie2_up(&bus
->drv_pcie2
);
343 bcma_core_pci_up(&bus
->drv_pci
[0]);
345 EXPORT_SYMBOL_GPL(bcma_host_pci_up
);
347 /* See also pcicore_down */
348 void bcma_host_pci_down(struct bcma_bus
*bus
)
350 if (bus
->hosttype
!= BCMA_HOSTTYPE_PCI
)
353 if (!bus
->host_is_pcie2
)
354 bcma_core_pci_down(&bus
->drv_pci
[0]);
356 EXPORT_SYMBOL_GPL(bcma_host_pci_down
);
358 /* See also si_pci_setup */
359 int bcma_host_pci_irq_ctl(struct bcma_bus
*bus
, struct bcma_device
*core
,
362 struct pci_dev
*pdev
;
366 if (bus
->hosttype
!= BCMA_HOSTTYPE_PCI
) {
367 /* This bcma device is not on a PCI host-bus. So the IRQs are
368 * not routed through the PCI core.
369 * So we must not enable routing through the PCI core. */
373 pdev
= bus
->host_pci
;
375 err
= pci_read_config_dword(pdev
, BCMA_PCI_IRQMASK
, &tmp
);
379 coremask
= BIT(core
->core_index
) << 8;
385 err
= pci_write_config_dword(pdev
, BCMA_PCI_IRQMASK
, tmp
);
390 EXPORT_SYMBOL_GPL(bcma_host_pci_irq_ctl
);