aboutsummaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/agesa/f12/Proc/Fch/Sata/Family/Hudson2/Hudson2SataService.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vendorcode/amd/agesa/f12/Proc/Fch/Sata/Family/Hudson2/Hudson2SataService.c')
-rwxr-xr-xsrc/vendorcode/amd/agesa/f12/Proc/Fch/Sata/Family/Hudson2/Hudson2SataService.c681
1 files changed, 681 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f12/Proc/Fch/Sata/Family/Hudson2/Hudson2SataService.c b/src/vendorcode/amd/agesa/f12/Proc/Fch/Sata/Family/Hudson2/Hudson2SataService.c
new file mode 100755
index 0000000000..6aefa35e1b
--- /dev/null
+++ b/src/vendorcode/amd/agesa/f12/Proc/Fch/Sata/Family/Hudson2/Hudson2SataService.c
@@ -0,0 +1,681 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * Graphics Controller family specific service procedure
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: FCH
+ * @e \$Revision: 48230 $ @e \$Date: 2011-03-05 06:55:12 +0800 (Sat, 05 Mar 2011) $
+ *
+ */
+
+/*
+*****************************************************************************
+*
+* Copyright (c) 2011, 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.
+* ***************************************************************************
+*/
+
+
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+#include "FchPlatform.h"
+#include "Filecode.h"
+#define FILECODE PROC_FCH_SATA_FAMILY_HUDSON2_HUDSON2SATASERVICE_FILECODE
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+UINT8 NumOfSataPorts = 8;
+
+/**
+ * FchSataGpioInitial - Sata GPIO function Procedure
+ *
+ * - Private function
+ *
+ * @param[in] FchDataPtr Fch configuration structure pointer.
+ *
+ */
+VOID
+FchSataGpioInitial (
+ IN VOID *FchDataPtr
+ )
+{
+ UINT32 Bar5;
+ UINT32 FchSataBarRegDword;
+ UINT32 EMb;
+ UINT32 SataGpioVariableDword;
+ UINT8 FchSataSgpio0;
+ FCH_DATA_BLOCK *LocalCfgPtr;
+
+ LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr;
+
+ Bar5 = 0;
+ EMb = 0;
+ FchSataSgpio0 = (UINT8) LocalCfgPtr->Sata.SataSgpio0;
+
+ SataBar5setting (LocalCfgPtr, &Bar5);
+ ReadMem (Bar5 + FCH_SATA_BAR5_REG1C , AccessWidth32, &FchSataBarRegDword);
+ EMb = (Bar5 + (( FchSataBarRegDword & 0xFFFF0000) >> 14));
+
+ if ( EMb ) {
+ SataGpioVariableDword = 0x03040C00;
+ WriteMem ( Bar5 + EMb, AccessWidth32, &SataGpioVariableDword);
+ SataGpioVariableDword = 0x00C08240;
+ WriteMem ( Bar5 + EMb + 4, AccessWidth32, &SataGpioVariableDword);
+ SataGpioVariableDword = 0x00000001;
+ WriteMem ( Bar5 + EMb + 8, AccessWidth32, &SataGpioVariableDword);
+
+ if ( FchSataSgpio0 ) {
+ SataGpioVariableDword = 0x00000060;
+ } else {
+ SataGpioVariableDword = 0x00000061;
+ }
+
+ WriteMem ( Bar5 + EMb + 0x0C, AccessWidth32, &SataGpioVariableDword);
+ RwMem ((Bar5 + FCH_SATA_BAR5_REG20), AccessWidth16, ~(BIT8), BIT8);
+
+ do {
+ ReadMem (Bar5 + FCH_SATA_BAR5_REG20 , AccessWidth32, &FchSataBarRegDword);
+ FchSataBarRegDword = FchSataBarRegDword & BIT8;
+ } while ( FchSataBarRegDword != 0 );
+
+ SataGpioVariableDword = 0x03040F00;
+ WriteMem ( Bar5 + EMb, AccessWidth32, &SataGpioVariableDword);
+ SataGpioVariableDword = 0x00008240;
+ WriteMem ( Bar5 + EMb + 4, AccessWidth32, &SataGpioVariableDword);
+ SataGpioVariableDword = 0x00000002;
+ WriteMem ( Bar5 + EMb + 8, AccessWidth32, &SataGpioVariableDword);
+ SataGpioVariableDword = 0x00800000;
+ WriteMem ( Bar5 + EMb + 0x0C, AccessWidth32, &SataGpioVariableDword);
+ SataGpioVariableDword = 0x0F003700;
+ WriteMem ( Bar5 + EMb + 0x0C, AccessWidth32, &SataGpioVariableDword);
+ RwMem ((Bar5 + FCH_SATA_BAR5_REG20), AccessWidth16, ~(BIT8), BIT8);
+
+ do {
+ ReadMem (Bar5 + FCH_SATA_BAR5_REG20 , AccessWidth32, &FchSataBarRegDword);
+ FchSataBarRegDword = FchSataBarRegDword & BIT8;
+ } while ( FchSataBarRegDword != 0 );
+ }
+}
+
+/**
+ * FchInitMidProgramSataRegs - Sata Pci Configuration Space
+ * register setting
+ *
+ *
+ * @param[in] FchDataPtr Fch configuration structure pointer.
+ *
+ */
+VOID
+FchInitMidProgramSataRegs (
+ IN VOID *FchDataPtr
+ )
+{
+ UINT8 FchSataMsiCapability;
+ UINT8 FchSataTargetSupport8Device;
+ UINT8 FchSataDisableGenericMode;
+ UINT8 FchSataSgpio0;
+ UINT8 FchSataSgpio1;
+ UINT8 FchSataPhyPllShutDown;
+ FCH_DATA_BLOCK *LocalCfgPtr;
+ AMD_CONFIG_PARAMS *StdHeader;
+
+ LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr;
+ StdHeader = LocalCfgPtr->StdHeader;
+
+ FchSataMsiCapability = (UINT8) LocalCfgPtr->Sata.SataMsiCapability;
+ FchSataTargetSupport8Device = (UINT8) LocalCfgPtr->Sata.SataTargetSupport8Device;
+ FchSataDisableGenericMode = (UINT8) LocalCfgPtr->Sata.SataDisableGenericMode;
+ FchSataSgpio0 = (UINT8) LocalCfgPtr->Sata.SataSgpio0;
+ FchSataSgpio1 = (UINT8) LocalCfgPtr->Sata.SataSgpio1;
+ FchSataPhyPllShutDown = (UINT8) LocalCfgPtr->Sata.SataPhyPllShutDown;
+
+ //
+ // Enabled SATA MSI capability
+ // SATA MSI and D3 Power State Capability
+ //
+ if ( FchSataMsiCapability ) {
+ RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG34), AccessWidth8, 0, 0x50, StdHeader);
+ } else {
+ RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG34), AccessWidth8, 0, 0x70, StdHeader);
+ }
+
+ //
+ // Disable SATA FLR Capability
+ //
+ RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG70), AccessWidth16, 0x00FF, 0x00, StdHeader);
+
+ //
+ // Sata Target Support 8 devices function
+ //
+ if ( FchSataTargetSupport8Device ) {
+ RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGDA, AccessWidth16, ~BIT12, BIT12);
+ } else {
+ RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGDA, AccessWidth16, ~BIT12, 0x00);
+ }
+
+ //
+ // Sata Generic Mode setting
+ //
+ if ( FchSataDisableGenericMode ) {
+ RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGDA, AccessWidth16, ~BIT13, BIT13);
+ } else {
+ RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGDA, AccessWidth16, ~BIT13, 0x00);
+ }
+
+ //
+ // Sata GPIO Initial
+ //
+ if ( FchSataSgpio0 ) {
+ FchSataGpioInitial ( LocalCfgPtr );
+ }
+
+ if ( FchSataSgpio1 ) {
+ FchSataGpioInitial ( LocalCfgPtr );
+ }
+
+ //
+ // Sata Phy Pll Shutdown setting
+ //
+ if ( FchSataPhyPllShutDown ) {
+ RwPci (((SATA_BUS_DEV_FUN << 16) + 0x87), AccessWidth8, ~(BIT6), BIT6, StdHeader);
+ } else {
+ RwPci (((SATA_BUS_DEV_FUN << 16) + 0x87), AccessWidth8, ~(BIT6), 0x00, StdHeader);
+ }
+
+ RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG4C), AccessWidth32, (UINT32) (~ (0x3f << 26)), (UINT32) (0x3f << 26), StdHeader);
+ RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG48), AccessWidth32, (UINT32) (~ (0x01 << 11)), (UINT32) (0x01 << 11), StdHeader);
+ RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG84), AccessWidth32, (UINT32) (~ (0x01 << 31)), (UINT32) (0x00 << 31), StdHeader);
+}
+
+
+/**
+ * FchInitLateProgramSataRegs - Sata Pci Configuration Space
+ * register setting
+ *
+ *
+ * @param[in] FchDataPtr Fch configuration structure pointer.
+ *
+ */
+VOID
+FchInitLateProgramSataRegs (
+ IN VOID *FchDataPtr
+ )
+{
+ UINT8 PortNumByte;
+ UINT32 Bar5;
+ FCH_DATA_BLOCK *LocalCfgPtr;
+ AMD_CONFIG_PARAMS *StdHeader;
+
+ LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr;
+ StdHeader = LocalCfgPtr->StdHeader;
+
+ SataBar5setting (LocalCfgPtr, &Bar5);
+ //
+ //Clear error status
+ //
+ RwMem ((Bar5 + FCH_SATA_BAR5_REG130), AccessWidth32, 0xFFFFFFFF, 0xFFFFFFFF);
+ RwMem ((Bar5 + FCH_SATA_BAR5_REG1B0), AccessWidth32, 0xFFFFFFFF, 0xFFFFFFFF);
+ RwMem ((Bar5 + FCH_SATA_BAR5_REG230), AccessWidth32, 0xFFFFFFFF, 0xFFFFFFFF);
+ RwMem ((Bar5 + FCH_SATA_BAR5_REG2B0), AccessWidth32, 0xFFFFFFFF, 0xFFFFFFFF);
+ RwMem ((Bar5 + FCH_SATA_BAR5_REG330), AccessWidth32, 0xFFFFFFFF, 0xFFFFFFFF);
+ RwMem ((Bar5 + FCH_SATA_BAR5_REG3B0), AccessWidth32, 0xFFFFFFFF, 0xFFFFFFFF);
+ RwMem ((Bar5 + FCH_SATA_BAR5_REG430), AccessWidth32, 0xFFFFFFFF, 0xFFFFFFFF);
+ RwMem ((Bar5 + FCH_SATA_BAR5_REG4B0), AccessWidth32, 0xFFFFFFFF, 0xFFFFFFFF);
+
+ for ( PortNumByte = 0; PortNumByte < MAX_SATA_PORTS; PortNumByte++ ) {
+ RwMem ((Bar5 + 0x110 + (PortNumByte * 0x80)), AccessWidth32, 0xFFFFFFFF, 0x00);
+ }
+}
+
+/**
+ * sataBar5RegSet - Sata Bar5 register setting
+ *
+ *
+ * @param[in] FchDataPtr Fch configuration structure pointer.
+ *
+ */
+VOID
+SataBar5RegSet (
+ IN VOID *FchDataPtr
+ )
+{
+ UINT32 AndMaskDword;
+ UINT32 OrMaskDword;
+ UINT32 Bar5;
+ UINT8 EfuseByte;
+ UINT8 FchSataAggrLinkPmCap;
+ UINT8 FchSataPortMultCap;
+ UINT8 FchSataPscCap;
+ UINT8 FchSataSscCap;
+ UINT8 FchSataFisBasedSwitching;
+ UINT8 FchSataCccSupport;
+ UINT8 FchSataAhciEnclosureManagement;
+ FCH_DATA_BLOCK *LocalCfgPtr;
+
+ LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr;
+
+ FchSataAggrLinkPmCap = (UINT8) LocalCfgPtr->Sata.SataAggrLinkPmCap;
+ FchSataPortMultCap = (UINT8) LocalCfgPtr->Sata.SataPortMultCap;
+ FchSataPscCap = (UINT8) LocalCfgPtr->Sata.SataPscCap;
+ FchSataSscCap = (UINT8) LocalCfgPtr->Sata.SataSscCap;
+ FchSataFisBasedSwitching = (UINT8) LocalCfgPtr->Sata.SataFisBasedSwitching;
+ FchSataCccSupport = (UINT8) LocalCfgPtr->Sata.SataCccSupport;
+ FchSataAhciEnclosureManagement = (UINT8) LocalCfgPtr->Sata.SataAhciEnclosureManagement;
+
+ AndMaskDword = 0;
+ OrMaskDword = 0;
+ Bar5 = 0;
+
+ SataBar5setting (LocalCfgPtr, &Bar5);
+ EfuseByte = SATA_FIS_BASE_EFUSE_LOC;
+ GetEfuseStatus (&EfuseByte, LocalCfgPtr->StdHeader);
+
+ if ( !FchSataPortMultCap ) {
+ AndMaskDword |= BIT12;
+ }
+
+ if ( FchSataAggrLinkPmCap ) {
+ OrMaskDword |= BIT11;
+ } else {
+ AndMaskDword |= BIT11;
+ }
+
+ if ( FchSataPscCap ) {
+ OrMaskDword |= BIT1;
+ } else {
+ AndMaskDword |= BIT1;
+ }
+
+ if ( FchSataSscCap ) {
+ OrMaskDword |= BIT26;
+ } else {
+ AndMaskDword |= BIT26;
+ }
+
+ if ( FchSataFisBasedSwitching ) {
+ if (EfuseByte & BIT1) {
+ AndMaskDword |= BIT10;
+ } else {
+ OrMaskDword |= BIT10;
+ }
+ } else {
+ AndMaskDword |= BIT10;
+ }
+
+ //
+ // Disabling CCC (Command Completion Coalescing) support.
+ //
+ if ( FchSataCccSupport ) {
+ OrMaskDword |= BIT19;
+ } else {
+ AndMaskDword |= BIT19;
+ }
+
+ if ( FchSataAhciEnclosureManagement ) {
+ OrMaskDword |= BIT27;
+ } else {
+ AndMaskDword |= BIT27;
+ }
+
+ RwMem ((Bar5 + FCH_SATA_BAR5_REGFC), AccessWidth32, ~AndMaskDword, OrMaskDword);
+
+ //
+ // 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 ( LocalCfgPtr->Sata.SataEspPort.SataPortReg != 0 ) {
+ RwMem ((Bar5 + FCH_SATA_BAR5_REGF8), AccessWidth32, ~(LocalCfgPtr->Sata.SataEspPort.SataPortReg), 0);
+ RwMem ((Bar5 + FCH_SATA_BAR5_REGF8), AccessWidth32, 0xFF00FF00, (LocalCfgPtr->Sata.SataEspPort.SataPortReg << 16));
+ //
+ // External SATA Port Indication Registers
+ // If any of the ports was programmed as an external port, HCAP.SXS should also be set
+ //
+ RwMem ((Bar5 + FCH_SATA_BAR5_REGFC), AccessWidth32, ~(BIT20), BIT20);
+ } else {
+ //
+ // External SATA Port Indication Registers
+ // If any of the ports was programmed as an external port, HCAP.SXS should also be set (Clear for no ESP port)
+ //
+ RwMem ((Bar5 + FCH_SATA_BAR5_REGF8), AccessWidth32, 0xFF00FF00, 0x00);
+ RwMem ((Bar5 + FCH_SATA_BAR5_REGFC), AccessWidth32, ~(BIT20), 0x00);
+ }
+
+ if ( FchSataFisBasedSwitching ) {
+ if (EfuseByte & BIT1) {
+ RwMem ((Bar5 + FCH_SATA_BAR5_REGF8), AccessWidth32, 0x00FFFFFF, 0x00);
+ } else {
+ RwMem ((Bar5 + FCH_SATA_BAR5_REGF8), AccessWidth32, 0x00FFFFFF, 0xFF000000);
+ }
+ } else {
+ RwMem ((Bar5 + FCH_SATA_BAR5_REGF8), AccessWidth32, 0x00FFFFFF, 0x00);
+ }
+
+ if ( LocalCfgPtr->Sata.BiosOsHandOff == 1 ) {
+ RwMem ((Bar5 + FCH_SATA_BAR5_REG24), AccessWidth8, ~BIT0, BIT0);
+ } else {
+ RwMem ((Bar5 + FCH_SATA_BAR5_REG24), AccessWidth8, ~BIT0, 0x00);
+ }
+}
+
+/**
+ * FchSataSetDeviceNumMsi - Program Sata controller support
+ * device number cap & MSI cap
+ *
+ *
+ *
+ * @param[in] FchDataPtr Fch configuration structure pointer.
+ *
+ */
+VOID
+FchSataSetDeviceNumMsi (
+ IN VOID *FchDataPtr
+ )
+{
+ UINT32 Bar5;
+ FCH_DATA_BLOCK *LocalCfgPtr;
+ AMD_CONFIG_PARAMS *StdHeader;
+
+ LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr;
+ StdHeader = LocalCfgPtr->StdHeader;
+
+ Bar5 = 0;
+ SataBar5setting (LocalCfgPtr, &Bar5);
+ //
+ // RAID or AHCI
+ //
+ if (LocalCfgPtr->Sata.SataMode.IdeEnable == DISABLED) {
+ //
+ // IDE2 Controller is enabled
+ //
+ if (LocalCfgPtr->Sata.SataMode.Sata6AhciCap == ENABLED) {
+ //
+ // 6 AHCI mode
+ //
+ RwMem ((Bar5 + FCH_SATA_BAR5_REG0C), AccessWidth8, 0x00, 0x3F);
+ RwMem ((Bar5 + FCH_SATA_BAR5_REG00), AccessWidth8, ~(BIT2 + BIT1 + BIT0), BIT2 + BIT0);
+ RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG50 + 2), AccessWidth8, ~(BIT3 + BIT2 + BIT1), BIT2 + BIT1, StdHeader);
+ RwMem ((Bar5 + FCH_SATA_BAR5_REGFC), AccessWidth8, 0x07, 0x30);
+ } else {
+ RwMem ((Bar5 + FCH_SATA_BAR5_REG0C), AccessWidth8, 0x00, 0x0F);
+ if ( LocalCfgPtr->Sata.SataCccSupport ) {
+ RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG50 + 2), AccessWidth8, ~(BIT3 + BIT2 + BIT1), BIT2 + BIT1, StdHeader);
+ RwMem ((Bar5 + FCH_SATA_BAR5_REGFC), AccessWidth8, 0x07, 0x20);
+ } else {
+ RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG50 + 2), AccessWidth8, ~(BIT3 + BIT2 + BIT1), BIT2, StdHeader);
+ }
+ }
+ } else {
+ //
+ // IDE2 Controller is disabled
+ //
+ RwMem ((Bar5 + FCH_SATA_BAR5_REG00), AccessWidth8, ~(BIT2 + BIT1 + BIT0), BIT2 + BIT1 + BIT0);
+ RwMem ((Bar5 + FCH_SATA_BAR5_REG0C), AccessWidth8, 0x00, 0xFF);
+ if ( LocalCfgPtr->Sata.SataCccSupport ) {
+ RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG50 + 2), AccessWidth8, ~(BIT3 + BIT2 + BIT1), BIT3, StdHeader);
+ RwMem ((Bar5 + FCH_SATA_BAR5_REGFC), AccessWidth8, 0x07, 0x40);
+ } else {
+ RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG50 + 2), AccessWidth8, ~(BIT3 + BIT2 + BIT1), BIT2 + BIT1, StdHeader);
+ }
+ }
+}
+
+
+/**
+ * FchSataDriveDetection - Sata drive detection
+ *
+ * - Sata Ide & Sata Ide to Ahci only
+ *
+ * @param[in] FchDataPtr Fch configuration structure pointer.
+ * @param[in] *Bar5Ptr Sata BAR5 base address.
+ *
+ */
+VOID
+FchSataDriveDetection (
+ IN VOID *FchDataPtr,
+ IN UINT32 *Bar5Ptr
+ )
+{
+ UINT32 SataBarInfo;
+ UINT8 PortNumByte;
+ UINT8 SataPortType;
+ UINT16 IoBaseWord;
+ UINT16 SataLoopVarWord;
+ FCH_DATA_BLOCK *LocalCfgPtr;
+ AMD_CONFIG_PARAMS *StdHeader;
+
+ LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr;
+ StdHeader = LocalCfgPtr->StdHeader;
+
+ for ( PortNumByte = 0; PortNumByte < 4; PortNumByte++ ) {
+
+ ReadMem (*Bar5Ptr + FCH_SATA_BAR5_REG128 + PortNumByte * 0x80, AccessWidth32, &SataBarInfo);
+
+ if ( ( SataBarInfo & 0x0F ) == 0x03 ) {
+ if ( PortNumByte & BIT0 ) {
+ //
+ //this port belongs to secondary channel
+ //
+ ReadPci (((UINT32) (SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG18), AccessWidth16, &IoBaseWord, StdHeader);
+ } else {
+ //
+ //this port belongs to primary channel
+ //
+ ReadPci (((UINT32) (SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG10), AccessWidth16, &IoBaseWord, StdHeader);
+ }
+
+ //
+ //if legacy ide mode, then the bar registers don't contain the correct values. So we need to hardcode them
+ //
+ if ( LocalCfgPtr->Sata.SataClass == SataLegacyIde ) {
+ IoBaseWord = ( (0x170) | ((UINT16) ( (~((UINT8) (PortNumByte & BIT0) << 7)) & 0x80 )) );
+ }
+
+ if ( PortNumByte & BIT1 ) {
+ //
+ //this port is slave
+ //
+ SataPortType = 0xB0;
+ } else {
+ //
+ //this port is master
+ //
+ SataPortType = 0xA0;
+ }
+
+ IoBaseWord &= 0xFFF8;
+ LibAmdIoWrite (AccessWidth8, IoBaseWord + 6, &SataPortType, StdHeader);
+
+ //
+ //Wait in loop for 30s for the drive to become ready
+ //
+ for ( SataLoopVarWord = 0; SataLoopVarWord < 300000; SataLoopVarWord++ ) {
+ LibAmdIoRead (AccessWidth8, IoBaseWord + 7, &SataPortType, StdHeader);
+ if ( (SataPortType & 0x88) == 0 ) {
+ break;
+ }
+ FchStall (100, StdHeader);
+ }
+ }
+ }
+}
+
+/**
+ * FchShutdownUnconnectedSataPortClock - Shutdown unconnected
+ * Sata port clock
+ *
+ * - Sata Ide & Sata Ide to Ahci only
+ *
+ * @param[in] FchDataPtr Fch configuration structure pointer.
+ * @param[in] Bar5 Sata BAR5 base address.
+ *
+ */
+VOID
+FchShutdownUnconnectedSataPortClock (
+ IN VOID *FchDataPtr,
+ IN UINT32 Bar5
+ )
+{
+ UINT8 PortNumByte;
+ UINT8 PortSataStatusByte;
+ UINT8 NumOfPorts;
+ UINT8 FchSataClkAutoOff;
+ FCH_DATA_BLOCK *LocalCfgPtr;
+ AMD_CONFIG_PARAMS *StdHeader;
+
+ LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr;
+ StdHeader = LocalCfgPtr->StdHeader;
+ FchSataClkAutoOff = (UINT8) LocalCfgPtr->Sata.SataClkAutoOff;
+
+ NumOfPorts = 0;
+ //
+ // Enable SATA auto clock control by default
+ //
+ for ( PortNumByte = 0; PortNumByte < MAX_SATA_PORTS; PortNumByte++ ) {
+ ReadMem (Bar5 + FCH_SATA_BAR5_REG128 + (PortNumByte * 0x80), AccessWidth8, &PortSataStatusByte);
+ //
+ // Shutdown the clock for the port and do the necessary port reporting changes.
+ // Error port status should be 1 not 3
+ //
+ if ( ((PortSataStatusByte & 0x0F) != 0x03) && (! ((LocalCfgPtr->Sata.SataEspPort.SataPortReg) & (1 << PortNumByte))) ) {
+ RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG40 + 2), AccessWidth8, 0xFF, (1 << PortNumByte), StdHeader);
+ RwMem (Bar5 + FCH_SATA_BAR5_REG0C, AccessWidth8, ~(1 << PortNumByte), 00);
+ }
+ } ///end of for (PortNumByte=0;PortNumByte<6;PortNumByte++)
+
+ ReadMem (Bar5 + FCH_SATA_BAR5_REG0C, AccessWidth8, &PortSataStatusByte);
+
+ //
+ //if all ports are in disabled state, report at least one port
+ //
+ if ( (PortSataStatusByte & 0xFF) == 0) {
+ RwMem (Bar5 + FCH_SATA_BAR5_REG0C, AccessWidth8, (UINT32) ~(0xFF), 01);
+ }
+
+ ReadMem (Bar5 + FCH_SATA_BAR5_REG0C, AccessWidth8, &PortSataStatusByte);
+
+ for (PortNumByte = 0; PortNumByte < MAX_SATA_PORTS; PortNumByte ++) {
+ if (PortSataStatusByte & (1 << PortNumByte)) {
+ NumOfPorts++;
+ }
+ }
+
+ if ( NumOfPorts == 0) {
+ NumOfPorts = 0x01;
+ }
+
+ RwMem (Bar5 + FCH_SATA_BAR5_REG00, AccessWidth8, 0xE0, NumOfPorts - 1);
+}
+
+/**
+ * FchSataSetPortGenMode - Set Sata port mode (each) for
+ * Gen1/Gen2/Gen3
+ *
+ *
+ * @param[in] FchDataPtr Fch configuration structure pointer.
+ *
+ */
+VOID
+FchSataSetPortGenMode (
+ IN VOID *FchDataPtr
+ )
+{
+ UINT32 Bar5;
+ UINT8 PortNumByte;
+ UINT8 PortModeByte;
+ UINT16 SataPortMode;
+ BOOLEAN FchSataHotRemovalEnh;
+ FCH_DATA_BLOCK *LocalCfgPtr;
+ AMD_CONFIG_PARAMS *StdHeader;
+
+ LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr;
+ StdHeader = LocalCfgPtr->StdHeader;
+
+ FchSataHotRemovalEnh = LocalCfgPtr->Sata.SataHotRemovalEnh;
+
+ SataBar5setting (LocalCfgPtr, &Bar5);
+ SataPortMode = (UINT16)LocalCfgPtr->Sata.SataPortMd.SataPortMode;
+ PortNumByte = 0;
+
+ while ( PortNumByte < 8 ) {
+ PortModeByte = (UINT8) (SataPortMode & 3);
+ if ( (PortModeByte == BIT0) || (PortModeByte == BIT1) ) {
+ if ( PortModeByte == BIT0 ) {
+ //
+ // set GEN 1
+ //
+ RwMem (Bar5 + FCH_SATA_BAR5_REG12C + PortNumByte * 0x80, AccessWidth8, 0x0F, 0x10);
+ }
+
+ if ( PortModeByte == BIT1 ) {
+ //
+ // set GEN2 (default is GEN3)
+ //
+ RwMem (Bar5 + FCH_SATA_BAR5_REG12C + PortNumByte * 0x80, AccessWidth8, 0x0F, 0x20);
+ }
+
+ RwMem (Bar5 + FCH_SATA_BAR5_REG12C + PortNumByte * 0x80, AccessWidth8, 0xFF, 0x01);
+ }
+
+ SataPortMode >>= 2;
+ PortNumByte ++;
+ }
+
+ FchStall (1000, StdHeader);
+ SataPortMode = (UINT16)LocalCfgPtr->Sata.SataPortMd.SataPortMode;
+ PortNumByte = 0;
+
+ while ( PortNumByte < 8 ) {
+ PortModeByte = (UINT8) (SataPortMode & 3);
+
+ if ( (PortModeByte == BIT0) || (PortModeByte == BIT1) ) {
+ RwMem (Bar5 + FCH_SATA_BAR5_REG12C + PortNumByte * 0x80, AccessWidth8, 0xFE, 0x00);
+ }
+
+ PortNumByte ++;
+ SataPortMode >>= 2;
+ }
+
+ //
+ // Sata Hot Removal Enhance setting
+ //
+ if ( FchSataHotRemovalEnh ) {
+ RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG80), AccessWidth16, ~BIT8, BIT8, StdHeader);
+ RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REGA8), AccessWidth16, ~BIT0, BIT0, StdHeader);
+ RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG80), AccessWidth16, ~BIT8, 0, StdHeader);
+ }
+}
+