13 #include <linux/pci.h>
14 #include <linux/export.h>
21 #define mips_busprobe32(val, addr) get_dbe((val), ((u32 *)(addr)))
24 #define BCMA_PCI_SLOT_MAX 16
25 #define PCI_CONFIG_SPACE_SIZE 256
33 chipid_top = (bus->
chipinfo.id & 0xFF00);
34 if (chipid_top != 0x4700 &&
39 bcma_info(bus,
"This PCI core is disabled and not working\n");
64 unsigned int func,
unsigned int off)
79 addr = pc->host_controller->host_cfg_addr;
88 static int bcma_extpci_read_config(
struct bcma_drv_pci *pc,
unsigned int dev,
89 unsigned int func,
unsigned int off,
97 if (
unlikely(len != 1 && len != 2 && len != 4))
109 addr |= (off & 0x0FFF);
110 val = bcma_pcie_read_config(pc, addr);
114 addr |= (off & 0xfc);
118 addr = bcma_get_cfgspace_addr(pc, dev, func, off);
133 val >>= (8 * (off & 3));
137 *((
u8 *)buf) = (
u8)val;
154 static int bcma_extpci_write_config(
struct bcma_drv_pci *pc,
unsigned int dev,
155 unsigned int func,
unsigned int off,
156 const void *buf,
int len)
159 u32 addr = 0, val = 0;
164 if (
unlikely(len != 1 && len != 2 && len != 4))
173 addr |= (off & 0xfc);
179 addr = bcma_get_cfgspace_addr(pc, dev, func, off);
196 val &= ~(0xFF << (8 * (off & 3)));
197 val |= *((
const u8 *)buf) << (8 * (off & 3));
201 val &= ~(0xFFFF << (8 * (off & 3)));
202 val |= *((
const u16 *)buf) << (8 * (off & 3));
205 val = *((
const u32 *)buf);
208 if (dev == 0 && !addr) {
213 addr |= (off & 0x0FFF);
214 bcma_pcie_write_config(pc, addr, val);
231 static int bcma_core_pci_hostmode_read_config(
struct pci_bus *
bus,
238 struct bcma_drv_pci_host *pc_host;
244 err = bcma_extpci_read_config(pc,
PCI_SLOT(devfn),
246 spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags);
251 static int bcma_core_pci_hostmode_write_config(
struct pci_bus *bus,
253 int reg,
int size,
u32 val)
258 struct bcma_drv_pci_host *pc_host;
264 err = bcma_extpci_write_config(pc,
PCI_SLOT(devfn),
266 spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags);
274 unsigned int func,
u8 req_cap_id,
289 bcma_extpci_read_config(pc, dev, func,
PCI_STATUS, &byte_val,
302 bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id,
sizeof(
u8));
303 while (cap_id != req_cap_id) {
304 bcma_extpci_read_config(pc, dev, func, cap_ptr + 1, &cap_ptr,
308 bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id,
313 if ((buf !=
NULL) && (buflen !=
NULL)) {
323 cap_data = cap_ptr + 2;
328 bcma_extpci_read_config(pc, dev, func, cap_data, buf,
352 bcma_extpci_read_config(pc, 0, 0, root_cap, &val16,
sizeof(
u16));
357 bcma_extpci_read_config(pc, 0, 0, root_ctrl, &val16,
374 for (i = 0; i < 100000; i++) {
375 bcma_extpci_read_config(pc, dev, 0,
383 bcma_err(bus,
"PCI: Broken device in slot %d\n",
392 struct bcma_drv_pci_host *pc_host;
395 unsigned long io_map_base;
397 bcma_info(bus,
"PCIEcore in host mode found\n");
399 pc_host = kzalloc(
sizeof(*pc_host),
GFP_KERNEL);
401 bcma_err(bus,
"can not allocate memory");
405 pc->host_controller = pc_host;
406 pc_host->pci_controller.io_resource = &pc_host->io_resource;
407 pc_host->pci_controller.mem_resource = &pc_host->mem_resource;
408 pc_host->pci_controller.pci_ops = &pc_host->pci_ops;
414 pc_host->pci_ops.read = bcma_core_pci_hostmode_read_config;
415 pc_host->pci_ops.write = bcma_core_pci_hostmode_write_config;
417 pc_host->mem_resource.name =
"BCMA PCIcore external memory",
422 pc_host->io_resource.name =
"BCMA PCIcore external I/O",
423 pc_host->io_resource.start = 0x100;
424 pc_host->io_resource.end = 0x7FF;
451 if (pc->
core->core_unit == 0) {
458 }
else if (pc->
core->core_unit == 1) {
486 bcma_core_pci_enable_crs(pc);
490 bcma_extpci_write_config(pc, 0, 0,
PCI_COMMAND, &tmp,
sizeof(tmp));
499 resource_size(&pc_host->mem_resource));
500 pc_host->pci_controller.io_map_base = io_map_base;
501 set_io_port_base(pc_host->pci_controller.io_map_base);
510 static void bcma_core_pci_fixup_pcibridge(
struct pci_dev *dev)
512 if (dev->
bus->ops->read != bcma_core_pci_hostmode_read_config) {
519 pr_info(
"PCI: Fixing up bridge %s\n", pci_name(dev));
524 pr_err(
"PCI: BCMA bridge enable failed\n");
534 static void bcma_core_pci_fixup_addresses(
struct pci_dev *dev)
539 if (dev->
bus->ops->read != bcma_core_pci_hostmode_read_config) {
546 pr_info(
"PCI: Fixing up addresses %s\n", pci_name(dev));
548 for (pos = 0; pos < 6; pos++) {
560 struct bcma_drv_pci_host *pc_host;
562 if (dev->
bus->ops->read != bcma_core_pci_hostmode_read_config) {
569 pr_info(
"PCI: Fixing up device %s\n", pci_name(dev));
582 struct bcma_drv_pci_host *pc_host;
584 if (dev->
bus->ops->read != bcma_core_pci_hostmode_read_config) {