bcm53xx: add xHCI support
[openwrt.git] / target / linux / bcm53xx / patches-3.18 / 820-xhci-add-Broadcom-specific-fake-doorbell.patch
1 From 9cc14ca0aae53c16d10ffea49848ac61a5015562 Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
3 Date: Sun, 21 Jun 2015 11:10:49 +0200
4 Subject: [PATCH] xhci: add Broadcom specific fake doorbell
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 This fixes problem with controller seeing devices only in some small
10 percentage of cold boots.
11
12 Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
13 ---
14  drivers/usb/host/xhci.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++
15  1 file changed, 62 insertions(+)
16
17 diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
18 index 3bceabe..0737ab2 100644
19 --- a/drivers/usb/host/xhci.c
20 +++ b/drivers/usb/host/xhci.c
21 @@ -122,6 +122,64 @@ int xhci_halt(struct xhci_hcd *xhci)
22         return ret;
23  }
24  
25 +#ifdef CONFIG_ARCH_BCM_5301X
26 +int xhci_fake_doorbell(struct xhci_hcd *xhci, int slot_id)
27 +{
28 +       unsigned int temp1, ret;
29 +
30 +       /* alloc a virt device for slot */
31 +       if (!xhci_alloc_virt_device(xhci, slot_id, 0, GFP_NOIO)) {
32 +               xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n");
33 +               return 1;
34 +        }
35 +
36 +       /* ring fake doorbell for slot_id ep 0 */
37 +       xhci_ring_ep_doorbell(xhci, slot_id, 0, 0);
38 +       mdelay(1);
39 +
40 +       /* read the status register to check if HSE is set or not? */
41 +       temp1 = readl(&xhci->op_regs->status);
42 +       xhci_dbg(xhci, "op reg status = %x\n",temp1);
43 +
44 +       /* clear HSE if set */
45 +       if(temp1 & STS_FATAL) {
46 +               xhci_dbg(xhci, "HSE problem detected\n");
47 +               temp1 &= ~(0x1fff);
48 +               temp1 |= STS_FATAL;
49 +               xhci_dbg(xhci, "temp1=%x\n",temp1);
50 +               writel(temp1, &xhci->op_regs->status);
51 +               mdelay(1);
52 +               temp1 = readl(&xhci->op_regs->status);
53 +               xhci_dbg(xhci, "After clear op reg status=%x\n", temp1);
54 +       }
55 +
56 +       /* Free virt device */
57 +       xhci_free_virt_device(xhci, slot_id);
58 +
59 +       /* Run the controller if needed */
60 +       temp1 = readl(&xhci->op_regs->command);
61 +       if (temp1 & CMD_RUN)
62 +               return 0;
63 +       temp1 |= (CMD_RUN);
64 +
65 +       writel(temp1, &xhci->op_regs->command);
66 +       /*
67 +        * Wait for the HCHalted Status bit to be 0 to indicate the host is running.
68 +        */
69 +       ret = xhci_handshake(xhci, &xhci->op_regs->status,
70 +                            STS_HALT, 0, XHCI_MAX_HALT_USEC);
71 +
72 +       if (ret == -ETIMEDOUT) {
73 +               xhci_err(xhci, "Host took too long to start, "
74 +                               "waited %u microseconds.\n",
75 +                               XHCI_MAX_HALT_USEC);
76 +               return 1;
77 +       }
78 +
79 +       return 0;
80 +}
81 +#endif /* CONFIG_ARCH_BCM_5301X */
82 +
83  /*
84   * Set the run bit and wait for the host to be running.
85   */
86 @@ -146,6 +204,10 @@ static int xhci_start(struct xhci_hcd *xhci)
87                 xhci_err(xhci, "Host took too long to start, "
88                                 "waited %u microseconds.\n",
89                                 XHCI_MAX_HALT_USEC);
90 +#ifdef CONFIG_ARCH_BCM_5301X
91 +       xhci_fake_doorbell(xhci, 1);
92 +#endif /* CONFIG_ARCH_BCM_5301X */
93 +
94         if (!ret)
95                 xhci->xhc_state &= ~XHCI_STATE_HALTED;
96         return ret;
97 -- 
98 1.8.4.5
99