Browse Source

[xhci] Enable USB3 ports on Intel PCH8/PCH9 controllers

Intel PCH controllers default to routing USB2 ports to EHCI rather
than xHCI, and default to disabling SuperSpeed connections.
Manipulate the PCI configuration space registers as necessary to
reroute ports and enable SuperSpeed.

Originally-fixed-by: Dan Ellis <Dan.Ellis@displaylink.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 10 years ago
parent
commit
ff320404d5
2 changed files with 55 additions and 0 deletions
  1. 40
    0
      src/drivers/usb/xhci.c
  2. 15
    0
      src/drivers/usb/xhci.h

+ 40
- 0
src/drivers/usb/xhci.c View File

3013
 	},
3013
 	},
3014
 };
3014
 };
3015
 
3015
 
3016
+/**
3017
+ * Fix Intel PCH-specific quirks
3018
+ *
3019
+ * @v xhci		xHCI device
3020
+ * @v pci		PCI device
3021
+ */
3022
+static void xhci_pch ( struct xhci_device *xhci, struct pci_device *pci ) {
3023
+	uint32_t xusb2pr;
3024
+	uint32_t xusb2prm;
3025
+	uint32_t usb3pssen;
3026
+	uint32_t usb3prm;
3027
+
3028
+	/* Enable SuperSpeed capability.  Do this before rerouting
3029
+	 * USB2 ports, so that USB3 devices connect at SuperSpeed.
3030
+	 */
3031
+	pci_read_config_dword ( pci, XHCI_PCH_USB3PSSEN, &usb3pssen );
3032
+	pci_read_config_dword ( pci, XHCI_PCH_USB3PRM, &usb3prm );
3033
+	if ( usb3prm & ~usb3pssen ) {
3034
+		DBGC ( xhci, "XHCI %p enabling SuperSpeed on ports %08x\n",
3035
+		       xhci, ( usb3prm & ~usb3pssen ) );
3036
+	}
3037
+	usb3pssen |= usb3prm;
3038
+	pci_write_config_dword ( pci, XHCI_PCH_USB3PSSEN, usb3pssen );
3039
+
3040
+	/* Route USB2 ports from EHCI to xHCI */
3041
+	pci_read_config_dword ( pci, XHCI_PCH_XUSB2PR, &xusb2pr );
3042
+	pci_read_config_dword ( pci, XHCI_PCH_XUSB2PRM, &xusb2prm );
3043
+	if ( xusb2prm & ~xusb2pr ) {
3044
+		DBGC ( xhci, "XHCI %p routing ports %08x from EHCI to xHCI\n",
3045
+		       xhci, ( xusb2prm & ~xusb2pr ) );
3046
+	}
3047
+	xusb2pr |= xusb2prm;
3048
+	pci_write_config_dword ( pci, XHCI_PCH_XUSB2PR, xusb2pr );
3049
+}
3050
+
3016
 /**
3051
 /**
3017
  * Probe PCI device
3052
  * Probe PCI device
3018
  *
3053
  *
3054
 	if ( ( rc = xhci_legacy_claim ( xhci ) ) != 0 )
3089
 	if ( ( rc = xhci_legacy_claim ( xhci ) ) != 0 )
3055
 		goto err_legacy_claim;
3090
 		goto err_legacy_claim;
3056
 
3091
 
3092
+	/* Fix Intel PCH-specific quirks, if applicable */
3093
+	if ( pci->id->driver_data & XHCI_PCH )
3094
+		xhci_pch ( xhci, pci );
3095
+
3057
 	/* Reset device */
3096
 	/* Reset device */
3058
 	if ( ( rc = xhci_reset ( xhci ) ) != 0 )
3097
 	if ( ( rc = xhci_reset ( xhci ) ) != 0 )
3059
 		goto err_reset;
3098
 		goto err_reset;
3115
 
3154
 
3116
 /** XHCI PCI device IDs */
3155
 /** XHCI PCI device IDs */
3117
 static struct pci_device_id xhci_ids[] = {
3156
 static struct pci_device_id xhci_ids[] = {
3157
+	PCI_ROM ( 0x8086, 0xffff, "xhci-pch", "xHCI (Intel PCH)", XHCI_PCH ),
3118
 	PCI_ROM ( 0xffff, 0xffff, "xhci", "xHCI", 0 ),
3158
 	PCI_ROM ( 0xffff, 0xffff, "xhci", "xHCI", 0 ),
3119
 };
3159
 };
3120
 
3160
 

+ 15
- 0
src/drivers/usb/xhci.h View File

1103
 	struct xhci_trb_ring ring;
1103
 	struct xhci_trb_ring ring;
1104
 };
1104
 };
1105
 
1105
 
1106
+/** Intel PCH quirk */
1107
+#define XHCI_PCH 0x0001
1108
+
1109
+/** Intel PCH USB2 port routing register */
1110
+#define XHCI_PCH_XUSB2PR 0xd0
1111
+
1112
+/** Intel PCH USB2 port routing mask register */
1113
+#define XHCI_PCH_XUSB2PRM 0xd4
1114
+
1115
+/** Intel PCH USB3 port SuperSpeed enable register */
1116
+#define XHCI_PCH_USB3PSSEN 0xd8
1117
+
1118
+/** Intel PCH USB3 port routing mask register */
1119
+#define XHCI_PCH_USB3PRM 0xdc
1120
+
1106
 #endif /* _IPXE_XHCI_H */
1121
 #endif /* _IPXE_XHCI_H */

Loading…
Cancel
Save