aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3/gadget.c
diff options
context:
space:
mode:
authorPaul Zimmerman <Paul.Zimmerman@synopsys.com>2012-04-27 06:10:52 -0400
committerFelipe Balbi <balbi@ti.com>2012-06-03 16:08:23 -0400
commit802fde983e8a3391e059bd41fc272993ae642816 (patch)
tree8f54686b7195e1762154ab1de4c515182ada62d8 /drivers/usb/dwc3/gadget.c
parentd7a46a8dfc45191b39daa19c05d3ff74d1881f15 (diff)
usb: dwc3: support new revisions of DWC3 core
Recent cores (>= 1.94a) have a set of new features, commands and a slightly different programming model. This patch aims to support those changes. Signed-off-by: Paul Zimmerman <paulz@synopsys.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/dwc3/gadget.c')
-rw-r--r--drivers/usb/dwc3/gadget.c83
1 files changed, 70 insertions, 13 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 852bde5cc139..04048333ec1a 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -100,6 +100,23 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state)
100 int retries = 10000; 100 int retries = 10000;
101 u32 reg; 101 u32 reg;
102 102
103 /*
104 * Wait until device controller is ready. Only applies to 1.94a and
105 * later RTL.
106 */
107 if (dwc->revision >= DWC3_REVISION_194A) {
108 while (--retries) {
109 reg = dwc3_readl(dwc->regs, DWC3_DSTS);
110 if (reg & DWC3_DSTS_DCNRD)
111 udelay(5);
112 else
113 break;
114 }
115
116 if (retries <= 0)
117 return -ETIMEDOUT;
118 }
119
103 reg = dwc3_readl(dwc->regs, DWC3_DCTL); 120 reg = dwc3_readl(dwc->regs, DWC3_DCTL);
104 reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK; 121 reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK;
105 122
@@ -107,6 +124,13 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state)
107 reg |= DWC3_DCTL_ULSTCHNGREQ(state); 124 reg |= DWC3_DCTL_ULSTCHNGREQ(state);
108 dwc3_writel(dwc->regs, DWC3_DCTL, reg); 125 dwc3_writel(dwc->regs, DWC3_DCTL, reg);
109 126
127 /*
128 * The following code is racy when called from dwc3_gadget_wakeup,
129 * and is not needed, at least on newer versions
130 */
131 if (dwc->revision >= DWC3_REVISION_194A)
132 return 0;
133
110 /* wait for a change in DSTS */ 134 /* wait for a change in DSTS */
111 retries = 10000; 135 retries = 10000;
112 while (--retries) { 136 while (--retries) {
@@ -266,8 +290,8 @@ static const char *dwc3_gadget_ep_cmd_string(u8 cmd)
266 return "Clear Stall"; 290 return "Clear Stall";
267 case DWC3_DEPCMD_SETSTALL: 291 case DWC3_DEPCMD_SETSTALL:
268 return "Set Stall"; 292 return "Set Stall";
269 case DWC3_DEPCMD_GETSEQNUMBER: 293 case DWC3_DEPCMD_GETEPSTATE:
270 return "Get Data Sequence Number"; 294 return "Get Endpoint State";
271 case DWC3_DEPCMD_SETTRANSFRESOURCE: 295 case DWC3_DEPCMD_SETTRANSFRESOURCE:
272 return "Set Endpoint Transfer Resource"; 296 return "Set Endpoint Transfer Resource";
273 case DWC3_DEPCMD_SETEPCONFIG: 297 case DWC3_DEPCMD_SETEPCONFIG:
@@ -1280,9 +1304,12 @@ static int dwc3_gadget_wakeup(struct usb_gadget *g)
1280 goto out; 1304 goto out;
1281 } 1305 }
1282 1306
1283 /* write zeroes to Link Change Request */ 1307 /* Recent versions do this automatically */
1284 reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK; 1308 if (dwc->revision < DWC3_REVISION_194A) {
1285 dwc3_writel(dwc->regs, DWC3_DCTL, reg); 1309 /* write zeroes to Link Change Request */
1310 reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK;
1311 dwc3_writel(dwc->regs, DWC3_DCTL, reg);
1312 }
1286 1313
1287 /* poll until Link State changes to ON */ 1314 /* poll until Link State changes to ON */
1288 timeout = jiffies + msecs_to_jiffies(100); 1315 timeout = jiffies + msecs_to_jiffies(100);
@@ -1326,9 +1353,14 @@ static void dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on)
1326 1353
1327 reg = dwc3_readl(dwc->regs, DWC3_DCTL); 1354 reg = dwc3_readl(dwc->regs, DWC3_DCTL);
1328 if (is_on) { 1355 if (is_on) {
1329 reg &= ~DWC3_DCTL_TRGTULST_MASK; 1356 if (dwc->revision <= DWC3_REVISION_187A) {
1330 reg |= (DWC3_DCTL_RUN_STOP 1357 reg &= ~DWC3_DCTL_TRGTULST_MASK;
1331 | DWC3_DCTL_TRGTULST_RX_DET); 1358 reg |= DWC3_DCTL_TRGTULST_RX_DET;
1359 }
1360
1361 if (dwc->revision >= DWC3_REVISION_194A)
1362 reg &= ~DWC3_DCTL_KEEP_CONNECT;
1363 reg |= DWC3_DCTL_RUN_STOP;
1332 } else { 1364 } else {
1333 reg &= ~DWC3_DCTL_RUN_STOP; 1365 reg &= ~DWC3_DCTL_RUN_STOP;
1334 } 1366 }
@@ -1468,6 +1500,7 @@ static int dwc3_gadget_stop(struct usb_gadget *g,
1468 1500
1469 return 0; 1501 return 0;
1470} 1502}
1503
1471static const struct usb_gadget_ops dwc3_gadget_ops = { 1504static const struct usb_gadget_ops dwc3_gadget_ops = {
1472 .get_frame = dwc3_gadget_get_frame, 1505 .get_frame = dwc3_gadget_get_frame,
1473 .wakeup = dwc3_gadget_wakeup, 1506 .wakeup = dwc3_gadget_wakeup,
@@ -1962,9 +1995,12 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)
1962 /* after reset -> Default State */ 1995 /* after reset -> Default State */
1963 dwc->dev_state = DWC3_DEFAULT_STATE; 1996 dwc->dev_state = DWC3_DEFAULT_STATE;
1964 1997
1965 /* Resume PHYs */ 1998 /* Recent versions support automatic phy suspend and don't need this */
1966 dwc3_gadget_usb2_phy_suspend(dwc, false); 1999 if (dwc->revision < DWC3_REVISION_194A) {
1967 dwc3_gadget_usb3_phy_suspend(dwc, false); 2000 /* Resume PHYs */
2001 dwc3_gadget_usb2_phy_suspend(dwc, false);
2002 dwc3_gadget_usb3_phy_suspend(dwc, false);
2003 }
1968 2004
1969 if (dwc->gadget.speed != USB_SPEED_UNKNOWN) 2005 if (dwc->gadget.speed != USB_SPEED_UNKNOWN)
1970 dwc3_disconnect_gadget(dwc); 2006 dwc3_disconnect_gadget(dwc);
@@ -2082,8 +2118,11 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
2082 break; 2118 break;
2083 } 2119 }
2084 2120
2085 /* Suspend unneded PHY */ 2121 /* Recent versions support automatic phy suspend and don't need this */
2086 dwc3_gadget_phy_suspend(dwc, dwc->gadget.speed); 2122 if (dwc->revision < DWC3_REVISION_194A) {
2123 /* Suspend unneeded PHY */
2124 dwc3_gadget_phy_suspend(dwc, dwc->gadget.speed);
2125 }
2087 2126
2088 dep = dwc->eps[0]; 2127 dep = dwc->eps[0];
2089 ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL); 2128 ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL);
@@ -2389,6 +2428,24 @@ int __devinit dwc3_gadget_init(struct dwc3 *dwc)
2389 DWC3_DEVTEN_DISCONNEVTEN); 2428 DWC3_DEVTEN_DISCONNEVTEN);
2390 dwc3_writel(dwc->regs, DWC3_DEVTEN, reg); 2429 dwc3_writel(dwc->regs, DWC3_DEVTEN, reg);
2391 2430
2431 /* Enable USB2 LPM and automatic phy suspend only on recent versions */
2432 if (dwc->revision >= DWC3_REVISION_194A) {
2433 reg = dwc3_readl(dwc->regs, DWC3_DCFG);
2434 reg |= DWC3_DCFG_LPM_CAP;
2435 dwc3_writel(dwc->regs, DWC3_DCFG, reg);
2436
2437 reg = dwc3_readl(dwc->regs, DWC3_DCTL);
2438 reg &= ~(DWC3_DCTL_HIRD_THRES_MASK | DWC3_DCTL_L1_HIBER_EN);
2439
2440 /* TODO: This should be configurable */
2441 reg |= DWC3_DCTL_HIRD_THRES(31);
2442
2443 dwc3_writel(dwc->regs, DWC3_DCTL, reg);
2444
2445 dwc3_gadget_usb2_phy_suspend(dwc, true);
2446 dwc3_gadget_usb3_phy_suspend(dwc, true);
2447 }
2448
2392 ret = device_register(&dwc->gadget.dev); 2449 ret = device_register(&dwc->gadget.dev);
2393 if (ret) { 2450 if (ret) {
2394 dev_err(dwc->dev, "failed to register gadget device\n"); 2451 dev_err(dwc->dev, "failed to register gadget device\n");