1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* |
3 | * Copyright 2005-2009 MontaVista Software, Inc. |
4 | * Copyright 2008,2012,2015 Freescale Semiconductor, Inc. |
5 | * |
6 | * Ported to 834x by Randy Vinson <rvinson@mvista.com> using code provided |
7 | * by Hunter Wu. |
8 | * Power Management support by Dave Liu <daveliu@freescale.com>, |
9 | * Jerry Huang <Chang-Ming.Huang@freescale.com> and |
10 | * Anton Vorontsov <avorontsov@ru.mvista.com>. |
11 | */ |
12 | |
13 | #include <linux/kernel.h> |
14 | #include <linux/module.h> |
15 | #include <linux/types.h> |
16 | #include <linux/delay.h> |
17 | #include <linux/pm.h> |
18 | #include <linux/err.h> |
19 | #include <linux/usb.h> |
20 | #include <linux/usb/ehci_def.h> |
21 | #include <linux/usb/hcd.h> |
22 | #include <linux/usb/otg.h> |
23 | #include <linux/platform_device.h> |
24 | #include <linux/fsl_devices.h> |
25 | #include <linux/of.h> |
26 | #include <linux/io.h> |
27 | |
28 | #include "ehci.h" |
29 | #include "ehci-fsl.h" |
30 | |
31 | #define DRIVER_DESC "Freescale EHCI Host controller driver" |
32 | #define DRV_NAME "fsl-ehci" |
33 | |
34 | static struct hc_driver __read_mostly fsl_ehci_hc_driver; |
35 | |
36 | /* configure so an HC device and id are always provided */ |
37 | /* always called with process context; sleeping is OK */ |
38 | |
39 | /* |
40 | * fsl_ehci_drv_probe - initialize FSL-based HCDs |
41 | * @pdev: USB Host Controller being probed |
42 | * |
43 | * Context: task context, might sleep |
44 | * |
45 | * Allocates basic resources for this USB host controller. |
46 | */ |
47 | static int fsl_ehci_drv_probe(struct platform_device *pdev) |
48 | { |
49 | struct fsl_usb2_platform_data *pdata; |
50 | struct usb_hcd *hcd; |
51 | struct resource *res; |
52 | int irq; |
53 | int retval; |
54 | u32 tmp; |
55 | |
56 | pr_debug("initializing FSL-SOC USB Controller\n" ); |
57 | |
58 | /* Need platform data for setup */ |
59 | pdata = dev_get_platdata(dev: &pdev->dev); |
60 | if (!pdata) { |
61 | dev_err(&pdev->dev, |
62 | "No platform data for %s.\n" , dev_name(&pdev->dev)); |
63 | return -ENODEV; |
64 | } |
65 | |
66 | /* |
67 | * This is a host mode driver, verify that we're supposed to be |
68 | * in host mode. |
69 | */ |
70 | if (!((pdata->operating_mode == FSL_USB2_DR_HOST) || |
71 | (pdata->operating_mode == FSL_USB2_MPH_HOST) || |
72 | (pdata->operating_mode == FSL_USB2_DR_OTG))) { |
73 | dev_err(&pdev->dev, |
74 | "Non Host Mode configured for %s. Wrong driver linked.\n" , |
75 | dev_name(&pdev->dev)); |
76 | return -ENODEV; |
77 | } |
78 | |
79 | irq = platform_get_irq(pdev, 0); |
80 | if (irq < 0) |
81 | return irq; |
82 | |
83 | hcd = __usb_create_hcd(driver: &fsl_ehci_hc_driver, sysdev: pdev->dev.parent, |
84 | dev: &pdev->dev, bus_name: dev_name(dev: &pdev->dev), NULL); |
85 | if (!hcd) { |
86 | retval = -ENOMEM; |
87 | goto err1; |
88 | } |
89 | |
90 | hcd->regs = devm_platform_get_and_ioremap_resource(pdev, index: 0, res: &res); |
91 | if (IS_ERR(ptr: hcd->regs)) { |
92 | retval = PTR_ERR(ptr: hcd->regs); |
93 | goto err2; |
94 | } |
95 | |
96 | hcd->rsrc_start = res->start; |
97 | hcd->rsrc_len = resource_size(res); |
98 | |
99 | pdata->regs = hcd->regs; |
100 | |
101 | if (pdata->power_budget) |
102 | hcd->power_budget = pdata->power_budget; |
103 | |
104 | /* |
105 | * do platform specific init: check the clock, grab/config pins, etc. |
106 | */ |
107 | if (pdata->init && pdata->init(pdev)) { |
108 | retval = -ENODEV; |
109 | goto err2; |
110 | } |
111 | |
112 | /* Enable USB controller, 83xx or 8536 */ |
113 | if (pdata->have_sysif_regs && pdata->controller_ver < FSL_USB_VER_1_6) { |
114 | tmp = ioread32be(hcd->regs + FSL_SOC_USB_CTRL); |
115 | tmp &= ~CONTROL_REGISTER_W1C_MASK; |
116 | tmp |= 0x4; |
117 | iowrite32be(tmp, hcd->regs + FSL_SOC_USB_CTRL); |
118 | } |
119 | |
120 | /* Set USB_EN bit to select ULPI phy for USB controller version 2.5 */ |
121 | if (pdata->controller_ver == FSL_USB_VER_2_5 && |
122 | pdata->phy_mode == FSL_USB2_PHY_ULPI) |
123 | iowrite32be(USB_CTRL_USB_EN, hcd->regs + FSL_SOC_USB_CTRL); |
124 | |
125 | /* |
126 | * Enable UTMI phy and program PTS field in UTMI mode before asserting |
127 | * controller reset for USB Controller version 2.5 |
128 | */ |
129 | if (pdata->has_fsl_erratum_a007792) { |
130 | tmp = ioread32be(hcd->regs + FSL_SOC_USB_CTRL); |
131 | tmp &= ~CONTROL_REGISTER_W1C_MASK; |
132 | tmp |= CTRL_UTMI_PHY_EN; |
133 | iowrite32be(tmp, hcd->regs + FSL_SOC_USB_CTRL); |
134 | |
135 | writel(PORT_PTS_UTMI, addr: hcd->regs + FSL_SOC_USB_PORTSC1); |
136 | } |
137 | |
138 | /* Don't need to set host mode here. It will be done by tdi_reset() */ |
139 | |
140 | retval = usb_add_hcd(hcd, irqnum: irq, IRQF_SHARED); |
141 | if (retval != 0) |
142 | goto err2; |
143 | device_wakeup_enable(dev: hcd->self.controller); |
144 | |
145 | #ifdef CONFIG_USB_OTG |
146 | if (pdata->operating_mode == FSL_USB2_DR_OTG) { |
147 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
148 | |
149 | hcd->usb_phy = usb_get_phy(type: USB_PHY_TYPE_USB2); |
150 | dev_dbg(&pdev->dev, "hcd=0x%p ehci=0x%p, phy=0x%p\n" , |
151 | hcd, ehci, hcd->usb_phy); |
152 | |
153 | if (!IS_ERR_OR_NULL(ptr: hcd->usb_phy)) { |
154 | retval = otg_set_host(otg: hcd->usb_phy->otg, |
155 | host: &ehci_to_hcd(ehci)->self); |
156 | if (retval) { |
157 | usb_put_phy(hcd->usb_phy); |
158 | goto err2; |
159 | } |
160 | } else { |
161 | dev_err(&pdev->dev, "can't find phy\n" ); |
162 | retval = -ENODEV; |
163 | goto err2; |
164 | } |
165 | |
166 | hcd->skip_phy_initialization = 1; |
167 | } |
168 | #endif |
169 | return retval; |
170 | |
171 | err2: |
172 | usb_put_hcd(hcd); |
173 | err1: |
174 | dev_err(&pdev->dev, "init %s fail, %d\n" , dev_name(&pdev->dev), retval); |
175 | if (pdata->exit) |
176 | pdata->exit(pdev); |
177 | return retval; |
178 | } |
179 | |
180 | static bool usb_phy_clk_valid(struct usb_hcd *hcd) |
181 | { |
182 | void __iomem *non_ehci = hcd->regs; |
183 | bool ret = true; |
184 | |
185 | if (!(ioread32be(non_ehci + FSL_SOC_USB_CTRL) & PHY_CLK_VALID)) |
186 | ret = false; |
187 | |
188 | return ret; |
189 | } |
190 | |
191 | static int ehci_fsl_setup_phy(struct usb_hcd *hcd, |
192 | enum fsl_usb2_phy_modes phy_mode, |
193 | unsigned int port_offset) |
194 | { |
195 | u32 portsc, tmp; |
196 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
197 | void __iomem *non_ehci = hcd->regs; |
198 | struct device *dev = hcd->self.controller; |
199 | struct fsl_usb2_platform_data *pdata = dev_get_platdata(dev); |
200 | |
201 | if (pdata->controller_ver < 0) { |
202 | dev_warn(hcd->self.controller, "Could not get controller version\n" ); |
203 | return -ENODEV; |
204 | } |
205 | |
206 | portsc = ehci_readl(ehci, regs: &ehci->regs->port_status[port_offset]); |
207 | portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW); |
208 | |
209 | switch (phy_mode) { |
210 | case FSL_USB2_PHY_ULPI: |
211 | if (pdata->have_sysif_regs && pdata->controller_ver) { |
212 | /* controller version 1.6 or above */ |
213 | /* turn off UTMI PHY first */ |
214 | tmp = ioread32be(non_ehci + FSL_SOC_USB_CTRL); |
215 | tmp &= ~(CONTROL_REGISTER_W1C_MASK | UTMI_PHY_EN); |
216 | iowrite32be(tmp, non_ehci + FSL_SOC_USB_CTRL); |
217 | |
218 | /* then turn on ULPI and enable USB controller */ |
219 | tmp = ioread32be(non_ehci + FSL_SOC_USB_CTRL); |
220 | tmp &= ~CONTROL_REGISTER_W1C_MASK; |
221 | tmp |= ULPI_PHY_CLK_SEL | USB_CTRL_USB_EN; |
222 | iowrite32be(tmp, non_ehci + FSL_SOC_USB_CTRL); |
223 | } |
224 | portsc |= PORT_PTS_ULPI; |
225 | break; |
226 | case FSL_USB2_PHY_SERIAL: |
227 | portsc |= PORT_PTS_SERIAL; |
228 | break; |
229 | case FSL_USB2_PHY_UTMI_WIDE: |
230 | portsc |= PORT_PTS_PTW; |
231 | fallthrough; |
232 | case FSL_USB2_PHY_UTMI: |
233 | /* Presence of this node "has_fsl_erratum_a006918" |
234 | * in device-tree is used to stop USB controller |
235 | * initialization in Linux |
236 | */ |
237 | if (pdata->has_fsl_erratum_a006918) { |
238 | dev_warn(dev, "USB PHY clock invalid\n" ); |
239 | return -EINVAL; |
240 | } |
241 | fallthrough; |
242 | case FSL_USB2_PHY_UTMI_DUAL: |
243 | /* PHY_CLK_VALID bit is de-featured from all controller |
244 | * versions below 2.4 and is to be checked only for |
245 | * internal UTMI phy |
246 | */ |
247 | if (pdata->controller_ver > FSL_USB_VER_2_4 && |
248 | pdata->have_sysif_regs && !usb_phy_clk_valid(hcd)) { |
249 | dev_err(dev, "USB PHY clock invalid\n" ); |
250 | return -EINVAL; |
251 | } |
252 | |
253 | if (pdata->have_sysif_regs && pdata->controller_ver) { |
254 | /* controller version 1.6 or above */ |
255 | tmp = ioread32be(non_ehci + FSL_SOC_USB_CTRL); |
256 | tmp &= ~CONTROL_REGISTER_W1C_MASK; |
257 | tmp |= UTMI_PHY_EN; |
258 | iowrite32be(tmp, non_ehci + FSL_SOC_USB_CTRL); |
259 | |
260 | mdelay(FSL_UTMI_PHY_DLY); /* Delay for UTMI PHY CLK to |
261 | become stable - 10ms*/ |
262 | } |
263 | /* enable UTMI PHY */ |
264 | if (pdata->have_sysif_regs) { |
265 | tmp = ioread32be(non_ehci + FSL_SOC_USB_CTRL); |
266 | tmp &= ~CONTROL_REGISTER_W1C_MASK; |
267 | tmp |= CTRL_UTMI_PHY_EN; |
268 | iowrite32be(tmp, non_ehci + FSL_SOC_USB_CTRL); |
269 | } |
270 | portsc |= PORT_PTS_UTMI; |
271 | break; |
272 | case FSL_USB2_PHY_NONE: |
273 | break; |
274 | } |
275 | |
276 | if (pdata->have_sysif_regs && |
277 | pdata->controller_ver > FSL_USB_VER_1_6 && |
278 | !usb_phy_clk_valid(hcd)) { |
279 | dev_warn(hcd->self.controller, "USB PHY clock invalid\n" ); |
280 | return -EINVAL; |
281 | } |
282 | |
283 | ehci_writel(ehci, val: portsc, regs: &ehci->regs->port_status[port_offset]); |
284 | |
285 | if (phy_mode != FSL_USB2_PHY_ULPI && pdata->have_sysif_regs) { |
286 | tmp = ioread32be(non_ehci + FSL_SOC_USB_CTRL); |
287 | tmp &= ~CONTROL_REGISTER_W1C_MASK; |
288 | tmp |= USB_CTRL_USB_EN; |
289 | iowrite32be(tmp, non_ehci + FSL_SOC_USB_CTRL); |
290 | } |
291 | |
292 | return 0; |
293 | } |
294 | |
295 | static int ehci_fsl_usb_setup(struct ehci_hcd *ehci) |
296 | { |
297 | struct usb_hcd *hcd = ehci_to_hcd(ehci); |
298 | struct fsl_usb2_platform_data *pdata; |
299 | void __iomem *non_ehci = hcd->regs; |
300 | |
301 | pdata = dev_get_platdata(dev: hcd->self.controller); |
302 | |
303 | if (pdata->have_sysif_regs) { |
304 | /* |
305 | * Turn on cache snooping hardware, since some PowerPC platforms |
306 | * wholly rely on hardware to deal with cache coherent |
307 | */ |
308 | |
309 | /* Setup Snooping for all the 4GB space */ |
310 | /* SNOOP1 starts from 0x0, size 2G */ |
311 | iowrite32be(0x0 | SNOOP_SIZE_2GB, |
312 | non_ehci + FSL_SOC_USB_SNOOP1); |
313 | /* SNOOP2 starts from 0x80000000, size 2G */ |
314 | iowrite32be(0x80000000 | SNOOP_SIZE_2GB, |
315 | non_ehci + FSL_SOC_USB_SNOOP2); |
316 | } |
317 | |
318 | /* Deal with USB erratum A-005275 */ |
319 | if (pdata->has_fsl_erratum_a005275 == 1) |
320 | ehci->has_fsl_hs_errata = 1; |
321 | |
322 | if (pdata->has_fsl_erratum_a005697 == 1) |
323 | ehci->has_fsl_susp_errata = 1; |
324 | |
325 | if ((pdata->operating_mode == FSL_USB2_DR_HOST) || |
326 | (pdata->operating_mode == FSL_USB2_DR_OTG)) |
327 | if (ehci_fsl_setup_phy(hcd, phy_mode: pdata->phy_mode, port_offset: 0)) |
328 | return -EINVAL; |
329 | |
330 | if (pdata->operating_mode == FSL_USB2_MPH_HOST) { |
331 | |
332 | /* Deal with USB Erratum #14 on MPC834x Rev 1.0 & 1.1 chips */ |
333 | if (pdata->has_fsl_erratum_14 == 1) |
334 | ehci->has_fsl_port_bug = 1; |
335 | |
336 | if (pdata->port_enables & FSL_USB2_PORT0_ENABLED) |
337 | if (ehci_fsl_setup_phy(hcd, phy_mode: pdata->phy_mode, port_offset: 0)) |
338 | return -EINVAL; |
339 | |
340 | if (pdata->port_enables & FSL_USB2_PORT1_ENABLED) |
341 | if (ehci_fsl_setup_phy(hcd, phy_mode: pdata->phy_mode, port_offset: 1)) |
342 | return -EINVAL; |
343 | } |
344 | |
345 | if (pdata->have_sysif_regs) { |
346 | #ifdef CONFIG_FSL_SOC_BOOKE |
347 | iowrite32be(0x00000008, non_ehci + FSL_SOC_USB_PRICTRL); |
348 | iowrite32be(0x00000080, non_ehci + FSL_SOC_USB_AGECNTTHRSH); |
349 | #else |
350 | iowrite32be(0x0000000c, non_ehci + FSL_SOC_USB_PRICTRL); |
351 | iowrite32be(0x00000040, non_ehci + FSL_SOC_USB_AGECNTTHRSH); |
352 | #endif |
353 | iowrite32be(0x00000001, non_ehci + FSL_SOC_USB_SICTRL); |
354 | } |
355 | |
356 | return 0; |
357 | } |
358 | |
359 | /* called after powerup, by probe or system-pm "wakeup" */ |
360 | static int ehci_fsl_reinit(struct ehci_hcd *ehci) |
361 | { |
362 | if (ehci_fsl_usb_setup(ehci)) |
363 | return -EINVAL; |
364 | |
365 | return 0; |
366 | } |
367 | |
368 | /* called during probe() after chip reset completes */ |
369 | static int ehci_fsl_setup(struct usb_hcd *hcd) |
370 | { |
371 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
372 | int retval; |
373 | struct fsl_usb2_platform_data *pdata; |
374 | struct device *dev; |
375 | |
376 | dev = hcd->self.controller; |
377 | pdata = dev_get_platdata(dev: hcd->self.controller); |
378 | ehci->big_endian_desc = pdata->big_endian_desc; |
379 | ehci->big_endian_mmio = pdata->big_endian_mmio; |
380 | |
381 | /* EHCI registers start at offset 0x100 */ |
382 | ehci->caps = hcd->regs + 0x100; |
383 | |
384 | #if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_85xx) |
385 | /* |
386 | * Deal with MPC834X/85XX that need port power to be cycled |
387 | * after the power fault condition is removed. Otherwise the |
388 | * state machine does not reflect PORTSC[CSC] correctly. |
389 | */ |
390 | ehci->need_oc_pp_cycle = 1; |
391 | #endif |
392 | |
393 | hcd->has_tt = 1; |
394 | |
395 | retval = ehci_setup(hcd); |
396 | if (retval) |
397 | return retval; |
398 | |
399 | if (of_device_is_compatible(device: dev->parent->of_node, |
400 | "fsl,mpc5121-usb2-dr" )) { |
401 | /* |
402 | * set SBUSCFG:AHBBRST so that control msgs don't |
403 | * fail when doing heavy PATA writes. |
404 | */ |
405 | ehci_writel(ehci, SBUSCFG_INCR8, |
406 | regs: hcd->regs + FSL_SOC_USB_SBUSCFG); |
407 | } |
408 | |
409 | retval = ehci_fsl_reinit(ehci); |
410 | return retval; |
411 | } |
412 | |
413 | struct ehci_fsl { |
414 | struct ehci_hcd ehci; |
415 | |
416 | #ifdef CONFIG_PM |
417 | /* Saved USB PHY settings, need to restore after deep sleep. */ |
418 | u32 usb_ctrl; |
419 | #endif |
420 | }; |
421 | |
422 | #ifdef CONFIG_PM |
423 | |
424 | #ifdef CONFIG_PPC_MPC512x |
425 | static int ehci_fsl_mpc512x_drv_suspend(struct device *dev) |
426 | { |
427 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
428 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
429 | struct fsl_usb2_platform_data *pdata = dev_get_platdata(dev); |
430 | u32 tmp; |
431 | |
432 | #ifdef CONFIG_DYNAMIC_DEBUG |
433 | u32 mode = ehci_readl(ehci, hcd->regs + FSL_SOC_USB_USBMODE); |
434 | mode &= USBMODE_CM_MASK; |
435 | tmp = ehci_readl(ehci, hcd->regs + 0x140); /* usbcmd */ |
436 | |
437 | dev_dbg(dev, "suspend=%d already_suspended=%d " |
438 | "mode=%d usbcmd %08x\n" , pdata->suspended, |
439 | pdata->already_suspended, mode, tmp); |
440 | #endif |
441 | |
442 | /* |
443 | * If the controller is already suspended, then this must be a |
444 | * PM suspend. Remember this fact, so that we will leave the |
445 | * controller suspended at PM resume time. |
446 | */ |
447 | if (pdata->suspended) { |
448 | dev_dbg(dev, "already suspended, leaving early\n" ); |
449 | pdata->already_suspended = 1; |
450 | return 0; |
451 | } |
452 | |
453 | dev_dbg(dev, "suspending...\n" ); |
454 | |
455 | ehci->rh_state = EHCI_RH_SUSPENDED; |
456 | dev->power.power_state = PMSG_SUSPEND; |
457 | |
458 | /* ignore non-host interrupts */ |
459 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
460 | |
461 | /* stop the controller */ |
462 | tmp = ehci_readl(ehci, &ehci->regs->command); |
463 | tmp &= ~CMD_RUN; |
464 | ehci_writel(ehci, tmp, &ehci->regs->command); |
465 | |
466 | /* save EHCI registers */ |
467 | pdata->pm_command = ehci_readl(ehci, &ehci->regs->command); |
468 | pdata->pm_command &= ~CMD_RUN; |
469 | pdata->pm_status = ehci_readl(ehci, &ehci->regs->status); |
470 | pdata->pm_intr_enable = ehci_readl(ehci, &ehci->regs->intr_enable); |
471 | pdata->pm_frame_index = ehci_readl(ehci, &ehci->regs->frame_index); |
472 | pdata->pm_segment = ehci_readl(ehci, &ehci->regs->segment); |
473 | pdata->pm_frame_list = ehci_readl(ehci, &ehci->regs->frame_list); |
474 | pdata->pm_async_next = ehci_readl(ehci, &ehci->regs->async_next); |
475 | pdata->pm_configured_flag = |
476 | ehci_readl(ehci, &ehci->regs->configured_flag); |
477 | pdata->pm_portsc = ehci_readl(ehci, &ehci->regs->port_status[0]); |
478 | pdata->pm_usbgenctrl = ehci_readl(ehci, |
479 | hcd->regs + FSL_SOC_USB_USBGENCTRL); |
480 | |
481 | /* clear the W1C bits */ |
482 | pdata->pm_portsc &= cpu_to_hc32(ehci, ~PORT_RWC_BITS); |
483 | |
484 | pdata->suspended = 1; |
485 | |
486 | /* clear PP to cut power to the port */ |
487 | tmp = ehci_readl(ehci, &ehci->regs->port_status[0]); |
488 | tmp &= ~PORT_POWER; |
489 | ehci_writel(ehci, tmp, &ehci->regs->port_status[0]); |
490 | |
491 | return 0; |
492 | } |
493 | |
494 | static int ehci_fsl_mpc512x_drv_resume(struct device *dev) |
495 | { |
496 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
497 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
498 | struct fsl_usb2_platform_data *pdata = dev_get_platdata(dev); |
499 | u32 tmp; |
500 | |
501 | dev_dbg(dev, "suspend=%d already_suspended=%d\n" , |
502 | pdata->suspended, pdata->already_suspended); |
503 | |
504 | /* |
505 | * If the controller was already suspended at suspend time, |
506 | * then don't resume it now. |
507 | */ |
508 | if (pdata->already_suspended) { |
509 | dev_dbg(dev, "already suspended, leaving early\n" ); |
510 | pdata->already_suspended = 0; |
511 | return 0; |
512 | } |
513 | |
514 | if (!pdata->suspended) { |
515 | dev_dbg(dev, "not suspended, leaving early\n" ); |
516 | return 0; |
517 | } |
518 | |
519 | pdata->suspended = 0; |
520 | |
521 | dev_dbg(dev, "resuming...\n" ); |
522 | |
523 | /* set host mode */ |
524 | tmp = USBMODE_CM_HOST | (pdata->es ? USBMODE_ES : 0); |
525 | ehci_writel(ehci, tmp, hcd->regs + FSL_SOC_USB_USBMODE); |
526 | |
527 | ehci_writel(ehci, pdata->pm_usbgenctrl, |
528 | hcd->regs + FSL_SOC_USB_USBGENCTRL); |
529 | ehci_writel(ehci, ISIPHYCTRL_PXE | ISIPHYCTRL_PHYE, |
530 | hcd->regs + FSL_SOC_USB_ISIPHYCTRL); |
531 | |
532 | ehci_writel(ehci, SBUSCFG_INCR8, hcd->regs + FSL_SOC_USB_SBUSCFG); |
533 | |
534 | /* restore EHCI registers */ |
535 | ehci_writel(ehci, pdata->pm_command, &ehci->regs->command); |
536 | ehci_writel(ehci, pdata->pm_intr_enable, &ehci->regs->intr_enable); |
537 | ehci_writel(ehci, pdata->pm_frame_index, &ehci->regs->frame_index); |
538 | ehci_writel(ehci, pdata->pm_segment, &ehci->regs->segment); |
539 | ehci_writel(ehci, pdata->pm_frame_list, &ehci->regs->frame_list); |
540 | ehci_writel(ehci, pdata->pm_async_next, &ehci->regs->async_next); |
541 | ehci_writel(ehci, pdata->pm_configured_flag, |
542 | &ehci->regs->configured_flag); |
543 | ehci_writel(ehci, pdata->pm_portsc, &ehci->regs->port_status[0]); |
544 | |
545 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
546 | ehci->rh_state = EHCI_RH_RUNNING; |
547 | dev->power.power_state = PMSG_ON; |
548 | |
549 | tmp = ehci_readl(ehci, &ehci->regs->command); |
550 | tmp |= CMD_RUN; |
551 | ehci_writel(ehci, tmp, &ehci->regs->command); |
552 | |
553 | usb_hcd_resume_root_hub(hcd); |
554 | |
555 | return 0; |
556 | } |
557 | #else |
558 | static inline int ehci_fsl_mpc512x_drv_suspend(struct device *dev) |
559 | { |
560 | return 0; |
561 | } |
562 | |
563 | static inline int ehci_fsl_mpc512x_drv_resume(struct device *dev) |
564 | { |
565 | return 0; |
566 | } |
567 | #endif /* CONFIG_PPC_MPC512x */ |
568 | |
569 | static struct ehci_fsl *hcd_to_ehci_fsl(struct usb_hcd *hcd) |
570 | { |
571 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
572 | |
573 | return container_of(ehci, struct ehci_fsl, ehci); |
574 | } |
575 | |
576 | static int ehci_fsl_drv_suspend(struct device *dev) |
577 | { |
578 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
579 | struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd); |
580 | void __iomem *non_ehci = hcd->regs; |
581 | |
582 | if (of_device_is_compatible(device: dev->parent->of_node, |
583 | "fsl,mpc5121-usb2-dr" )) { |
584 | return ehci_fsl_mpc512x_drv_suspend(dev); |
585 | } |
586 | |
587 | ehci_prepare_ports_for_controller_suspend(hcd_to_ehci(hcd), |
588 | device_may_wakeup(dev)); |
589 | if (!fsl_deep_sleep()) |
590 | return 0; |
591 | |
592 | ehci_fsl->usb_ctrl = ioread32be(non_ehci + FSL_SOC_USB_CTRL); |
593 | return 0; |
594 | } |
595 | |
596 | static int ehci_fsl_drv_resume(struct device *dev) |
597 | { |
598 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
599 | struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd); |
600 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
601 | void __iomem *non_ehci = hcd->regs; |
602 | |
603 | if (of_device_is_compatible(device: dev->parent->of_node, |
604 | "fsl,mpc5121-usb2-dr" )) { |
605 | return ehci_fsl_mpc512x_drv_resume(dev); |
606 | } |
607 | |
608 | ehci_prepare_ports_for_controller_resume(ehci); |
609 | if (!fsl_deep_sleep()) |
610 | return 0; |
611 | |
612 | usb_root_hub_lost_power(rhdev: hcd->self.root_hub); |
613 | |
614 | /* Restore USB PHY settings and enable the controller. */ |
615 | iowrite32be(ehci_fsl->usb_ctrl, non_ehci + FSL_SOC_USB_CTRL); |
616 | |
617 | ehci_reset(ehci); |
618 | ehci_fsl_reinit(ehci); |
619 | |
620 | return 0; |
621 | } |
622 | |
623 | static int ehci_fsl_drv_restore(struct device *dev) |
624 | { |
625 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
626 | |
627 | usb_root_hub_lost_power(rhdev: hcd->self.root_hub); |
628 | return 0; |
629 | } |
630 | |
631 | static const struct dev_pm_ops ehci_fsl_pm_ops = { |
632 | .suspend = ehci_fsl_drv_suspend, |
633 | .resume = ehci_fsl_drv_resume, |
634 | .restore = ehci_fsl_drv_restore, |
635 | }; |
636 | |
637 | #define EHCI_FSL_PM_OPS (&ehci_fsl_pm_ops) |
638 | #else |
639 | #define EHCI_FSL_PM_OPS NULL |
640 | #endif /* CONFIG_PM */ |
641 | |
642 | #ifdef CONFIG_USB_OTG |
643 | static int ehci_start_port_reset(struct usb_hcd *hcd, unsigned port) |
644 | { |
645 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
646 | u32 status; |
647 | |
648 | if (!port) |
649 | return -EINVAL; |
650 | |
651 | port--; |
652 | |
653 | /* start port reset before HNP protocol time out */ |
654 | status = readl(addr: &ehci->regs->port_status[port]); |
655 | if (!(status & PORT_CONNECT)) |
656 | return -ENODEV; |
657 | |
658 | /* hub_wq will finish the reset later */ |
659 | if (ehci_is_TDI(ehci)) { |
660 | writel(PORT_RESET | |
661 | (status & ~(PORT_CSC | PORT_PEC | PORT_OCC)), |
662 | addr: &ehci->regs->port_status[port]); |
663 | } else { |
664 | writel(PORT_RESET, addr: &ehci->regs->port_status[port]); |
665 | } |
666 | |
667 | return 0; |
668 | } |
669 | #else |
670 | #define ehci_start_port_reset NULL |
671 | #endif /* CONFIG_USB_OTG */ |
672 | |
673 | static const struct ehci_driver_overrides ehci_fsl_overrides __initconst = { |
674 | .extra_priv_size = sizeof(struct ehci_fsl), |
675 | .reset = ehci_fsl_setup, |
676 | }; |
677 | |
678 | /** |
679 | * fsl_ehci_drv_remove - shutdown processing for FSL-based HCDs |
680 | * @pdev: USB Host Controller being removed |
681 | * |
682 | * Context: task context, might sleep |
683 | * |
684 | * Reverses the effect of usb_hcd_fsl_probe(). |
685 | */ |
686 | static void fsl_ehci_drv_remove(struct platform_device *pdev) |
687 | { |
688 | struct fsl_usb2_platform_data *pdata = dev_get_platdata(dev: &pdev->dev); |
689 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
690 | |
691 | if (!IS_ERR_OR_NULL(ptr: hcd->usb_phy)) { |
692 | otg_set_host(otg: hcd->usb_phy->otg, NULL); |
693 | usb_put_phy(hcd->usb_phy); |
694 | } |
695 | |
696 | usb_remove_hcd(hcd); |
697 | |
698 | /* |
699 | * do platform specific un-initialization: |
700 | * release iomux pins, disable clock, etc. |
701 | */ |
702 | if (pdata->exit) |
703 | pdata->exit(pdev); |
704 | usb_put_hcd(hcd); |
705 | } |
706 | |
707 | static struct platform_driver ehci_fsl_driver = { |
708 | .probe = fsl_ehci_drv_probe, |
709 | .remove_new = fsl_ehci_drv_remove, |
710 | .shutdown = usb_hcd_platform_shutdown, |
711 | .driver = { |
712 | .name = DRV_NAME, |
713 | .pm = EHCI_FSL_PM_OPS, |
714 | }, |
715 | }; |
716 | |
717 | static int __init ehci_fsl_init(void) |
718 | { |
719 | if (usb_disabled()) |
720 | return -ENODEV; |
721 | |
722 | ehci_init_driver(drv: &fsl_ehci_hc_driver, over: &ehci_fsl_overrides); |
723 | |
724 | fsl_ehci_hc_driver.product_desc = |
725 | "Freescale On-Chip EHCI Host Controller" ; |
726 | fsl_ehci_hc_driver.start_port_reset = ehci_start_port_reset; |
727 | |
728 | |
729 | return platform_driver_register(&ehci_fsl_driver); |
730 | } |
731 | module_init(ehci_fsl_init); |
732 | |
733 | static void __exit ehci_fsl_cleanup(void) |
734 | { |
735 | platform_driver_unregister(&ehci_fsl_driver); |
736 | } |
737 | module_exit(ehci_fsl_cleanup); |
738 | |
739 | MODULE_DESCRIPTION(DRIVER_DESC); |
740 | MODULE_LICENSE("GPL" ); |
741 | MODULE_ALIAS("platform:" DRV_NAME); |
742 | |