/***************************************************************************** * * Copyright (C) 2012 Advanced Micro Devices, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Advanced Micro Devices, Inc. nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***************************************************************************/ #include "Platform.h" void usbInitBeforePciEnum(AMDSBCFG* pConfig){ UINT8 dbVar=0; TRACE((DMSG_SB_TRACE, "Entering PreInit Usb \n")); if (pConfig->Usb1Ohci0){ dbVar = (pConfig->Usb1Ehci << 2); dbVar |= ((pConfig->Usb1Ohci0) << 0); dbVar |= ((pConfig->Usb1Ohci1) << 1); RWPCI((SMBUS_BUS_DEV_FUN << 16) + SB_SMBUS_REG68, AccWidthUint8 | S3_SAVE, ~(UINT32)(BIT0+BIT1+BIT2), dbVar ); } if (pConfig->Usb2Ohci0){ dbVar = (pConfig->Usb2Ehci << 6) ; dbVar |= ((pConfig->Usb2Ohci0) << 4); dbVar |= ((pConfig->Usb2Ohci1) << 5); RWPCI((SMBUS_BUS_DEV_FUN << 16) + SB_SMBUS_REG68, AccWidthUint8 | S3_SAVE, ~(UINT32)(BIT6+BIT4+BIT5), dbVar ); } if (pConfig->Usb3Ohci) RWPCI((SMBUS_BUS_DEV_FUN << 16) + SB_SMBUS_REG68, AccWidthUint8 | S3_SAVE, ~(UINT32)(BIT7), ((pConfig->Usb3Ohci) << 7) ); RWPCI((USB1_OHCI0_BUS_DEV_FUN << 16) + SB_OHCI_REG50+1, AccWidthUint16 | S3_SAVE, ~(UINT32)(BIT4), BIT4); } void usbInitAfterPciInit(AMDSBCFG* pConfig){ UINT32 ddBarAddress, ddVar; ReadPCI((USB1_EHCI_BUS_DEV_FUN << 16) + SB_EHCI_REG10, AccWidthUint32, &ddBarAddress);//Get BAR address if ( (ddBarAddress != -1) && (ddBarAddress != 0) ){ //Enable Memory access RWPCI((USB1_EHCI_BUS_DEV_FUN << 16) + SB_EHCI_REG04, AccWidthUint8, 0, BIT1); //USB Common PHY CAL & Control Register setting ddVar = 0x00020F00; WriteMEM(ddBarAddress+SB_EHCI_BAR_REGC0, AccWidthUint32, &ddVar); //RPR - IN AND OUT DATA PACKET FIFO THRESHOLD //EHCI BAR 0xA4 //IN threshold bits[7:0]=0x40 //OUT threshold bits[23:16]=0x40 RWMEM(ddBarAddress+SB_EHCI_BAR_REGA4, AccWidthUint32, 0xFF00FF00, 0x00400040); //RPR - EHCI dynamic clock gating feature //EHCI_BAR 0xBC Bit[12] = 0, For normal operation, the clock gating feature must be disabled. // Disables HS uFrame babble detection for erratum: EHCI_EOR + 9Ch [11] = 1 RWMEM(ddBarAddress+SB_EHCI_BAR_REGBC, AccWidthUint16, ~(UINT32)(BIT12+BIT11), BIT11); } ReadPCI((USB2_EHCI_BUS_DEV_FUN << 16) + SB_EHCI_REG10, AccWidthUint32, &ddBarAddress);//Get BAR address if ( (ddBarAddress != -1) && (ddBarAddress != 0) ){ //Enable Memory access RWPCI((USB2_EHCI_BUS_DEV_FUN << 16) + SB_EHCI_REG04, AccWidthUint8, 0, BIT1); //USB Common PHY CAL & Control Register setting ddVar = 0x00020F00; WriteMEM(ddBarAddress+SB_EHCI_BAR_REGC0, AccWidthUint32, &ddVar); //RPR - IN AND OUT DATA PACKET FIFO THRESHOLD //EHCI BAR 0xA4 //IN threshold bits[7:0]=0x40 //OUT threshold bits[23:16]=0x40 RWMEM(ddBarAddress+SB_EHCI_BAR_REGA4, AccWidthUint32, 0xFF00FF00, 0x00400040); //RPR - EHCI dynamic clock gating feature //EHCI_BAR 0xBC Bit[12] = 0, For normal operation, the clock gating feature must be disabled. // Disables HS uFrame babble detection for erratum: EHCI_EOR + 9Ch [11] = 1 RWMEM(ddBarAddress+SB_EHCI_BAR_REGBC, AccWidthUint16, ~(UINT32)(BIT12+BIT11), BIT11); } if (pConfig->UsbPhyPowerDown) RWPMIO(SB_PMIO_REG65, AccWidthUint8 | S3_SAVE, ~(UINT32)BIT0, BIT0); else RWPMIO(SB_PMIO_REG65, AccWidthUint8 | S3_SAVE, ~(UINT32)BIT0, 0); // Disable the MSI capability of USB host controllers RWPCI((USB1_OHCI0_BUS_DEV_FUN << 16) + SB_OHCI_REG40+1, AccWidthUint8 | S3_SAVE, 0xFF, BIT1+BIT0); RWPCI((USB2_OHCI0_BUS_DEV_FUN << 16) + SB_OHCI_REG40+1, AccWidthUint8 | S3_SAVE, 0xFF, BIT1+BIT0); RWPCI((USB3_OHCI_BUS_DEV_FUN << 16) + SB_OHCI_REG40+1, AccWidthUint8 | S3_SAVE, 0xFF, BIT0); //RPR recommended setting "EHCI Advance Asynchronous Enhancement DISABLE" //Set EHCI_pci_configx50[28]='1' to disable the advance async enhancement feature to avoid the bug found in Linux. //Set EHCI_pci_configx50[6]='1' to disable EHCI MSI support //RPR recommended setting "EHCI Async Park Mode" //Set EHCI_pci_configx50[23]='1' to disable "EHCI Async Park Mode support" // RPR recommended setting "EHCI Advance PHY Power Savings" // Set EHCI_pci_configx50[31]='1' if SB700 A12 & above // Fix for EHCI controller driver yellow sign issue under device manager // when used in conjunction with HSET tool driver. EHCI PCI config 0x50[20]=1 RWPCI((USB1_EHCI_BUS_DEV_FUN << 16) + SB_EHCI_REG50, AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, BIT31+BIT28+BIT23+BIT20+BIT6); RWPCI((USB2_EHCI_BUS_DEV_FUN << 16) + SB_EHCI_REG50, AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, BIT31+BIT28+BIT23+BIT20+BIT6); //RPR recommended setting to, enable fix to cover the corner case S3 wake up issue from some USB 1.1 devices //OHCI 0_PCI_Config 0x50[16] = 1 RWPCI((USB1_OHCI0_BUS_DEV_FUN << 16) + SB_OHCI_REG50+2, AccWidthUint8 | S3_SAVE, 0xFF, BIT0); RWPCI((USB2_OHCI0_BUS_DEV_FUN << 16) + SB_OHCI_REG50+2, AccWidthUint8 | S3_SAVE, 0xFF, BIT0); RWPCI((USB3_OHCI_BUS_DEV_FUN << 16) + SB_OHCI_REG50+2, AccWidthUint8 | S3_SAVE, 0xFF, BIT0); if (getRevisionID() >= SB700_A14){ RWPCI((USB1_EHCI_BUS_DEV_FUN << 16) + SB_EHCI_REG50, AccWidthUint32 | S3_SAVE, ~(UINT32)(BIT28), BIT8+BIT7+BIT4+BIT3); RWPCI((USB2_EHCI_BUS_DEV_FUN << 16) + SB_EHCI_REG50, AccWidthUint32 | S3_SAVE, ~(UINT32)(BIT28), BIT8+BIT7+BIT4+BIT3); RWPCI((USB1_OHCI0_BUS_DEV_FUN << 16) + SB_OHCI_REG50, AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, BIT26+BIT25+BIT17); RWPCI((USB2_OHCI0_BUS_DEV_FUN << 16) + SB_OHCI_REG50, AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, BIT26+BIT25+BIT17); RWPCI((USB3_OHCI_BUS_DEV_FUN << 16) + SB_OHCI_REG50, AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, BIT26+BIT25); } if (getRevisionID() >= SB700_A15) { //USB PID Error checking RWPCI((USB1_EHCI_BUS_DEV_FUN << 16) + SB_EHCI_REG50+1, AccWidthUint8 | S3_SAVE, 0xFF, BIT1); RWPCI((USB2_EHCI_BUS_DEV_FUN << 16) + SB_EHCI_REG50+1, AccWidthUint8 | S3_SAVE, 0xFF, BIT1); } // RPR 6.25 - Optionally disable OHCI isochronous out prefetch if (pConfig->OhciIsoOutPrefetchDis) { RWPCI((USB1_OHCI0_BUS_DEV_FUN << 16) + SB_OHCI_REG50, AccWidthUint16 | S3_SAVE, ~(UINT32)(BIT9 + BIT8), 0); RWPCI((USB2_OHCI0_BUS_DEV_FUN << 16) + SB_OHCI_REG50, AccWidthUint16 | S3_SAVE, ~(UINT32)(BIT9 + BIT8), 0); RWPCI((USB3_OHCI_BUS_DEV_FUN << 16) + SB_OHCI_REG50, AccWidthUint16 | S3_SAVE, ~(UINT32)(BIT9 + BIT8), 0); } if ( pConfig->EhciDataCacheDis ) { // Disable Async Data Cache, EHCI_pci_configx50[26]='1' RWPCI ((USB1_EHCI_BUS_DEV_FUN << 16) + SB_EHCI_REG50, AccWidthUint32 | S3_SAVE, ~(UINT32)BIT26, BIT26); RWPCI ((USB2_EHCI_BUS_DEV_FUN << 16) + SB_EHCI_REG50, AccWidthUint32 | S3_SAVE, ~(UINT32)BIT26, BIT26); } } void usbInitMidPost(AMDSBCFG* pConfig){ if (pConfig->UsbOhciLegacyEmulation == 0){ RWPCI((SMBUS_BUS_DEV_FUN << 16) + SB_SMBUS_REG60+2, AccWidthUint8 | S3_SAVE, 0xFF, BIT1+BIT0); RWPCI((SMBUS_BUS_DEV_FUN << 16) + SB_SMBUS_REG64+3, AccWidthUint8 | S3_SAVE, 0xFF, BIT7); } else{ programOhciMmioForEmulation(); } } void programOhciMmioForEmulation(void){ UINT32 ddBarAddress; ReadPCI((USB1_OHCI0_BUS_DEV_FUN << 16) + SB_OHCI_REG10, AccWidthUint32, &ddBarAddress);//Get BAR address ddBarAddress &= 0xFFFFF000; if ( (ddBarAddress != 0xFFFFF000) && (ddBarAddress != 0) ){ //Enable Memory access RWPCI((USB1_OHCI0_BUS_DEV_FUN << 16) + SB_OHCI_REG04, AccWidthUint8, 0, BIT1); RWMEM(ddBarAddress+SB_OHCI_BAR_REG160, AccWidthUint32, 0, 0); } ReadPCI((USB2_OHCI0_BUS_DEV_FUN << 16) + SB_OHCI_REG10, AccWidthUint32, &ddBarAddress);//Get BAR address ddBarAddress &= 0xFFFFF000; if ( (ddBarAddress != 0xFFFFF000) && (ddBarAddress != 0) ){ //Enable Memory access RWPCI((USB2_OHCI0_BUS_DEV_FUN << 16) + SB_OHCI_REG04, AccWidthUint8, 0, BIT1); RWMEM(ddBarAddress+SB_OHCI_BAR_REG160, AccWidthUint32, 0, 0); } ReadPCI((USB3_OHCI_BUS_DEV_FUN << 16) + SB_OHCI_REG10, AccWidthUint32, &ddBarAddress);//Get BAR address if ( (ddBarAddress != 0xFFFFF000) && (ddBarAddress != 0) ){ //Enable Memory access RWPCI((USB3_OHCI_BUS_DEV_FUN << 16) + SB_OHCI_REG04, AccWidthUint8, 0, BIT1); RWMEM(ddBarAddress+SB_OHCI_BAR_REG160, AccWidthUint32, 0, 0); } }