ar71xx: improve SPI flash read/write performance
[openwrt.git] / target / linux / ar71xx / patches-3.2 / 110-MIPS-ath79-fix-broken-ar724x_pci_-read-write-functio.patch
1 From 2e535c334018d58b0bf6df583486abda5bfb2003 Mon Sep 17 00:00:00 2001
2 From: Gabor Juhos <juhosg@openwrt.org>
3 Date: Fri, 18 Nov 2011 22:25:30 +0100
4 Subject: [PATCH 10/35] MIPS: ath79: fix broken ar724x_pci_{read,write} functions
5
6 The current ar724x_pci_{read,write} functions are
7 broken. Due to that, pci_read_config_byte returns
8 with bogus values, and pci_write_config_{byte,word}
9 unconditionally clears the accessed PCI configuration
10 registers instead of changing the value of them.
11
12 The patch fixes the broken functions, thus the PCI
13 configuration space can be accessed correctly.
14
15 Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
16
17 v2: - no changes
18
19 Output of 'lspci -vv' without the patch:
20
21 00:00.0 Network controller: Atheros Communications Inc. AR9285 Wireless
22 Network Adapter (PCI-Express) (rev 01)
23 Subsystem: Atheros Communications Inc. Device a091
24 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
25 Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
26 Latency: 0
27 Interrupt: pin A routed to IRQ 0
28 Region 0: Memory at 10000000 (64-bit, non-prefetchable) [size=64K]
29 Capabilities: [40] Power Management version 3
30 Flags: PMEClk- DSI- D1+ D2- AuxCurrent=375mA PME(D0+,D1+,D2-,D3hot+,D3cold-)
31 Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
32 Capabilities: [50] MSI: Enable- Count=1/1 Maskable- 64bit-
33 Address: 00000000 Data: 0000
34 Capabilities: [60] Express (v2) Legacy Endpoint, MSI 00
35 DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <512ns, L1 <64us
36 ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
37 DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
38 RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop-
39 MaxPayload 128 bytes, MaxReadReq 512 bytes
40 DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
41 LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM unknown, Latency L0 <512ns, L1 <64us
42 ClockPM- Surprise- LLActRep- BwNot-
43 LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk-
44 ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
45 LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
46 DevCap2: Completion Timeout: Not Supported, TimeoutDis+
47 DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-
48 LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance- SpeedDis-, Selectable De-emphasis: -6dB
49 Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
50 Compliance De-emphasis: -6dB
51 LnkSta2: Current De-emphasis Level: -6dB
52
53 Output of 'lspci -vv' with the patch:
54
55 00:00.0 Network controller: Atheros Communications Inc. AR9285 Wireless
56 Network Adapter (PCI-Express) (rev 01)
57 Subsystem: Atheros Communications Inc. Device a091
58 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
59 Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
60 Latency: 0
61 Interrupt: pin A routed to IRQ 48
62 Region 0: Memory at 10000000 (64-bit, non-prefetchable) [size=64K]
63 Capabilities: [40] Power Management version 3
64 Flags: PMEClk- DSI- D1+ D2- AuxCurrent=375mA PME(D0+,D1+,D2-,D3hot+,D3cold-)
65 Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
66 Capabilities: [50] MSI: Enable- Count=1/1 Maskable- 64bit-
67 Address: 00000000 Data: 0000
68 Capabilities: [60] Express (v2) Legacy Endpoint, MSI 00
69 DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <512ns, L1 <64us
70 ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
71 DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
72 RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop-
73 MaxPayload 128 bytes, MaxReadReq 512 bytes
74 DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
75 LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM unknown, Latency L0 <512ns, L1 <64us
76 ClockPM- Surprise- LLActRep- BwNot-
77 LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk-
78 ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
79 LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
80 DevCap2: Completion Timeout: Not Supported, TimeoutDis+
81 DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-
82 LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance- SpeedDis-, Selectable De-emphasis: -6dB
83 Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
84 Compliance De-emphasis: -6dB
85 LnkSta2: Current De-emphasis Level: -6dB
86 Capabilities: [100 v1] Advanced Error Reporting
87 UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
88 UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
89 UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
90 CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr-
91 CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
92 AERCap: First Error Pointer: 00, GenCap+ CGenEn- ChkCap+ ChkEn-
93 Capabilities: [140 v1] Virtual Channel
94 Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
95 Arb: Fixed- WRR32- WRR64- WRR128-
96 Ctrl: ArbSelect=Fixed
97 Status: InProgress-
98 VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
99 Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
100 Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=ff
101 Status: NegoPending- InProgress-
102 Capabilities: [160 v1] Device Serial Number 00-15-17-ff-ff-24-14-12
103 Capabilities: [170 v1] Power Budgeting <?>
104 ---
105 arch/mips/pci/pci-ar724x.c | 52 ++++++++++++++++++++++----------------------
106 1 files changed, 26 insertions(+), 26 deletions(-)
107
108 --- a/arch/mips/pci/pci-ar724x.c
109 +++ b/arch/mips/pci/pci-ar724x.c
110 @@ -22,8 +22,9 @@ static void __iomem *ar724x_pci_devcfg_b
111 static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
112 int size, uint32_t *value)
113 {
114 - unsigned long flags, addr, tval, mask;
115 + unsigned long flags;
116 void __iomem *base;
117 + u32 data;
118
119 if (devfn)
120 return PCIBIOS_DEVICE_NOT_FOUND;
121 @@ -31,24 +32,22 @@ static int ar724x_pci_read(struct pci_bu
122 base = ar724x_pci_devcfg_base;
123
124 spin_lock_irqsave(&ar724x_pci_lock, flags);
125 + data = __raw_readl(base + (where & ~3));
126
127 switch (size) {
128 case 1:
129 - addr = where & ~3;
130 - mask = 0xff000000 >> ((where % 4) * 8);
131 - tval = __raw_readl(base + addr);
132 - tval = tval & ~mask;
133 - *value = (tval >> ((4 - (where % 4))*8));
134 + if (where & 1)
135 + data >>= 8;
136 + if (where & 2)
137 + data >>= 16;
138 + data &= 0xff;
139 break;
140 case 2:
141 - addr = where & ~3;
142 - mask = 0xffff0000 >> ((where % 4)*8);
143 - tval = __raw_readl(base + addr);
144 - tval = tval & ~mask;
145 - *value = (tval >> ((4 - (where % 4))*8));
146 + if (where & 2)
147 + data >>= 16;
148 + data &= 0xffff;
149 break;
150 case 4:
151 - *value = __raw_readl(base + where);
152 break;
153 default:
154 spin_unlock_irqrestore(&ar724x_pci_lock, flags);
155 @@ -57,6 +56,7 @@ static int ar724x_pci_read(struct pci_bu
156 }
157
158 spin_unlock_irqrestore(&ar724x_pci_lock, flags);
159 + *value = data;
160
161 return PCIBIOS_SUCCESSFUL;
162 }
163 @@ -64,8 +64,10 @@ static int ar724x_pci_read(struct pci_bu
164 static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
165 int size, uint32_t value)
166 {
167 - unsigned long flags, tval, addr, mask;
168 + unsigned long flags;
169 void __iomem *base;
170 + u32 data;
171 + int s;
172
173 if (devfn)
174 return PCIBIOS_DEVICE_NOT_FOUND;
175 @@ -73,26 +75,21 @@ static int ar724x_pci_write(struct pci_b
176 base = ar724x_pci_devcfg_base;
177
178 spin_lock_irqsave(&ar724x_pci_lock, flags);
179 + data = __raw_readl(base + (where & ~3));
180
181 switch (size) {
182 case 1:
183 - addr = where & ~3;
184 - mask = 0xff000000 >> ((where % 4)*8);
185 - tval = __raw_readl(base + addr);
186 - tval = tval & ~mask;
187 - tval |= (value << ((4 - (where % 4))*8)) & mask;
188 - __raw_writel(tval, base + addr);
189 + s = ((where & 3) * 8);
190 + data &= ~(0xff << s);
191 + data |= ((value & 0xff) << s);
192 break;
193 case 2:
194 - addr = where & ~3;
195 - mask = 0xffff0000 >> ((where % 4)*8);
196 - tval = __raw_readl(base + addr);
197 - tval = tval & ~mask;
198 - tval |= (value << ((4 - (where % 4))*8)) & mask;
199 - __raw_writel(tval, base + addr);
200 + s = ((where & 2) * 8);
201 + data &= ~(0xffff << s);
202 + data |= ((value & 0xffff) << s);
203 break;
204 case 4:
205 - __raw_writel(value, (base + where));
206 + data = value;
207 break;
208 default:
209 spin_unlock_irqrestore(&ar724x_pci_lock, flags);
210 @@ -100,6 +97,9 @@ static int ar724x_pci_write(struct pci_b
211 return PCIBIOS_BAD_REGISTER_NUMBER;
212 }
213
214 + __raw_writel(data, base + (where & ~3));
215 + /* flush write */
216 + __raw_readl(base + (where & ~3));
217 spin_unlock_irqrestore(&ar724x_pci_lock, flags);
218
219 return PCIBIOS_SUCCESSFUL;
This page took 0.059008 seconds and 5 git commands to generate.