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 pci_write_config_dword(core
->bus
->host_pci
, BCMA_PCI_BAR0_WIN
,
18 pci_write_config_dword(core
->bus
->host_pci
, BCMA_PCI_BAR0_WIN2
,
20 core
->bus
->mapped_core
= core
;
21 pr_debug("Switched to core: 0x%X\n", core
->id
.id
);
24 static u8
bcma_host_pci_read8(struct bcma_device
*core
, u16 offset
)
26 if (core
->bus
->mapped_core
!= core
)
27 bcma_host_pci_switch_core(core
);
28 return ioread8(core
->bus
->mmio
+ offset
);
31 static u16
bcma_host_pci_read16(struct bcma_device
*core
, u16 offset
)
33 if (core
->bus
->mapped_core
!= core
)
34 bcma_host_pci_switch_core(core
);
35 return ioread16(core
->bus
->mmio
+ offset
);
38 static u32
bcma_host_pci_read32(struct bcma_device
*core
, u16 offset
)
40 if (core
->bus
->mapped_core
!= core
)
41 bcma_host_pci_switch_core(core
);
42 return ioread32(core
->bus
->mmio
+ offset
);
45 static void bcma_host_pci_write8(struct bcma_device
*core
, u16 offset
,
48 if (core
->bus
->mapped_core
!= core
)
49 bcma_host_pci_switch_core(core
);
50 iowrite8(value
, core
->bus
->mmio
+ offset
);
53 static void bcma_host_pci_write16(struct bcma_device
*core
, u16 offset
,
56 if (core
->bus
->mapped_core
!= core
)
57 bcma_host_pci_switch_core(core
);
58 iowrite16(value
, core
->bus
->mmio
+ offset
);
61 static void bcma_host_pci_write32(struct bcma_device
*core
, u16 offset
,
64 if (core
->bus
->mapped_core
!= core
)
65 bcma_host_pci_switch_core(core
);
66 iowrite32(value
, core
->bus
->mmio
+ offset
);
69 #ifdef CONFIG_BCMA_BLOCKIO
70 void bcma_host_pci_block_read(struct bcma_device
*core
, void *buffer
,
71 size_t count
, u16 offset
, u8 reg_width
)
73 void __iomem
*addr
= core
->bus
->mmio
+ offset
;
74 if (core
->bus
->mapped_core
!= core
)
75 bcma_host_pci_switch_core(core
);
78 ioread8_rep(addr
, buffer
, count
);
82 ioread16_rep(addr
, buffer
, count
>> 1);
86 ioread32_rep(addr
, buffer
, count
>> 2);
93 void bcma_host_pci_block_write(struct bcma_device
*core
, const void *buffer
,
94 size_t count
, u16 offset
, u8 reg_width
)
96 void __iomem
*addr
= core
->bus
->mmio
+ offset
;
97 if (core
->bus
->mapped_core
!= core
)
98 bcma_host_pci_switch_core(core
);
101 iowrite8_rep(addr
, buffer
, count
);
105 iowrite16_rep(addr
, buffer
, count
>> 1);
109 iowrite32_rep(addr
, buffer
, count
>> 2);
117 static u32
bcma_host_pci_aread32(struct bcma_device
*core
, u16 offset
)
119 if (core
->bus
->mapped_core
!= core
)
120 bcma_host_pci_switch_core(core
);
121 return ioread32(core
->bus
->mmio
+ (1 * BCMA_CORE_SIZE
) + offset
);
124 static void bcma_host_pci_awrite32(struct bcma_device
*core
, u16 offset
,
127 if (core
->bus
->mapped_core
!= core
)
128 bcma_host_pci_switch_core(core
);
129 iowrite32(value
, core
->bus
->mmio
+ (1 * BCMA_CORE_SIZE
) + offset
);
132 const struct bcma_host_ops bcma_host_pci_ops
= {
133 .read8
= bcma_host_pci_read8
,
134 .read16
= bcma_host_pci_read16
,
135 .read32
= bcma_host_pci_read32
,
136 .write8
= bcma_host_pci_write8
,
137 .write16
= bcma_host_pci_write16
,
138 .write32
= bcma_host_pci_write32
,
139 #ifdef CONFIG_BCMA_BLOCKIO
140 .block_read
= bcma_host_pci_block_read
,
141 .block_write
= bcma_host_pci_block_write
,
143 .aread32
= bcma_host_pci_aread32
,
144 .awrite32
= bcma_host_pci_awrite32
,
147 static int bcma_host_pci_probe(struct pci_dev
*dev
,
148 const struct pci_device_id
*id
)
150 struct bcma_bus
*bus
;
156 bus
= kzalloc(sizeof(*bus
), GFP_KERNEL
);
160 /* Basic PCI configuration */
161 err
= pci_enable_device(dev
);
165 name
= dev_name(&dev
->dev
);
166 if (dev
->driver
&& dev
->driver
->name
)
167 name
= dev
->driver
->name
;
168 err
= pci_request_regions(dev
, name
);
170 goto err_pci_disable
;
173 /* Disable the RETRY_TIMEOUT register (0x41) to keep
174 * PCI Tx retries from interfering with C3 CPU state */
175 pci_read_config_dword(dev
, 0x40, &val
);
176 if ((val
& 0x0000ff00) != 0)
177 pci_write_config_dword(dev
, 0x40, val
& 0xffff00ff);
179 /* SSB needed additional powering up, do we have any AMBA PCI cards? */
180 if (!pci_is_pcie(dev
))
181 pr_err("PCI card detected, report problems.\n");
185 bus
->mmio
= pci_iomap(dev
, 0, ~0UL);
187 goto err_pci_release_regions
;
191 bus
->hosttype
= BCMA_HOSTTYPE_PCI
;
192 bus
->ops
= &bcma_host_pci_ops
;
195 err
= bcma_bus_register(bus
);
197 goto err_pci_unmap_mmio
;
199 pci_set_drvdata(dev
, bus
);
205 pci_iounmap(dev
, bus
->mmio
);
206 err_pci_release_regions
:
207 pci_release_regions(dev
);
209 pci_disable_device(dev
);
215 static void bcma_host_pci_remove(struct pci_dev
*dev
)
217 struct bcma_bus
*bus
= pci_get_drvdata(dev
);
219 bcma_bus_unregister(bus
);
220 pci_iounmap(dev
, bus
->mmio
);
221 pci_release_regions(dev
);
222 pci_disable_device(dev
);
224 pci_set_drvdata(dev
, NULL
);
227 static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl
) = {
228 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM
, 0x0576) },
229 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM
, 0x4331) },
230 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM
, 0x4353) },
231 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM
, 0x4357) },
232 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM
, 0x4727) },
235 MODULE_DEVICE_TABLE(pci
, bcma_pci_bridge_tbl
);
237 static struct pci_driver bcma_pci_bridge_driver
= {
238 .name
= "bcma-pci-bridge",
239 .id_table
= bcma_pci_bridge_tbl
,
240 .probe
= bcma_host_pci_probe
,
241 .remove
= bcma_host_pci_remove
,
244 int __init
bcma_host_pci_init(void)
246 return pci_register_driver(&bcma_pci_bridge_driver
);
249 void __exit
bcma_host_pci_exit(void)
251 pci_unregister_driver(&bcma_pci_bridge_driver
);