1 // SPDX-License-Identifier: GPL-2.0
3 * MUSB OTG driver virtual root hub support
5 * Copyright 2005 Mentor Graphics Corporation
6 * Copyright (C) 2005-2006 by Texas Instruments
7 * Copyright (C) 2006-2007 Nokia Corporation
10 #include <linux/module.h>
11 #include <linux/kernel.h>
12 #include <linux/sched.h>
13 #include <linux/errno.h>
14 #include <linux/time.h>
15 #include <linux/timer.h>
17 #include <asm/unaligned.h>
19 #include "musb_core.h"
21 void musb_host_finish_resume(struct work_struct
*work
)
27 musb
= container_of(work
, struct musb
, finish_resume_work
.work
);
29 spin_lock_irqsave(&musb
->lock
, flags
);
31 power
= musb_readb(musb
->mregs
, MUSB_POWER
);
32 power
&= ~MUSB_POWER_RESUME
;
33 musb_dbg(musb
, "root port resume stopped, power %02x", power
);
34 musb_writeb(musb
->mregs
, MUSB_POWER
, power
);
37 * ISSUE: DaVinci (RTL 1.300) disconnects after
38 * resume of high speed peripherals (but not full
42 musb
->port1_status
&= ~(USB_PORT_STAT_SUSPEND
| MUSB_PORT_STAT_RESUME
);
43 musb
->port1_status
|= USB_PORT_STAT_C_SUSPEND
<< 16;
44 usb_hcd_poll_rh_status(musb
->hcd
);
45 /* NOTE: it might really be A_WAIT_BCON ... */
46 musb
->xceiv
->otg
->state
= OTG_STATE_A_HOST
;
48 spin_unlock_irqrestore(&musb
->lock
, flags
);
51 void musb_port_suspend(struct musb
*musb
, bool do_suspend
)
53 struct usb_otg
*otg
= musb
->xceiv
->otg
;
55 void __iomem
*mbase
= musb
->mregs
;
57 if (!is_host_active(musb
))
60 /* NOTE: this doesn't necessarily put PHY into low power mode,
61 * turning off its clock; that's a function of PHY integration and
62 * MUSB_POWER_ENSUSPEND. PHY may need a clock (sigh) to detect
63 * SE0 changing to connect (J) or wakeup (K) states.
65 power
= musb_readb(mbase
, MUSB_POWER
);
69 power
&= ~MUSB_POWER_RESUME
;
70 power
|= MUSB_POWER_SUSPENDM
;
71 musb_writeb(mbase
, MUSB_POWER
, power
);
73 /* Needed for OPT A tests */
74 power
= musb_readb(mbase
, MUSB_POWER
);
75 while (power
& MUSB_POWER_SUSPENDM
) {
76 power
= musb_readb(mbase
, MUSB_POWER
);
81 musb_dbg(musb
, "Root port suspended, power %02x", power
);
83 musb
->port1_status
|= USB_PORT_STAT_SUSPEND
;
84 switch (musb
->xceiv
->otg
->state
) {
85 case OTG_STATE_A_HOST
:
86 musb
->xceiv
->otg
->state
= OTG_STATE_A_SUSPEND
;
87 musb
->is_active
= otg
->host
->b_hnp_enable
;
89 mod_timer(&musb
->otg_timer
, jiffies
91 OTG_TIME_A_AIDL_BDIS
));
92 musb_platform_try_idle(musb
, 0);
94 case OTG_STATE_B_HOST
:
95 musb
->xceiv
->otg
->state
= OTG_STATE_B_WAIT_ACON
;
96 musb
->is_active
= otg
->host
->b_hnp_enable
;
97 musb_platform_try_idle(musb
, 0);
100 musb_dbg(musb
, "bogus rh suspend? %s",
101 usb_otg_state_string(musb
->xceiv
->otg
->state
));
103 } else if (power
& MUSB_POWER_SUSPENDM
) {
104 power
&= ~MUSB_POWER_SUSPENDM
;
105 power
|= MUSB_POWER_RESUME
;
106 musb_writeb(mbase
, MUSB_POWER
, power
);
108 musb_dbg(musb
, "Root port resuming, power %02x", power
);
110 musb
->port1_status
|= MUSB_PORT_STAT_RESUME
;
111 schedule_delayed_work(&musb
->finish_resume_work
,
112 msecs_to_jiffies(USB_RESUME_TIMEOUT
));
116 void musb_port_reset(struct musb
*musb
, bool do_reset
)
119 void __iomem
*mbase
= musb
->mregs
;
121 if (musb
->xceiv
->otg
->state
== OTG_STATE_B_IDLE
) {
122 musb_dbg(musb
, "HNP: Returning from HNP; no hub reset from b_idle");
123 musb
->port1_status
&= ~USB_PORT_STAT_RESET
;
127 if (!is_host_active(musb
))
130 /* NOTE: caller guarantees it will turn off the reset when
131 * the appropriate amount of time has passed
133 power
= musb_readb(mbase
, MUSB_POWER
);
136 * If RESUME is set, we must make sure it stays minimum 20 ms.
137 * Then we must clear RESUME and wait a bit to let musb start
138 * generating SOFs. If we don't do this, OPT HS A 6.8 tests
139 * fail with "Error! Did not receive an SOF before suspend
142 if (power
& MUSB_POWER_RESUME
) {
143 long remain
= (unsigned long) musb
->rh_timer
- jiffies
;
145 if (musb
->rh_timer
> 0 && remain
> 0) {
146 /* take into account the minimum delay after resume */
147 schedule_delayed_work(
148 &musb
->deassert_reset_work
, remain
);
152 musb_writeb(mbase
, MUSB_POWER
,
153 power
& ~MUSB_POWER_RESUME
);
155 /* Give the core 1 ms to clear MUSB_POWER_RESUME */
156 schedule_delayed_work(&musb
->deassert_reset_work
,
157 msecs_to_jiffies(1));
162 musb_writeb(mbase
, MUSB_POWER
,
163 power
| MUSB_POWER_RESET
);
165 musb
->port1_status
|= USB_PORT_STAT_RESET
;
166 musb
->port1_status
&= ~USB_PORT_STAT_ENABLE
;
167 schedule_delayed_work(&musb
->deassert_reset_work
,
168 msecs_to_jiffies(50));
170 musb_dbg(musb
, "root port reset stopped");
171 musb_platform_pre_root_reset_end(musb
);
172 musb_writeb(mbase
, MUSB_POWER
,
173 power
& ~MUSB_POWER_RESET
);
174 musb_platform_post_root_reset_end(musb
);
176 power
= musb_readb(mbase
, MUSB_POWER
);
177 if (power
& MUSB_POWER_HSMODE
) {
178 musb_dbg(musb
, "high-speed device connected");
179 musb
->port1_status
|= USB_PORT_STAT_HIGH_SPEED
;
182 musb
->port1_status
&= ~USB_PORT_STAT_RESET
;
183 musb
->port1_status
|= USB_PORT_STAT_ENABLE
184 | (USB_PORT_STAT_C_RESET
<< 16)
185 | (USB_PORT_STAT_C_ENABLE
<< 16);
186 usb_hcd_poll_rh_status(musb
->hcd
);
188 musb
->vbuserr_retry
= VBUSERR_RETRY_COUNT
;
192 void musb_root_disconnect(struct musb
*musb
)
194 struct usb_otg
*otg
= musb
->xceiv
->otg
;
196 musb
->port1_status
= USB_PORT_STAT_POWER
197 | (USB_PORT_STAT_C_CONNECTION
<< 16);
199 usb_hcd_poll_rh_status(musb
->hcd
);
202 switch (musb
->xceiv
->otg
->state
) {
203 case OTG_STATE_A_SUSPEND
:
204 if (otg
->host
->b_hnp_enable
) {
205 musb
->xceiv
->otg
->state
= OTG_STATE_A_PERIPHERAL
;
206 musb
->g
.is_a_peripheral
= 1;
210 case OTG_STATE_A_HOST
:
211 musb
->xceiv
->otg
->state
= OTG_STATE_A_WAIT_BCON
;
214 case OTG_STATE_A_WAIT_VFALL
:
215 musb
->xceiv
->otg
->state
= OTG_STATE_B_IDLE
;
218 musb_dbg(musb
, "host disconnect (%s)",
219 usb_otg_state_string(musb
->xceiv
->otg
->state
));
222 EXPORT_SYMBOL_GPL(musb_root_disconnect
);
225 /*---------------------------------------------------------------------*/
227 /* Caller may or may not hold musb->lock */
228 int musb_hub_status_data(struct usb_hcd
*hcd
, char *buf
)
230 struct musb
*musb
= hcd_to_musb(hcd
);
233 /* called in_irq() via usb_hcd_poll_rh_status() */
234 if (musb
->port1_status
& 0xffff0000) {
241 static int musb_has_gadget(struct musb
*musb
)
244 * In host-only mode we start a connection right away. In OTG mode
245 * we have to wait until we loaded a gadget. We don't really need a
246 * gadget if we operate as a host but we should not start a session
247 * as a device without a gadget or else we explode.
249 #ifdef CONFIG_USB_MUSB_HOST
252 return musb
->port_mode
== MUSB_PORT_MODE_HOST
;
256 int musb_hub_control(
264 struct musb
*musb
= hcd_to_musb(hcd
);
268 bool start_musb
= false;
270 spin_lock_irqsave(&musb
->lock
, flags
);
272 if (unlikely(!HCD_HW_ACCESSIBLE(hcd
))) {
273 spin_unlock_irqrestore(&musb
->lock
, flags
);
277 /* hub features: always zero, setting is a NOP
278 * port features: reported, sometimes updated when host is active
282 case ClearHubFeature
:
285 case C_HUB_OVER_CURRENT
:
286 case C_HUB_LOCAL_POWER
:
292 case ClearPortFeature
:
293 if ((wIndex
& 0xff) != 1)
297 case USB_PORT_FEAT_ENABLE
:
299 case USB_PORT_FEAT_SUSPEND
:
300 musb_port_suspend(musb
, false);
302 case USB_PORT_FEAT_POWER
:
303 if (!hcd
->self
.is_b_host
)
304 musb_platform_set_vbus(musb
, 0);
306 case USB_PORT_FEAT_C_CONNECTION
:
307 case USB_PORT_FEAT_C_ENABLE
:
308 case USB_PORT_FEAT_C_OVER_CURRENT
:
309 case USB_PORT_FEAT_C_RESET
:
310 case USB_PORT_FEAT_C_SUSPEND
:
315 musb_dbg(musb
, "clear feature %d", wValue
);
316 musb
->port1_status
&= ~(1 << wValue
);
318 case GetHubDescriptor
:
320 struct usb_hub_descriptor
*desc
= (void *)buf
;
322 desc
->bDescLength
= 9;
323 desc
->bDescriptorType
= USB_DT_HUB
;
325 desc
->wHubCharacteristics
= cpu_to_le16(
326 HUB_CHAR_INDV_PORT_LPSM
/* per-port power switching */
327 | HUB_CHAR_NO_OCPM
/* no overcurrent reporting */
329 desc
->bPwrOn2PwrGood
= 5; /* msec/2 */
330 desc
->bHubContrCurrent
= 0;
332 /* workaround bogus struct definition */
333 desc
->u
.hs
.DeviceRemovable
[0] = 0x02; /* port 1 */
334 desc
->u
.hs
.DeviceRemovable
[1] = 0xff;
339 *(__le32
*) buf
= cpu_to_le32(temp
);
345 put_unaligned(cpu_to_le32(musb
->port1_status
346 & ~MUSB_PORT_STAT_RESUME
),
349 /* port change status is more interesting */
350 musb_dbg(musb
, "port status %08x", musb
->port1_status
);
353 if ((wIndex
& 0xff) != 1)
357 case USB_PORT_FEAT_POWER
:
358 /* NOTE: this controller has a strange state machine
359 * that involves "requesting sessions" according to
360 * magic side effects from incompletely-described
361 * rules about startup...
363 * This call is what really starts the host mode; be
364 * very careful about side effects if you reorder any
365 * initialization logic, e.g. for OTG, or change any
366 * logic relating to VBUS power-up.
368 if (!hcd
->self
.is_b_host
&& musb_has_gadget(musb
))
371 case USB_PORT_FEAT_RESET
:
372 musb_port_reset(musb
, true);
374 case USB_PORT_FEAT_SUSPEND
:
375 musb_port_suspend(musb
, true);
377 case USB_PORT_FEAT_TEST
:
378 if (unlikely(is_host_active(musb
)))
384 pr_debug("TEST_J\n");
388 pr_debug("TEST_K\n");
392 pr_debug("TEST_SE0_NAK\n");
393 temp
= MUSB_TEST_SE0_NAK
;
396 pr_debug("TEST_PACKET\n");
397 temp
= MUSB_TEST_PACKET
;
398 musb_load_testpacket(musb
);
401 pr_debug("TEST_FORCE_ENABLE\n");
402 temp
= MUSB_TEST_FORCE_HOST
403 | MUSB_TEST_FORCE_HS
;
405 musb_writeb(musb
->mregs
, MUSB_DEVCTL
,
406 MUSB_DEVCTL_SESSION
);
409 pr_debug("TEST_FIFO_ACCESS\n");
410 temp
= MUSB_TEST_FIFO_ACCESS
;
415 musb_writeb(musb
->mregs
, MUSB_TESTMODE
, temp
);
420 musb_dbg(musb
, "set feature %d", wValue
);
421 musb
->port1_status
|= 1 << wValue
;
426 /* "protocol stall" on error */
429 spin_unlock_irqrestore(&musb
->lock
, flags
);