brcm2708: update against latest rpi-3.10.y branch
[openwrt/svn-archive/archive.git] / target / linux / brcm2708 / patches-3.10 / 0027-Add-FIQ-patch-to-dwc_otg-driver.-Enable-with-dwc_otg.patch
1 From c80392fbbb9a09f035f66a7d2a9fed2469373210 Mon Sep 17 00:00:00 2001
2 From: popcornmix <popcornmix@gmail.com>
3 Date: Wed, 3 Jul 2013 00:46:42 +0100
4 Subject: [PATCH 027/174] Add FIQ patch to dwc_otg driver. Enable with
5 dwc_otg.fiq_fix_enable=1. Should give about 10% more ARM performance. Thanks
6 to Gordon and Costas
7
8 ---
9 arch/arm/Kconfig | 1 +
10 arch/arm/include/asm/fiq.h | 1 +
11 arch/arm/kernel/fiq.c | 1 +
12 arch/arm/kernel/fiqasm.S | 7 ++
13 arch/arm/mach-bcm2708/armctrl.c | 19 ++-
14 arch/arm/mach-bcm2708/bcm2708.c | 29 ++++-
15 arch/arm/mach-bcm2708/include/mach/irqs.h | 159 +++++++++++++-------------
16 arch/arm/mach-bcm2708/include/mach/platform.h | 2 +
17 drivers/usb/host/dwc_otg/Makefile | 1 +
18 drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c | 14 ++-
19 drivers/usb/host/dwc_otg/dwc_otg_dbg.h | 1 +
20 drivers/usb/host/dwc_otg/dwc_otg_driver.c | 37 +++++-
21 drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 5 +
22 drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 2 +-
23 drivers/usb/host/dwc_otg/dwc_otg_hcd_if.h | 5 +
24 drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 154 ++++++++++++++++++++++---
25 drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 45 ++++++++
26 drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 20 +++-
27 drivers/usb/host/dwc_otg/dwc_otg_mphi_fix.c | 113 ++++++++++++++++++
28 drivers/usb/host/dwc_otg/dwc_otg_mphi_fix.h | 36 ++++++
29 drivers/usb/host/dwc_otg/dwc_otg_os_dep.h | 3 +
30 21 files changed, 545 insertions(+), 110 deletions(-)
31 create mode 100755 drivers/usb/host/dwc_otg/dwc_otg_mphi_fix.c
32 create mode 100755 drivers/usb/host/dwc_otg/dwc_otg_mphi_fix.h
33
34 --- a/arch/arm/Kconfig
35 +++ b/arch/arm/Kconfig
36 @@ -373,6 +373,7 @@ config ARCH_BCM2708
37 select ARM_ERRATA_411920
38 select MACH_BCM2708
39 select VC4
40 + select FIQ
41 help
42 This enables support for Broadcom BCM2708 boards.
43
44 --- a/arch/arm/include/asm/fiq.h
45 +++ b/arch/arm/include/asm/fiq.h
46 @@ -42,6 +42,7 @@ extern void disable_fiq(int fiq);
47 /* helpers defined in fiqasm.S: */
48 extern void __set_fiq_regs(unsigned long const *regs);
49 extern void __get_fiq_regs(unsigned long *regs);
50 +extern void __FIQ_Branch(unsigned long *regs);
51
52 static inline void set_fiq_regs(struct pt_regs const *regs)
53 {
54 --- a/arch/arm/kernel/fiq.c
55 +++ b/arch/arm/kernel/fiq.c
56 @@ -141,6 +141,7 @@ void disable_fiq(int fiq)
57 EXPORT_SYMBOL(set_fiq_handler);
58 EXPORT_SYMBOL(__set_fiq_regs); /* defined in fiqasm.S */
59 EXPORT_SYMBOL(__get_fiq_regs); /* defined in fiqasm.S */
60 +EXPORT_SYMBOL(__FIQ_Branch); /* defined in fiqasm.S */
61 EXPORT_SYMBOL(claim_fiq);
62 EXPORT_SYMBOL(release_fiq);
63 EXPORT_SYMBOL(enable_fiq);
64 --- a/arch/arm/kernel/fiqasm.S
65 +++ b/arch/arm/kernel/fiqasm.S
66 @@ -25,6 +25,9 @@
67 ENTRY(__set_fiq_regs)
68 mov r2, #PSR_I_BIT | PSR_F_BIT | FIQ_MODE
69 mrs r1, cpsr
70 +@@@@@@@@@@@@@@@ hack: enable the fiq here to keep usb driver happy
71 + and r1, #~PSR_F_BIT
72 +@@@@@@@@@@@@@@@ endhack: (need to find better place for this to happen)
73 msr cpsr_c, r2 @ select FIQ mode
74 mov r0, r0 @ avoid hazard prior to ARMv4
75 ldmia r0!, {r8 - r12}
76 @@ -47,3 +50,7 @@ ENTRY(__get_fiq_regs)
77 mov r0, r0 @ avoid hazard prior to ARMv4
78 mov pc, lr
79 ENDPROC(__get_fiq_regs)
80 +
81 +ENTRY(__FIQ_Branch)
82 + mov pc, r8
83 +ENDPROC(__FIQ_Branch)
84 --- a/arch/arm/mach-bcm2708/armctrl.c
85 +++ b/arch/arm/mach-bcm2708/armctrl.c
86 @@ -52,8 +52,12 @@ static void armctrl_mask_irq(struct irq_
87 0
88 };
89
90 - unsigned int data = (unsigned int)irq_get_chip_data(d->irq);
91 - writel(1 << (data & 0x1f), __io_address(disables[(data >> 5) & 0x3]));
92 + if (d->irq >= FIQ_START) {
93 + writel(0, __io_address(ARM_IRQ_FAST));
94 + } else {
95 + unsigned int data = (unsigned int)irq_get_chip_data(d->irq);
96 + writel(1 << (data & 0x1f), __io_address(disables[(data >> 5) & 0x3]));
97 + }
98 }
99
100 static void armctrl_unmask_irq(struct irq_data *d)
101 @@ -65,8 +69,14 @@ static void armctrl_unmask_irq(struct ir
102 0
103 };
104
105 - unsigned int data = (unsigned int)irq_get_chip_data(d->irq);
106 - writel(1 << (data & 0x1f), __io_address(enables[(data >> 5) & 0x3]));
107 + if (d->irq >= FIQ_START) {
108 + unsigned int data =
109 + (unsigned int)irq_get_chip_data(d->irq) - FIQ_START;
110 + writel(0x80 | data, __io_address(ARM_IRQ_FAST));
111 + } else {
112 + unsigned int data = (unsigned int)irq_get_chip_data(d->irq);
113 + writel(1 << (data & 0x1f), __io_address(enables[(data >> 5) & 0x3]));
114 + }
115 }
116
117 #if defined(CONFIG_PM)
118 @@ -204,5 +214,6 @@ int __init armctrl_init(void __iomem * b
119 }
120
121 armctrl_pm_register(base, irq_start, resume_sources);
122 + init_FIQ(FIQ_START);
123 return 0;
124 }
125 --- a/arch/arm/mach-bcm2708/bcm2708.c
126 +++ b/arch/arm/mach-bcm2708/bcm2708.c
127 @@ -309,12 +309,32 @@ static struct resource bcm2708_usb_resou
128 .flags = IORESOURCE_MEM,
129 },
130 [1] = {
131 - .start = IRQ_USB,
132 - .end = IRQ_USB,
133 + .start = MPHI_BASE,
134 + .end = MPHI_BASE + SZ_4K - 1,
135 + .flags = IORESOURCE_MEM,
136 + },
137 + [2] = {
138 + .start = IRQ_HOSTPORT,
139 + .end = IRQ_HOSTPORT,
140 .flags = IORESOURCE_IRQ,
141 },
142 };
143
144 +bool fiq_fix_enable = true;
145 +
146 +static struct resource bcm2708_usb_resources_no_fiq_fix[] = {
147 + [0] = {
148 + .start = USB_BASE,
149 + .end = USB_BASE + SZ_128K - 1,
150 + .flags = IORESOURCE_MEM,
151 + },
152 + [1] = {
153 + .start = IRQ_USB,
154 + .end = IRQ_USB,
155 + .flags = IORESOURCE_IRQ,
156 + },
157 +};
158 +
159 static u64 usb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
160
161 static struct platform_device bcm2708_usb_device = {
162 @@ -642,6 +662,11 @@ void __init bcm2708_init(void)
163 #endif
164 bcm_register_device(&bcm2708_systemtimer_device);
165 bcm_register_device(&bcm2708_fb_device);
166 + if (!fiq_fix_enable)
167 + {
168 + bcm2708_usb_device.resource = bcm2708_usb_resources_no_fiq_fix;
169 + bcm2708_usb_device.num_resources = ARRAY_SIZE(bcm2708_usb_resources_no_fiq_fix);
170 + }
171 bcm_register_device(&bcm2708_usb_device);
172 bcm_register_device(&bcm2708_uart1_device);
173 bcm_register_device(&bcm2708_powerman_device);
174 --- a/arch/arm/mach-bcm2708/include/mach/irqs.h
175 +++ b/arch/arm/mach-bcm2708/include/mach/irqs.h
176 @@ -106,91 +106,94 @@
177 #define IRQ_PENDING1 (IRQ_ARMCTRL_START + INTERRUPT_PENDING1)
178 #define IRQ_PENDING2 (IRQ_ARMCTRL_START + INTERRUPT_PENDING2)
179
180 +#define FIQ_START HARD_IRQS
181 +
182 /*
183 * FIQ interrupts definitions are the same as the INT definitions.
184 */
185 -#define FIQ_TIMER0 INT_TIMER0
186 -#define FIQ_TIMER1 INT_TIMER1
187 -#define FIQ_TIMER2 INT_TIMER2
188 -#define FIQ_TIMER3 INT_TIMER3
189 -#define FIQ_CODEC0 INT_CODEC0
190 -#define FIQ_CODEC1 INT_CODEC1
191 -#define FIQ_CODEC2 INT_CODEC2
192 -#define FIQ_JPEG INT_JPEG
193 -#define FIQ_ISP INT_ISP
194 -#define FIQ_USB INT_USB
195 -#define FIQ_3D INT_3D
196 -#define FIQ_TRANSPOSER INT_TRANSPOSER
197 -#define FIQ_MULTICORESYNC0 INT_MULTICORESYNC0
198 -#define FIQ_MULTICORESYNC1 INT_MULTICORESYNC1
199 -#define FIQ_MULTICORESYNC2 INT_MULTICORESYNC2
200 -#define FIQ_MULTICORESYNC3 INT_MULTICORESYNC3
201 -#define FIQ_DMA0 INT_DMA0
202 -#define FIQ_DMA1 INT_DMA1
203 -#define FIQ_DMA2 INT_DMA2
204 -#define FIQ_DMA3 INT_DMA3
205 -#define FIQ_DMA4 INT_DMA4
206 -#define FIQ_DMA5 INT_DMA5
207 -#define FIQ_DMA6 INT_DMA6
208 -#define FIQ_DMA7 INT_DMA7
209 -#define FIQ_DMA8 INT_DMA8
210 -#define FIQ_DMA9 INT_DMA9
211 -#define FIQ_DMA10 INT_DMA10
212 -#define FIQ_DMA11 INT_DMA11
213 -#define FIQ_DMA12 INT_DMA12
214 -#define FIQ_AUX INT_AUX
215 -#define FIQ_ARM INT_ARM
216 -#define FIQ_VPUDMA INT_VPUDMA
217 -#define FIQ_HOSTPORT INT_HOSTPORT
218 -#define FIQ_VIDEOSCALER INT_VIDEOSCALER
219 -#define FIQ_CCP2TX INT_CCP2TX
220 -#define FIQ_SDC INT_SDC
221 -#define FIQ_DSI0 INT_DSI0
222 -#define FIQ_AVE INT_AVE
223 -#define FIQ_CAM0 INT_CAM0
224 -#define FIQ_CAM1 INT_CAM1
225 -#define FIQ_HDMI0 INT_HDMI0
226 -#define FIQ_HDMI1 INT_HDMI1
227 -#define FIQ_PIXELVALVE1 INT_PIXELVALVE1
228 -#define FIQ_I2CSPISLV INT_I2CSPISLV
229 -#define FIQ_DSI1 INT_DSI1
230 -#define FIQ_PWA0 INT_PWA0
231 -#define FIQ_PWA1 INT_PWA1
232 -#define FIQ_CPR INT_CPR
233 -#define FIQ_SMI INT_SMI
234 -#define FIQ_GPIO0 INT_GPIO0
235 -#define FIQ_GPIO1 INT_GPIO1
236 -#define FIQ_GPIO2 INT_GPIO2
237 -#define FIQ_GPIO3 INT_GPIO3
238 -#define FIQ_I2C INT_I2C
239 -#define FIQ_SPI INT_SPI
240 -#define FIQ_I2SPCM INT_I2SPCM
241 -#define FIQ_SDIO INT_SDIO
242 -#define FIQ_UART INT_UART
243 -#define FIQ_SLIMBUS INT_SLIMBUS
244 -#define FIQ_VEC INT_VEC
245 -#define FIQ_CPG INT_CPG
246 -#define FIQ_RNG INT_RNG
247 -#define FIQ_ARASANSDIO INT_ARASANSDIO
248 -#define FIQ_AVSPMON INT_AVSPMON
249 -
250 -#define FIQ_ARM_TIMER INT_ARM_TIMER
251 -#define FIQ_ARM_MAILBOX INT_ARM_MAILBOX
252 -#define FIQ_ARM_DOORBELL_0 INT_ARM_DOORBELL_0
253 -#define FIQ_ARM_DOORBELL_1 INT_ARM_DOORBELL_1
254 -#define FIQ_VPU0_HALTED INT_VPU0_HALTED
255 -#define FIQ_VPU1_HALTED INT_VPU1_HALTED
256 -#define FIQ_ILLEGAL_TYPE0 INT_ILLEGAL_TYPE0
257 -#define FIQ_ILLEGAL_TYPE1 INT_ILLEGAL_TYPE1
258 -#define FIQ_PENDING1 INT_PENDING1
259 -#define FIQ_PENDING2 INT_PENDING2
260 +#define FIQ_TIMER0 (FIQ_START+INTERRUPT_TIMER0)
261 +#define FIQ_TIMER1 (FIQ_START+INTERRUPT_TIMER1)
262 +#define FIQ_TIMER2 (FIQ_START+INTERRUPT_TIMER2)
263 +#define FIQ_TIMER3 (FIQ_START+INTERRUPT_TIMER3)
264 +#define FIQ_CODEC0 (FIQ_START+INTERRUPT_CODEC0)
265 +#define FIQ_CODEC1 (FIQ_START+INTERRUPT_CODEC1)
266 +#define FIQ_CODEC2 (FIQ_START+INTERRUPT_CODEC2)
267 +#define FIQ_JPEG (FIQ_START+INTERRUPT_JPEG)
268 +#define FIQ_ISP (FIQ_START+INTERRUPT_ISP)
269 +#define FIQ_USB (FIQ_START+INTERRUPT_USB)
270 +#define FIQ_3D (FIQ_START+INTERRUPT_3D)
271 +#define FIQ_TRANSPOSER (FIQ_START+INTERRUPT_TRANSPOSER)
272 +#define FIQ_MULTICORESYNC0 (FIQ_START+INTERRUPT_MULTICORESYNC0)
273 +#define FIQ_MULTICORESYNC1 (FIQ_START+INTERRUPT_MULTICORESYNC1)
274 +#define FIQ_MULTICORESYNC2 (FIQ_START+INTERRUPT_MULTICORESYNC2)
275 +#define FIQ_MULTICORESYNC3 (FIQ_START+INTERRUPT_MULTICORESYNC3)
276 +#define FIQ_DMA0 (FIQ_START+INTERRUPT_DMA0)
277 +#define FIQ_DMA1 (FIQ_START+INTERRUPT_DMA1)
278 +#define FIQ_DMA2 (FIQ_START+INTERRUPT_DMA2)
279 +#define FIQ_DMA3 (FIQ_START+INTERRUPT_DMA3)
280 +#define FIQ_DMA4 (FIQ_START+INTERRUPT_DMA4)
281 +#define FIQ_DMA5 (FIQ_START+INTERRUPT_DMA5)
282 +#define FIQ_DMA6 (FIQ_START+INTERRUPT_DMA6)
283 +#define FIQ_DMA7 (FIQ_START+INTERRUPT_DMA7)
284 +#define FIQ_DMA8 (FIQ_START+INTERRUPT_DMA8)
285 +#define FIQ_DMA9 (FIQ_START+INTERRUPT_DMA9)
286 +#define FIQ_DMA10 (FIQ_START+INTERRUPT_DMA10)
287 +#define FIQ_DMA11 (FIQ_START+INTERRUPT_DMA11)
288 +#define FIQ_DMA12 (FIQ_START+INTERRUPT_DMA12)
289 +#define FIQ_AUX (FIQ_START+INTERRUPT_AUX)
290 +#define FIQ_ARM (FIQ_START+INTERRUPT_ARM)
291 +#define FIQ_VPUDMA (FIQ_START+INTERRUPT_VPUDMA)
292 +#define FIQ_HOSTPORT (FIQ_START+INTERRUPT_HOSTPORT)
293 +#define FIQ_VIDEOSCALER (FIQ_START+INTERRUPT_VIDEOSCALER)
294 +#define FIQ_CCP2TX (FIQ_START+INTERRUPT_CCP2TX)
295 +#define FIQ_SDC (FIQ_START+INTERRUPT_SDC)
296 +#define FIQ_DSI0 (FIQ_START+INTERRUPT_DSI0)
297 +#define FIQ_AVE (FIQ_START+INTERRUPT_AVE)
298 +#define FIQ_CAM0 (FIQ_START+INTERRUPT_CAM0)
299 +#define FIQ_CAM1 (FIQ_START+INTERRUPT_CAM1)
300 +#define FIQ_HDMI0 (FIQ_START+INTERRUPT_HDMI0)
301 +#define FIQ_HDMI1 (FIQ_START+INTERRUPT_HDMI1)
302 +#define FIQ_PIXELVALVE1 (FIQ_START+INTERRUPT_PIXELVALVE1)
303 +#define FIQ_I2CSPISLV (FIQ_START+INTERRUPT_I2CSPISLV)
304 +#define FIQ_DSI1 (FIQ_START+INTERRUPT_DSI1)
305 +#define FIQ_PWA0 (FIQ_START+INTERRUPT_PWA0)
306 +#define FIQ_PWA1 (FIQ_START+INTERRUPT_PWA1)
307 +#define FIQ_CPR (FIQ_START+INTERRUPT_CPR)
308 +#define FIQ_SMI (FIQ_START+INTERRUPT_SMI)
309 +#define FIQ_GPIO0 (FIQ_START+INTERRUPT_GPIO0)
310 +#define FIQ_GPIO1 (FIQ_START+INTERRUPT_GPIO1)
311 +#define FIQ_GPIO2 (FIQ_START+INTERRUPT_GPIO2)
312 +#define FIQ_GPIO3 (FIQ_START+INTERRUPT_GPIO3)
313 +#define FIQ_I2C (FIQ_START+INTERRUPT_I2C)
314 +#define FIQ_SPI (FIQ_START+INTERRUPT_SPI)
315 +#define FIQ_I2SPCM (FIQ_START+INTERRUPT_I2SPCM)
316 +#define FIQ_SDIO (FIQ_START+INTERRUPT_SDIO)
317 +#define FIQ_UART (FIQ_START+INTERRUPT_UART)
318 +#define FIQ_SLIMBUS (FIQ_START+INTERRUPT_SLIMBUS)
319 +#define FIQ_VEC (FIQ_START+INTERRUPT_VEC)
320 +#define FIQ_CPG (FIQ_START+INTERRUPT_CPG)
321 +#define FIQ_RNG (FIQ_START+INTERRUPT_RNG)
322 +#define FIQ_ARASANSDIO (FIQ_START+INTERRUPT_ARASANSDIO)
323 +#define FIQ_AVSPMON (FIQ_START+INTERRUPT_AVSPMON)
324 +
325 +#define FIQ_ARM_TIMER (FIQ_START+INTERRUPT_ARM_TIMER)
326 +#define FIQ_ARM_MAILBOX (FIQ_START+INTERRUPT_ARM_MAILBOX)
327 +#define FIQ_ARM_DOORBELL_0 (FIQ_START+INTERRUPT_ARM_DOORBELL_0)
328 +#define FIQ_ARM_DOORBELL_1 (FIQ_START+INTERRUPT_ARM_DOORBELL_1)
329 +#define FIQ_VPU0_HALTED (FIQ_START+INTERRUPT_VPU0_HALTED)
330 +#define FIQ_VPU1_HALTED (FIQ_START+INTERRUPT_VPU1_HALTED)
331 +#define FIQ_ILLEGAL_TYPE0 (FIQ_START+INTERRUPT_ILLEGAL_TYPE0)
332 +#define FIQ_ILLEGAL_TYPE1 (FIQ_START+INTERRUPT_ILLEGAL_TYPE1)
333 +#define FIQ_PENDING1 (FIQ_START+INTERRUPT_PENDING1)
334 +#define FIQ_PENDING2 (FIQ_START+INTERRUPT_PENDING2)
335
336 -#define HARD_IRQS (64 + 21)
337 -#define GPIO_IRQ_START HARD_IRQS
338 +#define GPIO_IRQ_START (HARD_IRQS + FIQ_IRQS)
339
340 -#define GPIO_IRQS 32*5
341 +#define HARD_IRQS (64 + 21)
342 +#define FIQ_IRQS (64 + 21)
343 +#define GPIO_IRQS (32*5)
344
345 -#define NR_IRQS HARD_IRQS+GPIO_IRQS
346 +#define NR_IRQS HARD_IRQS+FIQ_IRQS+GPIO_IRQS
347
348
349 #endif /* _BCM2708_IRQS_H_ */
350 --- a/arch/arm/mach-bcm2708/include/mach/platform.h
351 +++ b/arch/arm/mach-bcm2708/include/mach/platform.h
352 @@ -56,7 +56,9 @@
353 */
354
355 #define BCM2708_PERI_BASE 0x20000000
356 +#define IC0_BASE (BCM2708_PERI_BASE + 0x2000)
357 #define ST_BASE (BCM2708_PERI_BASE + 0x3000) /* System Timer */
358 +#define MPHI_BASE (BCM2708_PERI_BASE + 0x6000) /* Message -based Parallel Host Interface */
359 #define DMA_BASE (BCM2708_PERI_BASE + 0x7000) /* DMA controller */
360 #define ARM_BASE (BCM2708_PERI_BASE + 0xB000) /* BCM2708 ARM control block */
361 #define PM_BASE (BCM2708_PERI_BASE + 0x100000) /* Power Management, Reset controller and Watchdog registers */
362 --- a/drivers/usb/host/dwc_otg/Makefile
363 +++ b/drivers/usb/host/dwc_otg/Makefile
364 @@ -36,6 +36,7 @@ dwc_otg-objs += dwc_otg_cil.o dwc_otg_ci
365 dwc_otg-objs += dwc_otg_pcd_linux.o dwc_otg_pcd.o dwc_otg_pcd_intr.o
366 dwc_otg-objs += dwc_otg_hcd.o dwc_otg_hcd_linux.o dwc_otg_hcd_intr.o dwc_otg_hcd_queue.o dwc_otg_hcd_ddma.o
367 dwc_otg-objs += dwc_otg_adp.o
368 +dwc_otg-objs += dwc_otg_mphi_fix.o
369 ifneq ($(CFI),)
370 dwc_otg-objs += dwc_otg_cfi.o
371 endif
372 --- a/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c
373 +++ b/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c
374 @@ -45,6 +45,9 @@
375 #include "dwc_otg_driver.h"
376 #include "dwc_otg_pcd.h"
377 #include "dwc_otg_hcd.h"
378 +#include "dwc_otg_mphi_fix.h"
379 +
380 +extern bool fiq_fix_enable;
381
382 #ifdef DEBUG
383 inline const char *op_state_str(dwc_otg_core_if_t * core_if)
384 @@ -1351,10 +1354,15 @@ static inline uint32_t dwc_otg_read_comm
385 gintsts.d32, gintmsk.d32);
386 }
387 #endif
388 - if (gahbcfg.b.glblintrmsk)
389 + if (!fiq_fix_enable){
390 + if (gahbcfg.b.glblintrmsk)
391 + return ((gintsts.d32 & gintmsk.d32) & gintmsk_common.d32);
392 + else
393 + return 0;
394 + }
395 + else {
396 return ((gintsts.d32 & gintmsk.d32) & gintmsk_common.d32);
397 - else
398 - return 0;
399 + }
400
401 }
402
403 --- a/drivers/usb/host/dwc_otg/dwc_otg_dbg.h
404 +++ b/drivers/usb/host/dwc_otg/dwc_otg_dbg.h
405 @@ -49,6 +49,7 @@ static inline uint32_t SET_DEBUG_LEVEL(c
406 return old;
407 }
408
409 +#define DBG_USER (0x1)
410 /** When debug level has the DBG_CIL bit set, display CIL Debug messages. */
411 #define DBG_CIL (0x2)
412 /** When debug level has the DBG_CILV bit set, display CIL Verbose debug
413 --- a/drivers/usb/host/dwc_otg/dwc_otg_driver.c
414 +++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.c
415 @@ -64,6 +64,8 @@ bool microframe_schedule=true;
416
417 static const char dwc_driver_name[] = "dwc_otg";
418
419 +extern void* dummy_send;
420 +
421 extern int pcd_init(
422 #ifdef LM_INTERFACE
423 struct lm_device *_dev
424 @@ -238,6 +240,10 @@ static struct dwc_otg_driver_module_para
425 .adp_enable = -1,
426 };
427
428 +//Global variable to switch the fiq fix on or off (declared in bcm2708.c)
429 +extern bool fiq_fix_enable;
430 +
431 +
432 /**
433 * This function shows the Driver Version.
434 */
435 @@ -779,17 +785,33 @@ static int dwc_otg_driver_probe(
436 _dev->resource->start,
437 _dev->resource->end - _dev->resource->start + 1);
438 #if 1
439 - if (!request_mem_region(_dev->resource->start,
440 - _dev->resource->end - _dev->resource->start + 1,
441 + if (!request_mem_region(_dev->resource[0].start,
442 + _dev->resource[0].end - _dev->resource[0].start + 1,
443 "dwc_otg")) {
444 dev_dbg(&_dev->dev, "error reserving mapped memory\n");
445 retval = -EFAULT;
446 goto fail;
447 }
448
449 - dwc_otg_device->os_dep.base = ioremap_nocache(_dev->resource->start,
450 - _dev->resource->end -
451 - _dev->resource->start+1);
452 + dwc_otg_device->os_dep.base = ioremap_nocache(_dev->resource[0].start,
453 + _dev->resource[0].end -
454 + _dev->resource[0].start+1);
455 + if (fiq_fix_enable)
456 + {
457 + if (!request_mem_region(_dev->resource[1].start,
458 + _dev->resource[1].end - _dev->resource[1].start + 1,
459 + "dwc_otg")) {
460 + dev_dbg(&_dev->dev, "error reserving mapped memory\n");
461 + retval = -EFAULT;
462 + goto fail;
463 + }
464 +
465 + dwc_otg_device->os_dep.mphi_base = ioremap_nocache(_dev->resource[1].start,
466 + _dev->resource[1].end -
467 + _dev->resource[1].start + 1);
468 + dummy_send = (void *) kmalloc(16, GFP_ATOMIC);
469 + }
470 +
471 #else
472 {
473 struct map_desc desc = {
474 @@ -1063,6 +1085,7 @@ static int __init dwc_otg_driver_init(vo
475 printk(KERN_ERR "%s retval=%d\n", __func__, retval);
476 return retval;
477 }
478 + printk(KERN_DEBUG "dwc_otg: FIQ %s\n", fiq_fix_enable ? "enabled":"disabled");
479
480 error = driver_create_file(drv, &driver_attr_version);
481 #ifdef DEBUG
482 @@ -1343,6 +1366,10 @@ MODULE_PARM_DESC(otg_ver, "OTG revision
483 module_param(microframe_schedule, bool, 0444);
484 MODULE_PARM_DESC(microframe_schedule, "Enable the microframe scheduler");
485
486 +
487 +module_param(fiq_fix_enable, bool, 0444);
488 +MODULE_PARM_DESC(fiq_fix_enable, "Enable the fiq fix");
489 +
490 /** @page "Module Parameters"
491 *
492 * The following parameters may be specified when starting the module.
493 --- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
494 +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
495 @@ -53,6 +53,8 @@ static int last_sel_trans_num_avail_hc_a
496 static int last_sel_trans_num_avail_hc_at_end = 0;
497 #endif /* DEBUG_HOST_CHANNELS */
498
499 +extern int g_next_sched_frame, g_np_count, g_np_sent;
500 +
501 dwc_otg_hcd_t *dwc_otg_hcd_alloc_hcd(void)
502 {
503 return DWC_ALLOC(sizeof(dwc_otg_hcd_t));
504 @@ -407,6 +409,7 @@ static int dwc_otg_hcd_sleep_cb(void *p)
505 }
506 #endif
507
508 +
509 /**
510 * HCD Callback function for Remote Wakeup.
511 *
512 @@ -1330,6 +1333,8 @@ dwc_otg_transaction_type_e dwc_otg_hcd_s
513 &qh->qh_list_entry);
514 DWC_SPINUNLOCK_IRQRESTORE(channel_lock, flags);
515
516 + g_np_sent++;
517 +
518 if (ret_val == DWC_OTG_TRANSACTION_NONE) {
519 ret_val = DWC_OTG_TRANSACTION_NON_PERIODIC;
520 } else {
521 --- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.h
522 +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.h
523 @@ -594,7 +594,7 @@ extern void dwc_otg_hcd_queue_transactio
524 /** @name Interrupt Handler Functions */
525 /** @{ */
526 extern int32_t dwc_otg_hcd_handle_intr(dwc_otg_hcd_t * dwc_otg_hcd);
527 -extern int32_t dwc_otg_hcd_handle_sof_intr(dwc_otg_hcd_t * dwc_otg_hcd);
528 +extern int32_t dwc_otg_hcd_handle_sof_intr(dwc_otg_hcd_t * dwc_otg_hcd, int32_t);
529 extern int32_t dwc_otg_hcd_handle_rx_status_q_level_intr(dwc_otg_hcd_t *
530 dwc_otg_hcd);
531 extern int32_t dwc_otg_hcd_handle_np_tx_fifo_empty_intr(dwc_otg_hcd_t *
532 --- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_if.h
533 +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_if.h
534 @@ -113,6 +113,11 @@ extern void dwc_otg_hcd_remove(dwc_otg_h
535 */
536 extern int32_t dwc_otg_hcd_handle_intr(dwc_otg_hcd_t * dwc_otg_hcd);
537
538 +/** This function is used to handle the fast interrupt
539 + *
540 + */
541 +extern void __attribute__ ((naked)) dwc_otg_hcd_handle_fiq(void);
542 +
543 /**
544 * Returns private data set by
545 * dwc_otg_hcd_set_priv_data function.
546 --- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
547 +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
548 @@ -34,6 +34,11 @@
549
550 #include "dwc_otg_hcd.h"
551 #include "dwc_otg_regs.h"
552 +#include "dwc_otg_mphi_fix.h"
553 +
554 +#include <linux/jiffies.h>
555 +#include <mach/hardware.h>
556 +
557
558 extern bool microframe_schedule;
559
560 @@ -41,36 +46,105 @@ extern bool microframe_schedule;
561 * This file contains the implementation of the HCD Interrupt handlers.
562 */
563
564 +/*
565 + * Some globals to communicate between the FIQ and INTERRUPT
566 + */
567 +
568 +void * dummy_send;
569 +mphi_regs_t c_mphi_regs;
570 +int fiq_done, int_done;
571 +int g_next_sched_frame, g_np_count, g_np_sent, g_work_expected;
572 +static int mphi_int_count = 0 ;
573 +
574 +extern bool fiq_fix_enable;
575 +
576 +void __attribute__ ((naked)) dwc_otg_hcd_handle_fiq(void)
577 +{
578 + gintsts_data_t gintsts;
579 + hfnum_data_t hfnum;
580 +
581 + /* entry takes care to store registers we will be treading on here */
582 + asm __volatile__ (
583 + "mov ip, sp ;"
584 + /* stash FIQ and normal regs */
585 + "stmdb sp!, {r0-r12, lr};"
586 + /* !! THIS SETS THE FRAME, adjust to > sizeof locals */
587 + "sub fp, ip, #256 ;"
588 + );
589 +
590 + fiq_done++;
591 + gintsts.d32 = FIQ_READ_IO_ADDRESS(USB_BASE + 0x14) & FIQ_READ_IO_ADDRESS(USB_BASE + 0x18);
592 + hfnum.d32 = FIQ_READ_IO_ADDRESS(USB_BASE + 0x408);
593 +
594 + if(gintsts.d32)
595 + {
596 + if(gintsts.b.sofintr && g_np_count == g_np_sent && dwc_frame_num_gt(g_next_sched_frame, hfnum.b.frnum))
597 + {
598 + /*
599 + * If np_count != np_sent that means we need to queue non-periodic (bulk) packets this packet
600 + * g_next_sched_frame is the next frame we have periodic packets for
601 + *
602 + * if neither of these are required for this frame then just clear the interrupt
603 + */
604 + gintsts.d32 = 0;
605 + gintsts.b.sofintr = 1;
606 + FIQ_WRITE_IO_ADDRESS((USB_BASE + 0x14), gintsts.d32);
607 +
608 + g_work_expected = 0;
609 + }
610 + else
611 + {
612 + g_work_expected = 1;
613 + /* To enable the MPHI interrupt (INT 32)
614 + */
615 + FIQ_WRITE( c_mphi_regs.outdda, (int) dummy_send);
616 + FIQ_WRITE( c_mphi_regs.outddb, (1 << 29));
617 +
618 + mphi_int_count++;
619 + /* Clear the USB global interrupt so we don't just sit in the FIQ */
620 + FIQ_MODIFY_IO_ADDRESS((USB_BASE + 0x8),1,0);
621 +
622 + }
623 + }
624 + mb();
625 +
626 + /* exit back to normal mode restoring everything */
627 + asm __volatile__ (
628 + /* return FIQ regs back to pristine state
629 + * and get normal regs back
630 + */
631 + "ldmia sp!, {r0-r12, lr};"
632 +
633 + /* return */
634 + "subs pc, lr, #4;"
635 + );
636 +}
637 +
638 /** This function handles interrupts for the HCD. */
639 int32_t dwc_otg_hcd_handle_intr(dwc_otg_hcd_t * dwc_otg_hcd)
640 {
641 int retval = 0;
642 + static int last_time;
643
644 dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
645 gintsts_data_t gintsts;
646 + hfnum_data_t hfnum;
647 +
648 #ifdef DEBUG
649 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
650
651 - //GRAYG: debugging
652 - if (NULL == global_regs) {
653 - DWC_DEBUGPL(DBG_HCD, "**** NULL regs: dwc_otg_hcd=%p "
654 - "core_if=%p\n",
655 - dwc_otg_hcd, global_regs);
656 - return retval;
657 - }
658 #endif
659
660 /* Exit from ISR if core is hibernated */
661 if (core_if->hibernation_suspend == 1) {
662 - return retval;
663 + goto exit_handler_routine;
664 }
665 DWC_SPINLOCK(dwc_otg_hcd->lock);
666 /* Check if HOST Mode */
667 if (dwc_otg_is_host_mode(core_if)) {
668 gintsts.d32 = dwc_otg_read_core_intr(core_if);
669 if (!gintsts.d32) {
670 - DWC_SPINUNLOCK(dwc_otg_hcd->lock);
671 - return 0;
672 + goto exit_handler_routine;
673 }
674 #ifdef DEBUG
675 /* Don't print debug message in the interrupt handler on SOF */
676 @@ -88,9 +162,14 @@ int32_t dwc_otg_hcd_handle_intr(dwc_otg_
677 "DWC OTG HCD Interrupt Detected gintsts&gintmsk=0x%08x core_if=%p\n",
678 gintsts.d32, core_if);
679 #endif
680 -
681 - if (gintsts.b.sofintr) {
682 - retval |= dwc_otg_hcd_handle_sof_intr(dwc_otg_hcd);
683 + hfnum.d32 = DWC_READ_REG32(&dwc_otg_hcd->core_if->host_if->host_global_regs->hfnum);
684 + if (gintsts.b.sofintr && g_np_count == g_np_sent && dwc_frame_num_gt(g_next_sched_frame, hfnum.b.frnum))
685 + {
686 + /* Note, we should never get here if the FIQ is doing it's job properly*/
687 + retval |= dwc_otg_hcd_handle_sof_intr(dwc_otg_hcd, g_work_expected);
688 + }
689 + else if (gintsts.b.sofintr) {
690 + retval |= dwc_otg_hcd_handle_sof_intr(dwc_otg_hcd, g_work_expected);
691 }
692 if (gintsts.b.rxstsqlvl) {
693 retval |=
694 @@ -138,11 +217,37 @@ int32_t dwc_otg_hcd_handle_intr(dwc_otg_
695 #endif
696
697 }
698 +
699 +exit_handler_routine:
700 +
701 + if (fiq_fix_enable)
702 + {
703 + /* Clear the MPHI interrupt */
704 + DWC_WRITE_REG32(c_mphi_regs.intstat, (1<<16));
705 + if (mphi_int_count >= 60)
706 + {
707 + DWC_WRITE_REG32(c_mphi_regs.ctrl, ((1<<31) + (1<<16)));
708 + DWC_WRITE_REG32(c_mphi_regs.ctrl, (1<<31));
709 + mphi_int_count = 0;
710 + }
711 + int_done++;
712 + if((jiffies / HZ) > last_time)
713 + {
714 + /* Once a second output the fiq and irq numbers, useful for debug */
715 + last_time = jiffies / HZ;
716 + DWC_DEBUGPL(DBG_USER, "int_done = %d fiq_done = %d\n", int_done, fiq_done);
717 + }
718 +
719 + /* Re-Enable FIQ interrupt from USB peripheral */
720 + DWC_MODIFY_REG32((uint32_t *)IO_ADDRESS(USB_BASE + 0x8), 0 , 1);
721 + }
722 +
723 DWC_SPINUNLOCK(dwc_otg_hcd->lock);
724 return retval;
725 }
726
727 #ifdef DWC_TRACK_MISSED_SOFS
728 +
729 #warning Compiling code to track missed SOFs
730 #define FRAME_NUM_ARRAY_SIZE 1000
731 /**
732 @@ -182,13 +287,15 @@ static inline void track_missed_sofs(uin
733 * (micro)frame. Periodic transactions may be queued to the controller for the
734 * next (micro)frame.
735 */
736 -int32_t dwc_otg_hcd_handle_sof_intr(dwc_otg_hcd_t * hcd)
737 +int32_t dwc_otg_hcd_handle_sof_intr(dwc_otg_hcd_t * hcd, int32_t work_expected)
738 {
739 hfnum_data_t hfnum;
740 dwc_list_link_t *qh_entry;
741 dwc_otg_qh_t *qh;
742 dwc_otg_transaction_type_e tr_type;
743 gintsts_data_t gintsts = {.d32 = 0 };
744 + int did_something = 0;
745 + int32_t next_sched_frame = -1;
746
747 hfnum.d32 =
748 DWC_READ_REG32(&hcd->core_if->host_if->host_global_regs->hfnum);
749 @@ -218,12 +325,30 @@ int32_t dwc_otg_hcd_handle_sof_intr(dwc_
750 */
751 DWC_LIST_MOVE_HEAD(&hcd->periodic_sched_ready,
752 &qh->qh_list_entry);
753 +
754 + did_something = 1;
755 + }
756 + else
757 + {
758 + if(next_sched_frame < 0 || dwc_frame_num_le(qh->sched_frame, next_sched_frame))
759 + {
760 + next_sched_frame = qh->sched_frame;
761 + }
762 }
763 }
764 +
765 + g_next_sched_frame = next_sched_frame;
766 +
767 tr_type = dwc_otg_hcd_select_transactions(hcd);
768 if (tr_type != DWC_OTG_TRANSACTION_NONE) {
769 dwc_otg_hcd_queue_transactions(hcd, tr_type);
770 + did_something = 1;
771 }
772 + if(work_expected && !did_something)
773 + DWC_DEBUGPL(DBG_USER, "Nothing to do !! frame = %x, g_next_sched_frame = %x\n", (int) hfnum.b.frnum, g_next_sched_frame);
774 + if(!work_expected && did_something)
775 + DWC_DEBUGPL(DBG_USER, "Unexpected work done !! frame = %x, g_next_sched_frame = %x\n", (int) hfnum.b.frnum, g_next_sched_frame);
776 +
777
778 /* Clear interrupt */
779 gintsts.b.sofintr = 1;
780 @@ -2102,5 +2227,4 @@ int32_t dwc_otg_hcd_handle_hc_n_intr(dwc
781
782 return retval;
783 }
784 -
785 #endif /* DWC_DEVICE_ONLY */
786 --- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
787 +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
788 @@ -1,3 +1,4 @@
789 +
790 /* ==========================================================================
791 * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_linux.c $
792 * $Revision: #20 $
793 @@ -50,6 +51,7 @@
794 #include <linux/dma-mapping.h>
795 #include <linux/version.h>
796 #include <asm/io.h>
797 +#include <asm/fiq.h>
798 #include <linux/usb.h>
799 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)
800 #include <../drivers/usb/core/hcd.h>
801 @@ -67,6 +69,8 @@
802 #include "dwc_otg_dbg.h"
803 #include "dwc_otg_driver.h"
804 #include "dwc_otg_hcd.h"
805 +#include "dwc_otg_mphi_fix.h"
806 +
807 /**
808 * Gets the endpoint number from a _bEndpointAddress argument. The endpoint is
809 * qualified with its direction (possible 32 endpoints per device).
810 @@ -76,6 +80,8 @@
811
812 static const char dwc_otg_hcd_name[] = "dwc_otg_hcd";
813
814 +extern bool fiq_fix_enable;
815 +
816 /** @name Linux HC Driver API Functions */
817 /** @{ */
818 /* manage i/o requests, device state */
819 @@ -366,6 +372,12 @@ static struct dwc_otg_hcd_function_ops h
820 .get_b_hnp_enable = _get_b_hnp_enable,
821 };
822
823 +static struct fiq_handler fh = {
824 + .name = "usb_fiq",
825 +};
826 +static uint8_t fiqStack[1024];
827 +
828 +extern mphi_regs_t c_mphi_regs;
829 /**
830 * Initializes the HCD. This function allocates memory for and initializes the
831 * static parts of the usb_hcd and dwc_otg_hcd structures. It also registers the
832 @@ -379,6 +391,7 @@ int hcd_init(dwc_bus_dev_t *_dev)
833 dwc_otg_device_t *otg_dev = DWC_OTG_BUSDRVDATA(_dev);
834 int retval = 0;
835 u64 dmamask;
836 + struct pt_regs regs;
837
838 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT otg_dev=%p\n", otg_dev);
839
840 @@ -396,6 +409,18 @@ int hcd_init(dwc_bus_dev_t *_dev)
841 pci_set_consistent_dma_mask(_dev, dmamask);
842 #endif
843
844 + if (fiq_fix_enable)
845 + {
846 + // Set up fiq
847 + claim_fiq(&fh);
848 + set_fiq_handler(__FIQ_Branch, 4);
849 + memset(&regs,0,sizeof(regs));
850 + regs.ARM_r8 = (long)dwc_otg_hcd_handle_fiq;
851 + regs.ARM_r9 = (long)0;
852 + regs.ARM_sp = (long)fiqStack + sizeof(fiqStack) - 4;
853 + set_fiq_regs(&regs);
854 + }
855 +
856 /*
857 * Allocate memory for the base HCD plus the DWC OTG HCD.
858 * Initialize the base HCD.
859 @@ -415,6 +440,26 @@ int hcd_init(dwc_bus_dev_t *_dev)
860
861 hcd->regs = otg_dev->os_dep.base;
862
863 + if (fiq_fix_enable)
864 + {
865 + //Set the mphi periph to the required registers
866 + c_mphi_regs.base = otg_dev->os_dep.mphi_base;
867 + c_mphi_regs.ctrl = otg_dev->os_dep.mphi_base + 0x4c;
868 + c_mphi_regs.outdda = otg_dev->os_dep.mphi_base + 0x28;
869 + c_mphi_regs.outddb = otg_dev->os_dep.mphi_base + 0x2c;
870 + c_mphi_regs.intstat = otg_dev->os_dep.mphi_base + 0x50;
871 +
872 + //Enable mphi peripheral
873 + writel((1<<31),c_mphi_regs.ctrl);
874 +#ifdef DEBUG
875 + if (readl(c_mphi_regs.ctrl) & 0x80000000)
876 + DWC_DEBUGPL(DBG_USER, "MPHI periph has been enabled\n");
877 + else
878 + DWC_DEBUGPL(DBG_USER, "MPHI periph has NOT been enabled\n");
879 +#endif
880 + // Enable FIQ interrupt from USB peripheral
881 + enable_fiq(INTERRUPT_VC_USB);
882 + }
883 /* Initialize the DWC OTG HCD. */
884 dwc_otg_hcd = dwc_otg_hcd_alloc_hcd();
885 if (!dwc_otg_hcd) {
886 --- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c
887 +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c
888 @@ -572,6 +572,9 @@ static int check_max_xfer_size(dwc_otg_h
889 return status;
890 }
891
892 +
893 +extern int g_next_sched_frame, g_np_count, g_np_sent;
894 +
895 /**
896 * Schedules an interrupt or isochronous transfer in the periodic schedule.
897 *
898 @@ -630,8 +633,13 @@ static int schedule_periodic(dwc_otg_hcd
899 DWC_LIST_INSERT_TAIL(&hcd->periodic_sched_ready, &qh->qh_list_entry);
900 }
901 else {
902 - /* Always start in the inactive schedule. */
903 - DWC_LIST_INSERT_TAIL(&hcd->periodic_sched_inactive, &qh->qh_list_entry);
904 + if(DWC_LIST_EMPTY(&hcd->periodic_sched_inactive) || dwc_frame_num_le(qh->sched_frame, g_next_sched_frame))
905 + {
906 + g_next_sched_frame = qh->sched_frame;
907 +
908 + }
909 + /* Always start in the inactive schedule. */
910 + DWC_LIST_INSERT_TAIL(&hcd->periodic_sched_inactive, &qh->qh_list_entry);
911 }
912
913 if (!microframe_schedule) {
914 @@ -645,6 +653,7 @@ static int schedule_periodic(dwc_otg_hcd
915 return status;
916 }
917
918 +
919 /**
920 * This function adds a QH to either the non periodic or periodic schedule if
921 * it is not already in the schedule. If the QH is already in the schedule, no
922 @@ -667,6 +676,7 @@ int dwc_otg_hcd_qh_add(dwc_otg_hcd_t * h
923 /* Always start in the inactive schedule. */
924 DWC_LIST_INSERT_TAIL(&hcd->non_periodic_sched_inactive,
925 &qh->qh_list_entry);
926 + g_np_count++;
927 } else {
928 status = schedule_periodic(hcd, qh);
929 if ( !hcd->periodic_qh_count ) {
930 @@ -767,6 +777,7 @@ void dwc_otg_hcd_qh_deactivate(dwc_otg_h
931 if (sched_next_periodic_split) {
932
933 qh->sched_frame = frame_number;
934 +
935 if (dwc_frame_num_le(frame_number,
936 dwc_frame_num_inc
937 (qh->start_split_frame,
938 @@ -815,6 +826,11 @@ void dwc_otg_hcd_qh_deactivate(dwc_otg_h
939 DWC_LIST_MOVE_HEAD(&hcd->periodic_sched_ready,
940 &qh->qh_list_entry);
941 } else {
942 + if(!dwc_frame_num_le(g_next_sched_frame, qh->sched_frame))
943 + {
944 + g_next_sched_frame = qh->sched_frame;
945 + }
946 +
947 DWC_LIST_MOVE_HEAD
948 (&hcd->periodic_sched_inactive,
949 &qh->qh_list_entry);
950 --- /dev/null
951 +++ b/drivers/usb/host/dwc_otg/dwc_otg_mphi_fix.c
952 @@ -0,0 +1,113 @@
953 +#include "dwc_otg_regs.h"
954 +#include "dwc_otg_dbg.h"
955 +
956 +void dwc_debug_print_core_int_reg(gintsts_data_t gintsts, const char* function_name)
957 +{
958 + DWC_DEBUGPL(DBG_USER, "*** Debugging from within the %s function: ***\n"
959 + "curmode: %1i Modemismatch: %1i otgintr: %1i sofintr: %1i\n"
960 + "rxstsqlvl: %1i nptxfempty : %1i ginnakeff: %1i goutnakeff: %1i\n"
961 + "ulpickint: %1i i2cintr: %1i erlysuspend:%1i usbsuspend: %1i\n"
962 + "usbreset: %1i enumdone: %1i isooutdrop: %1i eopframe: %1i\n"
963 + "restoredone: %1i epmismatch: %1i inepint: %1i outepintr: %1i\n"
964 + "incomplisoin:%1i incomplisoout:%1i fetsusp: %1i resetdet: %1i\n"
965 + "portintr: %1i hcintr: %1i ptxfempty: %1i lpmtranrcvd:%1i\n"
966 + "conidstschng:%1i disconnect: %1i sessreqintr:%1i wkupintr: %1i\n",
967 + function_name,
968 + gintsts.b.curmode,
969 + gintsts.b.modemismatch,
970 + gintsts.b.otgintr,
971 + gintsts.b.sofintr,
972 + gintsts.b.rxstsqlvl,
973 + gintsts.b.nptxfempty,
974 + gintsts.b.ginnakeff,
975 + gintsts.b.goutnakeff,
976 + gintsts.b.ulpickint,
977 + gintsts.b.i2cintr,
978 + gintsts.b.erlysuspend,
979 + gintsts.b.usbsuspend,
980 + gintsts.b.usbreset,
981 + gintsts.b.enumdone,
982 + gintsts.b.isooutdrop,
983 + gintsts.b.eopframe,
984 + gintsts.b.restoredone,
985 + gintsts.b.epmismatch,
986 + gintsts.b.inepint,
987 + gintsts.b.outepintr,
988 + gintsts.b.incomplisoin,
989 + gintsts.b.incomplisoout,
990 + gintsts.b.fetsusp,
991 + gintsts.b.resetdet,
992 + gintsts.b.portintr,
993 + gintsts.b.hcintr,
994 + gintsts.b.ptxfempty,
995 + gintsts.b.lpmtranrcvd,
996 + gintsts.b.conidstschng,
997 + gintsts.b.disconnect,
998 + gintsts.b.sessreqintr,
999 + gintsts.b.wkupintr);
1000 + return;
1001 +}
1002 +
1003 +void dwc_debug_core_int_mask(gintmsk_data_t gintmsk, const char* function_name)
1004 +{
1005 + DWC_DEBUGPL(DBG_USER, "Interrupt Mask status (called from %s) :\n"
1006 + "modemismatch: %1i otgintr: %1i sofintr: %1i rxstsqlvl: %1i\n"
1007 + "nptxfempty: %1i ginnakeff: %1i goutnakeff: %1i ulpickint: %1i\n"
1008 + "i2cintr: %1i erlysuspend:%1i usbsuspend: %1i usbreset: %1i\n"
1009 + "enumdone: %1i isooutdrop: %1i eopframe: %1i restoredone: %1i\n"
1010 + "epmismatch: %1i inepintr: %1i outepintr: %1i incomplisoin:%1i\n"
1011 + "incomplisoout:%1i fetsusp: %1i resetdet: %1i portintr: %1i\n"
1012 + "hcintr: %1i ptxfempty: %1i lpmtranrcvd:%1i conidstschng:%1i\n"
1013 + "disconnect: %1i sessreqintr:%1i wkupintr: %1i\n",
1014 + function_name,
1015 + gintmsk.b.modemismatch,
1016 + gintmsk.b.otgintr,
1017 + gintmsk.b.sofintr,
1018 + gintmsk.b.rxstsqlvl,
1019 + gintmsk.b.nptxfempty,
1020 + gintmsk.b.ginnakeff,
1021 + gintmsk.b.goutnakeff,
1022 + gintmsk.b.ulpickint,
1023 + gintmsk.b.i2cintr,
1024 + gintmsk.b.erlysuspend,
1025 + gintmsk.b.usbsuspend,
1026 + gintmsk.b.usbreset,
1027 + gintmsk.b.enumdone,
1028 + gintmsk.b.isooutdrop,
1029 + gintmsk.b.eopframe,
1030 + gintmsk.b.restoredone,
1031 + gintmsk.b.epmismatch,
1032 + gintmsk.b.inepintr,
1033 + gintmsk.b.outepintr,
1034 + gintmsk.b.incomplisoin,
1035 + gintmsk.b.incomplisoout,
1036 + gintmsk.b.fetsusp,
1037 + gintmsk.b.resetdet,
1038 + gintmsk.b.portintr,
1039 + gintmsk.b.hcintr,
1040 + gintmsk.b.ptxfempty,
1041 + gintmsk.b.lpmtranrcvd,
1042 + gintmsk.b.conidstschng,
1043 + gintmsk.b.disconnect,
1044 + gintmsk.b.sessreqintr,
1045 + gintmsk.b.wkupintr);
1046 + return;
1047 +}
1048 +
1049 +void dwc_debug_otg_int(gotgint_data_t gotgint, const char* function_name)
1050 +{
1051 + DWC_DEBUGPL(DBG_USER, "otg int register (from %s function):\n"
1052 + "sesenddet:%1i sesreqsucstschung:%2i hstnegsucstschng:%1i\n"
1053 + "hstnegdet:%1i adevtoutchng: %2i debdone: %1i\n"
1054 + "mvic: %1i\n",
1055 + function_name,
1056 + gotgint.b.sesenddet,
1057 + gotgint.b.sesreqsucstschng,
1058 + gotgint.b.hstnegsucstschng,
1059 + gotgint.b.hstnegdet,
1060 + gotgint.b.adevtoutchng,
1061 + gotgint.b.debdone,
1062 + gotgint.b.mvic);
1063 +
1064 + return;
1065 +}
1066 --- /dev/null
1067 +++ b/drivers/usb/host/dwc_otg/dwc_otg_mphi_fix.h
1068 @@ -0,0 +1,36 @@
1069 +#ifndef __DWC_OTG_MPHI_FIX_H__
1070 +#define __DWC_OTG_MPHI_FIX_H__
1071 +
1072 +#define FIQ_WRITE_IO_ADDRESS(_addr_,_data_) *(volatile uint32_t *) IO_ADDRESS(_addr_) = _data_
1073 +#define FIQ_READ_IO_ADDRESS(_addr_) *(volatile uint32_t *) IO_ADDRESS(_addr_)
1074 +#define FIQ_MODIFY_IO_ADDRESS(_addr_,_clear_,_set_) FIQ_WRITE_IO_ADDRESS(_addr_ , (FIQ_READ_IO_ADDRESS(_addr_)&~_clear_)|_set_)
1075 +#define FIQ_WRITE(_addr_,_data_) *(volatile uint32_t *) _addr_ = _data_
1076 +
1077 +typedef struct {
1078 + volatile void* base;
1079 + volatile void* ctrl;
1080 + volatile void* outdda;
1081 + volatile void* outddb;
1082 + volatile void* intstat;
1083 +} mphi_regs_t;
1084 +
1085 +void dwc_debug_print_core_int_reg(gintsts_data_t gintsts, const char* function_name);
1086 +void dwc_debug_core_int_mask(gintsts_data_t gintmsk, const char* function_name);
1087 +void dwc_debug_otg_int(gotgint_data_t gotgint, const char* function_name);
1088 +
1089 +
1090 +
1091 +#ifdef DEBUG
1092 +#define DWC_DBG_PRINT_CORE_INT(_arg_) dwc_debug_print_core_int_reg(_arg_,__func__)
1093 +#define DWC_DBG_PRINT_CORE_INT_MASK(_arg_) dwc_debug_core_int_mask(_arg_,__func__)
1094 +#define DWC_DBG_PRINT_OTG_INT(_arg_) dwc_debug_otg_int(_arg_,__func__)
1095 +
1096 +#else
1097 +#define DWC_DBG_PRINT_CORE_INT(_arg_)
1098 +#define DWC_DBG_PRINT_CORE_INT_MASK(_arg_)
1099 +#define DWC_DBG_PRINT_OTG_INT(_arg_)
1100 +
1101 +
1102 +#endif
1103 +
1104 +#endif
1105 --- a/drivers/usb/host/dwc_otg/dwc_otg_os_dep.h
1106 +++ b/drivers/usb/host/dwc_otg/dwc_otg_os_dep.h
1107 @@ -97,6 +97,9 @@ typedef struct os_dependent {
1108 /** Register offset for Diagnostic API */
1109 uint32_t reg_offset;
1110
1111 + /** Base address for MPHI peripheral */
1112 + void *mphi_base;
1113 +
1114 #ifdef LM_INTERFACE
1115 struct lm_device *lmdev;
1116 #elif defined(PCI_INTERFACE)