/** @file
Perform related functions for PCH Sata in DXE phase
Copyright (c) 2017, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include
/**
Perform the remaining configuration on PCH SATA to perform device detection,
then set the SATA SPD and PxE corresponding, and set the Register Lock on PCH SATA
@retval None
**/
VOID
ConfigurePchSataOnEndOfDxe (
VOID
)
{
UINTN PciSataRegBase;
UINT16 SataPortsEnabled;
PCH_SERIES PchSeries;
UINT16 WordReg;
UINT32 DwordReg;
UINTN Index;
///
/// SATA PCS: Enable the port in any of below condition:
/// i.) Hot plug is enabled
/// ii.) A device is attached
/// iii.) Test mode is enabled
/// iv.) Configured as eSATA port
///
PciSataRegBase = MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SATA, PCI_FUNCTION_NUMBER_PCH_SATA);
PchSeries = GetPchSeries ();
SataPortsEnabled = 0;
if (MmioRead16 (PciSataRegBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
return;
}
if (PchSeries == PchLp) {
WordReg = MmioRead16 (PciSataRegBase + R_PCH_LP_SATA_PCS);
for (Index = 0; Index < GetPchMaxSataPortNum (); Index++) {
if ((mPchConfigHob->Sata.PortSettings[Index].HotPlug == TRUE) ||
(WordReg & (B_PCH_LP_SATA_PCS_P0P << Index)) ||
(mPchConfigHob->Sata.TestMode == TRUE) ||
(mPchConfigHob->Sata.PortSettings[Index].External == TRUE)) {
SataPortsEnabled |= (mPchConfigHob->Sata.PortSettings[Index].Enable << Index);
}
}
///
/// Set MAP."Sata PortX Disable", SATA PCI offset 90h[10:8] to 1b if SATA Port 0/1/2 is disabled
///
MmioOr16 (PciSataRegBase + R_PCH_LP_SATA_MAP, ((~SataPortsEnabled << N_PCH_LP_SATA_MAP_SPD) & (UINT16) B_PCH_LP_SATA_MAP_SPD));
S3BootScriptSaveMemWrite (
S3BootScriptWidthUint16,
(UINTN) (PciSataRegBase + R_PCH_LP_SATA_MAP),
1,
(VOID *) (UINTN) (PciSataRegBase + R_PCH_LP_SATA_MAP)
);
///
/// Program PCS "Port X Enabled", SATA PCI offset 92h[2:0] = Port 0~2 Enabled bit as per SataPortsEnabled value.
///
MmioOr16 (PciSataRegBase + R_PCH_LP_SATA_PCS, SataPortsEnabled);
S3BootScriptSaveMemWrite (
S3BootScriptWidthUint16,
(UINTN) (PciSataRegBase + R_PCH_LP_SATA_PCS),
1,
(VOID *) (UINTN) (PciSataRegBase + R_PCH_LP_SATA_PCS)
);
} else {
DwordReg = MmioRead32 (PciSataRegBase + R_PCH_H_SATA_PCS);
for (Index = 0; Index < GetPchMaxSataPortNum (); Index++) {
if ((mPchConfigHob->Sata.PortSettings[Index].HotPlug == TRUE) ||
(DwordReg & (B_PCH_H_SATA_PCS_P0P << Index)) ||
(mPchConfigHob->Sata.TestMode == TRUE) ||
(mPchConfigHob->Sata.PortSettings[Index].External == TRUE)) {
SataPortsEnabled |= (mPchConfigHob->Sata.PortSettings[Index].Enable << Index);
}
}
///
/// Set MAP."Sata PortX Disable", SATA PCI offset 90h[23:16] to 1b if SATA Port 0/1/2/3/4/5/6/7 is disabled
///
MmioOr32 (PciSataRegBase + R_PCH_H_SATA_MAP, ((~SataPortsEnabled << N_PCH_H_SATA_MAP_SPD) & (UINT32) B_PCH_H_SATA_MAP_SPD));
S3BootScriptSaveMemWrite (
S3BootScriptWidthUint32,
(UINTN) (PciSataRegBase + R_PCH_H_SATA_MAP),
1,
(VOID *) (UINTN) (PciSataRegBase + R_PCH_H_SATA_MAP)
);
///
/// Program PCS "Port X Enabled", SATA PCI offset 94h[7:0] = Port 0~7 Enabled bit as per SataPortsEnabled value.
///
MmioOr16 (PciSataRegBase + R_PCH_H_SATA_PCS, SataPortsEnabled);
S3BootScriptSaveMemWrite (
S3BootScriptWidthUint16,
(UINTN) (PciSataRegBase + R_PCH_H_SATA_PCS),
1,
(VOID *) (UINTN) (PciSataRegBase + R_PCH_H_SATA_PCS)
);
}
///
/// Step 14
/// Program SATA PCI offset 9Ch [31] to 1b
///
MmioOr32 ((UINTN) (PciSataRegBase + R_PCH_SATA_SATAGC), BIT31);
S3BootScriptSaveMemWrite (
S3BootScriptWidthUint32,
(UINTN) (PciSataRegBase + R_PCH_SATA_SATAGC),
1,
(VOID *) (UINTN) (PciSataRegBase + R_PCH_SATA_SATAGC)
);
}