Signed-off-by: Joe Lee
---
drivers/usb/host/pci-quirks.c | 128 ++
drivers/usb/host/pci-quirks.h | 5 ++
drivers/usb/host/xhci-hub.c | 7 +++
drivers/usb/host/xhci-pci.c | 11
drivers/usb/host/xhci.h | 2 +-
5 files changed, 152 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 6dda362..d66a2c6 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -65,6 +65,23 @@
#defineAX_INDXC0x30
#defineAX_DATAC0x34
+#define PT_ADDR_INDX 0xE8
+#define PT_READ_INDX 0xE4
+#define PT_SIG_1_ADDR 0xA520
+#define PT_SIG_2_ADDR 0xA521
+#define PT_SIG_3_ADDR 0xA522
+#define PT_SIG_4_ADDR 0xA523
+#define PT_SIG_1_DATA 0x78
+#define PT_SIG_2_DATA 0x56
+#define PT_SIG_3_DATA 0x34
+#define PT_SIG_4_DATA 0x12
+#define PT4_P1_REG 0xB521
+#define PT4_P2_REG 0xB522
+#define PT2_P1_REG 0xD520
+#define PT2_P2_REG 0xD521
+#define PT1_P1_REG 0xD522
+#define PT1_P2_REG 0xD523
+
#defineNB_PCIE_INDX_ADDR 0xe0
#defineNB_PCIE_INDX_DATA 0xe4
#definePCIE_P_CNTL 0x10040
@@ -511,6 +528,117 @@ void usb_amd_dev_put(void)
}
EXPORT_SYMBOL_GPL(usb_amd_dev_put);
+bool usb_amd_pt_check_port(struct device *device, int port)
+{
+ unsigned char value;
+ struct pci_dev *pdev;
+
+ pdev = to_pci_dev(device);
+ pci_write_config_word(pdev, PT_ADDR_INDX, PT_SIG_1_ADDR);
+
+ pci_read_config_byte(pdev, PT_READ_INDX, );
+ if (value != PT_SIG_1_DATA)
+ return 0;
+
+ pci_write_config_word(pdev, PT_ADDR_INDX, PT_SIG_2_ADDR);
+
+ pci_read_config_byte(pdev, PT_READ_INDX, );
+ if (value != PT_SIG_2_DATA)
+ return 0;
+
+ pci_write_config_word(pdev, PT_ADDR_INDX, PT_SIG_3_ADDR);
+
+ pci_read_config_byte(pdev, PT_READ_INDX, );
+ if (value != PT_SIG_3_DATA)
+ return 0;
+
+ pci_write_config_word(pdev, PT_ADDR_INDX, PT_SIG_4_ADDR);
+
+ pci_read_config_byte(pdev, PT_READ_INDX, );
+ if (value != PT_SIG_4_DATA)
+ return 0;
+
+ if ((pdev->device == 0x43b9) || (pdev->device == 0x43ba)) {
+ /* device is AMD_PROMONTORYA_4(0x43b9) or
+* PROMONTORYA_3(0x43ba)
+* disable port setting
+* PT_4_P1_REG[7..1] is USB2.0 port6 to 0
+* PT4_P2_REG[6..0] is USB 13 to port 7
+* 0 : disable ;1 : enable
+*/
+ if (port > 6) {
+ pci_write_config_word(pdev, PT_ADDR_INDX,
+ PT4_P2_REG);
+
+ pci_read_config_byte(pdev, PT_READ_INDX, );
+ if (value & (1<<(port - 7)))
+ return 0;
+ else
+ return 1;
+ } else {
+ pci_write_config_word(pdev, PT_ADDR_INDX,
+ PT4_P1_REG);
+
+ pci_read_config_byte(pdev, PT_READ_INDX, );
+ if (value & (1<<(port + 1)))
+ return 0;
+ else
+ return 1;
+ }
+ } else if (pdev->device == 0x43bb) {
+ /* device is AMD_PROMONTORYA_2(0x43bb)
+* disable port setting
+* PT2_P1_REG[7..5] is USB2.0 port2 to 0
+* PT2_P2_REG[5..0] is USB 9 to port3
+* 0 : disable ;1 : enable
+*/
+ if (port > 2) {
+ pci_write_config_word(pdev, PT_ADDR_INDX, PT2_P2_REG);
+
+ pci_read_config_byte(pdev, PT_READ_INDX, );
+ if (value & (1<<(port - 3)))
+ return 0;
+ else
+ return 1;
+ } else {
+ pci_write_config_word(pdev, PT_ADDR_INDX, PT2_P1_REG);
+
+ pci_read_config_byte(pdev, PT_READ_INDX, );
+ if (value & (1<<(port + 5)))
+ return 0;
+ else
+ return 1;
+ }
+ } else {
+ /* device is AMD_PROMONTORYA_1(0x43bc)
+* disable port setting
+* PT1_P1_REG[7..4] is USB2.0 port3 to 0
+* PT1_P2_REG[5..0] is USB 9 to port4
+* 0 : disable ;1 : enable
+*/
+ if (port > 3) {
+ pci_write_config_word(pdev, PT_ADDR_INDX, PT1_P2_REG);
+
+