Skip to content
Snippets Groups Projects
Commit 5624dfd5 authored by Bin Meng's avatar Bin Meng Committed by Marek Vasut
Browse files

usb: hub: Parse and save TT details from device descriptor


A high speed hub has a special responsibility to handle full speed/
low speed devices connected on downstream ports. In this case, the
hub must isolate the high speed signaling environment from the full
speed/low speed signaling environment with the help of Transaction
Translator (TT). TT details are provided by hub descriptors and we
parse and save it to hub uclass_priv for later use.

Signed-off-by: default avatarBin Meng <bmeng.cn@gmail.com>
Reviewed-by: default avatarSimon Glass <sjg@chromium.org>
parent 493b8dd0
No related branches found
No related tags found
No related merge requests found
...@@ -700,6 +700,56 @@ static int usb_hub_configure(struct usb_device *dev) ...@@ -700,6 +700,56 @@ static int usb_hub_configure(struct usb_device *dev)
break; break;
} }
switch (dev->descriptor.bDeviceProtocol) {
case USB_HUB_PR_FS:
break;
case USB_HUB_PR_HS_SINGLE_TT:
debug("Single TT\n");
break;
case USB_HUB_PR_HS_MULTI_TT:
ret = usb_set_interface(dev, 0, 1);
if (ret == 0) {
debug("TT per port\n");
hub->tt.multi = true;
} else {
debug("Using single TT (err %d)\n", ret);
}
break;
case USB_HUB_PR_SS:
/* USB 3.0 hubs don't have a TT */
break;
default:
debug("Unrecognized hub protocol %d\n",
dev->descriptor.bDeviceProtocol);
break;
}
/* Note 8 FS bit times == (8 bits / 12000000 bps) ~= 666ns */
switch (hubCharacteristics & HUB_CHAR_TTTT) {
case HUB_TTTT_8_BITS:
if (dev->descriptor.bDeviceProtocol != 0) {
hub->tt.think_time = 666;
debug("TT requires at most %d FS bit times (%d ns)\n",
8, hub->tt.think_time);
}
break;
case HUB_TTTT_16_BITS:
hub->tt.think_time = 666 * 2;
debug("TT requires at most %d FS bit times (%d ns)\n",
16, hub->tt.think_time);
break;
case HUB_TTTT_24_BITS:
hub->tt.think_time = 666 * 3;
debug("TT requires at most %d FS bit times (%d ns)\n",
24, hub->tt.think_time);
break;
case HUB_TTTT_32_BITS:
hub->tt.think_time = 666 * 4;
debug("TT requires at most %d FS bit times (%d ns)\n",
32, hub->tt.think_time);
break;
}
debug("power on to power good time: %dms\n", debug("power on to power good time: %dms\n",
descriptor->bPwrOn2PwrGood * 2); descriptor->bPwrOn2PwrGood * 2);
debug("hub controller current requirement: %dmA\n", debug("hub controller current requirement: %dmA\n",
......
...@@ -537,6 +537,21 @@ struct usb_hub_status { ...@@ -537,6 +537,21 @@ struct usb_hub_status {
unsigned short wHubChange; unsigned short wHubChange;
} __attribute__ ((packed)); } __attribute__ ((packed));
/*
* Hub Device descriptor
* USB Hub class device protocols
*/
#define USB_HUB_PR_FS 0 /* Full speed hub */
#define USB_HUB_PR_HS_NO_TT 0 /* Hi-speed hub without TT */
#define USB_HUB_PR_HS_SINGLE_TT 1 /* Hi-speed hub with single TT */
#define USB_HUB_PR_HS_MULTI_TT 2 /* Hi-speed hub with multiple TT */
#define USB_HUB_PR_SS 3 /* Super speed hub */
/* Transaction Translator Think Times, in bits */
#define HUB_TTTT_8_BITS 0x00
#define HUB_TTTT_16_BITS 0x20
#define HUB_TTTT_24_BITS 0x40
#define HUB_TTTT_32_BITS 0x60
/* Hub descriptor */ /* Hub descriptor */
struct usb_hub_descriptor { struct usb_hub_descriptor {
...@@ -571,6 +586,7 @@ struct usb_hub_device { ...@@ -571,6 +586,7 @@ struct usb_hub_device {
ulong query_delay; /* Device query delay in ms */ ulong query_delay; /* Device query delay in ms */
int overcurrent_count[USB_MAXCHILDREN]; /* Over-current counter */ int overcurrent_count[USB_MAXCHILDREN]; /* Over-current counter */
int hub_depth; /* USB 3.0 hub depth */ int hub_depth; /* USB 3.0 hub depth */
struct usb_tt tt; /* Transaction Translator */
}; };
#ifdef CONFIG_DM_USB #ifdef CONFIG_DM_USB
......
...@@ -293,6 +293,7 @@ ...@@ -293,6 +293,7 @@
#define HUB_CHAR_LPSM 0x0003 #define HUB_CHAR_LPSM 0x0003
#define HUB_CHAR_COMPOUND 0x0004 #define HUB_CHAR_COMPOUND 0x0004
#define HUB_CHAR_OCPM 0x0018 #define HUB_CHAR_OCPM 0x0018
#define HUB_CHAR_TTTT 0x0060 /* TT Think Time mask */
/* /*
* Hub Status & Hub Change bit masks * Hub Status & Hub Change bit masks
...@@ -309,6 +310,17 @@ ...@@ -309,6 +310,17 @@
/* Hub class request codes */ /* Hub class request codes */
#define USB_REQ_SET_HUB_DEPTH 0x0c #define USB_REQ_SET_HUB_DEPTH 0x0c
/*
* As of USB 2.0, full/low speed devices are segregated into trees.
* One type grows from USB 1.1 host controllers (OHCI, UHCI etc).
* The other type grows from high speed hubs when they connect to
* full/low speed devices using "Transaction Translators" (TTs).
*/
struct usb_tt {
bool multi; /* true means one TT per port */
unsigned think_time; /* think time in ns */
};
/* /*
* CBI style * CBI style
*/ */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment