blob: 6aefa35e1b76dc4074654c09f92da8ed644ae796 [file] [log] [blame]
/* $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);
}
}