/** * gecInitAfterPciEnum - Config GEC controller after PCI emulation * * * * @param[in] pConfig Southbridge configuration structure pointer. * */ VOID gecInitAfterPciEnum ( IN AMDSBCFG* pConfig ) { VOID* GecRomAddress; VOID* GecShadowRomAddress; UINT32 ddTemp; UINT8 dbVar; UINT8 dbTemp; if ( pConfig->GecConfig == 0) { dbVar = 0; ReadPCI ((GEC_BUS_DEV_FUN << 16) + SB_GEC_REG04, AccWidthUint8, &dbVar); dbTemp = 0x07; WritePCI ((GEC_BUS_DEV_FUN << 16) + SB_GEC_REG04, AccWidthUint8, &dbTemp); if ( !pConfig->DYNAMICGECROM.DynamicGecRomAddress_Ptr == NULL ) { GecRomAddress = pConfig->DYNAMICGECROM.DynamicGecRomAddress_Ptr; GecShadowRomAddress = (VOID*) (UINTN) pConfig->BuildParameters.GecShadowRomBase; AmdSbCopyMem (GecShadowRomAddress, GecRomAddress, 0x100); ReadPCI ((GEC_BUS_DEV_FUN << 16) + SB_GEC_REG10, AccWidthUint32, &ddTemp); ddTemp = ddTemp & 0xFFFFFFF0; RWMEM (ddTemp + 0x6804, AccWidthUint32, 0, BIT0 + BIT29); } WritePCI ((GEC_BUS_DEV_FUN << 16) + SB_GEC_REG04, AccWidthUint8, &dbVar); } }
/** * sbFindPciCap - Find PCI Cap * * * @param[in] pciAddress PCI Address. * @param[in] targetCapId Target Cap ID. * */ UINT8 sbFindPciCap ( IN UINT32 pciAddress, IN UINT8 targetCapId ) { UINT8 NextCapPtr; UINT8 CapId; NextCapPtr = 0x34; while (NextCapPtr != 0) { ReadPCI (pciAddress + NextCapPtr, AccWidthUint8, &NextCapPtr); if (NextCapPtr == 0xff) { return 0; } if (NextCapPtr != 0) { ReadPCI (pciAddress + NextCapPtr, AccWidthUint8, &CapId); if (CapId == targetCapId) { break; } else { NextCapPtr++; } } } return NextCapPtr; }
/*++ Routine Description: SATA Late Configuration if the mode is selected as IDE->AHCI { 1. Set class ID to AHCI 2. Enable AHCI interrupt } Arguments: pConfig - SBconfiguration Returns: void --*/ void sataInitLatePost(AMDSBCFG* pConfig){ UINT32 ddBar5; UINT8 dbVar; //Return immediately is sata controller is not enabled if (pConfig->SataController == 0) return; restrictSataCapabilities(pConfig); //Get BAR5 value ReadPCI( ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG24), AccWidthUint32, &ddBar5); //Assign temporary BAR if is not already assigned if ( (ddBar5 == 0) || (ddBar5 == -1) ){ //assign temporary BAR5 if ( (pConfig->TempMMIO == 0) || (pConfig->TempMMIO == -1)) ddBar5 = 0xFEC01000; else ddBar5=pConfig->TempMMIO; WritePCI( ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG24), AccWidthUint32, &ddBar5); } ReadPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG04), AccWidthUint8, &dbVar); //Enable memory and io access RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG04), AccWidthUint8, 0xFF, 0x03); //Enable write access to pci header, pm capabilities RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40), AccWidthUint8 | S3_SAVE, 0xff, BIT0); shutdownUnconnectedSataPortClock(pConfig, ddBar5); if ( (pConfig->SataClass == IDE_TO_AHCI_MODE) || (pConfig->SataClass == IDE_TO_AMD_AHCI_MODE)){ //program the AHCI class code RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG08), AccWidthUint32 | S3_SAVE, 0, 0x01060100); //Set interrupt enable bit RWMEM((ddBar5 + 0x04),AccWidthUint8,~(UINT32)0,BIT1); //program the correct device id for AHCI mode RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG02), AccWidthUint16 | S3_SAVE, 0, 0x4391); if (pConfig->SataClass == IDE_TO_AMD_AHCI_MODE) //program the correct device id for AMD-AHCI mode RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40 + 3), AccWidthUint8 | S3_SAVE, 0xFF, BIT0); } //Disable write access to pci header and pm capabilities RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40), AccWidthUint8 | S3_SAVE, ~(UINT32)BIT0, 0); //Clear error status RWMEM((ddBar5 + SB_SATA_BAR5_REG130),AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, 0xFFFFFFFF); RWMEM((ddBar5 + SB_SATA_BAR5_REG1B0),AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, 0xFFFFFFFF); RWMEM((ddBar5 + SB_SATA_BAR5_REG230),AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, 0xFFFFFFFF); RWMEM((ddBar5 + SB_SATA_BAR5_REG2B0),AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, 0xFFFFFFFF); //Restore memory and io access bits WritePCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG04), AccWidthUint8, &dbVar ); }
static U32 FindHECIDevice( void ) { U32 uAddr, uBus, uDev, uFunc, uDevId, uSearchId; for( uBus = 0; uBus < 256; uBus++ ) { for( uDev = 0; uDev < 32; uDev++ ) { for( uFunc = 0; uFunc < 8; uFunc++ ) { for ( uDevId = 0; uDevId < NumHECIPCIDevIds; uDevId++ ) { uSearchId = PCI_INTEL_VENDOR_ID | (HECIPCIDevIds[uDevId] << 16); uAddr = 0x80000000 | (uBus << 16) | (uDev << 11) | (uFunc << 8 ); if( ReadPCI( uAddr ) == uSearchId ) return( uAddr ); } } } } return( 0 ); }
/** * Read Southbridge Revision ID cie Base * * * @retval 0xXXXXXXXX Revision ID * */ UINT8 getRevisionID ( OUT VOID ) { UINT8 dbVar0; ReadPCI (((SMBUS_BUS_DEV_FUN << 16) + SB_CFG_REG08), AccWidthUint8, &dbVar0); return dbVar0; }
void ExitEcConfig() { UINT16 dwEcIndexPort; ReadPCI((LPC_BUS_DEV_FUN << 16) + SB_LPC_REGA4, AccWidthUint16 | S3_SAVE, &dwEcIndexPort); dwEcIndexPort &= ~(UINT16)(BIT0); RWIO(dwEcIndexPort, AccWidthUint8, 0x00, 0xA5); }
void sataDriveDetection(AMDSBCFG* pConfig, UINT32 ddBar5){ UINT32 ddVar0; UINT8 dbPortNum, dbVar0; UINT32 dwIoBase, dwVar0; TRACE((DMSG_SB_TRACE, "CIMx - Entering sata drive detection procedure\n\n")); TRACE((DMSG_SB_TRACE, "SATA BAR5 is %X \n", ddBar5)); if ( (pConfig->SataClass == NATIVE_IDE_MODE) || (pConfig->SataClass == LEGACY_IDE_MODE) || (pConfig->SataClass == IDE_TO_AHCI_MODE) || (pConfig->SataClass == IDE_TO_AMD_AHCI_MODE) ){ for (dbPortNum=0;dbPortNum<4;dbPortNum++){ ReadMEM(ddBar5+ SB_SATA_BAR5_REG128 + dbPortNum * 0x80, AccWidthUint32, &ddVar0); if ( ( ddVar0 & 0x0F ) == 0x03){ if ( dbPortNum & BIT0) //this port belongs to secondary channel ReadPCI( ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG18), AccWidthUint16, &dwIoBase); else //this port belongs to primary channel ReadPCI( ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG10), AccWidthUint16, &dwIoBase); //if legacy ide mode, then the bar registers don't contain the correct values. So we need to hardcode them if (pConfig->SataClass == LEGACY_IDE_MODE) dwIoBase = ( (0x170) | ( (~((dbPortNum & BIT0) << 7)) & 0x80 ) ); if ( dbPortNum & BIT1) //this port is slave dbVar0=0xB0; else //this port is master dbVar0=0xA0; dwIoBase &= 0xFFF8; WriteIO(dwIoBase+6, AccWidthUint8, &dbVar0); //Wait in loop for 30s for the drive to become ready for (dwVar0=0;dwVar0<3000;dwVar0++){ ReadIO(dwIoBase+7, AccWidthUint8, &dbVar0); if ( (dbVar0 & 0x88) == 0) break; Stall(10000); } } //end of if ( ( ddVar0 & 0x0F ) == 0x03) } //for (dbPortNum=0;dbPortNum<4;dbPortNum++) } //if ( (pConfig->SataClass == NATIVE_IDE_MODE) || (pConfig->SataClass == LEGACY_IDE_MODE) || (pConfig->SataClass == IDE_TO_AHCI_MODE) || (pConfig->SataClass == IDE_TO_AMD_AHCI_MODE) ) }
void ScanPCI() { // формат адресного регистра: // ---- ---- BBBB BBBB DDDD DFFF RRRR RR00 // B - bus, D - device, F - function, R - register PutString("# PCI Device List:\n"); for (unsigned int addr=0; addr<0x01000000; addr+=256) { unsigned int id = ReadPCI(addr); if ((id & 0xFFFF) != 0xFFFF) { unsigned int sub = ReadPCI(addr+0x2C); PutString("Addr="); PutDWORD(addr); PutString(" Vendor="); PutWORD(id & 0xFFFF); PutString(" ID="); PutWORD((id >> 16) & 0xFFFF); //PutString(" SubVendor="); //PutWORD(sub & 0xFFFF); //PutString(" SubID="); //PutWORD((sub >> 16) & 0xFFFF); /*PutString("\nBAR="); for (int i=0; i<6; i++) { WritePCI(addr+0x10+i*4, 0xFFFFFFFF); PutDWORD(ReadPCI(addr+0x10+i*4)); PutString(" "); }*/ unsigned int cls = ReadPCI(addr+0x08); unsigned int baseClass = (cls >> 24) & 0xFF; unsigned int subClass = (cls >> 16) & 0xFF; unsigned int iface = (cls >> 8) & 0xFF; for (int i=0; i<sizeof(classes)/sizeof(PciDevClass); i++) { if (classes[i].baseClass == baseClass && classes[i].subClass == subClass && classes[i].iface == 0xFF) { PutString(" "); PutString(classes[i].name); break; } } //PutBYTE(baseClass); //PutBYTE(subClass); //PutBYTE(iface); PutString("\n"); } }
void WriteEC8 ( UINT8 Address, UINT8* Value ) { UINT16 dwEcIndexPort; ReadPCI((LPC_BUS_DEV_FUN << 16) + SB_LPC_REGA4, AccWidthUint16 | S3_SAVE, &dwEcIndexPort); dwEcIndexPort &= ~(UINT16)(BIT0); WriteIO(dwEcIndexPort, AccWidthUint8, &Address); // SB_IOMAP_REGCD6 WriteIO(dwEcIndexPort+1, AccWidthUint8, Value); // SB_IOMAP_REGCD7 }
/** * ReadEC8 - Read EC register data * * * * @param[in] Address - EC Register Offset Value * @param[in] Value - Read Data Buffer * */ VOID ReadEC8 ( IN UINT8 Address, IN UINT8* Value ) { UINT16 dwEcIndexPort; ReadPCI ((LPC_BUS_DEV_FUN << 16) + SB_LPC_REGA4, AccWidthUint16 | S3_SAVE, &dwEcIndexPort); dwEcIndexPort &= ~(BIT0); WriteIO (dwEcIndexPort, AccWidthUint8, &Address); ReadIO (dwEcIndexPort + 1, AccWidthUint8, Value); }
/** * gecInitAfterPciEnum - Config GEC controller after PCI emulation * * * * @param[in] pConfig Southbridge configuration structure pointer. * */ VOID gecInitAfterPciEnum ( IN AMDSBCFG* pConfig ) { VOID* GecRomAddress; VOID* GecShadowRomAddress; UINT32 ddTemp; if ( pConfig->DYNAMICGECROM.DynamicGecRomAddress_Ptr != NULL ) { GecRomAddress = pConfig->DYNAMICGECROM.DynamicGecRomAddress_Ptr; GecShadowRomAddress = (VOID*) (UINTN) pConfig->BuildParameters.GecShadowRomBase; AmdSbCopyMem (GecShadowRomAddress, GecRomAddress, 0x100); ReadPCI ((GEC_BUS_DEV_FUN << 16) + SB_GEC_REG10, AccWidthUint32, &ddTemp); ddTemp = ddTemp & 0xFFFFFFF0; RWMEM (ddTemp + 0x6804, AccWidthUint32, 0, BIT0 + BIT29); } TRACE ((DMSG_SB_TRACE, "Exiting gec Init after PCI emulation\n")); }
/********************************************************************************* * * Routine Description: Config SB during late POST * * Arguments: * * pConfig - SBconfiguration * * Returns: void * * Reference: atiSbLatePost * **********************************************************************************/ void sbLatePost(AMDSBCFG* pConfig){ UINT16 dwVar; BUILDPARAM *pStaticOptions; pStaticOptions = &pConfig->BuildParameters; TRACE((DMSG_SB_TRACE, "CIMx - Entering sbLatePost \n")); ReadPCI((SMBUS_BUS_DEV_FUN << 16) + SB_SMBUS_REG02, AccWidthUint16, &dwVar); if (dwVar != SB7XX_DEVICE_ID){ // Display message that the SB is wrong and stop the system TRACE((DMSG_SB_TRACE, "Current system does not have SB700 chipset. Stopping\n")); for(;;); } commonInitLateBoot(pConfig); sataInitLatePost(pConfig); hpetInit(pConfig, pStaticOptions); // SB Configure HPET base and enable bit #ifndef NO_EC_SUPPORT ecInitLatePost(pConfig); #endif }
BOOL QstInitialize( void ) { U32 uHeciAddr, uMsgSize = MAX_MESSAGE_SIZE; // Locate the HECI device in the PCI address space uHeciAddr = FindHECIDevice(); if( !uHeciAddr ) { errno = ENXIO; return( FALSE ); } // Get base address for HECI device's registers uHeciBAR = ReadPCI( uHeciAddr | PCI_HECI_MBAR_REG ) & 0xFFFFFF00; // Initialize the HECI Interface if( !HECIInitialize( uHeciBAR ) ) { errno = EIO; return( FALSE ); } // Create a receive buffer pvBuffer = malloc( MAX_MESSAGE_SIZE ); if( !pvBuffer ) { errno = ENOMEM; return( FALSE ); } // Clear any unattended messages left in the input stream while( HECIReceive( NON_BLOCKING, uHeciBAR, (U32 *)pvBuffer, &uMsgSize, HOST_PROC_ADDRESS, QST_PROC_ADDRESS ) ); // We're ready! return( TRUE ); }
/** * sbGppSetAspm - Set GPP ASPM * * * @param[in] pciAddress PCI Address. * @param[in] LxState Lane State. * */ VOID sbGppSetAspm ( IN UINT32 pciAddress, IN UINT8 LxState ) { UINT8 pcieCapOffset; UINT8 value8; pcieCapOffset = sbFindPciCap (pciAddress, PCIE_CAP_ID); if (pcieCapOffset) { // Read link capabilities register (0x0C[11:10] - ASPM support) ReadPCI (pciAddress + pcieCapOffset + 0x0D, AccWidthUint8, &value8); if (value8 & BIT2) { value8 = (value8 >> 2) & (BIT1 + BIT0); // Set ASPM state in link control register RWPCI (pciAddress + pcieCapOffset + 0x10, AccWidthUint8, 0xffffffff, LxState & value8); } }
void sbSmmAcpiOn(AMDSBCFG* pConfig){ UINT32 ddBar5; UINT8 dbPort; //RWPCI((SMBUS_BUS_DEV_FUN << 16) + SB_SMBUS_REG60+2, AccWidthUint8 | S3_SAVE, ~(UINT32)(BIT1+BIT0), 0); if (getRevisionID() >= SB700_A13) RWPCI((SMBUS_BUS_DEV_FUN << 16) + SB_SMBUS_REG43, AccWidthUint8 | S3_SAVE, 0xFF, BIT0); //Enable Legacy DMA prefetch enhancement RWPCI((SMBUS_BUS_DEV_FUN << 16) + SB_SMBUS_REG60+2, AccWidthUint8 | S3_SAVE, ~(UINT32)(BIT1+BIT0), 0); RWPCI((SMBUS_BUS_DEV_FUN << 16) + SB_SMBUS_REG64+3, AccWidthUint8| S3_SAVE, ~(UINT32)BIT7, 0); programOhciMmioForEmulation(); // For IDE_TO_AHCI_MODE and IDE_TO_AMD_AHCI_MODE, clear Interrupt Status register for all ports ReadPCI( ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG24), AccWidthUint32, &ddBar5); if ((pConfig->SataClass == IDE_TO_AHCI_MODE) || (pConfig->SataClass == IDE_TO_AMD_AHCI_MODE)){ for (dbPort = 0; dbPort <= 5; dbPort++) { RWMEM(ddBar5 + SB_SATA_BAR5_REG110 + dbPort * 0x80, AccWidthUint32, 0x00, 0xFFFFFFFF); } } }
void sataInitBeforePciEnum(AMDSBCFG* pConfig){ UINT32 ddValue, *tempptr; UINT16 *pDeviceIdptr, dwDeviceId; UINT8 dbValue, dbOrMask, dbAndMask; dbAndMask=0; dbOrMask=0; // Enable/Disable Combined mode & do primary/secondary selections, enable/disable if (pConfig->SataIdeCombinedMode == CIMX_OPTION_DISABLED) dbAndMask= BIT3; //Clear BIT3 if (pConfig->SataIdeCombMdPriSecOpt == 1) dbOrMask = BIT4; //Set BIT4 if (pConfig->SataSmbus == 0) dbOrMask = BIT1; RWPCI(((SMBUS_BUS_DEV_FUN << 16) + SB_SMBUS_REGAD), AccWidthUint8 | S3_SAVE, ~(dbAndMask), dbOrMask); if (pConfig->SataController == 0){ // SATA Controller Disabled & set Power Saving mode to disabled RWPCI(((SMBUS_BUS_DEV_FUN << 16) + SB_SMBUS_REGAD), AccWidthUint8 | S3_SAVE, ~(UINT32)BIT0, BIT1); return; } restrictSataCapabilities(pConfig); // Get the appropriate class code from the table and write it to PCI register 08h-0Bh // Set the appropriate SATA class based on the input parameters dbValue=pConfig->SataClass; tempptr= (UINT32 *) FIXUP_PTR (&sataIfCodeTable[0]); ddValue=tempptr[dbValue]; // BIT0: Enable write access to PCI header (reg 08h-0Bh) by setting SATA PCI register 40h, bit 0 // BIT4:disable fast boot RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40), AccWidthUint8 | S3_SAVE, 0xff, BIT4+BIT0); // Write the class code to SATA PCI register 08h-0Bh RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG08), AccWidthUint32 | S3_SAVE, 0, ddValue); if (pConfig->SataClass == LEGACY_IDE_MODE) //SATA = Legacy IDE //Set PATA controller to native mode RWPCI(((IDE_BUS_DEV_FUN << 16) + SB_IDE_REG09), AccWidthUint8 | S3_SAVE, 0x00, 0x08F); //Change the appropriate device id if (pConfig->SataClass == AMD_AHCI_MODE) { RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40 + 3), AccWidthUint8 | S3_SAVE, 0xff, BIT0); } pDeviceIdptr= (UINT16 *) FIXUP_PTR (&sataDeviceIDTable[0]); ReadPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG02), AccWidthUint16 | S3_SAVE, &dwDeviceId); if ( !((dwDeviceId==SB750_SATA_DEFAULT_DEVICE_ID) && (pConfig->SataClass == RAID_MODE)) ){ //if not (SB750 & RAID mode), then program the device id dwDeviceId=pDeviceIdptr[dbValue]; RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG02), AccWidthUint16 | S3_SAVE, 0, dwDeviceId); } if (pConfig->AcpiS1Supported) RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG34), AccWidthUint8 | S3_SAVE, 00, 0x70);//Disable SATA PM & MSI capability else RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG60+1), AccWidthUint8 | S3_SAVE, 00, 0x70);//Disable SATA MSI capability if (getRevisionID() >= SB700_A13){ //Enable test/enhancement mode for A13 RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40+3), AccWidthUint8 | S3_SAVE, ~(UINT32)BIT5, 00); RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG48), AccWidthUint32 | S3_SAVE, ~(UINT32)(BIT24+BIT21), 0xBF80); } if (getRevisionID() >= SB700_A14){ //Fix for TT SB01352 - LED Stays On When ODD Attached To Slave Port In IDE Mode RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG48), AccWidthUint8 | S3_SAVE, 0xFF, BIT6); } // Disable write access to PCI header RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40), AccWidthUint8 | S3_SAVE, ~(UINT32)BIT0, 0); // RPR 6.5 SATA PHY Programming Sequence RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG86, AccWidthUint16 | S3_SAVE, 0x00, 0x2C00); RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG88, AccWidthUint32 | S3_SAVE, 0x00, 0x01B48016); RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG8C, AccWidthUint32 | S3_SAVE, 0x00, 0x01B48016); RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG90, AccWidthUint32 | S3_SAVE, 0x00, 0x01B48016); RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG94, AccWidthUint32 | S3_SAVE, 0x00, 0x01B48016); RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG98, AccWidthUint32 | S3_SAVE, 0x00, 0x01B48016); RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG9C, AccWidthUint32 | S3_SAVE, 0x00, 0x01B48016); RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REGA0, AccWidthUint32 | S3_SAVE, 0x00, 0xA07AA07A); RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REGA4, AccWidthUint32 | S3_SAVE, 0x00, 0xA07AA07A); RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REGA8, AccWidthUint32 | S3_SAVE, 0x00, 0xA07AA07A); CallBackToOEM(SATA_PHY_PROGRAMMING, NULL, pConfig); }
/** * azaliaInitAfterPciEnum - Config HD Audio after PCI emulation * * * * @param[in] pConfig Southbridge configuration structure pointer. * */ VOID azaliaInitAfterPciEnum ( IN AMDSBCFG* pConfig ) { UINT8 Data; UINT8 i; UINT8 dbEnableAzalia; UINT8 dbPinRouting; UINT8 dbChannelNum; UINT8 dbTempVariable; UINT16 dwTempVariable; UINT32 ddBAR0; UINT32 ddTempVariable; dbEnableAzalia = 0; dbChannelNum = 0; dbTempVariable = 0; dwTempVariable = 0; ddBAR0 = 0; ddTempVariable = 0; if ( pConfig->AzaliaController == 1 ) { return; } if ( pConfig->AzaliaController != 1 ) { RWPCI ((AZALIA_BUS_DEV_FUN << 16) + SB_AZ_REG04, AccWidthUint8 | S3_SAVE, ~BIT1, BIT1); if ( pConfig->BuildParameters.AzaliaSsid != NULL ) { RWPCI ((AZALIA_BUS_DEV_FUN << 16) + SB_AZ_REG2C, AccWidthUint32 | S3_SAVE, 0x00, pConfig->BuildParameters.AzaliaSsid); } ReadPCI ((AZALIA_BUS_DEV_FUN << 16) + SB_AZ_REG10, AccWidthUint32, &ddBAR0); if ( ddBAR0 != 0 ) { if ( ddBAR0 != 0xFFFFFFFF ) { ddBAR0 &= ~(0x03FFF); dbEnableAzalia = 1; TRACE ((DMSG_SB_TRACE, "CIMxSB - Enabling Azalia controller (BAR setup is ok) \n")); } } } if ( dbEnableAzalia ) { pConfig->AZALIACONFIG.AzaliaConfig.AzaliaSdin0 = 0x03 & (pConfig->AZALIACONFIG.AzaliaSdinPin >> 0); pConfig->AZALIACONFIG.AzaliaConfig.AzaliaSdin1 = 0x03 & (pConfig->AZALIACONFIG.AzaliaSdinPin >> 2); pConfig->AZALIACONFIG.AzaliaConfig.AzaliaSdin2 = 0x03 & (pConfig->AZALIACONFIG.AzaliaSdinPin >> 4); pConfig->AZALIACONFIG.AzaliaConfig.AzaliaSdin3 = 0x03 & (pConfig->AZALIACONFIG.AzaliaSdinPin >> 6); // Get SDIN Configuration if ( pConfig->AZALIACONFIG.AzaliaConfig.AzaliaSdin0 == 2 ) { RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GPIO_REG167, AccWidthUint8, 0, 0x3E); RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + SB_GPIO_REG167, AccWidthUint8, 0, 0x00); } else { RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GPIO_REG167, AccWidthUint8, 0, 0x0); RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + SB_GPIO_REG167, AccWidthUint8, 0, 0x01); } if ( pConfig->AZALIACONFIG.AzaliaConfig.AzaliaSdin1 == 2 ) { RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GPIO_REG168, AccWidthUint8, 0, 0x3E); RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + SB_GPIO_REG168, AccWidthUint8, 0, 0x00); } else { RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GPIO_REG168, AccWidthUint8, 0, 0x0); RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + SB_GPIO_REG168, AccWidthUint8, 0, 0x01); } if ( pConfig->AZALIACONFIG.AzaliaConfig.AzaliaSdin2 == 2 ) { RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GPIO_REG169, AccWidthUint8, 0, 0x3E); RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + SB_GPIO_REG169, AccWidthUint8, 0, 0x00); } else { RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GPIO_REG169, AccWidthUint8, 0, 0x0); RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + SB_GPIO_REG169, AccWidthUint8, 0, 0x01); } if ( pConfig->AZALIACONFIG.AzaliaConfig.AzaliaSdin3 == 2 ) { RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GPIO_REG170, AccWidthUint8, 0, 0x3E); RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + SB_GPIO_REG170, AccWidthUint8, 0, 0x00); } else { RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GPIO_REG170, AccWidthUint8, 0, 0x0); RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + SB_GPIO_REG170, AccWidthUint8, 0, 0x01); } // INT#A Azalia resource Data = 0x93; // Azalia APIC index WriteIO (SB_IOMAP_REGC00, AccWidthUint8, &Data); Data = 0x10; // IRQ16 (INTA#) WriteIO (SB_IOMAP_REGC01, AccWidthUint8, &Data); i = 11; do { ReadMEM ( ddBAR0 + SB_AZ_BAR_REG08, AccWidthUint8 | S3_SAVE, &dbTempVariable); dbTempVariable |= BIT0; WriteMEM (ddBAR0 + SB_AZ_BAR_REG08, AccWidthUint8 | S3_SAVE, &dbTempVariable); SbStall (1000); ReadMEM (ddBAR0 + SB_AZ_BAR_REG08, AccWidthUint8 | S3_SAVE, &dbTempVariable); i--; } while ((! (dbTempVariable & BIT0)) && (i > 0) ); if ( i == 0 ) { TRACE ((DMSG_SB_TRACE, "CIMxSB - Problem in resetting Azalia controller\n")); return; } SbStall (1000); ReadMEM ( ddBAR0 + SB_AZ_BAR_REG0E, AccWidthUint16, &dwTempVariable); if ( dwTempVariable & 0x0F ) { TRACE ((DMSG_SB_TRACE, "CIMxSB - At least One Azalia CODEC found \n")); //atleast one azalia codec found dbPinRouting = pConfig->AZALIACONFIG.AzaliaSdinPin; do { if ( ( ! (dbPinRouting & BIT0) ) && (dbPinRouting & BIT1) ) { configureAzaliaPinCmd (pConfig, ddBAR0, dbChannelNum); } dbPinRouting >>= 2; dbChannelNum++; } while ( dbChannelNum != 4 ); } else {
void sataInitAfterPciEnum(AMDSBCFG* pConfig){ UINT32 ddAndMask=0, ddOrMask=0, ddBar5=0; UINT8 dbVar, dbPortNum; if (pConfig->SataController == 0) return; //return if SATA controller is disabled. //Enable write access to pci header, pm capabilities RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40), AccWidthUint8 | S3_SAVE, 0xFF, BIT0); //Disable AHCI enhancement function (RPR 7.2) RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40 + 2), AccWidthUint8 | S3_SAVE, 0xFF, BIT7); restrictSataCapabilities(pConfig); ReadPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG24), AccWidthUint32, &ddBar5); if ( (ddBar5 == 0) || (ddBar5 == -1) ) { //assign temporary BAR5 if ( (pConfig->TempMMIO == 0) || (pConfig->TempMMIO == -1)) ddBar5 = 0xFEC01000; else ddBar5=pConfig->TempMMIO; WritePCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG24), AccWidthUint32, &ddBar5); } ReadPCI( ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG04), AccWidthUint8, &dbVar); RWPCI( ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG04), AccWidthUint8,0xFF, 0x03); //memory and io access enable ddBar5 &= 0xFFFFFC00; //Clear Bits 9:0 if (!pConfig->SataPortMultCap) ddAndMask |= BIT12; if (!pConfig->SataAggrLinkPmCap) ddAndMask |= BIT11; if (pConfig->SataSscPscCap) ddOrMask |= BIT1; RWMEM((ddBar5 + SB_SATA_BAR5_REGFC),AccWidthUint32 | S3_SAVE, ~ddAndMask, ddOrMask); //Clear HPCP and ESP by default RWMEM((ddBar5 + SB_SATA_BAR5_REGF8),AccWidthUint32 | S3_SAVE, 0xFFFC0FC0, 0); if (pConfig->SataHpcpButNonESP !=0) { RWMEM((ddBar5 + SB_SATA_BAR5_REGF8),AccWidthUint32 | S3_SAVE, 0xFFFFFFC0, pConfig->SataHpcpButNonESP); } // SATA ESP port setting // These config bits are set for SATA driver to identify which ports are external SATA ports and need to // support hotplug. If a port is set as an external SATA port and need to support hotplug, then driver will // not enable power management(HIPM & DIPM) for these ports. if (pConfig->SataEspPort !=0) { RWMEM((ddBar5 + SB_SATA_BAR5_REGFC),AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, BIT20); RWMEM((ddBar5 + SB_SATA_BAR5_REGF8),AccWidthUint32 | S3_SAVE, ~(pConfig->SataEspPort), 0); RWMEM((ddBar5 + SB_SATA_BAR5_REGF8),AccWidthUint32 | S3_SAVE, ~(UINT32)(BIT17+BIT16+BIT15+BIT14+BIT13+BIT12),(pConfig->SataEspPort << 12)); } if ( ((pConfig->SataClass) != NATIVE_IDE_MODE) && ((pConfig->SataClass) != LEGACY_IDE_MODE) ) RWPCI( ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG50+2), AccWidthUint8, ~(UINT32)(BIT3+BIT2+BIT1), BIT2+BIT1); //set MSI to 8 messages if ( ((pConfig->SataClass) != NATIVE_IDE_MODE) && ((pConfig->SataClass) != LEGACY_IDE_MODE) && ((pConfig->SataIdeCombinedMode) == CIMX_OPTION_DISABLED) ){ RWMEM((ddBar5 + SB_SATA_BAR5_REG00),AccWidthUint8 | S3_SAVE, ~(UINT32)(BIT2+BIT1+BIT0), BIT2+BIT0); RWMEM((ddBar5 + SB_SATA_BAR5_REG0C),AccWidthUint8 | S3_SAVE, 0xC0, 0x3F); } for (dbPortNum=0;dbPortNum<=5;dbPortNum++){ if (pConfig->SataPortMode & (1 << dbPortNum)){ //downgrade to GEN1 RWMEM(ddBar5+ SB_SATA_BAR5_REG12C + dbPortNum * 0x80, AccWidthUint8, 0x0F, 0x10); RWMEM(ddBar5+ SB_SATA_BAR5_REG12C + dbPortNum * 0x80, AccWidthUint8, 0xFF, 0x01); Stall(1000); RWMEM(ddBar5+ SB_SATA_BAR5_REG12C + dbPortNum * 0x80, AccWidthUint8, 0xFE, 0x00); } } //If this is not S3 resume and also if SATA set to one of IDE mode, then implement drive detection workaround. if ( !(pConfig->S3Resume) && ( ((pConfig->SataClass) != AHCI_MODE) && ((pConfig->SataClass) != RAID_MODE) && ((pConfig->SataClass) != AMD_AHCI_MODE) ) ) sataDriveDetection(pConfig, ddBar5); if ( (pConfig->SataPhyWorkaround==1) || ( (pConfig->SataPhyWorkaround==0) && (getRevisionID() < SB700_A13)) ) sataPhyWorkaround(pConfig, ddBar5); // Set the handshake bit for IDE driver to detect the disabled IDE channel correctly. // Set IDE PCI Config 0x63 [3] if primary channel disabled, [4] if secondary channel disabled. if (pConfig->SataIdeCombinedMode == CIMX_OPTION_DISABLED) RWPCI( ((IDE_BUS_DEV_FUN << 16) + SB_IDE_REG63), AccWidthUint8 , 0xF9, (0x02 << (pConfig->SataIdeCombMdPriSecOpt)) ); WritePCI( ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG04), AccWidthUint8, &dbVar); //Disable write access to pci header, pm capabilities RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40), AccWidthUint8 | S3_SAVE, ~(UINT32)BIT0, 0); }
/** * azaliaInitAfterPciEnum - Config HD Audio after PCI emulation * * * * @param[in] pConfig Southbridge configuration structure pointer. * */ VOID azaliaInitAfterPciEnum ( IN AMDSBCFG* pConfig ) { UINT8 Data; UINT8 i; UINT8 dbEnableAzalia; UINT8 dbPinRouting; UINT8 dbChannelNum; UINT8 dbTempVariable; UINT16 dwTempVariable; UINT32 ddBAR0; UINT32 ddTempVariable; dbEnableAzalia = 0; dbChannelNum = 0; dbTempVariable = 0; dwTempVariable = 0; ddBAR0 = 0; ddTempVariable = 0; if ( pConfig->AzaliaController == 1 ) { return; } if ( pConfig->AzaliaController != 1 ) { RWPCI ((AZALIA_BUS_DEV_FUN << 16) + SB_AZ_REG04, AccWidthUint8 | S3_SAVE, ~BIT1, BIT1); if ( pConfig->BuildParameters.AzaliaSsid != NULL ) { RWPCI ((AZALIA_BUS_DEV_FUN << 16) + SB_AZ_REG2C, AccWidthUint32 | S3_SAVE, 0x00, pConfig->BuildParameters.AzaliaSsid); } ReadPCI ((AZALIA_BUS_DEV_FUN << 16) + SB_AZ_REG10, AccWidthUint32, &ddBAR0); if ( ddBAR0 != 0 ) { if ( ddBAR0 != 0xFFFFFFFF ) { ddBAR0 &= ~(0x03FFF); dbEnableAzalia = 1; } } } if ( dbEnableAzalia ) { // Get SDIN Configuration if ( pConfig->AZALIACONFIG.AzaliaConfig.AzaliaSdin0 == 2 ) { RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GPIO_REG167, AccWidthUint8, 0, 0x3E); RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + SB_GPIO_REG167, AccWidthUint8, 0, 0x00); } else { RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GPIO_REG167, AccWidthUint8, 0, 0x0); RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + SB_GPIO_REG167, AccWidthUint8, 0, 0x01); } if ( pConfig->AZALIACONFIG.AzaliaConfig.AzaliaSdin1 == 2 ) { RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GPIO_REG168, AccWidthUint8, 0, 0x3E); RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + SB_GPIO_REG168, AccWidthUint8, 0, 0x00); } else { RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GPIO_REG168, AccWidthUint8, 0, 0x0); RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + SB_GPIO_REG168, AccWidthUint8, 0, 0x01); } if ( pConfig->AZALIACONFIG.AzaliaConfig.AzaliaSdin2 == 2 ) { RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GPIO_REG169, AccWidthUint8, 0, 0x3E); RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + SB_GPIO_REG169, AccWidthUint8, 0, 0x00); } else { RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GPIO_REG169, AccWidthUint8, 0, 0x0); RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + SB_GPIO_REG169, AccWidthUint8, 0, 0x01); } if ( pConfig->AZALIACONFIG.AzaliaConfig.AzaliaSdin3 == 2 ) { RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GPIO_REG170, AccWidthUint8, 0, 0x3E); RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + SB_GPIO_REG170, AccWidthUint8, 0, 0x00); } else { RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GPIO_REG170, AccWidthUint8, 0, 0x0); RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + SB_GPIO_REG170, AccWidthUint8, 0, 0x01); } // INT#A Azalia resource Data = 0x93; // Azalia APIC index WriteIO (SB_IOMAP_REGC00, AccWidthUint8, &Data); Data = 0x10; // IRQ16 (INTA#) WriteIO (SB_IOMAP_REGC01, AccWidthUint8, &Data); i = 11; do { ReadMEM ( ddBAR0 + SB_AZ_BAR_REG08, AccWidthUint8 | S3_SAVE, &dbTempVariable); dbTempVariable |= BIT0; WriteMEM (ddBAR0 + SB_AZ_BAR_REG08, AccWidthUint8 | S3_SAVE, &dbTempVariable); SbStall (1000); ReadMEM (ddBAR0 + SB_AZ_BAR_REG08, AccWidthUint8 | S3_SAVE, &dbTempVariable); i--; } while ((! (dbTempVariable & BIT0)) && (i > 0) ); if ( i == 0 ) { return; } SbStall (1000); ReadMEM ( ddBAR0 + SB_AZ_BAR_REG0E, AccWidthUint16, &dwTempVariable); if ( dwTempVariable & 0x0F ) { //atleast one azalia codec found // ?? E0 is not real register what we expect. we have change to GPIO/and program GPIO Mux //ReadMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGE0, AccWidthUint8, &dbPinRouting); dbPinRouting = pConfig->AZALIACONFIG.AzaliaSdinPin; do { if ( ( ! (dbPinRouting & BIT0) ) && (dbPinRouting & BIT1) ) { // dbChannelNum = 3; configureAzaliaPinCmd (pConfig, ddBAR0, dbChannelNum); } dbPinRouting >>= 2; dbChannelNum++; } while ( dbChannelNum != 4 ); } else { //No Azalia codec found if ( pConfig->AzaliaController != 2 ) {
// Read data from specified PCI32 configuration address. uint32 ReadPCI32(unsigned int bus, unsigned int device, unsigned int func, unsigned int reg, uint32* data) { uint32 address = GetExtendedConfigurationSpaceAddress(bus, device, func, reg); DRVPRINT(" bus %u , device %u , func %u , reg %u , address %u \n", bus, device, func, reg, address); return ReadPCI(address , data); }