*
* Licensed under the GNU/GPL. See COPYING for details.
*/
-@@ -16,120 +17,124 @@
+@@ -16,120 +17,131 @@
* R/W ops.
**************************************************/
}
-#endif
- static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
+-static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
++static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u16 phy)
{
- const u16 mdio_control = 0x128;
- const u16 mdio_data = 0x12C;
}
}
- static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address)
+-static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address)
++static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u16 device, u8 address)
{
- const u16 mdio_control = 0x128;
- const u16 mdio_data = 0x12C;
return ret;
}
- static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
+-static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
++static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u16 device,
u8 address, u16 data)
{
- const u16 mdio_control = 0x128;
}
- pcicore_write32(pc, mdio_control, 0);
+ pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
++}
++
++static u16 bcma_pcie_mdio_writeread(struct bcma_drv_pci *pc, u16 device,
++ u8 address, u16 data)
++{
++ bcma_pcie_mdio_write(pc, device, address, data);
++ return bcma_pcie_mdio_read(pc, device, address);
}
/**************************************************
-@@ -138,88 +143,108 @@ static void bcma_pcie_mdio_write(struct
+@@ -138,88 +150,134 @@ static void bcma_pcie_mdio_write(struct
static u8 bcma_pcicore_polarity_workaround(struct bcma_drv_pci *pc)
{
- pr_err("Driver compiled without support for hostmode PCI\n");
#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
- } else {
-- bcma_core_pci_clientmode_init(pc);
++
++ if (!pc->hostmode)
+ bcma_core_pci_clientmode_init(pc);
- }
++}
++
++void bcma_core_pci_power_save(struct bcma_bus *bus, bool up)
++{
++ struct bcma_drv_pci *pc;
++ u16 data;
- pc->setup_done = true;
-+ if (!pc->hostmode)
-+ bcma_core_pci_clientmode_init(pc);
++ if (bus->hosttype != BCMA_HOSTTYPE_PCI)
++ return;
++
++ pc = &bus->drv_pci[0];
++
++ if (pc->core->id.rev >= 15 && pc->core->id.rev <= 20) {
++ data = up ? 0x74 : 0x7C;
++ bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
++ BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7F64);
++ bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
++ BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data);
++ } else if (pc->core->id.rev >= 21 && pc->core->id.rev <= 22) {
++ data = up ? 0x75 : 0x7D;
++ bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
++ BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7E65);
++ bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
++ BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data);
++ }
}
++EXPORT_SYMBOL_GPL(bcma_core_pci_power_save);
int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
bool enable)
err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
if (err)
goto out;
-@@ -236,3 +261,17 @@ out:
+@@ -236,3 +294,42 @@ out:
return err;
}
EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl);
+
-+void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend)
++static void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend)
+{
+ u32 w;
+
+ bcma_pcie_write(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG, w);
+ bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG);
+}
-+EXPORT_SYMBOL_GPL(bcma_core_pci_extend_L1timer);
++
++void bcma_core_pci_up(struct bcma_bus *bus)
++{
++ struct bcma_drv_pci *pc;
++
++ if (bus->hosttype != BCMA_HOSTTYPE_PCI)
++ return;
++
++ pc = &bus->drv_pci[0];
++
++ bcma_core_pci_extend_L1timer(pc, true);
++}
++EXPORT_SYMBOL_GPL(bcma_core_pci_up);
++
++void bcma_core_pci_down(struct bcma_bus *bus)
++{
++ struct bcma_drv_pci *pc;
++
++ if (bus->hosttype != BCMA_HOSTTYPE_PCI)
++ return;
++
++ pc = &bus->drv_pci[0];
++
++ bcma_core_pci_extend_L1timer(pc, false);
++}
++EXPORT_SYMBOL_GPL(bcma_core_pci_down);
--- a/drivers/bcma/driver_pci_host.c
+++ b/drivers/bcma/driver_pci_host.c
-@@ -2,13 +2,616 @@
+@@ -2,13 +2,622 @@
* Broadcom specific AMBA
* PCI Core in hostmode
*
+int bcma_core_pci_plat_dev_init(struct pci_dev *dev)
+{
+ struct bcma_drv_pci_host *pc_host;
++ int readrq;
+
+ if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
+ /* This is not a device on the PCI-core bridge. */
+ dev->irq = bcma_core_irq(pc_host->pdev->core);
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+
++ readrq = pcie_get_readrq(dev);
++ if (readrq > 128) {
++ pr_info("change PCIe max read request size from %i to 128\n", readrq);
++ pcie_set_readrq(dev, 128);
++ }
+ return 0;
+}
+EXPORT_SYMBOL(bcma_core_pci_plat_dev_init);
/* SBtoPCIx */
#define BCMA_CORE_PCI_SBTOPCI_MEM 0x00000000
-@@ -72,20 +108,120 @@ struct pci_dev;
+@@ -72,20 +108,143 @@ struct pci_dev;
#define BCMA_CORE_PCI_SBTOPCI_RC_READL 0x00000010 /* Memory read line */
#define BCMA_CORE_PCI_SBTOPCI_RC_READM 0x00000020 /* Memory read multiple */
+
+#define BCMA_CORE_PCI_CFG_DEVCTRL 0xd8
+
++#define BCMA_CORE_PCI_
++
++/* MDIO devices (SERDES modules) */
++#define BCMA_CORE_PCI_MDIO_IEEE0 0x000
++#define BCMA_CORE_PCI_MDIO_IEEE1 0x001
++#define BCMA_CORE_PCI_MDIO_BLK0 0x800
++#define BCMA_CORE_PCI_MDIO_BLK1 0x801
++#define BCMA_CORE_PCI_MDIO_BLK1_MGMT0 0x16
++#define BCMA_CORE_PCI_MDIO_BLK1_MGMT1 0x17
++#define BCMA_CORE_PCI_MDIO_BLK1_MGMT2 0x18
++#define BCMA_CORE_PCI_MDIO_BLK1_MGMT3 0x19
++#define BCMA_CORE_PCI_MDIO_BLK1_MGMT4 0x1A
++#define BCMA_CORE_PCI_MDIO_BLK2 0x802
++#define BCMA_CORE_PCI_MDIO_BLK3 0x803
++#define BCMA_CORE_PCI_MDIO_BLK4 0x804
++#define BCMA_CORE_PCI_MDIO_TXPLL 0x808 /* TXPLL register block idx */
++#define BCMA_CORE_PCI_MDIO_TXCTRL0 0x820
++#define BCMA_CORE_PCI_MDIO_SERDESID 0x831
++#define BCMA_CORE_PCI_MDIO_RXCTRL0 0x840
++
+/* PCIE Root Capability Register bits (Host mode only) */
+#define BCMA_CORE_PCI_RC_CRS_VISIBILITY 0x0001
+
+struct bcma_drv_pci;
++struct bcma_bus;
+
+#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
+struct bcma_drv_pci_host {
+extern void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc);
extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc,
struct bcma_device *core, bool enable);
-+extern void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend);
++extern void bcma_core_pci_up(struct bcma_bus *bus);
++extern void bcma_core_pci_down(struct bcma_bus *bus);
++extern void bcma_core_pci_power_save(struct bcma_bus *bus, bool up);
+
+extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev);
+extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev);