diff options
| -rw-r--r-- | usr/src/uts/common/io/usb/hcd/openhci/ohci.c | 34 | ||||
| -rw-r--r-- | usr/src/uts/common/sys/usb/hcd/openhci/ohci.h | 22 |
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 |
