usbdebug: Allow an USB hub on the debug dongle

Some development kits with USB 2.0 HS OTG have an USB hub instead
of being directly connected to the USB host/device controller.

Send the necessary initialisation sequence, using HUB CLASS requests
of PORT_POWER and PORT_RESET to enable a pre-selected port number
where a device supporting debug descriptor is located.

This also adds the Kconfig option for BeagleBone.

Change-Id: I7a5d0ba0962a9ca06bf3196232ed4a03bdfb2b06
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: http://review.coreboot.org/3925
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
This commit is contained in:
Kyösti Mälkki 2013-08-23 23:33:16 +03:00
parent 8f485dee0d
commit d2dac0a7d6
2 changed files with 128 additions and 2 deletions

View File

@ -173,10 +173,11 @@ config USBDEBUG
If unsure, say N. If unsure, say N.
if USBDEBUG
config USBDEBUG_HCD_INDEX config USBDEBUG_HCD_INDEX
int "Index for EHCI controller to use with usbdebug" int "Index for EHCI controller to use with usbdebug"
default 0 default 0
depends on USBDEBUG
help help
Some boards have multiple EHCI controllers with possibly only Some boards have multiple EHCI controllers with possibly only
one having the Debug Port capability on an external USB port. one having the Debug Port capability on an external USB port.
@ -188,7 +189,6 @@ config USBDEBUG_HCD_INDEX
config USBDEBUG_DEFAULT_PORT config USBDEBUG_DEFAULT_PORT
int "Default USB port to use as Debug Port" int "Default USB port to use as Debug Port"
default 0 default 0
depends on USBDEBUG
help help
Selects which physical USB port usbdebug dongle is connected to. Selects which physical USB port usbdebug dongle is connected to.
Setting of 0 means to scan possible ports starting from 1. Setting of 0 means to scan possible ports starting from 1.
@ -202,6 +202,27 @@ config USBDEBUG_DEFAULT_PORT
your mainboard) is highly board-specific, and you'll likely your mainboard) is highly board-specific, and you'll likely
have to find out by trial-and-error. have to find out by trial-and-error.
choice
prompt "Type of dongle"
default USBDEBUG_DONGLE_STD
config USBDEBUG_DONGLE_STD
bool "Net20DC or compatible"
config USBDEBUG_DONGLE_BEAGLEBONE
bool "BeagleBone"
help
Use this to configure the USB hub on BeagleBone board.
endchoice
config USBDEBUG_OPTIONAL_HUB_PORT
int
default 2 if USBDEBUG_DONGLE_BEAGLEBONE
default 0
endif # USBDEBUG
# TODO: Deps? # TODO: Deps?
# TODO: Improve description. # TODO: Improve description.
config ONBOARD_VGA_IS_PRIMARY config ONBOARD_VGA_IS_PRIMARY

View File

@ -483,6 +483,102 @@ static int ehci_wait_for_port(struct ehci_regs *ehci_regs, int port)
return -1; //-ENOTCONN; return -1; //-ENOTCONN;
} }
#define USB_HUB_PORT_CONNECTION 0
#define USB_HUB_PORT_ENABLED 1
#define USB_HUB_PORT_RESET 4
#define USB_HUB_PORT_POWER 8
#define USB_HUB_C_PORT_CONNECTION 16
#define USB_HUB_C_PORT_RESET 20
#if CONFIG_USBDEBUG_OPTIONAL_HUB_PORT
static int hub_port_status(const char * buf, int feature)
{
return !!(buf[feature>>3] & (1<<(feature&0x7)));
}
static int dbgp_hub_enable(struct ehci_dbg_port *ehci_debug, unsigned int port)
{
const u8 hub_addr = USB_DEBUG_DEVNUM-1;
char status[8];
int ret, loop;
/* Move hub to address 126. */
ret = dbgp_control_msg(ehci_debug, 0,
USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
USB_REQ_SET_ADDRESS, hub_addr, 0, NULL, 0);
if (ret < 0)
goto err;
/* Enter configured state on hub. */
ret = dbgp_control_msg(ehci_debug, hub_addr,
USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
USB_REQ_SET_CONFIGURATION, 1, 0, NULL, 0);
if (ret < 0)
goto err;
/* Set PORT_POWER, poll for PORT_CONNECTION. */
ret = dbgp_control_msg(ehci_debug, hub_addr,
USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_OTHER,
USB_REQ_SET_FEATURE, USB_HUB_PORT_POWER, port, NULL, 0);
if (ret < 0)
goto err;
loop = 100;
do {
dbgp_mdelay(10);
ret = dbgp_control_msg(ehci_debug, hub_addr,
USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_OTHER,
USB_REQ_GET_STATUS, 0, port, status, 4);
if (ret < 0)
goto err;
if (hub_port_status(status, USB_HUB_PORT_CONNECTION))
break;
} while (--loop);
if (! loop)
goto err;
ret = dbgp_control_msg(ehci_debug, hub_addr,
USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_OTHER,
USB_REQ_CLEAR_FEATURE, USB_HUB_C_PORT_CONNECTION, port, NULL, 0);
if (ret < 0)
goto err;
/* Set PORT_RESET, poll for C_PORT_RESET. */
ret = dbgp_control_msg(ehci_debug, hub_addr,
USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_OTHER,
USB_REQ_SET_FEATURE, USB_HUB_PORT_RESET, port, NULL, 0);
if (ret < 0)
goto err;
loop = 100;
do {
dbgp_mdelay(10);
ret = dbgp_control_msg(ehci_debug, hub_addr,
USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_OTHER,
USB_REQ_GET_STATUS, 0, port, status, 4);
if (ret < 0)
goto err;
if (hub_port_status(status, USB_HUB_C_PORT_RESET))
break;
} while (--loop);
if (! loop)
goto err;
ret = dbgp_control_msg(ehci_debug, hub_addr,
USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_OTHER,
USB_REQ_CLEAR_FEATURE, USB_HUB_C_PORT_RESET, port, NULL, 0);
if (ret < 0)
goto err;
if (hub_port_status(status, USB_HUB_PORT_ENABLED))
return 0;
err:
return -1;
}
#endif /* CONFIG_USBDEBUG_OPTIONAL_HUB_PORT */
#if defined(__PRE_RAM__) || !CONFIG_EARLY_CONSOLE #if defined(__PRE_RAM__) || !CONFIG_EARLY_CONSOLE
static void enable_usbdebug(void) static void enable_usbdebug(void)
{ {
@ -640,6 +736,15 @@ try_next_port:
dbgp_mdelay(100); dbgp_mdelay(100);
#if CONFIG_USBDEBUG_OPTIONAL_HUB_PORT
ret = dbgp_hub_enable(ehci_debug, CONFIG_USBDEBUG_OPTIONAL_HUB_PORT);
if (ret < 0) {
dprintk(BIOS_INFO, "Could not enable USB hub on debug port.\n");
ret = -6;
goto err;
}
#endif
/* Find the debug device and make it device number 127 */ /* Find the debug device and make it device number 127 */
devnum = 0; devnum = 0;
debug_dev_retry: debug_dev_retry: