1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
bcma patch adding bcma_core_pci_up() and bcma_core_pci_down(), this gets
called by b43 and brcmsmac
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
--- a/drivers/bcma/driver_pci.c
+++ b/drivers/bcma/driver_pci.c
@@ -31,7 +31,7 @@ static void bcma_pcie_write(struct bcma_
pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_DATA, data);
}
-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)
{
u32 v;
int i;
@@ -55,7 +55,7 @@ static void bcma_pcie_mdio_set_phy(struc
}
}
-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)
{
int max_retries = 10;
u16 ret = 0;
@@ -98,7 +98,7 @@ static u16 bcma_pcie_mdio_read(struct bc
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, u16 device,
u8 address, u16 data)
{
int max_retries = 10;
@@ -137,6 +137,13 @@ static void bcma_pcie_mdio_write(struct
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);
+}
+
/**************************************************
* Workarounds.
**************************************************/
@@ -203,6 +210,25 @@ static void bcma_core_pci_config_fixup(s
}
}
+static void bcma_core_pci_power_save(struct bcma_drv_pci *pc, bool up)
+{
+ u16 data;
+
+ 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);
+ }
+}
+
/**************************************************
* Init.
**************************************************/
@@ -262,7 +288,7 @@ out:
}
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;
@@ -274,4 +300,38 @@ void bcma_core_pci_extend_L1timer(struct
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_power_save(pc, true);
+
+ bcma_core_pci_extend_L1timer(pc, true);
+
+ if ((pc->core->id.rev == 18 || pc->core->id.rev == 19) &&
+ bus->boardinfo.vendor != PCI_VENDOR_ID_APPLE) {
+ pcie_set_readrq(bus->host_pci, 128);
+ }
+}
+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);
+
+ bcma_core_pci_power_save(pc, false);
+}
+EXPORT_SYMBOL_GPL(bcma_core_pci_down);
--- a/include/linux/bcma/bcma_driver_pci.h
+++ b/include/linux/bcma/bcma_driver_pci.h
@@ -181,10 +181,31 @@ struct pci_dev;
#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 {
@@ -219,7 +240,8 @@ struct bcma_drv_pci {
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 int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev);
extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev);
|