ramips: add support for PandoraBox PBR-M1
[15.05/openwrt.git] / target / linux / brcm2708 / patches-3.18 / 0046-fiq_fsm-Implement-hack-for-Split-Interrupt-transacti.patch
1 From 099581aeb11b7eafbca02c9e69f6e6c8de0c57ec Mon Sep 17 00:00:00 2001
2 From: P33M <P33M@github.com>
3 Date: Fri, 20 Jun 2014 17:23:20 +0100
4 Subject: [PATCH 046/114] fiq_fsm: Implement hack for Split Interrupt
5  transactions
6
7 Hubs aren't too picky about which endpoint we send Control type split
8 transactions to. By treating Interrupt transfers as Control, it is
9 possible to use the non-periodic queue in the OTG core as well as the
10 non-periodic FIFOs in the hub itself. This massively reduces the
11 microframe exclusivity/contention that periodic split transactions
12 otherwise have to enforce.
13
14 It goes without saying that this is a fairly egregious USB specification
15 violation, but it works.
16
17 Original idea by Hans Petter Selasky @ FreeBSD.org.
18 ---
19  drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 32 ++++++++++++++++++++++++++------
20  1 file changed, 26 insertions(+), 6 deletions(-)
21
22 --- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
23 +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
24 @@ -1055,10 +1055,11 @@ int dwc_otg_hcd_init(dwc_otg_hcd_t * hcd
25                         for (i=0; i < hcd->core_if->core_params->host_channels; i++) {
26                                 dwc_otg_cleanup_fiq_channel(hcd, i);
27                         }
28 -                       DWC_PRINTF("FIQ FSM acceleration enabled for :\n%s%s%s",
29 +                       DWC_PRINTF("FIQ FSM acceleration enabled for :\n%s%s%s%s",
30                                 (fiq_fsm_mask & 0x1) ? "Non-periodic Split Transactions\n" : "",
31                                 (fiq_fsm_mask & 0x2) ? "Periodic Split Transactions\n" : "",
32 -                               (fiq_fsm_mask & 0x4) ? "High-Speed Isochronous Endpoints\n" : "");
33 +                               (fiq_fsm_mask & 0x4) ? "High-Speed Isochronous Endpoints\n" : "",
34 +                               (fiq_fsm_mask & 0x8) ? "Interrupt/Control Split Transaction hack enabled\n" : "");
35                 }
36         }
37  
38 @@ -1789,6 +1790,20 @@ int fiq_fsm_queue_split_transaction(dwc_
39         st->hcintmsk_copy.b.chhltd = 1;
40         st->hcintmsk_copy.b.ahberr = 1;
41  
42 +       /* Hack courtesy of FreeBSD: apparently forcing Interrupt Split transactions
43 +        * as Control puts the transfer into the non-periodic request queue and the
44 +        * non-periodic handler in the hub. Makes things lots easier.
45 +        */
46 +       if ((fiq_fsm_mask & 0x8) && hc->ep_type == UE_INTERRUPT) {
47 +               st->hcchar_copy.b.multicnt = 0;
48 +               st->hcchar_copy.b.oddfrm = 0;
49 +               st->hcchar_copy.b.eptype = UE_CONTROL;
50 +               if (hc->align_buff) {
51 +                       st->hcdma_copy.d32 = hc->align_buff;
52 +               } else {
53 +                       st->hcdma_copy.d32 = ((unsigned long) hc->xfer_buff & 0xFFFFFFFF);
54 +               }
55 +       }
56         DWC_WRITE_REG32(&hc_regs->hcdma, st->hcdma_copy.d32);
57         DWC_WRITE_REG32(&hc_regs->hctsiz, st->hctsiz_copy.d32);
58         DWC_WRITE_REG32(&hc_regs->hcsplt, st->hcsplt_copy.d32);
59 @@ -1842,6 +1857,9 @@ int fiq_fsm_queue_split_transaction(dwc_
60                         }
61                 }
62         }
63 +       if ((fiq_fsm_mask & 0x8) && hc->ep_type == UE_INTERRUPT)
64 +               start_immediate = 1;
65 +
66         fiq_print(FIQDBG_INT, hcd->fiq_state, "FSMQ %01d %01d", hc->hc_num, start_immediate);
67         fiq_print(FIQDBG_INT, hcd->fiq_state, "%08d", hfnum.b.frrem);
68         //fiq_print(FIQDBG_INT, hcd->fiq_state, "H:%02dP:%02d", hub_addr, port_addr);
69 @@ -1873,11 +1891,13 @@ int fiq_fsm_queue_split_transaction(dwc_
70                         }
71                         break;
72                 case UE_INTERRUPT:
73 -                               if (start_immediate) {
74 +                       if (fiq_fsm_mask & 0x8) {
75 +                               st->fsm = FIQ_NP_SSPLIT_STARTED;
76 +                       } else if (start_immediate) {
77                                         st->fsm = FIQ_PER_SSPLIT_STARTED;
78 -                               } else {
79 -                                       st->fsm = FIQ_PER_SSPLIT_QUEUED;
80 -                               }
81 +                       } else {
82 +                               st->fsm = FIQ_PER_SSPLIT_QUEUED;
83 +                       }
84                 default:
85                         break;
86         }