summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/uts/common/io/usb/hcd/openhci/ohci.c34
-rw-r--r--usr/src/uts/common/sys/usb/hcd/openhci/ohci.h22
2 files changed, 55 insertions, 1 deletions
diff --git a/usr/src/uts/common/io/usb/hcd/openhci/ohci.c b/usr/src/uts/common/io/usb/hcd/openhci/ohci.c
index 2e717d7fe0..1579aaa48b 100644
--- a/usr/src/uts/common/io/usb/hcd/openhci/ohci.c
+++ b/usr/src/uts/common/io/usb/hcd/openhci/ohci.c
@@ -1373,6 +1373,22 @@ ohci_init_ctlr(ohci_state_t *ohcip)
}
}
+ /*
+ * Workaround for ULI1575 chipset. Following OHCI Operational Memory
+ * Registers are not cleared to their default value on reset.
+ * Explicitly set the registers to default value.
+ */
+ if (ohcip->ohci_vendor_id == PCI_ULI1575_VENID &&
+ ohcip->ohci_device_id == PCI_ULI1575_DEVID) {
+ Set_OpReg(hcr_control, HCR_CONTROL_DEFAULT);
+ Set_OpReg(hcr_intr_enable, HCR_INT_ENABLE_DEFAULT);
+ Set_OpReg(hcr_HCCA, HCR_HCCA_DEFAULT);
+ Set_OpReg(hcr_ctrl_head, HCR_CONTROL_HEAD_ED_DEFAULT);
+ Set_OpReg(hcr_bulk_head, HCR_BULK_HEAD_ED_DEFAULT);
+ Set_OpReg(hcr_frame_interval, HCR_FRAME_INTERVAL_DEFAULT);
+ Set_OpReg(hcr_periodic_strt, HCR_PERIODIC_START_DEFAULT);
+ }
+
/* Set the HcHCCA to the physical address of the HCCA block */
Set_OpReg(hcr_HCCA, (uint_t)ohcip->ohci_hcca_cookie.dmac_address);
@@ -1852,6 +1868,24 @@ ohci_cleanup(ohci_state_t *ohcip)
/* Wait for sometime */
drv_usecwait(OHCI_TIMEWAIT);
+ /*
+ * Workaround for ULI1575 chipset. Following OHCI Operational
+ * Memory Registers are not cleared to their default value
+ * on reset. Explicitly set the registers to default value.
+ */
+ if (ohcip->ohci_vendor_id == PCI_ULI1575_VENID &&
+ ohcip->ohci_device_id == PCI_ULI1575_DEVID) {
+ Set_OpReg(hcr_control, HCR_CONTROL_DEFAULT);
+ Set_OpReg(hcr_intr_enable, HCR_INT_ENABLE_DEFAULT);
+ Set_OpReg(hcr_HCCA, HCR_HCCA_DEFAULT);
+ Set_OpReg(hcr_ctrl_head, HCR_CONTROL_HEAD_ED_DEFAULT);
+ Set_OpReg(hcr_bulk_head, HCR_BULK_HEAD_ED_DEFAULT);
+ Set_OpReg(hcr_frame_interval,
+ HCR_FRAME_INTERVAL_DEFAULT);
+ Set_OpReg(hcr_periodic_strt,
+ HCR_PERIODIC_START_DEFAULT);
+ }
+
mutex_exit(&ohcip->ohci_int_mutex);
/* disable interrupt */
diff --git a/usr/src/uts/common/sys/usb/hcd/openhci/ohci.h b/usr/src/uts/common/sys/usb/hcd/openhci/ohci.h
index 864042d2ad..c7edb2c51c 100644
--- a/usr/src/uts/common/sys/usb/hcd/openhci/ohci.h
+++ b/usr/src/uts/common/sys/usb/hcd/openhci/ohci.h
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -100,6 +100,26 @@ extern "C" {
#define OHCI_DMA_ATTR_HCCA_ALIGNMENT 0x100
/*
+ * Vendor id and Device id for ULI1575 southbridge.
+ */
+#define PCI_ULI1575_VENID 0x10B9
+#define PCI_ULI1575_DEVID 0x5237
+
+/*
+ * Need a workaround for ULI1575 chipset. Following OHCI
+ * Operational Memory Registers are not cleared to their
+ * default value on reset. Explicitly set the registers
+ * to default value after reset.
+ */
+#define HCR_CONTROL_DEFAULT 0x0
+#define HCR_INT_ENABLE_DEFAULT 0x0
+#define HCR_HCCA_DEFAULT 0x0
+#define HCR_CONTROL_HEAD_ED_DEFAULT 0x0
+#define HCR_BULK_HEAD_ED_DEFAULT 0x0
+#define HCR_FRAME_INTERVAL_DEFAULT 0x2edf
+#define HCR_PERIODIC_START_DEFAULT 0x0
+
+/*
* OpenHCI Operational Registers
*
* The Host Controller (HC) contains a set of on-chip operational registers