OpenWrt – Blame information for rev 4
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
4 | office | 1 | From a2a97f0d2c07a772899ca09967547bea6c9124c5 Mon Sep 17 00:00:00 2001 |
2 | From: Yangbo Lu <yangbo.lu@nxp.com> |
||
3 | Date: Wed, 17 Jan 2018 15:46:03 +0800 |
||
4 | Subject: [PATCH 29/30] usb: support layerscape |
||
5 | |||
6 | This is an integrated patch for layerscape usb support. |
||
7 | |||
8 | Signed-off-by: yinbo.zhu <yinbo.zhu@nxp.com> |
||
9 | Signed-off-by: Ramneek Mehresh <ramneek.mehresh@freescale.com> |
||
10 | Signed-off-by: Nikhil Badola <nikhil.badola@freescale.com> |
||
11 | Signed-off-by: Changming Huang <jerry.huang@nxp.com> |
||
12 | Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> |
||
13 | Signed-off-by: Rajesh Bhagat <rajesh.bhagat@freescale.com> |
||
14 | Signed-off-by: Suresh Gupta <suresh.gupta@freescale.com> |
||
15 | Signed-off-by: Zhao Chenhui <chenhui.zhao@freescale.com> |
||
16 | Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com> |
||
17 | --- |
||
18 | drivers/net/usb/cdc_ether.c | 8 + |
||
19 | drivers/net/usb/r8152.c | 6 + |
||
20 | drivers/usb/common/common.c | 50 ++++++ |
||
21 | drivers/usb/core/hub.c | 8 + |
||
22 | drivers/usb/dwc3/core.c | 243 ++++++++++++++++++++++++++++- |
||
23 | drivers/usb/dwc3/core.h | 51 ++++++- |
||
24 | drivers/usb/dwc3/ep0.c | 4 +- |
||
25 | drivers/usb/dwc3/gadget.c | 7 + |
||
26 | drivers/usb/dwc3/host.c | 24 ++- |
||
27 | drivers/usb/gadget/udc/fsl_udc_core.c | 46 +++--- |
||
28 | drivers/usb/gadget/udc/fsl_usb2_udc.h | 16 +- |
||
29 | drivers/usb/host/Kconfig | 2 +- |
||
30 | drivers/usb/host/ehci-fsl.c | 279 +++++++++++++++++++++++++++++++--- |
||
31 | drivers/usb/host/ehci-fsl.h | 3 + |
||
32 | drivers/usb/host/ehci-hub.c | 4 + |
||
33 | drivers/usb/host/ehci.h | 9 ++ |
||
34 | drivers/usb/host/fsl-mph-dr-of.c | 12 ++ |
||
35 | drivers/usb/host/xhci-plat.c | 10 ++ |
||
36 | drivers/usb/host/xhci-ring.c | 29 +++- |
||
37 | drivers/usb/host/xhci.c | 38 ++++- |
||
38 | drivers/usb/host/xhci.h | 5 +- |
||
39 | drivers/usb/phy/phy-fsl-usb.c | 59 +++++-- |
||
40 | drivers/usb/phy/phy-fsl-usb.h | 8 + |
||
41 | include/linux/usb.h | 1 + |
||
42 | include/linux/usb/of.h | 2 + |
||
43 | 25 files changed, 836 insertions(+), 88 deletions(-) |
||
44 | |||
45 | --- a/drivers/net/usb/cdc_ether.c |
||
46 | +++ b/drivers/net/usb/cdc_ether.c |
||
47 | @@ -533,6 +533,7 @@ static const struct driver_info wwan_inf |
||
48 | #define LINKSYS_VENDOR_ID 0x13b1 |
||
49 | #define NVIDIA_VENDOR_ID 0x0955 |
||
50 | #define HP_VENDOR_ID 0x03f0 |
||
51 | +#define TPLINK_VENDOR_ID 0x2357 |
||
52 | |||
53 | static const struct usb_device_id products[] = { |
||
54 | /* BLACKLIST !! |
||
55 | @@ -742,6 +743,13 @@ static const struct usb_device_id produc |
||
56 | USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), |
||
57 | .driver_info = 0, |
||
58 | }, |
||
59 | + |
||
60 | + /* TP-LINK UE300 USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */ |
||
61 | +{ |
||
62 | + USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, 0x0601, USB_CLASS_COMM, |
||
63 | + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), |
||
64 | + .driver_info = 0, |
||
65 | +}, |
||
66 | |||
67 | /* WHITELIST!!! |
||
68 | * |
||
69 | --- a/drivers/net/usb/r8152.c |
||
70 | +++ b/drivers/net/usb/r8152.c |
||
71 | @@ -521,6 +521,7 @@ enum rtl8152_flags { |
||
72 | #define VENDOR_ID_LENOVO 0x17ef |
||
73 | #define VENDOR_ID_LINKSYS 0x13b1 |
||
74 | #define VENDOR_ID_NVIDIA 0x0955 |
||
75 | +#define VENDOR_ID_TPLINK 0x2357 |
||
76 | |||
77 | #define MCU_TYPE_PLA 0x0100 |
||
78 | #define MCU_TYPE_USB 0x0000 |
||
79 | @@ -1817,6 +1818,10 @@ static int rx_bottom(struct r8152 *tp, i |
||
80 | unsigned int pkt_len; |
||
81 | struct sk_buff *skb; |
||
82 | |||
83 | + /* limite the skb numbers for rx_queue */ |
||
84 | + if (unlikely(skb_queue_len(&tp->rx_queue) >= 1000)) |
||
85 | + break; |
||
86 | + |
||
87 | pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK; |
||
88 | if (pkt_len < ETH_ZLEN) |
||
89 | break; |
||
90 | @@ -4510,6 +4515,7 @@ static struct usb_device_id rtl8152_tabl |
||
91 | {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x304f)}, |
||
92 | {REALTEK_USB_DEVICE(VENDOR_ID_LINKSYS, 0x0041)}, |
||
93 | {REALTEK_USB_DEVICE(VENDOR_ID_NVIDIA, 0x09ff)}, |
||
94 | + {REALTEK_USB_DEVICE(VENDOR_ID_TPLINK, 0x0601)}, |
||
95 | {} |
||
96 | }; |
||
97 | |||
98 | --- a/drivers/usb/common/common.c |
||
99 | +++ b/drivers/usb/common/common.c |
||
100 | @@ -105,6 +105,56 @@ static const char *const usb_dr_modes[] |
||
101 | [USB_DR_MODE_OTG] = "otg", |
||
102 | }; |
||
103 | |||
104 | +/** |
||
105 | + * of_usb_get_dr_mode - Get dual role mode for given device_node |
||
106 | + * @np: Pointer to the given device_node |
||
107 | + * |
||
108 | + * The function gets phy interface string from property 'dr_mode', |
||
109 | + * and returns the correspondig enum usb_dr_mode |
||
110 | + */ |
||
111 | +enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np) |
||
112 | +{ |
||
113 | + const char *dr_mode; |
||
114 | + int err, i; |
||
115 | + |
||
116 | + err = of_property_read_string(np, "dr_mode", &dr_mode); |
||
117 | + if (err < 0) |
||
118 | + return USB_DR_MODE_UNKNOWN; |
||
119 | + |
||
120 | + for (i = 0; i < ARRAY_SIZE(usb_dr_modes); i++) |
||
121 | + if (!strcmp(dr_mode, usb_dr_modes[i])) |
||
122 | + return i; |
||
123 | + |
||
124 | + return USB_DR_MODE_UNKNOWN; |
||
125 | +} |
||
126 | +EXPORT_SYMBOL_GPL(of_usb_get_dr_mode); |
||
127 | + |
||
128 | +/** |
||
129 | + * of_usb_get_maximum_speed - Get maximum requested speed for a given USB |
||
130 | + * controller. |
||
131 | + * @np: Pointer to the given device_node |
||
132 | + * |
||
133 | + * The function gets the maximum speed string from property "maximum-speed", |
||
134 | + * and returns the corresponding enum usb_device_speed. |
||
135 | + */ |
||
136 | +enum usb_device_speed of_usb_get_maximum_speed(struct device_node *np) |
||
137 | +{ |
||
138 | + const char *maximum_speed; |
||
139 | + int err; |
||
140 | + int i; |
||
141 | + |
||
142 | + err = of_property_read_string(np, "maximum-speed", &maximum_speed); |
||
143 | + if (err < 0) |
||
144 | + return USB_SPEED_UNKNOWN; |
||
145 | + |
||
146 | + for (i = 0; i < ARRAY_SIZE(speed_names); i++) |
||
147 | + if (strcmp(maximum_speed, speed_names[i]) == 0) |
||
148 | + return i; |
||
149 | + |
||
150 | + return USB_SPEED_UNKNOWN; |
||
151 | +} |
||
152 | +EXPORT_SYMBOL_GPL(of_usb_get_maximum_speed); |
||
153 | + |
||
154 | static enum usb_dr_mode usb_get_dr_mode_from_string(const char *str) |
||
155 | { |
||
156 | int ret; |
||
157 | --- a/drivers/usb/core/hub.c |
||
158 | +++ b/drivers/usb/core/hub.c |
||
159 | @@ -4431,6 +4431,14 @@ hub_port_init(struct usb_hub *hub, struc |
||
160 | else |
||
161 | speed = usb_speed_string(udev->speed); |
||
162 | |||
163 | +#if !defined(CONFIG_FSL_USB2_OTG) && !defined(CONFIG_FSL_USB2_OTG_MODULE) |
||
164 | +if (udev->speed != USB_SPEED_SUPER) |
||
165 | + dev_info(&udev->dev, |
||
166 | + "%s %s USB device number %d using %s\n", |
||
167 | + (udev->config) ? "reset" : "new", speed, |
||
168 | + devnum, udev->bus->controller->driver->name); |
||
169 | +#endif |
||
170 | + |
||
171 | if (udev->speed < USB_SPEED_SUPER) |
||
172 | dev_info(&udev->dev, |
||
173 | "%s %s USB device number %d using %s\n", |
||
174 | --- a/drivers/usb/dwc3/core.c |
||
175 | +++ b/drivers/usb/dwc3/core.c |
||
176 | @@ -58,6 +58,7 @@ static int dwc3_get_dr_mode(struct dwc3 |
||
177 | enum usb_dr_mode mode; |
||
178 | struct device *dev = dwc->dev; |
||
179 | unsigned int hw_mode; |
||
180 | + struct device_node *node = dev->of_node; |
||
181 | |||
182 | if (dwc->dr_mode == USB_DR_MODE_UNKNOWN) |
||
183 | dwc->dr_mode = USB_DR_MODE_OTG; |
||
184 | @@ -83,6 +84,24 @@ static int dwc3_get_dr_mode(struct dwc3 |
||
185 | mode = USB_DR_MODE_HOST; |
||
186 | break; |
||
187 | default: |
||
188 | + /* Adjust Frame Length */ |
||
189 | + if (dwc->configure_gfladj) |
||
190 | + dwc3_writel(dwc->regs, DWC3_GFLADJ, GFLADJ_30MHZ_REG_SEL | |
||
191 | + GFLADJ_30MHZ(GFLADJ_30MHZ_DEFAULT)); |
||
192 | + |
||
193 | + /* Change burst beat and outstanding pipelined transfers requests */ |
||
194 | + dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, |
||
195 | + (dwc3_readl(dwc->regs, DWC3_GSBUSCFG0) & ~0xff) | 0xf); |
||
196 | + dwc3_writel(dwc->regs, DWC3_GSBUSCFG1, |
||
197 | + dwc3_readl(dwc->regs, DWC3_GSBUSCFG1) | 0xf00); |
||
198 | + |
||
199 | + /* Enable Snooping */ |
||
200 | + if (node && of_dma_is_coherent(node)) { |
||
201 | + dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, |
||
202 | + dwc3_readl(dwc->regs, DWC3_GSBUSCFG0) | 0x22220000); |
||
203 | + dev_dbg(dev, "enabled snooping for usb\n"); |
||
204 | + } |
||
205 | + |
||
206 | if (IS_ENABLED(CONFIG_USB_DWC3_HOST)) |
||
207 | mode = USB_DR_MODE_HOST; |
||
208 | else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET)) |
||
209 | @@ -227,8 +246,9 @@ static void dwc3_frame_length_adjustment |
||
210 | |||
211 | reg = dwc3_readl(dwc->regs, DWC3_GFLADJ); |
||
212 | dft = reg & DWC3_GFLADJ_30MHZ_MASK; |
||
213 | - if (!dev_WARN_ONCE(dwc->dev, dft == dwc->fladj, |
||
214 | - "request value same as default, ignoring\n")) { |
||
215 | + if (dft == dwc->fladj) { |
||
216 | + dev_warn(dwc->dev, "request value same as default, ignoring\n"); |
||
217 | + } else { |
||
218 | reg &= ~DWC3_GFLADJ_30MHZ_MASK; |
||
219 | reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | dwc->fladj; |
||
220 | dwc3_writel(dwc->regs, DWC3_GFLADJ, reg); |
||
221 | @@ -599,6 +619,99 @@ static int dwc3_phy_setup(struct dwc3 *d |
||
222 | return 0; |
||
223 | } |
||
224 | |||
225 | +/* set global soc bus configuration registers */ |
||
226 | +static void dwc3_set_soc_bus_cfg(struct dwc3 *dwc) |
||
227 | +{ |
||
228 | + struct device *dev = dwc->dev; |
||
229 | + u32 *vals; |
||
230 | + u32 cfg; |
||
231 | + int ntype; |
||
232 | + int ret; |
||
233 | + int i; |
||
234 | + |
||
235 | + cfg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG0); |
||
236 | + |
||
237 | + /* |
||
238 | + * Handle property "snps,incr-burst-type-adjustment". |
||
239 | + * Get the number of value from this property: |
||
240 | + * result <= 0, means this property is not supported. |
||
241 | + * result = 1, means INCRx burst mode supported. |
||
242 | + * result > 1, means undefined length burst mode supported. |
||
243 | + */ |
||
244 | + ntype = device_property_read_u32_array(dev, |
||
245 | + "snps,incr-burst-type-adjustment", NULL, 0); |
||
246 | + if (ntype > 0) { |
||
247 | + vals = kcalloc(ntype, sizeof(u32), GFP_KERNEL); |
||
248 | + if (!vals) { |
||
249 | + dev_err(dev, "Error to get memory\n"); |
||
250 | + return; |
||
251 | + } |
||
252 | + /* Get INCR burst type, and parse it */ |
||
253 | + ret = device_property_read_u32_array(dev, |
||
254 | + "snps,incr-burst-type-adjustment", vals, ntype); |
||
255 | + if (ret) { |
||
256 | + dev_err(dev, "Error to get property\n"); |
||
257 | + return; |
||
258 | + } |
||
259 | + *(dwc->incrx_type + 1) = vals[0]; |
||
260 | + if (ntype > 1) { |
||
261 | + *dwc->incrx_type = 1; |
||
262 | + for (i = 1; i < ntype; i++) { |
||
263 | + if (vals[i] > *(dwc->incrx_type + 1)) |
||
264 | + *(dwc->incrx_type + 1) = vals[i]; |
||
265 | + } |
||
266 | + } else |
||
267 | + *dwc->incrx_type = 0; |
||
268 | + |
||
269 | + /* Enable Undefined Length INCR Burst and Enable INCRx Burst */ |
||
270 | + cfg &= ~DWC3_GSBUSCFG0_INCRBRST_MASK; |
||
271 | + if (*dwc->incrx_type) |
||
272 | + cfg |= DWC3_GSBUSCFG0_INCRBRSTENA; |
||
273 | + switch (*(dwc->incrx_type + 1)) { |
||
274 | + case 256: |
||
275 | + cfg |= DWC3_GSBUSCFG0_INCR256BRSTENA; |
||
276 | + break; |
||
277 | + case 128: |
||
278 | + cfg |= DWC3_GSBUSCFG0_INCR128BRSTENA; |
||
279 | + break; |
||
280 | + case 64: |
||
281 | + cfg |= DWC3_GSBUSCFG0_INCR64BRSTENA; |
||
282 | + break; |
||
283 | + case 32: |
||
284 | + cfg |= DWC3_GSBUSCFG0_INCR32BRSTENA; |
||
285 | + break; |
||
286 | + case 16: |
||
287 | + cfg |= DWC3_GSBUSCFG0_INCR16BRSTENA; |
||
288 | + break; |
||
289 | + case 8: |
||
290 | + cfg |= DWC3_GSBUSCFG0_INCR8BRSTENA; |
||
291 | + break; |
||
292 | + case 4: |
||
293 | + cfg |= DWC3_GSBUSCFG0_INCR4BRSTENA; |
||
294 | + break; |
||
295 | + case 1: |
||
296 | + break; |
||
297 | + default: |
||
298 | + dev_err(dev, "Invalid property\n"); |
||
299 | + break; |
||
300 | + } |
||
301 | + } |
||
302 | + |
||
303 | + /* Handle usb snooping */ |
||
304 | + if (dwc->dma_snooping_quirk) { |
||
305 | + cfg &= ~DWC3_GSBUSCFG0_SNP_MASK; |
||
306 | + cfg |= (AXI3_CACHE_TYPE_SNP << DWC3_GSBUSCFG0_DATARD_SHIFT) | |
||
307 | + (AXI3_CACHE_TYPE_SNP << DWC3_GSBUSCFG0_DESCRD_SHIFT) | |
||
308 | + (AXI3_CACHE_TYPE_SNP << DWC3_GSBUSCFG0_DATAWR_SHIFT) | |
||
309 | + (AXI3_CACHE_TYPE_SNP << DWC3_GSBUSCFG0_DESCWR_SHIFT); |
||
310 | + } |
||
311 | + |
||
312 | + dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, cfg); |
||
313 | + |
||
314 | +} |
||
315 | + |
||
316 | + |
||
317 | + |
||
318 | static void dwc3_core_exit(struct dwc3 *dwc) |
||
319 | { |
||
320 | dwc3_event_buffers_cleanup(dwc); |
||
321 | @@ -741,6 +854,8 @@ static int dwc3_core_init(struct dwc3 *d |
||
322 | if (ret) |
||
323 | goto err1; |
||
324 | |||
325 | + dwc3_set_soc_bus_cfg(dwc); |
||
326 | + |
||
327 | /* Adjust Frame Length */ |
||
328 | dwc3_frame_length_adjustment(dwc); |
||
329 | |||
330 | @@ -939,11 +1054,117 @@ static void dwc3_core_exit_mode(struct d |
||
331 | } |
||
332 | } |
||
333 | |||
334 | +static void dwc3_get_properties(struct dwc3 *dwc) |
||
335 | +{ |
||
336 | + struct device *dev = dwc->dev; |
||
337 | + struct device_node *node = dev->of_node; |
||
338 | + u8 lpm_nyet_threshold; |
||
339 | + u8 tx_de_emphasis; |
||
340 | + u8 hird_threshold; |
||
341 | + |
||
342 | + /* default to highest possible threshold */ |
||
343 | + lpm_nyet_threshold = 0xff; |
||
344 | + |
||
345 | + /* default to -3.5dB de-emphasis */ |
||
346 | + tx_de_emphasis = 1; |
||
347 | + |
||
348 | + /* |
||
349 | + * default to assert utmi_sleep_n and use maximum allowed HIRD |
||
350 | + * threshold value of 0b1100 |
||
351 | + */ |
||
352 | + hird_threshold = 12; |
||
353 | + |
||
354 | + dwc->maximum_speed = usb_get_maximum_speed(dev); |
||
355 | + dwc->dr_mode = usb_get_dr_mode(dev); |
||
356 | + dwc->hsphy_mode = of_usb_get_phy_mode(dev->of_node); |
||
357 | + |
||
358 | + dwc->sysdev_is_parent = device_property_read_bool(dev, |
||
359 | + "linux,sysdev_is_parent"); |
||
360 | + if (dwc->sysdev_is_parent) |
||
361 | + dwc->sysdev = dwc->dev->parent; |
||
362 | + else |
||
363 | + dwc->sysdev = dwc->dev; |
||
364 | + |
||
365 | + dwc->has_lpm_erratum = device_property_read_bool(dev, |
||
366 | + "snps,has-lpm-erratum"); |
||
367 | + device_property_read_u8(dev, "snps,lpm-nyet-threshold", |
||
368 | + &lpm_nyet_threshold); |
||
369 | + dwc->is_utmi_l1_suspend = device_property_read_bool(dev, |
||
370 | + "snps,is-utmi-l1-suspend"); |
||
371 | + device_property_read_u8(dev, "snps,hird-threshold", |
||
372 | + &hird_threshold); |
||
373 | + dwc->usb3_lpm_capable = device_property_read_bool(dev, |
||
374 | + "snps,usb3_lpm_capable"); |
||
375 | + dwc->quirk_reverse_in_out = device_property_read_bool(dev, |
||
376 | + "snps,quirk_reverse_in_out"); |
||
377 | + dwc->quirk_stop_transfer_in_block = device_property_read_bool(dev, |
||
378 | + "snps,quirk_stop_transfer_in_block"); |
||
379 | + dwc->quirk_stop_ep_in_u1 = device_property_read_bool(dev, |
||
380 | + "snps,quirk_stop_ep_in_u1"); |
||
381 | + |
||
382 | + dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize"); |
||
383 | + |
||
384 | + dwc->configure_gfladj = |
||
385 | + of_property_read_bool(node, "configure-gfladj"); |
||
386 | + dwc->dr_mode = usb_get_dr_mode(dev); |
||
387 | + |
||
388 | + dwc->disable_scramble_quirk = device_property_read_bool(dev, |
||
389 | + "snps,disable_scramble_quirk"); |
||
390 | + dwc->u2exit_lfps_quirk = device_property_read_bool(dev, |
||
391 | + "snps,u2exit_lfps_quirk"); |
||
392 | + dwc->u2ss_inp3_quirk = device_property_read_bool(dev, |
||
393 | + "snps,u2ss_inp3_quirk"); |
||
394 | + dwc->req_p1p2p3_quirk = device_property_read_bool(dev, |
||
395 | + "snps,req_p1p2p3_quirk"); |
||
396 | + dwc->del_p1p2p3_quirk = device_property_read_bool(dev, |
||
397 | + "snps,del_p1p2p3_quirk"); |
||
398 | + dwc->del_phy_power_chg_quirk = device_property_read_bool(dev, |
||
399 | + "snps,del_phy_power_chg_quirk"); |
||
400 | + dwc->lfps_filter_quirk = device_property_read_bool(dev, |
||
401 | + "snps,lfps_filter_quirk"); |
||
402 | + dwc->rx_detect_poll_quirk = device_property_read_bool(dev, |
||
403 | + "snps,rx_detect_poll_quirk"); |
||
404 | + dwc->dis_u3_susphy_quirk = device_property_read_bool(dev, |
||
405 | + "snps,dis_u3_susphy_quirk"); |
||
406 | + dwc->dis_u2_susphy_quirk = device_property_read_bool(dev, |
||
407 | + "snps,dis_u2_susphy_quirk"); |
||
408 | + dwc->dis_enblslpm_quirk = device_property_read_bool(dev, |
||
409 | + "snps,dis_enblslpm_quirk"); |
||
410 | + dwc->dis_rxdet_inp3_quirk = device_property_read_bool(dev, |
||
411 | + "snps,dis_rxdet_inp3_quirk"); |
||
412 | + dwc->dis_u2_freeclk_exists_quirk = device_property_read_bool(dev, |
||
413 | + "snps,dis-u2-freeclk-exists-quirk"); |
||
414 | + dwc->dis_del_phy_power_chg_quirk = device_property_read_bool(dev, |
||
415 | + "snps,dis-del-phy-power-chg-quirk"); |
||
416 | + dwc->dma_snooping_quirk = device_property_read_bool(dev, |
||
417 | + "snps,dma-snooping"); |
||
418 | + |
||
419 | + dwc->tx_de_emphasis_quirk = device_property_read_bool(dev, |
||
420 | + "snps,tx_de_emphasis_quirk"); |
||
421 | + dwc->disable_devinit_u1u2_quirk = device_property_read_bool(dev, |
||
422 | + "snps,disable_devinit_u1u2"); |
||
423 | + device_property_read_u8(dev, "snps,tx_de_emphasis", |
||
424 | + &tx_de_emphasis); |
||
425 | + device_property_read_string(dev, "snps,hsphy_interface", |
||
426 | + &dwc->hsphy_interface); |
||
427 | + device_property_read_u32(dev, "snps,quirk-frame-length-adjustment", |
||
428 | + &dwc->fladj); |
||
429 | + |
||
430 | + dwc->lpm_nyet_threshold = lpm_nyet_threshold; |
||
431 | + dwc->tx_de_emphasis = tx_de_emphasis; |
||
432 | + |
||
433 | + dwc->hird_threshold = hird_threshold |
||
434 | + | (dwc->is_utmi_l1_suspend << 4); |
||
435 | + |
||
436 | + dwc->imod_interval = 0; |
||
437 | +} |
||
438 | + |
||
439 | #define DWC3_ALIGN_MASK (16 - 1) |
||
440 | |||
441 | static int dwc3_probe(struct platform_device *pdev) |
||
442 | { |
||
443 | struct device *dev = &pdev->dev; |
||
444 | + struct device_node *node = dev->of_node; |
||
445 | struct resource *res; |
||
446 | struct dwc3 *dwc; |
||
447 | u8 lpm_nyet_threshold; |
||
448 | @@ -975,6 +1196,11 @@ static int dwc3_probe(struct platform_de |
||
449 | dwc->xhci_resources[0].flags = res->flags; |
||
450 | dwc->xhci_resources[0].name = res->name; |
||
451 | |||
452 | + if (node) { |
||
453 | + dwc->configure_gfladj = |
||
454 | + of_property_read_bool(node, "configure-gfladj"); |
||
455 | + } |
||
456 | + |
||
457 | res->start += DWC3_GLOBALS_REGS_START; |
||
458 | |||
459 | /* |
||
460 | @@ -1017,6 +1243,12 @@ static int dwc3_probe(struct platform_de |
||
461 | dwc->usb3_lpm_capable = device_property_read_bool(dev, |
||
462 | "snps,usb3_lpm_capable"); |
||
463 | |||
464 | + dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize"); |
||
465 | + |
||
466 | + dwc->configure_gfladj = |
||
467 | + of_property_read_bool(node, "configure-gfladj"); |
||
468 | + dwc->dr_mode = of_usb_get_dr_mode(node); |
||
469 | + |
||
470 | dwc->disable_scramble_quirk = device_property_read_bool(dev, |
||
471 | "snps,disable_scramble_quirk"); |
||
472 | dwc->u2exit_lfps_quirk = device_property_read_bool(dev, |
||
473 | @@ -1061,6 +1293,8 @@ static int dwc3_probe(struct platform_de |
||
474 | dwc->hird_threshold = hird_threshold |
||
475 | | (dwc->is_utmi_l1_suspend << 4); |
||
476 | |||
477 | + dwc3_get_properties(dwc); |
||
478 | + |
||
479 | platform_set_drvdata(pdev, dwc); |
||
480 | dwc3_cache_hwparams(dwc); |
||
481 | |||
482 | @@ -1084,6 +1318,11 @@ static int dwc3_probe(struct platform_de |
||
483 | if (ret < 0) |
||
484 | goto err1; |
||
485 | |||
486 | + /* Adjust Frame Length */ |
||
487 | + if (dwc->configure_gfladj) |
||
488 | + dwc3_writel(dwc->regs, DWC3_GFLADJ, GFLADJ_30MHZ_REG_SEL | |
||
489 | + GFLADJ_30MHZ(GFLADJ_30MHZ_DEFAULT)); |
||
490 | + |
||
491 | pm_runtime_forbid(dev); |
||
492 | |||
493 | ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE); |
||
494 | --- a/drivers/usb/dwc3/core.h |
||
495 | +++ b/drivers/usb/dwc3/core.h |
||
496 | @@ -26,6 +26,7 @@ |
||
497 | #include <linux/dma-mapping.h> |
||
498 | #include <linux/mm.h> |
||
499 | #include <linux/debugfs.h> |
||
500 | +#include <linux/of_address.h> |
||
501 | |||
502 | #include <linux/usb/ch9.h> |
||
503 | #include <linux/usb/gadget.h> |
||
504 | @@ -154,6 +155,32 @@ |
||
505 | |||
506 | /* Bit fields */ |
||
507 | |||
508 | +/* Global SoC Bus Configuration Register 0 */ |
||
509 | +#define AXI3_CACHE_TYPE_AW 0x8 /* write allocate */ |
||
510 | +#define AXI3_CACHE_TYPE_AR 0x4 /* read allocate */ |
||
511 | +#define AXI3_CACHE_TYPE_SNP 0x2 /* cacheable */ |
||
512 | +#define AXI3_CACHE_TYPE_BUF 0x1 /* bufferable */ |
||
513 | +#define DWC3_GSBUSCFG0_DATARD_SHIFT 28 |
||
514 | +#define DWC3_GSBUSCFG0_DESCRD_SHIFT 24 |
||
515 | +#define DWC3_GSBUSCFG0_DATAWR_SHIFT 20 |
||
516 | +#define DWC3_GSBUSCFG0_DESCWR_SHIFT 16 |
||
517 | +#define DWC3_GSBUSCFG0_SNP_MASK 0xffff0000 |
||
518 | +#define DWC3_GSBUSCFG0_DATABIGEND (1 << 11) |
||
519 | +#define DWC3_GSBUSCFG0_DESCBIGEND (1 << 10) |
||
520 | +#define DWC3_GSBUSCFG0_INCR256BRSTENA (1 << 7) /* INCR256 burst */ |
||
521 | +#define DWC3_GSBUSCFG0_INCR128BRSTENA (1 << 6) /* INCR128 burst */ |
||
522 | +#define DWC3_GSBUSCFG0_INCR64BRSTENA (1 << 5) /* INCR64 burst */ |
||
523 | +#define DWC3_GSBUSCFG0_INCR32BRSTENA (1 << 4) /* INCR32 burst */ |
||
524 | +#define DWC3_GSBUSCFG0_INCR16BRSTENA (1 << 3) /* INCR16 burst */ |
||
525 | +#define DWC3_GSBUSCFG0_INCR8BRSTENA (1 << 2) /* INCR8 burst */ |
||
526 | +#define DWC3_GSBUSCFG0_INCR4BRSTENA (1 << 1) /* INCR4 burst */ |
||
527 | +#define DWC3_GSBUSCFG0_INCRBRSTENA (1 << 0) /* undefined length enable */ |
||
528 | +#define DWC3_GSBUSCFG0_INCRBRST_MASK 0xff |
||
529 | + |
||
530 | +/* Global SoC Bus Configuration Register 1 */ |
||
531 | +#define DWC3_GSBUSCFG1_1KPAGEENA (1 << 12) /* 1K page boundary enable */ |
||
532 | +#define DWC3_GSBUSCFG1_PTRANSLIMIT_MASK 0xf00 |
||
533 | + |
||
534 | /* Global Debug Queue/FIFO Space Available Register */ |
||
535 | #define DWC3_GDBGFIFOSPACE_NUM(n) ((n) & 0x1f) |
||
536 | #define DWC3_GDBGFIFOSPACE_TYPE(n) (((n) << 5) & 0x1e0) |
||
537 | @@ -182,7 +209,6 @@ |
||
538 | #define DWC3_GCTL_CLK_PIPE (1) |
||
539 | #define DWC3_GCTL_CLK_PIPEHALF (2) |
||
540 | #define DWC3_GCTL_CLK_MASK (3) |
||
541 | - |
||
542 | #define DWC3_GCTL_PRTCAP(n) (((n) & (3 << 12)) >> 12) |
||
543 | #define DWC3_GCTL_PRTCAPDIR(n) ((n) << 12) |
||
544 | #define DWC3_GCTL_PRTCAP_HOST 1 |
||
545 | @@ -294,6 +320,10 @@ |
||
546 | /* Global Frame Length Adjustment Register */ |
||
547 | #define DWC3_GFLADJ_30MHZ_SDBND_SEL (1 << 7) |
||
548 | #define DWC3_GFLADJ_30MHZ_MASK 0x3f |
||
549 | +#define GFLADJ_30MHZ_REG_SEL (1 << 7) |
||
550 | +#define GFLADJ_30MHZ(n) ((n) & 0x3f) |
||
551 | +#define GFLADJ_30MHZ_DEFAULT 0x20 |
||
552 | + |
||
553 | |||
554 | /* Global User Control Register 2 */ |
||
555 | #define DWC3_GUCTL2_RST_ACTBITLATER (1 << 14) |
||
556 | @@ -758,6 +788,7 @@ struct dwc3_scratchpad_array { |
||
557 | * @regs: base address for our registers |
||
558 | * @regs_size: address space size |
||
559 | * @fladj: frame length adjustment |
||
560 | + * @incrx_type: INCR burst type adjustment |
||
561 | * @irq_gadget: peripheral controller's IRQ number |
||
562 | * @nr_scratch: number of scratch buffers |
||
563 | * @u1u2: only used on revisions <1.83a for workaround |
||
564 | @@ -834,6 +865,7 @@ struct dwc3_scratchpad_array { |
||
565 | * 1 - -3.5dB de-emphasis |
||
566 | * 2 - No de-emphasis |
||
567 | * 3 - Reserved |
||
568 | + * @disable_devinit_u1u2_quirk: disable device-initiated U1/U2 request. |
||
569 | */ |
||
570 | struct dwc3 { |
||
571 | struct usb_ctrlrequest *ctrl_req; |
||
572 | @@ -852,6 +884,7 @@ struct dwc3 { |
||
573 | spinlock_t lock; |
||
574 | |||
575 | struct device *dev; |
||
576 | + struct device *sysdev; |
||
577 | |||
578 | struct platform_device *xhci; |
||
579 | struct resource xhci_resources[DWC3_XHCI_RESOURCES_NUM]; |
||
580 | @@ -877,6 +910,12 @@ struct dwc3 { |
||
581 | enum usb_phy_interface hsphy_mode; |
||
582 | |||
583 | u32 fladj; |
||
584 | + /* |
||
585 | + * For INCR burst type. |
||
586 | + * First field: for undefined length INCR burst type enable. |
||
587 | + * Second field: for INCRx burst type enable |
||
588 | + */ |
||
589 | + u32 incrx_type[2]; |
||
590 | u32 irq_gadget; |
||
591 | u32 nr_scratch; |
||
592 | u32 u1u2; |
||
593 | @@ -953,9 +992,12 @@ struct dwc3 { |
||
594 | unsigned ep0_bounced:1; |
||
595 | unsigned ep0_expect_in:1; |
||
596 | unsigned has_hibernation:1; |
||
597 | + unsigned sysdev_is_parent:1; |
||
598 | unsigned has_lpm_erratum:1; |
||
599 | unsigned is_utmi_l1_suspend:1; |
||
600 | unsigned is_fpga:1; |
||
601 | + unsigned needs_fifo_resize:1; |
||
602 | + unsigned configure_gfladj:1; |
||
603 | unsigned pending_events:1; |
||
604 | unsigned pullups_connected:1; |
||
605 | unsigned setup_packet_pending:1; |
||
606 | @@ -976,9 +1018,16 @@ struct dwc3 { |
||
607 | unsigned dis_rxdet_inp3_quirk:1; |
||
608 | unsigned dis_u2_freeclk_exists_quirk:1; |
||
609 | unsigned dis_del_phy_power_chg_quirk:1; |
||
610 | + unsigned dma_snooping_quirk:1; |
||
611 | |||
612 | unsigned tx_de_emphasis_quirk:1; |
||
613 | unsigned tx_de_emphasis:2; |
||
614 | + unsigned disable_devinit_u1u2_quirk:1; |
||
615 | + unsigned quirk_reverse_in_out:1; |
||
616 | + unsigned quirk_stop_transfer_in_block:1; |
||
617 | + unsigned quirk_stop_ep_in_u1:1; |
||
618 | + |
||
619 | + u16 imod_interval; |
||
620 | }; |
||
621 | |||
622 | /* -------------------------------------------------------------------------- */ |
||
623 | --- a/drivers/usb/dwc3/ep0.c |
||
624 | +++ b/drivers/usb/dwc3/ep0.c |
||
625 | @@ -360,9 +360,9 @@ static int dwc3_ep0_handle_status(struct |
||
626 | if ((dwc->speed == DWC3_DSTS_SUPERSPEED) || |
||
627 | (dwc->speed == DWC3_DSTS_SUPERSPEED_PLUS)) { |
||
628 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); |
||
629 | - if (reg & DWC3_DCTL_INITU1ENA) |
||
630 | + if ((reg & DWC3_DCTL_INITU1ENA) && !dwc->disable_devinit_u1u2_quirk) |
||
631 | usb_status |= 1 << USB_DEV_STAT_U1_ENABLED; |
||
632 | - if (reg & DWC3_DCTL_INITU2ENA) |
||
633 | + if ((reg & DWC3_DCTL_INITU2ENA) && !dwc->disable_devinit_u1u2_quirk) |
||
634 | usb_status |= 1 << USB_DEV_STAT_U2_ENABLED; |
||
635 | } |
||
636 | |||
637 | --- a/drivers/usb/dwc3/gadget.c |
||
638 | +++ b/drivers/usb/dwc3/gadget.c |
||
639 | @@ -2932,6 +2932,7 @@ static irqreturn_t dwc3_interrupt(int ir |
||
640 | int dwc3_gadget_init(struct dwc3 *dwc) |
||
641 | { |
||
642 | int ret, irq; |
||
643 | + u32 reg; |
||
644 | struct platform_device *dwc3_pdev = to_platform_device(dwc->dev); |
||
645 | |||
646 | irq = platform_get_irq_byname(dwc3_pdev, "peripheral"); |
||
647 | @@ -3046,6 +3047,12 @@ int dwc3_gadget_init(struct dwc3 *dwc) |
||
648 | goto err5; |
||
649 | } |
||
650 | |||
651 | + if (dwc->disable_devinit_u1u2_quirk) { |
||
652 | + reg = dwc3_readl(dwc->regs, DWC3_DCTL); |
||
653 | + reg &= ~(DWC3_DCTL_INITU1ENA | DWC3_DCTL_INITU2ENA); |
||
654 | + dwc3_writel(dwc->regs, DWC3_DCTL, reg); |
||
655 | + } |
||
656 | + |
||
657 | return 0; |
||
658 | |||
659 | err5: |
||
660 | --- a/drivers/usb/dwc3/host.c |
||
661 | +++ b/drivers/usb/dwc3/host.c |
||
662 | @@ -17,6 +17,8 @@ |
||
663 | |||
664 | #include <linux/platform_device.h> |
||
665 | |||
666 | +#include <linux/of_device.h> |
||
667 | + |
||
668 | #include "core.h" |
||
669 | |||
670 | int dwc3_host_init(struct dwc3 *dwc) |
||
671 | @@ -73,12 +75,21 @@ int dwc3_host_init(struct dwc3 *dwc) |
||
672 | return -ENOMEM; |
||
673 | } |
||
674 | |||
675 | - dma_set_coherent_mask(&xhci->dev, dwc->dev->coherent_dma_mask); |
||
676 | + if (IS_ENABLED(CONFIG_OF) && dwc->dev->of_node) |
||
677 | + of_dma_configure(&xhci->dev, dwc->dev->of_node); |
||
678 | + else |
||
679 | + dma_set_coherent_mask(&xhci->dev, dwc->dev->coherent_dma_mask); |
||
680 | |||
681 | - xhci->dev.parent = dwc->dev; |
||
682 | + xhci->dev.parent = dwc->dev; |
||
683 | xhci->dev.dma_mask = dwc->dev->dma_mask; |
||
684 | xhci->dev.dma_parms = dwc->dev->dma_parms; |
||
685 | |||
686 | + /* set DMA operations */ |
||
687 | + if (dwc->dev->of_node && of_dma_is_coherent(dwc->dev->of_node)) { |
||
688 | + xhci->dev.archdata.dma_ops = dwc->dev->archdata.dma_ops; |
||
689 | + dev_dbg(dwc->dev, "set dma_ops for usb\n"); |
||
690 | + } |
||
691 | + |
||
692 | dwc->xhci = xhci; |
||
693 | |||
694 | ret = platform_device_add_resources(xhci, dwc->xhci_resources, |
||
695 | @@ -90,6 +101,15 @@ int dwc3_host_init(struct dwc3 *dwc) |
||
696 | |||
697 | memset(props, 0, sizeof(struct property_entry) * ARRAY_SIZE(props)); |
||
698 | |||
699 | + if (dwc->quirk_reverse_in_out) |
||
700 | + props[prop_idx++].name = "quirk-reverse-in-out"; |
||
701 | + |
||
702 | + if (dwc->quirk_stop_transfer_in_block) |
||
703 | + props[prop_idx++].name = "quirk-stop-transfer-in-block"; |
||
704 | + |
||
705 | + if (dwc->quirk_stop_ep_in_u1) |
||
706 | + props[prop_idx++].name = "quirk-stop-ep-in-u1"; |
||
707 | + |
||
708 | if (dwc->usb3_lpm_capable) |
||
709 | props[prop_idx++].name = "usb3-lpm-capable"; |
||
710 | |||
711 | --- a/drivers/usb/gadget/udc/fsl_udc_core.c |
||
712 | +++ b/drivers/usb/gadget/udc/fsl_udc_core.c |
||
713 | @@ -198,7 +198,11 @@ __acquires(ep->udc->lock) |
||
714 | |||
715 | spin_unlock(&ep->udc->lock); |
||
716 | |||
717 | - usb_gadget_giveback_request(&ep->ep, &req->req); |
||
718 | + /* this complete() should a func implemented by gadget layer, |
||
719 | + * eg fsg->bulk_in_complete() |
||
720 | + */ |
||
721 | + if (req->req.complete) |
||
722 | + usb_gadget_giveback_request(&ep->ep, &req->req); |
||
723 | |||
724 | spin_lock(&ep->udc->lock); |
||
725 | ep->stopped = stopped; |
||
726 | @@ -245,10 +249,10 @@ static int dr_controller_setup(struct fs |
||
727 | if (udc->pdata->have_sysif_regs) { |
||
728 | if (udc->pdata->controller_ver) { |
||
729 | /* controller version 1.6 or above */ |
||
730 | - ctrl = __raw_readl(&usb_sys_regs->control); |
||
731 | + ctrl = ioread32be(&usb_sys_regs->control); |
||
732 | ctrl &= ~USB_CTRL_UTMI_PHY_EN; |
||
733 | ctrl |= USB_CTRL_USB_EN; |
||
734 | - __raw_writel(ctrl, &usb_sys_regs->control); |
||
735 | + iowrite32be(ctrl, &usb_sys_regs->control); |
||
736 | } |
||
737 | } |
||
738 | portctrl |= PORTSCX_PTS_ULPI; |
||
739 | @@ -257,13 +261,14 @@ static int dr_controller_setup(struct fs |
||
740 | portctrl |= PORTSCX_PTW_16BIT; |
||
741 | /* fall through */ |
||
742 | case FSL_USB2_PHY_UTMI: |
||
743 | + case FSL_USB2_PHY_UTMI_DUAL: |
||
744 | if (udc->pdata->have_sysif_regs) { |
||
745 | if (udc->pdata->controller_ver) { |
||
746 | /* controller version 1.6 or above */ |
||
747 | - ctrl = __raw_readl(&usb_sys_regs->control); |
||
748 | + ctrl = ioread32be(&usb_sys_regs->control); |
||
749 | ctrl |= (USB_CTRL_UTMI_PHY_EN | |
||
750 | USB_CTRL_USB_EN); |
||
751 | - __raw_writel(ctrl, &usb_sys_regs->control); |
||
752 | + iowrite32be(ctrl, &usb_sys_regs->control); |
||
753 | mdelay(FSL_UTMI_PHY_DLY); /* Delay for UTMI |
||
754 | PHY CLK to become stable - 10ms*/ |
||
755 | } |
||
756 | @@ -329,22 +334,22 @@ static int dr_controller_setup(struct fs |
||
757 | /* Config control enable i/o output, cpu endian register */ |
||
758 | #ifndef CONFIG_ARCH_MXC |
||
759 | if (udc->pdata->have_sysif_regs) { |
||
760 | - ctrl = __raw_readl(&usb_sys_regs->control); |
||
761 | + ctrl = ioread32be(&usb_sys_regs->control); |
||
762 | ctrl |= USB_CTRL_IOENB; |
||
763 | - __raw_writel(ctrl, &usb_sys_regs->control); |
||
764 | + iowrite32be(ctrl, &usb_sys_regs->control); |
||
765 | } |
||
766 | #endif |
||
767 | |||
768 | -#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) |
||
769 | +#if !defined(CONFIG_NOT_COHERENT_CACHE) |
||
770 | /* Turn on cache snooping hardware, since some PowerPC platforms |
||
771 | * wholly rely on hardware to deal with cache coherent. */ |
||
772 | |||
773 | if (udc->pdata->have_sysif_regs) { |
||
774 | /* Setup Snooping for all the 4GB space */ |
||
775 | tmp = SNOOP_SIZE_2GB; /* starts from 0x0, size 2G */ |
||
776 | - __raw_writel(tmp, &usb_sys_regs->snoop1); |
||
777 | + iowrite32be(tmp, &usb_sys_regs->snoop1); |
||
778 | tmp |= 0x80000000; /* starts from 0x8000000, size 2G */ |
||
779 | - __raw_writel(tmp, &usb_sys_regs->snoop2); |
||
780 | + iowrite32be(tmp, &usb_sys_regs->snoop2); |
||
781 | } |
||
782 | #endif |
||
783 | |||
784 | @@ -1057,7 +1062,7 @@ static int fsl_ep_fifo_status(struct usb |
||
785 | struct ep_queue_head *qh; |
||
786 | |||
787 | ep = container_of(_ep, struct fsl_ep, ep); |
||
788 | - if (!_ep || (!ep->ep.desc && ep_index(ep) != 0)) |
||
789 | + if (!_ep || !ep->ep.desc || (ep_index(ep) == 0)) |
||
790 | return -ENODEV; |
||
791 | |||
792 | udc = (struct fsl_udc *)ep->udc; |
||
793 | @@ -1599,14 +1604,13 @@ static int process_ep_req(struct fsl_udc |
||
794 | struct fsl_req *curr_req) |
||
795 | { |
||
796 | struct ep_td_struct *curr_td; |
||
797 | - int td_complete, actual, remaining_length, j, tmp; |
||
798 | + int actual, remaining_length, j, tmp; |
||
799 | int status = 0; |
||
800 | int errors = 0; |
||
801 | struct ep_queue_head *curr_qh = &udc->ep_qh[pipe]; |
||
802 | int direction = pipe % 2; |
||
803 | |||
804 | curr_td = curr_req->head; |
||
805 | - td_complete = 0; |
||
806 | actual = curr_req->req.length; |
||
807 | |||
808 | for (j = 0; j < curr_req->dtd_count; j++) { |
||
809 | @@ -1651,11 +1655,9 @@ static int process_ep_req(struct fsl_udc |
||
810 | status = -EPROTO; |
||
811 | break; |
||
812 | } else { |
||
813 | - td_complete++; |
||
814 | break; |
||
815 | } |
||
816 | } else { |
||
817 | - td_complete++; |
||
818 | VDBG("dTD transmitted successful"); |
||
819 | } |
||
820 | |||
821 | @@ -1698,7 +1700,7 @@ static void dtd_complete_irq(struct fsl_ |
||
822 | curr_ep = get_ep_by_pipe(udc, i); |
||
823 | |||
824 | /* If the ep is configured */ |
||
825 | - if (!curr_ep->ep.name) { |
||
826 | + if (strncmp(curr_ep->name, "ep", 2)) { |
||
827 | WARNING("Invalid EP?"); |
||
828 | continue; |
||
829 | } |
||
830 | @@ -2420,10 +2422,12 @@ static int fsl_udc_probe(struct platform |
||
831 | usb_sys_regs = (void *)dr_regs + USB_DR_SYS_OFFSET; |
||
832 | #endif |
||
833 | |||
834 | +#ifdef CONFIG_ARCH_MXC |
||
835 | /* Initialize USB clocks */ |
||
836 | ret = fsl_udc_clk_init(pdev); |
||
837 | if (ret < 0) |
||
838 | goto err_iounmap_noclk; |
||
839 | +#endif |
||
840 | |||
841 | /* Read Device Controller Capability Parameters register */ |
||
842 | dccparams = fsl_readl(&dr_regs->dccparams); |
||
843 | @@ -2463,9 +2467,11 @@ static int fsl_udc_probe(struct platform |
||
844 | dr_controller_setup(udc_controller); |
||
845 | } |
||
846 | |||
847 | +#ifdef CONFIG_ARCH_MXC |
||
848 | ret = fsl_udc_clk_finalize(pdev); |
||
849 | if (ret) |
||
850 | goto err_free_irq; |
||
851 | +#endif |
||
852 | |||
853 | /* Setup gadget structure */ |
||
854 | udc_controller->gadget.ops = &fsl_gadget_ops; |
||
855 | @@ -2478,6 +2484,7 @@ static int fsl_udc_probe(struct platform |
||
856 | /* Setup gadget.dev and register with kernel */ |
||
857 | dev_set_name(&udc_controller->gadget.dev, "gadget"); |
||
858 | udc_controller->gadget.dev.of_node = pdev->dev.of_node; |
||
859 | + set_dma_ops(&udc_controller->gadget.dev, pdev->dev.archdata.dma_ops); |
||
860 | |||
861 | if (!IS_ERR_OR_NULL(udc_controller->transceiver)) |
||
862 | udc_controller->gadget.is_otg = 1; |
||
863 | @@ -2529,7 +2536,9 @@ err_free_irq: |
||
864 | err_iounmap: |
||
865 | if (pdata->exit) |
||
866 | pdata->exit(pdev); |
||
867 | +#ifdef CONFIG_ARCH_MXC |
||
868 | fsl_udc_clk_release(); |
||
869 | +#endif |
||
870 | err_iounmap_noclk: |
||
871 | iounmap(dr_regs); |
||
872 | err_release_mem_region: |
||
873 | @@ -2557,8 +2566,9 @@ static int fsl_udc_remove(struct platfor |
||
874 | udc_controller->done = &done; |
||
875 | usb_del_gadget_udc(&udc_controller->gadget); |
||
876 | |||
877 | +#ifdef CONFIG_ARCH_MXC |
||
878 | fsl_udc_clk_release(); |
||
879 | - |
||
880 | +#endif |
||
881 | /* DR has been stopped in usb_gadget_unregister_driver() */ |
||
882 | remove_proc_file(); |
||
883 | |||
884 | @@ -2570,7 +2580,7 @@ static int fsl_udc_remove(struct platfor |
||
885 | dma_pool_destroy(udc_controller->td_pool); |
||
886 | free_irq(udc_controller->irq, udc_controller); |
||
887 | iounmap(dr_regs); |
||
888 | - if (pdata->operating_mode == FSL_USB2_DR_DEVICE) |
||
889 | + if (res && (pdata->operating_mode == FSL_USB2_DR_DEVICE)) |
||
890 | release_mem_region(res->start, resource_size(res)); |
||
891 | |||
892 | /* free udc --wait for the release() finished */ |
||
893 | --- a/drivers/usb/gadget/udc/fsl_usb2_udc.h |
||
894 | +++ b/drivers/usb/gadget/udc/fsl_usb2_udc.h |
||
895 | @@ -20,6 +20,10 @@ |
||
896 | #define USB_MAX_CTRL_PAYLOAD 64 |
||
897 | #define USB_DR_SYS_OFFSET 0x400 |
||
898 | |||
899 | +#ifdef CONFIG_SOC_LS1021A |
||
900 | +#undef CONFIG_ARCH_MXC |
||
901 | +#endif |
||
902 | + |
||
903 | /* USB DR device mode registers (Little Endian) */ |
||
904 | struct usb_dr_device { |
||
905 | /* Capability register */ |
||
906 | @@ -597,18 +601,6 @@ struct platform_device; |
||
907 | int fsl_udc_clk_init(struct platform_device *pdev); |
||
908 | int fsl_udc_clk_finalize(struct platform_device *pdev); |
||
909 | void fsl_udc_clk_release(void); |
||
910 | -#else |
||
911 | -static inline int fsl_udc_clk_init(struct platform_device *pdev) |
||
912 | -{ |
||
913 | - return 0; |
||
914 | -} |
||
915 | -static inline int fsl_udc_clk_finalize(struct platform_device *pdev) |
||
916 | -{ |
||
917 | - return 0; |
||
918 | -} |
||
919 | -static inline void fsl_udc_clk_release(void) |
||
920 | -{ |
||
921 | -} |
||
922 | #endif |
||
923 | |||
924 | #endif |
||
925 | --- a/drivers/usb/host/Kconfig |
||
926 | +++ b/drivers/usb/host/Kconfig |
||
927 | @@ -165,7 +165,7 @@ config XPS_USB_HCD_XILINX |
||
928 | |||
929 | config USB_EHCI_FSL |
||
930 | tristate "Support for Freescale PPC on-chip EHCI USB controller" |
||
931 | - depends on FSL_SOC |
||
932 | + depends on USB_EHCI_HCD |
||
933 | select USB_EHCI_ROOT_HUB_TT |
||
934 | ---help--- |
||
935 | Variation of ARC USB block used in some Freescale chips. |
||
936 | --- a/drivers/usb/host/ehci-fsl.c |
||
937 | +++ b/drivers/usb/host/ehci-fsl.c |
||
938 | @@ -36,15 +36,127 @@ |
||
939 | #include <linux/platform_device.h> |
||
940 | #include <linux/fsl_devices.h> |
||
941 | #include <linux/of_platform.h> |
||
942 | +#include <linux/io.h> |
||
943 | + |
||
944 | +#ifdef CONFIG_PPC |
||
945 | +#include <asm/fsl_pm.h> |
||
946 | +#include <linux/suspend.h> |
||
947 | +#endif |
||
948 | |||
949 | #include "ehci.h" |
||
950 | #include "ehci-fsl.h" |
||
951 | |||
952 | +#define FSL_USB_PHY_ADDR 0xffe214000 |
||
953 | + |
||
954 | +struct ccsr_usb_port_ctrl { |
||
955 | + u32 ctrl; |
||
956 | + u32 drvvbuscfg; |
||
957 | + u32 pwrfltcfg; |
||
958 | + u32 sts; |
||
959 | + u8 res_14[0xc]; |
||
960 | + u32 bistcfg; |
||
961 | + u32 biststs; |
||
962 | + u32 abistcfg; |
||
963 | + u32 abiststs; |
||
964 | + u8 res_30[0x10]; |
||
965 | + u32 xcvrprg; |
||
966 | + u32 anaprg; |
||
967 | + u32 anadrv; |
||
968 | + u32 anasts; |
||
969 | +}; |
||
970 | + |
||
971 | +struct ccsr_usb_phy { |
||
972 | + u32 id; |
||
973 | + struct ccsr_usb_port_ctrl port1; |
||
974 | + u8 res_50[0xc]; |
||
975 | + u32 tvr; |
||
976 | + u32 pllprg[4]; |
||
977 | + u8 res_70[0x4]; |
||
978 | + u32 anaccfg; |
||
979 | + u32 dbg; |
||
980 | + u8 res_7c[0x4]; |
||
981 | + struct ccsr_usb_port_ctrl port2; |
||
982 | + u8 res_dc[0x334]; |
||
983 | +}; |
||
984 | + |
||
985 | #define DRIVER_DESC "Freescale EHCI Host controller driver" |
||
986 | #define DRV_NAME "ehci-fsl" |
||
987 | |||
988 | static struct hc_driver __read_mostly fsl_ehci_hc_driver; |
||
989 | |||
990 | +struct ehci_fsl { |
||
991 | + struct ehci_hcd ehci; |
||
992 | + |
||
993 | +#ifdef CONFIG_PM |
||
994 | +struct ehci_regs saved_regs; |
||
995 | +struct ccsr_usb_phy saved_phy_regs; |
||
996 | +/* Saved USB PHY settings, need to restore after deep sleep. */ |
||
997 | +u32 usb_ctrl; |
||
998 | +#endif |
||
999 | + /* |
||
1000 | + * store current hcd state for otg; |
||
1001 | + * have_hcd is true when host drv al already part of otg framework, |
||
1002 | + * otherwise false; |
||
1003 | + * hcd_add is true when otg framework wants to add host |
||
1004 | + * drv as part of otg;flase when it wants to remove it |
||
1005 | + */ |
||
1006 | +unsigned have_hcd:1; |
||
1007 | +unsigned hcd_add:1; |
||
1008 | +}; |
||
1009 | + |
||
1010 | +static struct ehci_fsl *hcd_to_ehci_fsl(struct usb_hcd *hcd) |
||
1011 | +{ |
||
1012 | +struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
||
1013 | + |
||
1014 | +return container_of(ehci, struct ehci_fsl, ehci); |
||
1015 | +} |
||
1016 | + |
||
1017 | +#if defined(CONFIG_FSL_USB2_OTG) || defined(CONFIG_FSL_USB2_OTG_MODULE) |
||
1018 | +static void do_change_hcd(struct work_struct *work) |
||
1019 | +{ |
||
1020 | +struct ehci_hcd *ehci = container_of(work, struct ehci_hcd, |
||
1021 | + change_hcd_work); |
||
1022 | +struct usb_hcd *hcd = ehci_to_hcd(ehci); |
||
1023 | +struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd); |
||
1024 | +void __iomem *non_ehci = hcd->regs; |
||
1025 | +int retval; |
||
1026 | + |
||
1027 | + if (ehci_fsl->hcd_add && !ehci_fsl->have_hcd) { |
||
1028 | + writel(USBMODE_CM_HOST, non_ehci + FSL_SOC_USB_USBMODE); |
||
1029 | + /* host, gadget and otg share same int line */ |
||
1030 | + retval = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); |
||
1031 | + if (retval == 0) |
||
1032 | + ehci_fsl->have_hcd = 1; |
||
1033 | + } else if (!ehci_fsl->hcd_add && ehci_fsl->have_hcd) { |
||
1034 | + usb_remove_hcd(hcd); |
||
1035 | + ehci_fsl->have_hcd = 0; |
||
1036 | + } |
||
1037 | +} |
||
1038 | +#endif |
||
1039 | + |
||
1040 | +#if defined(CONFIG_FSL_USB2_OTG) || defined(CONFIG_FSL_USB2_OTG_MODULE) |
||
1041 | +static void do_change_hcd(struct work_struct *work) |
||
1042 | +{ |
||
1043 | + struct ehci_hcd *ehci = container_of(work, struct ehci_hcd, |
||
1044 | + change_hcd_work); |
||
1045 | + struct usb_hcd *hcd = ehci_to_hcd(ehci); |
||
1046 | + struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd); |
||
1047 | + void __iomem *non_ehci = hcd->regs; |
||
1048 | + int retval; |
||
1049 | + |
||
1050 | + if (ehci_fsl->hcd_add && !ehci_fsl->have_hcd) { |
||
1051 | + writel(USBMODE_CM_HOST, non_ehci + FSL_SOC_USB_USBMODE); |
||
1052 | + /* host, gadget and otg share same int line */ |
||
1053 | + retval = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); |
||
1054 | + if (retval == 0) |
||
1055 | + ehci_fsl->have_hcd = 1; |
||
1056 | + } else if (!ehci_fsl->hcd_add && ehci_fsl->have_hcd) { |
||
1057 | + usb_remove_hcd(hcd); |
||
1058 | + ehci_fsl->have_hcd = 0; |
||
1059 | + } |
||
1060 | +} |
||
1061 | +#endif |
||
1062 | + |
||
1063 | /* configure so an HC device and id are always provided */ |
||
1064 | /* always called with process context; sleeping is OK */ |
||
1065 | |||
1066 | @@ -131,6 +243,12 @@ static int fsl_ehci_drv_probe(struct pla |
||
1067 | clrsetbits_be32(hcd->regs + FSL_SOC_USB_CTRL, |
||
1068 | CONTROL_REGISTER_W1C_MASK, 0x4); |
||
1069 | |||
1070 | + /* Set USB_EN bit to select ULPI phy for USB controller version 2.5 */ |
||
1071 | + if (pdata->controller_ver == FSL_USB_VER_2_5 && |
||
1072 | + pdata->phy_mode == FSL_USB2_PHY_ULPI) |
||
1073 | + iowrite32be(USB_CTRL_USB_EN, hcd->regs + FSL_SOC_USB_CTRL); |
||
1074 | + |
||
1075 | + |
||
1076 | /* |
||
1077 | * Enable UTMI phy and program PTS field in UTMI mode before asserting |
||
1078 | * controller reset for USB Controller version 2.5 |
||
1079 | @@ -143,16 +261,20 @@ static int fsl_ehci_drv_probe(struct pla |
||
1080 | |||
1081 | /* Don't need to set host mode here. It will be done by tdi_reset() */ |
||
1082 | |||
1083 | - retval = usb_add_hcd(hcd, irq, IRQF_SHARED); |
||
1084 | + retval = usb_add_hcd(hcd, irq, IRQF_SHARED | IRQF_NO_SUSPEND); |
||
1085 | if (retval != 0) |
||
1086 | goto err2; |
||
1087 | device_wakeup_enable(hcd->self.controller); |
||
1088 | |||
1089 | -#ifdef CONFIG_USB_OTG |
||
1090 | +#if defined(CONFIG_FSL_USB2_OTG) || defined(CONFIG_FSL_USB2_OTG_MODULE) |
||
1091 | if (pdata->operating_mode == FSL_USB2_DR_OTG) { |
||
1092 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
||
1093 | + struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd); |
||
1094 | |||
1095 | hcd->usb_phy = usb_get_phy(USB_PHY_TYPE_USB2); |
||
1096 | + |
||
1097 | + INIT_WORK(&ehci->change_hcd_work, do_change_hcd); |
||
1098 | + |
||
1099 | dev_dbg(&pdev->dev, "hcd=0x%p ehci=0x%p, phy=0x%p\n", |
||
1100 | hcd, ehci, hcd->usb_phy); |
||
1101 | |||
1102 | @@ -168,6 +290,11 @@ static int fsl_ehci_drv_probe(struct pla |
||
1103 | retval = -ENODEV; |
||
1104 | goto err2; |
||
1105 | } |
||
1106 | + |
||
1107 | + ehci_fsl->have_hcd = 1; |
||
1108 | + } else { |
||
1109 | + dev_err(&pdev->dev, "wrong operating mode\n"); |
||
1110 | + return -ENODEV; |
||
1111 | } |
||
1112 | #endif |
||
1113 | return retval; |
||
1114 | @@ -181,6 +308,17 @@ static int fsl_ehci_drv_probe(struct pla |
||
1115 | return retval; |
||
1116 | } |
||
1117 | |||
1118 | +static bool usb_phy_clk_valid(struct usb_hcd *hcd) |
||
1119 | +{ |
||
1120 | + void __iomem *non_ehci = hcd->regs; |
||
1121 | + bool ret = true; |
||
1122 | + |
||
1123 | + if (!(ioread32be(non_ehci + FSL_SOC_USB_CTRL) & PHY_CLK_VALID)) |
||
1124 | + ret = false; |
||
1125 | + |
||
1126 | + return ret; |
||
1127 | +} |
||
1128 | + |
||
1129 | static int ehci_fsl_setup_phy(struct usb_hcd *hcd, |
||
1130 | enum fsl_usb2_phy_modes phy_mode, |
||
1131 | unsigned int port_offset) |
||
1132 | @@ -219,6 +357,21 @@ static int ehci_fsl_setup_phy(struct usb |
||
1133 | /* fall through */ |
||
1134 | case FSL_USB2_PHY_UTMI: |
||
1135 | case FSL_USB2_PHY_UTMI_DUAL: |
||
1136 | + if (pdata->has_fsl_erratum_a006918) { |
||
1137 | + pr_warn("fsl-ehci: USB PHY clock invalid\n"); |
||
1138 | + return -EINVAL; |
||
1139 | + } |
||
1140 | + |
||
1141 | + /* PHY_CLK_VALID bit is de-featured from all controller |
||
1142 | + * versions below 2.4 and is to be checked only for |
||
1143 | + * internal UTMI phy |
||
1144 | + */ |
||
1145 | + if (pdata->controller_ver > FSL_USB_VER_2_4 && |
||
1146 | + pdata->have_sysif_regs && !usb_phy_clk_valid(hcd)) { |
||
1147 | + pr_err("fsl-ehci: USB PHY clock invalid\n"); |
||
1148 | + return -EINVAL; |
||
1149 | + } |
||
1150 | + |
||
1151 | if (pdata->have_sysif_regs && pdata->controller_ver) { |
||
1152 | /* controller version 1.6 or above */ |
||
1153 | clrsetbits_be32(non_ehci + FSL_SOC_USB_CTRL, |
||
1154 | @@ -286,20 +439,18 @@ static int ehci_fsl_usb_setup(struct ehc |
||
1155 | if (pdata->has_fsl_erratum_a005275 == 1) |
||
1156 | ehci->has_fsl_hs_errata = 1; |
||
1157 | |||
1158 | + if (pdata->has_fsl_erratum_a005697 == 1) |
||
1159 | + ehci->has_fsl_susp_errata = 1; |
||
1160 | + |
||
1161 | if ((pdata->operating_mode == FSL_USB2_DR_HOST) || |
||
1162 | (pdata->operating_mode == FSL_USB2_DR_OTG)) |
||
1163 | if (ehci_fsl_setup_phy(hcd, pdata->phy_mode, 0)) |
||
1164 | return -EINVAL; |
||
1165 | |||
1166 | if (pdata->operating_mode == FSL_USB2_MPH_HOST) { |
||
1167 | - unsigned int chip, rev, svr; |
||
1168 | - |
||
1169 | - svr = mfspr(SPRN_SVR); |
||
1170 | - chip = svr >> 16; |
||
1171 | - rev = (svr >> 4) & 0xf; |
||
1172 | |||
1173 | /* Deal with USB Erratum #14 on MPC834x Rev 1.0 & 1.1 chips */ |
||
1174 | - if ((rev == 1) && (chip >= 0x8050) && (chip <= 0x8055)) |
||
1175 | + if (pdata->has_fsl_erratum_14 == 1) |
||
1176 | ehci->has_fsl_port_bug = 1; |
||
1177 | |||
1178 | if (pdata->port_enables & FSL_USB2_PORT0_ENABLED) |
||
1179 | @@ -379,16 +530,57 @@ static int ehci_fsl_setup(struct usb_hcd |
||
1180 | return retval; |
||
1181 | } |
||
1182 | |||
1183 | -struct ehci_fsl { |
||
1184 | - struct ehci_hcd ehci; |
||
1185 | |||
1186 | #ifdef CONFIG_PM |
||
1187 | - /* Saved USB PHY settings, need to restore after deep sleep. */ |
||
1188 | - u32 usb_ctrl; |
||
1189 | -#endif |
||
1190 | -}; |
||
1191 | +void __iomem *phy_reg; |
||
1192 | |||
1193 | -#ifdef CONFIG_PM |
||
1194 | +#ifdef CONFIG_PPC |
||
1195 | +/* save usb registers */ |
||
1196 | +static int ehci_fsl_save_context(struct usb_hcd *hcd) |
||
1197 | +{ |
||
1198 | + struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd); |
||
1199 | + struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
||
1200 | + void __iomem *non_ehci = hcd->regs; |
||
1201 | + struct device *dev = hcd->self.controller; |
||
1202 | + struct fsl_usb2_platform_data *pdata = dev_get_platdata(dev); |
||
1203 | + |
||
1204 | + if (pdata->phy_mode == FSL_USB2_PHY_UTMI_DUAL) { |
||
1205 | + phy_reg = ioremap(FSL_USB_PHY_ADDR, |
||
1206 | + sizeof(struct ccsr_usb_phy)); |
||
1207 | + _memcpy_fromio((void *)&ehci_fsl->saved_phy_regs, phy_reg, |
||
1208 | + sizeof(struct ccsr_usb_phy)); |
||
1209 | + } |
||
1210 | + |
||
1211 | + _memcpy_fromio((void *)&ehci_fsl->saved_regs, ehci->regs, |
||
1212 | + sizeof(struct ehci_regs)); |
||
1213 | + ehci_fsl->usb_ctrl = ioread32be(non_ehci + FSL_SOC_USB_CTRL); |
||
1214 | + |
||
1215 | + return 0; |
||
1216 | +} |
||
1217 | + |
||
1218 | +/*Restore usb registers */ |
||
1219 | +static int ehci_fsl_restore_context(struct usb_hcd *hcd) |
||
1220 | +{ |
||
1221 | + struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd); |
||
1222 | + struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
||
1223 | + void __iomem *non_ehci = hcd->regs; |
||
1224 | + struct device *dev = hcd->self.controller; |
||
1225 | + struct fsl_usb2_platform_data *pdata = dev_get_platdata(dev); |
||
1226 | + |
||
1227 | + if (pdata->phy_mode == FSL_USB2_PHY_UTMI_DUAL) { |
||
1228 | + if (phy_reg) |
||
1229 | + _memcpy_toio(phy_reg, |
||
1230 | + (void *)&ehci_fsl->saved_phy_regs, |
||
1231 | + sizeof(struct ccsr_usb_phy)); |
||
1232 | + } |
||
1233 | + |
||
1234 | + _memcpy_toio(ehci->regs, (void *)&ehci_fsl->saved_regs, |
||
1235 | + sizeof(struct ehci_regs)); |
||
1236 | + iowrite32be(ehci_fsl->usb_ctrl, non_ehci + FSL_SOC_USB_CTRL); |
||
1237 | + |
||
1238 | + return 0; |
||
1239 | +} |
||
1240 | +#endif |
||
1241 | |||
1242 | #ifdef CONFIG_PPC_MPC512x |
||
1243 | static int ehci_fsl_mpc512x_drv_suspend(struct device *dev) |
||
1244 | @@ -535,26 +727,45 @@ static inline int ehci_fsl_mpc512x_drv_r |
||
1245 | } |
||
1246 | #endif /* CONFIG_PPC_MPC512x */ |
||
1247 | |||
1248 | -static struct ehci_fsl *hcd_to_ehci_fsl(struct usb_hcd *hcd) |
||
1249 | -{ |
||
1250 | - struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
||
1251 | - |
||
1252 | - return container_of(ehci, struct ehci_fsl, ehci); |
||
1253 | -} |
||
1254 | - |
||
1255 | static int ehci_fsl_drv_suspend(struct device *dev) |
||
1256 | { |
||
1257 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
||
1258 | struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd); |
||
1259 | void __iomem *non_ehci = hcd->regs; |
||
1260 | +#if defined(CONFIG_FSL_USB2_OTG) || defined(CONFIG_FSL_USB2_OTG_MODULE) |
||
1261 | + struct usb_bus host = hcd->self; |
||
1262 | +#endif |
||
1263 | + |
||
1264 | +#ifdef CONFIG_PPC |
||
1265 | +suspend_state_t pm_state; |
||
1266 | +/* FIXME:Need to port fsl_pm.h before enable below code. */ |
||
1267 | +/*pm_state = pm_suspend_state();*/ |
||
1268 | +pm_state = PM_SUSPEND_MEM; |
||
1269 | + |
||
1270 | +if (pm_state == PM_SUSPEND_MEM) |
||
1271 | + ehci_fsl_save_context(hcd); |
||
1272 | +#endif |
||
1273 | |||
1274 | if (of_device_is_compatible(dev->parent->of_node, |
||
1275 | "fsl,mpc5121-usb2-dr")) { |
||
1276 | return ehci_fsl_mpc512x_drv_suspend(dev); |
||
1277 | } |
||
1278 | |||
1279 | +#if defined(CONFIG_FSL_USB2_OTG) || defined(CONFIG_FSL_USB2_OTG_MODULE) |
||
1280 | + if (host.is_otg) { |
||
1281 | + struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
||
1282 | + |
||
1283 | + /* remove hcd */ |
||
1284 | + ehci_fsl->hcd_add = 0; |
||
1285 | + schedule_work(&ehci->change_hcd_work); |
||
1286 | + host.is_otg = 0; |
||
1287 | + return 0; |
||
1288 | + } |
||
1289 | +#endif |
||
1290 | + |
||
1291 | ehci_prepare_ports_for_controller_suspend(hcd_to_ehci(hcd), |
||
1292 | device_may_wakeup(dev)); |
||
1293 | + |
||
1294 | if (!fsl_deep_sleep()) |
||
1295 | return 0; |
||
1296 | |||
1297 | @@ -568,12 +779,36 @@ static int ehci_fsl_drv_resume(struct de |
||
1298 | struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd); |
||
1299 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
||
1300 | void __iomem *non_ehci = hcd->regs; |
||
1301 | +#if defined(CONFIG_FSL_USB2_OTG) || defined(CONFIG_FSL_USB2_OTG_MODULE) |
||
1302 | + struct usb_bus host = hcd->self; |
||
1303 | +#endif |
||
1304 | + |
||
1305 | +#ifdef CONFIG_PPC |
||
1306 | +suspend_state_t pm_state; |
||
1307 | +/* FIXME:Need to port fsl_pm.h before enable below code.*/ |
||
1308 | +/* pm_state = pm_suspend_state(); */ |
||
1309 | +pm_state = PM_SUSPEND_MEM; |
||
1310 | + |
||
1311 | +if (pm_state == PM_SUSPEND_MEM) |
||
1312 | + ehci_fsl_restore_context(hcd); |
||
1313 | +#endif |
||
1314 | |||
1315 | if (of_device_is_compatible(dev->parent->of_node, |
||
1316 | "fsl,mpc5121-usb2-dr")) { |
||
1317 | return ehci_fsl_mpc512x_drv_resume(dev); |
||
1318 | } |
||
1319 | |||
1320 | +#if defined(CONFIG_FSL_USB2_OTG) || defined(CONFIG_FSL_USB2_OTG_MODULE) |
||
1321 | + if (host.is_otg) { |
||
1322 | + /* add hcd */ |
||
1323 | + ehci_fsl->hcd_add = 1; |
||
1324 | + schedule_work(&ehci->change_hcd_work); |
||
1325 | + usb_hcd_resume_root_hub(hcd); |
||
1326 | + host.is_otg = 0; |
||
1327 | + return 0; |
||
1328 | + } |
||
1329 | +#endif |
||
1330 | + |
||
1331 | ehci_prepare_ports_for_controller_resume(ehci); |
||
1332 | if (!fsl_deep_sleep()) |
||
1333 | return 0; |
||
1334 | --- a/drivers/usb/host/ehci-fsl.h |
||
1335 | +++ b/drivers/usb/host/ehci-fsl.h |
||
1336 | @@ -63,4 +63,7 @@ |
||
1337 | #define UTMI_PHY_EN (1<<9) |
||
1338 | #define ULPI_PHY_CLK_SEL (1<<10) |
||
1339 | #define PHY_CLK_VALID (1<<17) |
||
1340 | + |
||
1341 | +/* Retry count for checking UTMI PHY CLK validity */ |
||
1342 | +#define UTMI_PHY_CLK_VALID_CHK_RETRY 5 |
||
1343 | #endif /* _EHCI_FSL_H */ |
||
1344 | --- a/drivers/usb/host/ehci-hub.c |
||
1345 | +++ b/drivers/usb/host/ehci-hub.c |
||
1346 | @@ -278,6 +278,8 @@ static int ehci_bus_suspend (struct usb_ |
||
1347 | else if ((t1 & PORT_PE) && !(t1 & PORT_SUSPEND)) { |
||
1348 | t2 |= PORT_SUSPEND; |
||
1349 | set_bit(port, &ehci->bus_suspended); |
||
1350 | + if (ehci_has_fsl_susp_errata(ehci)) |
||
1351 | + usleep_range(10000, 20000); |
||
1352 | } |
||
1353 | |||
1354 | /* enable remote wakeup on all ports, if told to do so */ |
||
1355 | @@ -305,6 +307,8 @@ static int ehci_bus_suspend (struct usb_ |
||
1356 | USB_PORT_STAT_HIGH_SPEED) |
||
1357 | fs_idle_delay = true; |
||
1358 | ehci_writel(ehci, t2, reg); |
||
1359 | + if (ehci_has_fsl_susp_errata(ehci)) |
||
1360 | + usleep_range(10000, 20000); |
||
1361 | changed = 1; |
||
1362 | } |
||
1363 | } |
||
1364 | --- a/drivers/usb/host/ehci.h |
||
1365 | +++ b/drivers/usb/host/ehci.h |
||
1366 | @@ -180,6 +180,9 @@ struct ehci_hcd { /* one per controlle |
||
1367 | unsigned periodic_count; /* periodic activity count */ |
||
1368 | unsigned uframe_periodic_max; /* max periodic time per uframe */ |
||
1369 | |||
1370 | +#if defined(CONFIG_FSL_USB2_OTG) || defined(CONFIG_FSL_USB2_OTG_MODULE) |
||
1371 | + struct work_struct change_hcd_work; |
||
1372 | +#endif |
||
1373 | |||
1374 | /* list of itds & sitds completed while now_frame was still active */ |
||
1375 | struct list_head cached_itd_list; |
||
1376 | @@ -219,6 +222,7 @@ struct ehci_hcd { /* one per controlle |
||
1377 | unsigned no_selective_suspend:1; |
||
1378 | unsigned has_fsl_port_bug:1; /* FreeScale */ |
||
1379 | unsigned has_fsl_hs_errata:1; /* Freescale HS quirk */ |
||
1380 | + unsigned has_fsl_susp_errata:1; /*Freescale SUSP quirk*/ |
||
1381 | unsigned big_endian_mmio:1; |
||
1382 | unsigned big_endian_desc:1; |
||
1383 | unsigned big_endian_capbase:1; |
||
1384 | @@ -704,10 +708,15 @@ ehci_port_speed(struct ehci_hcd *ehci, u |
||
1385 | #if defined(CONFIG_PPC_85xx) |
||
1386 | /* Some Freescale processors have an erratum (USB A-005275) in which |
||
1387 | * incoming packets get corrupted in HS mode |
||
1388 | + * Some Freescale processors have an erratum (USB A-005697) in which |
||
1389 | + * we need to wait for 10ms for bus to fo into suspend mode after |
||
1390 | + * setting SUSP bit |
||
1391 | */ |
||
1392 | #define ehci_has_fsl_hs_errata(e) ((e)->has_fsl_hs_errata) |
||
1393 | +#define ehci_has_fsl_susp_errata(e) ((e)->has_fsl_susp_errata) |
||
1394 | #else |
||
1395 | #define ehci_has_fsl_hs_errata(e) (0) |
||
1396 | +#define ehci_has_fsl_susp_errata(e) (0) |
||
1397 | #endif |
||
1398 | |||
1399 | /* |
||
1400 | --- a/drivers/usb/host/fsl-mph-dr-of.c |
||
1401 | +++ b/drivers/usb/host/fsl-mph-dr-of.c |
||
1402 | @@ -226,6 +226,18 @@ static int fsl_usb2_mph_dr_of_probe(stru |
||
1403 | of_property_read_bool(np, "fsl,usb-erratum-a007792"); |
||
1404 | pdata->has_fsl_erratum_a005275 = |
||
1405 | of_property_read_bool(np, "fsl,usb-erratum-a005275"); |
||
1406 | + pdata->has_fsl_erratum_a005697 = |
||
1407 | + of_property_read_bool(np, "fsl,usb_erratum-a005697"); |
||
1408 | + if (of_get_property(np, "fsl,erratum_a006918", NULL)) |
||
1409 | + pdata->has_fsl_erratum_a006918 = 1; |
||
1410 | + else |
||
1411 | + pdata->has_fsl_erratum_a006918 = 0; |
||
1412 | + |
||
1413 | + if (of_get_property(np, "fsl,usb_erratum_14", NULL)) |
||
1414 | + pdata->has_fsl_erratum_14 = 1; |
||
1415 | + else |
||
1416 | + pdata->has_fsl_erratum_14 = 0; |
||
1417 | + |
||
1418 | |||
1419 | /* |
||
1420 | * Determine whether phy_clk_valid needs to be checked |
||
1421 | --- a/drivers/usb/host/xhci-plat.c |
||
1422 | +++ b/drivers/usb/host/xhci-plat.c |
||
1423 | @@ -223,6 +223,16 @@ static int xhci_plat_probe(struct platfo |
||
1424 | if (device_property_read_bool(&pdev->dev, "usb3-lpm-capable")) |
||
1425 | xhci->quirks |= XHCI_LPM_SUPPORT; |
||
1426 | |||
1427 | + if (device_property_read_bool(&pdev->dev, "quirk-reverse-in-out")) |
||
1428 | + xhci->quirks |= XHCI_REVERSE_IN_OUT; |
||
1429 | + |
||
1430 | + if (device_property_read_bool(&pdev->dev, |
||
1431 | + "quirk-stop-transfer-in-block")) |
||
1432 | + xhci->quirks |= XHCI_STOP_TRANSFER_IN_BLOCK; |
||
1433 | + |
||
1434 | + if (device_property_read_bool(&pdev->dev, "quirk-stop-ep-in-u1")) |
||
1435 | + xhci->quirks |= XHCI_STOP_EP_IN_U1; |
||
1436 | + |
||
1437 | if (device_property_read_bool(&pdev->dev, "quirk-broken-port-ped")) |
||
1438 | xhci->quirks |= XHCI_BROKEN_PORT_PED; |
||
1439 | |||
1440 | --- a/drivers/usb/host/xhci-ring.c |
||
1441 | +++ b/drivers/usb/host/xhci-ring.c |
||
1442 | @@ -1852,14 +1852,17 @@ static int finish_td(struct xhci_hcd *xh |
||
1443 | union xhci_trb *event_trb, struct xhci_transfer_event *event, |
||
1444 | struct xhci_virt_ep *ep, int *status, bool skip) |
||
1445 | { |
||
1446 | + struct xhci_dequeue_state deq_state; |
||
1447 | struct xhci_virt_device *xdev; |
||
1448 | struct xhci_ring *ep_ring; |
||
1449 | + unsigned int stream_id; |
||
1450 | unsigned int slot_id; |
||
1451 | int ep_index; |
||
1452 | struct urb *urb = NULL; |
||
1453 | struct xhci_ep_ctx *ep_ctx; |
||
1454 | int ret = 0; |
||
1455 | struct urb_priv *urb_priv; |
||
1456 | + u32 remaining; |
||
1457 | u32 trb_comp_code; |
||
1458 | |||
1459 | slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags)); |
||
1460 | @@ -1885,13 +1888,29 @@ static int finish_td(struct xhci_hcd *xh |
||
1461 | if (trb_comp_code == COMP_STALL || |
||
1462 | xhci_requires_manual_halt_cleanup(xhci, ep_ctx, |
||
1463 | trb_comp_code)) { |
||
1464 | - /* Issue a reset endpoint command to clear the host side |
||
1465 | - * halt, followed by a set dequeue command to move the |
||
1466 | - * dequeue pointer past the TD. |
||
1467 | - * The class driver clears the device side halt later. |
||
1468 | + /* |
||
1469 | + * A-007463: After transaction error, controller switches |
||
1470 | + * control transfer data stage from IN to OUT direction. |
||
1471 | */ |
||
1472 | - xhci_cleanup_halted_endpoint(xhci, slot_id, ep_index, |
||
1473 | + remaining = EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); |
||
1474 | + if (remaining && xhci_requires_manual_halt_cleanup(xhci, ep_ctx, |
||
1475 | + trb_comp_code) && |
||
1476 | + (xhci->quirks & XHCI_REVERSE_IN_OUT)) { |
||
1477 | + memset(&deq_state, 0, sizeof(deq_state)); |
||
1478 | + xhci_find_new_dequeue_state(xhci, slot_id, |
||
1479 | + ep_index, td->urb->stream_id, td, &deq_state); |
||
1480 | + xhci_queue_new_dequeue_state(xhci, slot_id, ep_index, |
||
1481 | + stream_id, &deq_state); |
||
1482 | + xhci_ring_cmd_db(xhci); |
||
1483 | + } else { |
||
1484 | + /* Issue a reset endpoint command to clear the host side |
||
1485 | + * halt, followed by a set dequeue command to move the |
||
1486 | + * dequeue pointer past the TD. |
||
1487 | + * The class driver clears the device side halt later. |
||
1488 | + */ |
||
1489 | + xhci_cleanup_halted_endpoint(xhci, slot_id, ep_index, |
||
1490 | ep_ring->stream_id, td, event_trb); |
||
1491 | + } |
||
1492 | } else { |
||
1493 | /* Update ring dequeue pointer */ |
||
1494 | while (ep_ring->dequeue != td->last_trb) |
||
1495 | --- a/drivers/usb/host/xhci.c |
||
1496 | +++ b/drivers/usb/host/xhci.c |
||
1497 | @@ -1604,14 +1604,38 @@ int xhci_urb_dequeue(struct usb_hcd *hcd |
||
1498 | ret = -ENOMEM; |
||
1499 | goto done; |
||
1500 | } |
||
1501 | - ep->ep_state |= EP_HALT_PENDING; |
||
1502 | - ep->stop_cmds_pending++; |
||
1503 | - ep->stop_cmd_timer.expires = jiffies + |
||
1504 | + /* |
||
1505 | + *A-009611: Issuing an End Transfer command on an IN endpoint. |
||
1506 | + *when a transfer is in progress on USB blocks the transmission |
||
1507 | + *Workaround: Software must wait for all existing TRBs to |
||
1508 | + *complete before issuing End transfer command. |
||
1509 | + */ |
||
1510 | + if ((ep_ring->enqueue == ep_ring->dequeue && |
||
1511 | + (xhci->quirks & XHCI_STOP_TRANSFER_IN_BLOCK)) || |
||
1512 | + !(xhci->quirks & XHCI_STOP_TRANSFER_IN_BLOCK)) { |
||
1513 | + ep->ep_state |= EP_HALT_PENDING; |
||
1514 | + ep->stop_cmds_pending++; |
||
1515 | + ep->stop_cmd_timer.expires = jiffies + |
||
1516 | XHCI_STOP_EP_CMD_TIMEOUT * HZ; |
||
1517 | - add_timer(&ep->stop_cmd_timer); |
||
1518 | - xhci_queue_stop_endpoint(xhci, command, urb->dev->slot_id, |
||
1519 | - ep_index, 0); |
||
1520 | - xhci_ring_cmd_db(xhci); |
||
1521 | + add_timer(&ep->stop_cmd_timer); |
||
1522 | + xhci_queue_stop_endpoint(xhci, command, |
||
1523 | + urb->dev->slot_id, |
||
1524 | + ep_index, 0); |
||
1525 | + xhci_ring_cmd_db(xhci); |
||
1526 | + } |
||
1527 | + |
||
1528 | + /* |
||
1529 | + *A-009668: Stop Endpoint Command does not complete. |
||
1530 | + *Workaround: Instead of issuing a Stop Endpoint Command, |
||
1531 | + *issue a Disable Slot Command with the corresponding slot ID. |
||
1532 | + *Alternately, you can issue an Address Device Command with |
||
1533 | + *BSR=1 |
||
1534 | + */ |
||
1535 | + if ((urb->dev->speed <= USB_SPEED_HIGH) && |
||
1536 | + (xhci->quirks & XHCI_STOP_EP_IN_U1)) { |
||
1537 | + xhci_queue_slot_control(xhci, command, TRB_DISABLE_SLOT, |
||
1538 | + urb->dev->slot_id); |
||
1539 | + } |
||
1540 | } |
||
1541 | done: |
||
1542 | spin_unlock_irqrestore(&xhci->lock, flags); |
||
1543 | --- a/drivers/usb/host/xhci.h |
||
1544 | +++ b/drivers/usb/host/xhci.h |
||
1545 | @@ -1625,7 +1625,7 @@ struct xhci_hcd { |
||
1546 | #define XHCI_STATE_REMOVING (1 << 2) |
||
1547 | /* Statistics */ |
||
1548 | int error_bitmask; |
||
1549 | - unsigned int quirks; |
||
1550 | + u64 quirks; |
||
1551 | #define XHCI_LINK_TRB_QUIRK (1 << 0) |
||
1552 | #define XHCI_RESET_EP_QUIRK (1 << 1) |
||
1553 | #define XHCI_NEC_HOST (1 << 2) |
||
1554 | @@ -1661,6 +1661,9 @@ struct xhci_hcd { |
||
1555 | #define XHCI_SSIC_PORT_UNUSED (1 << 22) |
||
1556 | #define XHCI_NO_64BIT_SUPPORT (1 << 23) |
||
1557 | #define XHCI_MISSING_CAS (1 << 24) |
||
1558 | +#define XHCI_REVERSE_IN_OUT (1 << 29) |
||
1559 | +#define XHCI_STOP_TRANSFER_IN_BLOCK (1 << 30) |
||
1560 | +#define XHCI_STOP_EP_IN_U1 (1 << 31) |
||
1561 | /* For controller with a broken Port Disable implementation */ |
||
1562 | #define XHCI_BROKEN_PORT_PED (1 << 25) |
||
1563 | #define XHCI_LIMIT_ENDPOINT_INTERVAL_7 (1 << 26) |
||
1564 | --- a/drivers/usb/phy/phy-fsl-usb.c |
||
1565 | +++ b/drivers/usb/phy/phy-fsl-usb.c |
||
1566 | @@ -1,5 +1,5 @@ |
||
1567 | /* |
||
1568 | - * Copyright (C) 2007,2008 Freescale semiconductor, Inc. |
||
1569 | + * Copyright 2007,2008 Freescale Semiconductor, Inc. |
||
1570 | * |
||
1571 | * Author: Li Yang <LeoLi@freescale.com> |
||
1572 | * Jerry Huang <Chang-Ming.Huang@freescale.com> |
||
1573 | @@ -463,6 +463,7 @@ void otg_reset_controller(void) |
||
1574 | int fsl_otg_start_host(struct otg_fsm *fsm, int on) |
||
1575 | { |
||
1576 | struct usb_otg *otg = fsm->otg; |
||
1577 | + struct usb_bus *host = otg->host; |
||
1578 | struct device *dev; |
||
1579 | struct fsl_otg *otg_dev = |
||
1580 | container_of(otg->usb_phy, struct fsl_otg, phy); |
||
1581 | @@ -486,6 +487,7 @@ int fsl_otg_start_host(struct otg_fsm *f |
||
1582 | otg_reset_controller(); |
||
1583 | VDBG("host on......\n"); |
||
1584 | if (dev->driver->pm && dev->driver->pm->resume) { |
||
1585 | + host->is_otg = 1; |
||
1586 | retval = dev->driver->pm->resume(dev); |
||
1587 | if (fsm->id) { |
||
1588 | /* default-b */ |
||
1589 | @@ -510,8 +512,11 @@ int fsl_otg_start_host(struct otg_fsm *f |
||
1590 | else { |
||
1591 | VDBG("host off......\n"); |
||
1592 | if (dev && dev->driver) { |
||
1593 | - if (dev->driver->pm && dev->driver->pm->suspend) |
||
1594 | + if (dev->driver->pm && |
||
1595 | + dev->driver->pm->suspend) { |
||
1596 | + host->is_otg = 1; |
||
1597 | retval = dev->driver->pm->suspend(dev); |
||
1598 | + } |
||
1599 | if (fsm->id) |
||
1600 | /* default-b */ |
||
1601 | fsl_otg_drv_vbus(fsm, 0); |
||
1602 | @@ -539,8 +544,17 @@ int fsl_otg_start_gadget(struct otg_fsm |
||
1603 | dev = otg->gadget->dev.parent; |
||
1604 | |||
1605 | if (on) { |
||
1606 | - if (dev->driver->resume) |
||
1607 | + /* Delay gadget resume to synchronize between host and gadget |
||
1608 | + * drivers. Upon role-reversal host drv is shutdown by kernel |
||
1609 | + * worker thread. By the time host drv shuts down, controller |
||
1610 | + * gets programmed for gadget role. Shutting host drv after |
||
1611 | + * this results in controller getting reset, and it stops |
||
1612 | + * responding to otg events |
||
1613 | + */ |
||
1614 | + if (dev->driver->resume) { |
||
1615 | + msleep(1000); |
||
1616 | dev->driver->resume(dev); |
||
1617 | + } |
||
1618 | } else { |
||
1619 | if (dev->driver->suspend) |
||
1620 | dev->driver->suspend(dev, otg_suspend_state); |
||
1621 | @@ -672,6 +686,10 @@ static void fsl_otg_event(struct work_st |
||
1622 | fsl_otg_start_host(fsm, 0); |
||
1623 | otg_drv_vbus(fsm, 0); |
||
1624 | fsl_otg_start_gadget(fsm, 1); |
||
1625 | + } else { |
||
1626 | + fsl_otg_start_gadget(fsm, 0); |
||
1627 | + otg_drv_vbus(fsm, 1); |
||
1628 | + fsl_otg_start_host(fsm, 1); |
||
1629 | } |
||
1630 | } |
||
1631 | |||
1632 | @@ -724,6 +742,7 @@ irqreturn_t fsl_otg_isr(int irq, void *d |
||
1633 | { |
||
1634 | struct otg_fsm *fsm = &((struct fsl_otg *)dev_id)->fsm; |
||
1635 | struct usb_otg *otg = ((struct fsl_otg *)dev_id)->phy.otg; |
||
1636 | + struct fsl_otg *otg_dev = dev_id; |
||
1637 | u32 otg_int_src, otg_sc; |
||
1638 | |||
1639 | otg_sc = fsl_readl(&usb_dr_regs->otgsc); |
||
1640 | @@ -753,18 +772,8 @@ irqreturn_t fsl_otg_isr(int irq, void *d |
||
1641 | otg->gadget->is_a_peripheral = !fsm->id; |
||
1642 | VDBG("ID int (ID is %d)\n", fsm->id); |
||
1643 | |||
1644 | - if (fsm->id) { /* switch to gadget */ |
||
1645 | - schedule_delayed_work( |
||
1646 | - &((struct fsl_otg *)dev_id)->otg_event, |
||
1647 | - 100); |
||
1648 | - } else { /* switch to host */ |
||
1649 | - cancel_delayed_work(& |
||
1650 | - ((struct fsl_otg *)dev_id)-> |
||
1651 | - otg_event); |
||
1652 | - fsl_otg_start_gadget(fsm, 0); |
||
1653 | - otg_drv_vbus(fsm, 1); |
||
1654 | - fsl_otg_start_host(fsm, 1); |
||
1655 | - } |
||
1656 | + schedule_delayed_work(&otg_dev->otg_event, 100); |
||
1657 | + |
||
1658 | return IRQ_HANDLED; |
||
1659 | } |
||
1660 | } |
||
1661 | @@ -923,12 +932,32 @@ int usb_otg_start(struct platform_device |
||
1662 | temp &= ~(PORTSC_PHY_TYPE_SEL | PORTSC_PTW); |
||
1663 | switch (pdata->phy_mode) { |
||
1664 | case FSL_USB2_PHY_ULPI: |
||
1665 | + if (pdata->controller_ver) { |
||
1666 | + /* controller version 1.6 or above */ |
||
1667 | + setbits32(&p_otg->dr_mem_map->control, |
||
1668 | + USB_CTRL_ULPI_PHY_CLK_SEL); |
||
1669 | + /* |
||
1670 | + * Due to controller issue of PHY_CLK_VALID in ULPI |
||
1671 | + * mode, we set USB_CTRL_USB_EN before checking |
||
1672 | + * PHY_CLK_VALID, otherwise PHY_CLK_VALID doesn't work. |
||
1673 | + */ |
||
1674 | + clrsetbits_be32(&p_otg->dr_mem_map->control, |
||
1675 | + USB_CTRL_UTMI_PHY_EN, USB_CTRL_IOENB); |
||
1676 | + } |
||
1677 | temp |= PORTSC_PTS_ULPI; |
||
1678 | break; |
||
1679 | case FSL_USB2_PHY_UTMI_WIDE: |
||
1680 | temp |= PORTSC_PTW_16BIT; |
||
1681 | /* fall through */ |
||
1682 | case FSL_USB2_PHY_UTMI: |
||
1683 | + if (pdata->controller_ver) { |
||
1684 | + /* controller version 1.6 or above */ |
||
1685 | + setbits32(&p_otg->dr_mem_map->control, |
||
1686 | + USB_CTRL_UTMI_PHY_EN); |
||
1687 | + /* Delay for UTMI PHY CLK to become stable - 10ms */ |
||
1688 | + mdelay(FSL_UTMI_PHY_DLY); |
||
1689 | + } |
||
1690 | + setbits32(&p_otg->dr_mem_map->control, USB_CTRL_UTMI_PHY_EN); |
||
1691 | temp |= PORTSC_PTS_UTMI; |
||
1692 | /* fall through */ |
||
1693 | default: |
||
1694 | --- a/drivers/usb/phy/phy-fsl-usb.h |
||
1695 | +++ b/drivers/usb/phy/phy-fsl-usb.h |
||
1696 | @@ -199,6 +199,14 @@ |
||
1697 | /* control Register Bit Masks */ |
||
1698 | #define USB_CTRL_IOENB (0x1<<2) |
||
1699 | #define USB_CTRL_ULPI_INT0EN (0x1<<0) |
||
1700 | +#define USB_CTRL_WU_INT_EN (0x1<<1) |
||
1701 | +#define USB_CTRL_LINE_STATE_FILTER__EN (0x1<<3) |
||
1702 | +#define USB_CTRL_KEEP_OTG_ON (0x1<<4) |
||
1703 | +#define USB_CTRL_OTG_PORT (0x1<<5) |
||
1704 | +#define USB_CTRL_PLL_RESET (0x1<<8) |
||
1705 | +#define USB_CTRL_UTMI_PHY_EN (0x1<<9) |
||
1706 | +#define USB_CTRL_ULPI_PHY_CLK_SEL (0x1<<10) |
||
1707 | +#define USB_CTRL_PHY_CLK_VALID (0x1<<17) |
||
1708 | |||
1709 | /* BCSR5 */ |
||
1710 | #define BCSR5_INT_USB (0x02) |
||
1711 | --- a/include/linux/usb.h |
||
1712 | +++ b/include/linux/usb.h |
||
1713 | @@ -362,6 +362,7 @@ struct usb_bus { |
||
1714 | * for control transfers? |
||
1715 | */ |
||
1716 | u8 otg_port; /* 0, or number of OTG/HNP port */ |
||
1717 | + unsigned is_otg:1; /* true when host is also otg */ |
||
1718 | unsigned is_b_host:1; /* true during some HNP roleswitches */ |
||
1719 | unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */ |
||
1720 | unsigned no_stop_on_short:1; /* |
||
1721 | --- a/include/linux/usb/of.h |
||
1722 | +++ b/include/linux/usb/of.h |
||
1723 | @@ -11,6 +11,8 @@ |
||
1724 | #include <linux/usb/otg.h> |
||
1725 | #include <linux/usb/phy.h> |
||
1726 | |||
1727 | +enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np); |
||
1728 | + |
||
1729 | #if IS_ENABLED(CONFIG_OF) |
||
1730 | enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *np, int arg0); |
||
1731 | bool of_usb_host_tpl_support(struct device_node *np); |