libpayload/usb: add USB 3.1 GEN2 support

USB 3.1 GEN2 report speed type 4, add into speed enum.

BUG=b:139787920
BRANCH=N/A
TEST=Build libpayload and depthcharge on sarien and boot with
USB GEN2 HUB with USB disk. Check ultra speed device in cbmem log.

Signed-off-by: Eric Lai <ericr_lai@compal.corp-partner.google.com>
Change-Id: Ia0ef12b2f0d91bf0d0db766bbc9019de1614a4f4
Reviewed-on: https://review.coreboot.org/c/coreboot/+/35023
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/payloads/libpayload/drivers/usb/usb.c b/payloads/libpayload/drivers/usb/usb.c
index 9c9854d..4004def 100644
--- a/payloads/libpayload/drivers/usb/usb.c
+++ b/payloads/libpayload/drivers/usb/usb.c
@@ -265,6 +265,8 @@
 		}
 		return bMaxPacketSize0;
 	case SUPER_SPEED:
+	/* Intentional fallthrough */
+	case SUPER_SPEED_PLUS:
 		if (bMaxPacketSize0 != 9) {
 			usb_debug("Invalid MPS0: 0x%02x\n", bMaxPacketSize0);
 			bMaxPacketSize0 = 9;
@@ -284,6 +286,8 @@
 	case HIGH_SPEED:
 		return 64;
 	case SUPER_SPEED:
+	/* Intentional fallthrough */
+	case SUPER_SPEED_PLUS:
 	default:
 		return 512;
 	}
@@ -319,6 +323,8 @@
 			return LOG2(bInterval);
 		}
 	case SUPER_SPEED:
+	/* Intentional fallthrough */
+	case SUPER_SPEED_PLUS:
 		switch (type) {
 		case ISOCHRONOUS: case INTERRUPT:
 			return bInterval - 1;
@@ -657,7 +663,7 @@
 int
 usb_attach_device(hci_t *controller, int hubaddress, int port, usb_speed speed)
 {
-	static const char* speeds[] = { "full", "low", "high", "super" };
+	static const char *speeds[] = { "full", "low", "high", "super", "ultra" };
 	usb_debug ("%sspeed device\n", (speed < sizeof(speeds) / sizeof(char*))
 		? speeds[speed] : "invalid value - no");
 	int newdev = set_address (controller, speed, port, hubaddress);
@@ -693,6 +699,14 @@
 }
 
 /*
+ * returns the speed is above SUPER_SPEED or not
+ */
+_Bool is_usb_speed_ss(usb_speed speed)
+{
+	return (speed == SUPER_SPEED || speed == SUPER_SPEED_PLUS);
+}
+
+/*
  * returns the address of the closest USB2.0 hub, which is responsible for
  * split transactions, along with the number of the used downstream port
  */
diff --git a/payloads/libpayload/drivers/usb/usbhub.c b/payloads/libpayload/drivers/usb/usbhub.c
index 340e47a..78643c0 100644
--- a/payloads/libpayload/drivers/usb/usbhub.c
+++ b/payloads/libpayload/drivers/usb/usbhub.c
@@ -96,8 +96,8 @@
 	int ret = get_status (dev, port, DR_PORT, sizeof(buf), buf);
 	if (ret >= 0 && (buf[0] & PORT_ENABLE)) {
 		/* SuperSpeed hubs can only have SuperSpeed devices. */
-		if (dev->speed == SUPER_SPEED)
-			return SUPER_SPEED;
+		if (is_usb_speed_ss(dev->speed))
+			return dev->speed;
 
 		/*[bit] 10  9  (USB 2.0 port status word)
 		 *      0   0  full speed
@@ -176,7 +176,7 @@
 void
 usb_hub_init(usbdev_t *const dev)
 {
-	int type = dev->speed == SUPER_SPEED ? 0x2a : 0x29; /* similar enough */
+	int type = is_usb_speed_ss(dev->speed) ? 0x2a : 0x29; /* similar enough */
 	hub_descriptor_t desc;	/* won't fit the whole thing, we don't care */
 	if (get_descriptor(dev, gen_bmRequestType(device_to_host, class_type,
 		dev_recp), type, 0, &desc, sizeof(desc)) != sizeof(desc)) {
@@ -185,7 +185,7 @@
 		return;
 	}
 
-	if (dev->speed == SUPER_SPEED)
+	if (is_usb_speed_ss(dev->speed))
 		usb_hub_set_hub_depth(dev);
 	if (generic_hub_init(dev, desc.bNbrPorts, &usb_hub_ops) < 0)
 		return;
diff --git a/payloads/libpayload/drivers/usb/xhci_devconf.c b/payloads/libpayload/drivers/usb/xhci_devconf.c
index 99e3037..3f50caa 100644
--- a/payloads/libpayload/drivers/usb/xhci_devconf.c
+++ b/payloads/libpayload/drivers/usb/xhci_devconf.c
@@ -267,7 +267,7 @@
 static int
 xhci_finish_hub_config(usbdev_t *const dev, inputctx_t *const ic)
 {
-	int type = dev->speed == SUPER_SPEED ? 0x2a : 0x29; /* similar enough */
+	int type = is_usb_speed_ss(dev->speed) ? 0x2a : 0x29; /* similar enough */
 	hub_descriptor_t desc;
 
 	if (get_descriptor(dev, gen_bmRequestType(device_to_host, class_type,
diff --git a/payloads/libpayload/include/usb/usb.h b/payloads/libpayload/include/usb/usb.h
index db7ec57..8505c4f 100644
--- a/payloads/libpayload/include/usb/usb.h
+++ b/payloads/libpayload/include/usb/usb.h
@@ -210,6 +210,7 @@
 	LOW_SPEED = 1,
 	HIGH_SPEED = 2,
 	SUPER_SPEED = 3,
+	SUPER_SPEED_PLUS = 4,
 } usb_speed;
 
 struct usbdev {
@@ -293,6 +294,7 @@
 int set_configuration (usbdev_t *dev);
 int clear_feature (usbdev_t *dev, int endp, int feature, int rtype);
 int clear_stall (endpoint_t *ep);
+_Bool is_usb_speed_ss(usb_speed speed);
 
 void usb_nop_init (usbdev_t *dev);
 void usb_hub_init (usbdev_t *dev);