VOID SetAcpiPma ( IN UINT8 pmaControl ) { UINT16 pmaBase; UINT16 dwValue; ReadMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REG74, AccWidthUint16, &dwValue); dwValue &= ~BIT6; WriteMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REG74, AccWidthUint16, &dwValue); ReadMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REG6E, AccWidthUint16, &pmaBase); WriteIo8 (pmaBase, pmaControl); RWMEM (ACPI_MMIO_BASE + SMI_BASE + SB_PMIOA_REG98 + 3, AccWidthUint8, ~BIT7, pmaControl << 7); }
void shutdownUnconnectedSataPortClock(AMDSBCFG* pConfig, UINT32 ddBar5){ UINT8 dbPortNum, dbPortSataStatus, NumOfPorts=0; UINT8 UnusedPortBitMap; UINT8 SataType; UINT8 ClockOffEnabled ; UnusedPortBitMap = 0; // First scan for all unused SATA ports for (dbPortNum = 5; dbPortNum <= 5; dbPortNum--) { ReadMEM (ddBar5 + SB_SATA_BAR5_REG128 + (dbPortNum * 0x80), AccWidthUint8, &dbPortSataStatus); if ((!(dbPortSataStatus & 0x01)) && (!((pConfig->SataEspPort) & (1 << dbPortNum)))) { UnusedPortBitMap |= (1 << dbPortNum); } } // Decide if we need to shutdown the clock for all unused ports SataType = pConfig->SataClass; ClockOffEnabled = (pConfig->SataClkAutoOff && ((SataType == NATIVE_IDE_MODE) || (SataType == LEGACY_IDE_MODE) || \ (SataType == IDE_TO_AHCI_MODE) || (SataType == IDE_TO_AMD_AHCI_MODE))) || \ (pConfig->SataClkAutoOffAhciMode && ((SataType == AHCI_MODE) || (SataType == AMD_AHCI_MODE))); if (ClockOffEnabled) { //Shutdown the clock for the port and do the necessary port reporting changes. TRACE((DMSG_SB_TRACE, "Shutting down clock for SATA ports %X \n", UnusedPortBitMap)); RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40 + 2), AccWidthUint8, 0xFF, UnusedPortBitMap); RWMEM(ddBar5 + SB_SATA_BAR5_REG0C, AccWidthUint8, ~UnusedPortBitMap, 00); } // If all ports are in disabled state, report at least one ReadMEM (ddBar5 + SB_SATA_BAR5_REG0C, AccWidthUint8, &dbPortSataStatus); if ( (dbPortSataStatus & 0x3F) == 0) { dbPortSataStatus = 1; RWMEM (ddBar5 + SB_SATA_BAR5_REG0C, AccWidthUint8, ~(0x3F), dbPortSataStatus); } // Decide if we need to hide unused ports from being seen by OS (this saves OS startup time) if (pConfig->SataHideUnusedPort && ClockOffEnabled) { dbPortSataStatus &= ~UnusedPortBitMap; // Mask off unused ports for (dbPortNum = 0; dbPortNum <= 6; dbPortNum++) { if (dbPortSataStatus & (1 << dbPortNum)) NumOfPorts++; } if (NumOfPorts == 0 ) { NumOfPorts = 0x01; } RWMEM (ddBar5 + SB_SATA_BAR5_REG00, AccWidthUint8, 0xE0, NumOfPorts - 1); } }
/** * getChipSysMode - Get Chip status * * * @param[in] Value - Return Chip strap status * StrapStatus [15.0] - Hudson-2 chip Strap Status * @li <b>0001</b> - Not USED FWH * @li <b>0002</b> - Not USED LPC ROM * @li <b>0004</b> - EC enabled * @li <b>0008</b> - Reserved * @li <b>0010</b> - Internal Clock mode * */ VOID getChipSysMode ( IN VOID* Value ) { ReadMEM (ACPI_MMIO_BASE + MISC_BASE + SB_MISC_REG80, AccWidthUint8, Value); }
/** * getEfuseByte - Get Efuse Byte * * * @param[in] Index - Efuse Index value * */ UINT8 getEfuseByte ( IN UINT8 Index ) { UINT8 Data; WriteMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGD8, AccWidthUint8, &Index); ReadMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGD8 + 1, AccWidthUint8, &Data); return Data; }
/** * getEfuseStatue - Get Efuse status * * * @param[in] Value - Return Chip strap status * */ VOID getEfuseStatus ( IN VOID* Value ) { RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGC8, AccWidthUint8, ~BIT5, BIT5); WriteMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGD8, AccWidthUint8, Value); ReadMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGD8 + 1, AccWidthUint8, Value); RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGC8, AccWidthUint8, ~BIT5, 0); }
/** * BackUpCG2 * * * @retval VOID * */ VOID BackUpCG2 ( OUT VOID ) { UINT8 dByte; ReadMEM (ACPI_MMIO_BASE + MISC_BASE + 0x1C, AccWidthUint8, &dByte); if (dByte & BIT6) { RWMEM (ACPI_MMIO_BASE + MISC_BASE + 0x41, AccWidthUint8, ~(BIT6), (0)); } }
VOID RWMEM ( IN UINT32 Address, IN UINT8 OpFlag, IN UINT32 Mask, IN UINT32 Data ) { UINT32 Result; ReadMEM (Address, OpFlag, &Result); Result = (Result & Mask) | Data; WriteMEM (Address, OpFlag, &Result); }
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) ) }
//This patch is to workaround the SATA PHY logic hardware issue in the SB700. //Internally this workaround is called as 7NewA void sataPhyWorkaround(AMDSBCFG* pConfig, UINT32 ddBar5){ UINT8 dbPortNum, dbVar0; if (pConfig->Gen1DeviceShutdownDuringPhyWrknd == 0x01){ for (dbPortNum=0;dbPortNum<=5;dbPortNum++){ ReadMEM(ddBar5+ SB_SATA_BAR5_REG128 + dbPortNum * 0x80, AccWidthUint8, &dbVar0); if ( (dbVar0 & 0xF0) == 0x10){ RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40+2, AccWidthUint8 | S3_SAVE, 0xFF, (01 << dbPortNum)); } } } RWPMIO(SB_PMIO_REGD0, AccWidthUint8, ~(UINT32)(BIT4+BIT3), BIT4+BIT3);//set PMIO_D0[4:3] = 11b // this is to tell SATA PHY to use the internal 100MHz clock RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG86, AccWidthUint8 | S3_SAVE, 0x00, 0x40);// set SATA PCI_CFG 0x86[7:0] = 0x40 //after the reset is done, perform this to turn on the diff clock path into SATA PHY Stall(2000);// Wait for 2ms RWPMIO(SB_PMIO_REGD0, AccWidthUint8, ~(UINT32)(BIT4+BIT3), 00);//13. set PMIO_D0[4:3] = 00b Stall(20000);// Wait 20ms forceOOB(ddBar5);// Force OOB RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40+2, AccWidthUint8 | S3_SAVE, ~(0x03F), 00); }
/** * 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 ) {
/** * 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 {