1 // SPDX-License-Identifier: GPL-2.0+
3 * USB 3.0 DRD Controller
5 * (C) Copyright 2012-2014
6 * Texas Instruments Incorporated, <www.ti.com>
12 #include <asm/arch/psc_defs.h>
14 #include <linux/usb/dwc3.h>
15 #include <asm/arch/xhci-keystone.h>
16 #include <linux/errno.h>
17 #include <linux/list.h>
20 struct kdwc3_irq_regs {
21 u32 revision; /* 0x000 */
23 u32 sysconfig; /* 0x010 */
35 struct keystone_xhci {
36 struct xhci_hccr *hcd;
37 struct dwc3 *dwc3_reg;
38 struct xhci_hcor *hcor;
39 struct kdwc3_irq_regs *usbss;
40 struct keystone_xhci_phy *phy;
43 struct keystone_xhci keystone;
45 static void keystone_xhci_phy_set(struct keystone_xhci_phy *phy)
50 * VBUSVLDEXTSEL has a default value of 1 in BootCfg but shouldn't.
51 * It should always be cleared because our USB PHY has an onchip VBUS
54 val = readl(&phy->phy_clock);
55 /* quit selecting the vbusvldextsel by default! */
56 val &= ~USB3_PHY_OTG_VBUSVLDECTSEL;
57 writel(val, &phy->phy_clock);
60 static void keystone_xhci_phy_unset(struct keystone_xhci_phy *phy)
64 /* Disable the PHY REFCLK clock gate */
65 val = readl(&phy->phy_clock);
66 val &= ~USB3_PHY_REF_SSP_EN;
67 writel(val, &phy->phy_clock);
70 static int keystone_xhci_core_init(struct dwc3 *dwc3_reg)
74 ret = dwc3_core_init(dwc3_reg);
76 debug("failed to initialize core\n");
80 /* We are hard-coding DWC3 core to Host Mode */
81 dwc3_set_mode(dwc3_reg, DWC3_GCTL_PRTCAP_HOST);
86 int xhci_hcd_init(int index,
87 struct xhci_hccr **ret_hccr, struct xhci_hcor **ret_hcor)
91 struct xhci_hccr *hcd;
92 struct xhci_hcor *hcor;
93 struct kdwc3_irq_regs *usbss;
94 struct keystone_xhci_phy *phy;
96 usbss = (struct kdwc3_irq_regs *)CONFIG_USB_SS_BASE;
97 phy = (struct keystone_xhci_phy *)CONFIG_DEV_USB_PHY_BASE;
99 /* Enable the PHY REFCLK clock gate with phy_ref_ssp_en = 1 */
100 val = readl(&(phy->phy_clock));
101 val |= USB3_PHY_REF_SSP_EN;
102 writel(val, &phy->phy_clock);
106 /* Release USB from reset */
107 ret = psc_enable_module(KS2_LPSC_USB);
109 puts("Cannot enable USB module");
115 /* Initialize usb phy */
116 keystone_xhci_phy_set(phy);
118 /* soft reset usbss */
119 writel(1, &usbss->sysconfig);
120 while (readl(&usbss->sysconfig) & 1)
123 val = readl(&usbss->revision);
124 debug("usbss revision %x\n", val);
126 /* Initialize usb core */
127 hcd = (struct xhci_hccr *)CONFIG_USB_HOST_XHCI_BASE;
128 keystone.dwc3_reg = (struct dwc3 *)(CONFIG_USB_HOST_XHCI_BASE +
131 keystone_xhci_core_init(keystone.dwc3_reg);
133 /* set register addresses */
134 hcor = (struct xhci_hcor *)((uint32_t)hcd +
135 HC_LENGTH(readl(&hcd->cr_capbase)));
137 debug("Keystone2-xhci: init hccr %08x and hcor %08x hc_length %d\n",
139 (u32)HC_LENGTH(xhci_readl(&hcd->cr_capbase)));
141 keystone.usbss = usbss;
144 keystone.hcor = hcor;
152 static int keystone_xhci_phy_suspend(void)
155 struct xhci_hcor *hcor;
156 uint32_t *portsc_1 = NULL;
157 uint32_t *portsc_2 = NULL;
158 u32 val, usb2_pls, usb3_pls, event_q;
159 struct dwc3 *dwc3_reg = keystone.dwc3_reg;
161 /* set register addresses */
162 hcor = keystone.hcor;
164 /* Bypass Scrambling and Set Shorter Training sequence for simulation */
165 val = DWC3_GCTL_PWRDNSCALE(0x4b0) | DWC3_GCTL_PRTCAPDIR(0x2);
166 writel(val, &dwc3_reg->g_ctl);
169 val = readl(&dwc3_reg->g_usb2phycfg[0]);
171 /* assert bit 6 (SusPhy) */
172 val |= DWC3_GUSB2PHYCFG_SUSPHY;
173 writel(val, &dwc3_reg->g_usb2phycfg[0]);
176 val = readl(&dwc3_reg->g_usb3pipectl[0]);
179 * assert bit 29 to allow PHY to go to suspend when idle
180 * and cause the USB3 SS PHY to enter suspend mode
182 val |= (BIT(29) | DWC3_GUSB3PIPECTL_SUSPHY);
183 writel(val, &dwc3_reg->g_usb3pipectl[0]);
186 * Steps necessary to allow controller to suspend even when
188 * - Init DCFG[2:0] (DevSpd) to: 1=FS
189 * - Init GEVNTADR0 to point to an eventQ
190 * - Init GEVNTSIZ0 to 0x0100 to specify the size of the eventQ
191 * - Init DCTL::Run_nStop = 1
193 writel(0x00020001, &dwc3_reg->d_cfg);
194 /* TODO: local2global( (Uint32) eventQ )? */
195 writel((u32)&event_q, &dwc3_reg->g_evnt_buf[0].g_evntadrlo);
196 writel(0, &dwc3_reg->g_evnt_buf[0].g_evntadrhi);
197 writel(0x4, &dwc3_reg->g_evnt_buf[0].g_evntsiz);
199 writel(DWC3_DCTL_RUN_STOP, &dwc3_reg->d_ctl);
203 /* Wait for USB2 & USB3 PORTSC::PortLinkState to indicate suspend */
204 portsc_1 = (uint32_t *)(&hcor->portregs[0].or_portsc);
205 portsc_2 = (uint32_t *)(&hcor->portregs[1].or_portsc);
210 usb2_pls = (readl(portsc_1) & PORT_PLS_MASK) >> 5;
211 usb3_pls = (readl(portsc_2) & PORT_PLS_MASK) >> 5;
212 } while (((usb2_pls != 0x4) || (usb3_pls != 0x4)) && loop_cnt < 1000);
214 if (usb2_pls != 0x4 || usb3_pls != 0x4) {
215 debug("USB suspend failed - PLS USB2=%02x, USB3=%02x\n",
220 debug("USB2 and USB3 PLS - Disabled, loop_cnt=%d\n", loop_cnt);
224 void xhci_hcd_stop(int index)
227 if (keystone_xhci_phy_suspend())
230 if (psc_disable_module(KS2_LPSC_USB)) {
231 debug("PSC disable module USB failed!\n");
236 keystone_xhci_phy_unset(keystone.phy);
238 /* memset(&keystone, 0, sizeof(struct keystone_xhci)); */
239 debug("xhci_hcd_stop OK.\n");