if (func > (MPI_L2PCFG_FUNC_MASK >> MPI_L2PCFG_FUNC_SHIFT)) return1;
if (reg > (MPI_L2PCFG_REG_MASK >> MPI_L2PCFG_REG_SHIFT)) return1;
/* ok, setup config access */
val = (reg << MPI_L2PCFG_REG_SHIFT);
val |= (func << MPI_L2PCFG_FUNC_SHIFT);
val |= (slot << MPI_L2PCFG_DEVNUM_SHIFT);
val |= MPI_L2PCFG_CFG_USEREG_MASK;
val |= MPI_L2PCFG_CFG_SEL_MASK; /* type 0 cycle for local bus, type 1 cycle for anything else */ if (type != 0) { /* FIXME: how to specify bus ??? */
val |= (1 << MPI_L2PCFG_CFG_TYPE_SHIFT);
}
bcm_mpi_writel(val, MPI_L2PCFG_REG);
return0;
}
staticint bcm63xx_do_cfg_read(int type, unsignedint busn, unsignedint devfn, int where, int size,
u32 *val)
{
u32 data;
/* two phase cycle, first we write address, then read data at *anotherlocation,calleralreadyhasaspinlocksononeed
* to add one here */ if (bcm63xx_setup_cfg_access(type, busn, devfn, where)) return PCIBIOS_DEVICE_NOT_FOUND;
iob();
data = le32_to_cpu(__raw_readl(pci_iospace_start)); /* restore IO space normal behaviour */
bcm_mpi_writel(0, MPI_L2PCFG_REG);
*val = postprocess_read(data, where, size);
return PCIBIOS_SUCCESSFUL;
}
staticint bcm63xx_do_cfg_write(int type, unsignedint busn, unsignedint devfn, int where, int size,
u32 val)
{
u32 data;
/* two phase cycle, first we write address, then write data to *anotherlocation,calleralreadyhasaspinlocksononeed
* to add one here */ if (bcm63xx_setup_cfg_access(type, busn, devfn, where)) return PCIBIOS_DEVICE_NOT_FOUND;
iob();
data = le32_to_cpu(__raw_readl(pci_iospace_start));
data = preprocess_write(data, val, where, size);
__raw_writel(cpu_to_le32(data), pci_iospace_start);
wmb(); /* no way to know the access is done, we have to wait */
udelay(500); /* restore IO space normal behaviour */
bcm_mpi_writel(0, MPI_L2PCFG_REG);
return PCIBIOS_SUCCESSFUL;
}
staticint bcm63xx_pci_read(struct pci_bus *bus, unsignedint devfn, int where, int size, u32 *val)
{ int type;
type = bus->parent ? 1 : 0;
if (type == 0 && PCI_SLOT(devfn) == CARDBUS_PCI_IDSEL) return PCIBIOS_DEVICE_NOT_FOUND;
data = 0;
reg = where >> 2; switch (reg) { case (PCI_VENDOR_ID >> 2): case (PCI_CB_SUBSYSTEM_VENDOR_ID >> 2): /* create dummy vendor/device id from our cpu id */
data = (bcm63xx_get_cpu_id() << 16) | PCI_VENDOR_ID_BROADCOM; break;
case (PCI_COMMAND >> 2):
data = (PCI_STATUS_DEVSEL_SLOW << 16);
data |= fake_cb_bridge_regs.pci_command; break;
case (PCI_CLASS_REVISION >> 2):
data = (PCI_CLASS_BRIDGE_CARDBUS << 16); break;
case (PCI_CACHE_LINE_SIZE >> 2):
data = (PCI_HEADER_TYPE_CARDBUS << 16); break;
case (PCI_INTERRUPT_LINE >> 2): /* bridge control */
data = (fake_cb_bridge_regs.bridge_control << 16); /* pin:intA line:0xff */
data |= (0x1 << 8) | 0xff; break;
case (PCI_CB_PRIMARY_BUS >> 2):
data = (fake_cb_bridge_regs.cb_latency << 24);
data |= (fake_cb_bridge_regs.subordinate_busn << 16);
data |= (fake_cb_bridge_regs.cardbus_busn << 8);
data |= fake_cb_bridge_regs.pci_busn; break;
case (PCI_CB_MEMORY_BASE_0 >> 2):
data = fake_cb_bridge_regs.mem_base0; break;
case (PCI_CB_MEMORY_LIMIT_0 >> 2):
data = fake_cb_bridge_regs.mem_limit0; break;
case (PCI_CB_MEMORY_BASE_1 >> 2):
data = fake_cb_bridge_regs.mem_base1; break;
case (PCI_CB_MEMORY_LIMIT_1 >> 2):
data = fake_cb_bridge_regs.mem_limit1; break;
case (PCI_CB_IO_BASE_0 >> 2): /* | 1 for 32bits io support */
data = fake_cb_bridge_regs.io_base0 | 0x1; break;
case (PCI_CB_IO_LIMIT_0 >> 2):
data = fake_cb_bridge_regs.io_limit0; break;
case (PCI_CB_IO_BASE_1 >> 2): /* | 1 for 32bits io support */
data = fake_cb_bridge_regs.io_base1 | 0x1; break;
case (PCI_CB_IO_LIMIT_1 >> 2):
data = fake_cb_bridge_regs.io_limit1; break;
}
/* look for any io resource */
found = 0;
pci_dev_for_each_resource(dev, r) { if (resource_type(r) == IORESOURCE_IO) {
found = 1; break;
}
} if (!found) return;
/* skip our fake bus with only cardbus bridge on it */ if (dev->bus->number == fake_cb_bridge_bus_number) return;
/* find on which bus the device is */ if (fake_cb_bridge_regs.bus_assigned &&
dev->bus->number == fake_cb_bridge_regs.cardbus_busn &&
PCI_SLOT(dev->devfn) == 0)
new_io_window = 1; else
new_io_window = 0;
if (new_io_window == io_window) return;
if (io_window != -1) {
printk(KERN_ERR "bcm63xx: both PCI and cardbus devices " "need IO, which hardware cannot do\n"); return;
}
val = bcm_mpi_readl(MPI_L2PIOREMAP_REG); if (io_window)
val |= MPI_L2PREMAP_IS_CARDBUS_MASK; else
val &= ~MPI_L2PREMAP_IS_CARDBUS_MASK;
bcm_mpi_writel(val, MPI_L2PIOREMAP_REG);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.