| /***************************************************************************** |
| * |
| * 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); |
| } |
| } |