summaryrefslogtreecommitdiff
path: root/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchSata.c
diff options
context:
space:
mode:
Diffstat (limited to 'ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchSata.c')
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchSata.c1547
1 files changed, 1547 insertions, 0 deletions
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchSata.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchSata.c
new file mode 100644
index 0000000..56021ca
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchSata.c
@@ -0,0 +1,1547 @@
+/** @file
+ Configures PCH Sata Controller
+
+@copyright
+ Copyright (c) 2008 - 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#include "PchInit.h"
+
+
+EFI_STATUS
+ConfigureSataAhci (
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ UINT32 RootComplexBar,
+ UINT16 GpioBase
+ );
+
+EFI_STATUS
+ConfigureSataSpeedIde (
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ UINTN PciDevFuncRegBase,
+ UINTN MaxPorts
+ );
+
+EFI_STATUS
+DisableSataController (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN OUT UINT32 *FuncDisableReg
+ );
+
+/**
+ Configures PCH Sata Controller
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in, out] FuncDisableReg Function Disable Register
+ @param[in] GpioBase GPIO base address of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ConfigureSata (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar,
+ IN OUT UINT32 *FuncDisableReg,
+ IN UINT16 GpioBase
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Index;
+ UINT16 WordReg;
+ UINT16 SataGcReg;
+ UINTN PciD31F2RegBase;
+ PCH_SATA_CONFIG *SataConfig;
+ UINT16 SataPortsEnabled;
+ UINT16 SataModeSelect;
+ UINTN PciD31F5RegBase;
+ UINTN PciDevFuncRegBase;
+ UINTN MaxPorts;
+ UINT32 Data32And;
+ UINT32 Data32Or;
+ PCH_SERIES PchSeries;
+
+ DEBUG ((EFI_D_INFO, "ConfigureSata() Start\n"));
+
+ PchSeries = GetPchSeries();
+ SataConfig = PchPlatformPolicy->SataConfig;
+ PciD31F2RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 31, 2, 0);
+ PciD31F5RegBase = 0;
+ if (PchSeries == PchH) {
+ PciD31F5RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 31, 5, 0);
+ }
+ SataModeSelect = MmioRead16 (PciD31F2RegBase + R_PCH_SATA_MAP) & B_PCH_SATA_MAP_SMS_MASK;
+ Status = EFI_SUCCESS;
+
+ ///
+ /// Check to disable SATA controller
+ ///
+ if (PchPlatformPolicy->DeviceEnabling->Sata == PCH_DEVICE_DISABLE) {
+ Status = DisableSataController (PchPlatformPolicy, FuncDisableReg);
+ return Status;
+ }
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 section 14.1.7 Additional Programming Requirements during
+ /// SATA Initialization
+ /// Step 12
+ /// Program D31:F2:9Ch[5] to 1b (Note: this must be programmed together with D31:F2:9Ch[7:6]
+ /// in word write)
+ ///
+ SataGcReg = MmioRead16 (PciD31F2RegBase + R_PCH_SATA_SCLKGC);
+ SataGcReg |= BIT5;
+
+ switch (SataModeSelect) {
+#ifdef TRAD_FLAG
+ case V_PCH_SATA_MAP_SMS_IDE:
+ if (PchSeries == PchH) {
+ ///
+ /// Set Native IDE decoding
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 14.1.3 Set the Programming Interface
+ /// Using native IDE is only possible when the SATA controller is operating in IDE mode.
+ /// The programming interface is selected by setting the programming interface register
+ /// (PI = Reg: 09h) appropriately. There are two native mode enabling bits in the
+ /// PI register to control the primary and secondary channels of SATA1.
+ ///
+ /// Only D31:F2 needs to be set. D31:F5 is readonly
+ ///
+ if (SataConfig->LegacyMode == PCH_DEVICE_ENABLE) {
+ MmioAnd8 (
+ PciD31F2RegBase + R_PCH_SATA_PI_REGISTER,
+ (UINT8)~(B_PCH_SATA_PI_REGISTER_PNE | B_PCH_SATA_PI_REGISTER_SNE)
+ );
+ } else {
+ MmioOr8 (
+ PciD31F2RegBase + R_PCH_SATA_PI_REGISTER,
+ (UINT8) B_PCH_SATA_PI_REGISTER_PNE | B_PCH_SATA_PI_REGISTER_SNE
+ );
+ }
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_PI_REGISTER),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_PI_REGISTER)
+ );
+ MmioOr16 ((UINTN) (PciD31F5RegBase + R_PCH_SATA_TIMP), (UINT16) (B_PCH_SATA_TIM_IDE));
+ WordReg = MmioRead16 (PciD31F5RegBase + R_PCH_SATA_TIMP);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F5RegBase + R_PCH_SATA_TIMP),
+ 1,
+ &WordReg
+ );
+ MmioOr16 ((UINTN) (PciD31F5RegBase + R_PCH_SATA_TIMS), (UINT16) (B_PCH_SATA_TIM_IDE));
+ WordReg = MmioRead16 (PciD31F5RegBase + R_PCH_SATA_TIMS);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F5RegBase + R_PCH_SATA_TIMS),
+ 1,
+ &WordReg
+ );
+ }
+ break;
+#endif // TRAD_FLAG
+
+ case V_PCH_SATA_MAP_SMS_RAID:
+ ///
+ /// When RAID alternate ID is enabled, the Device ID will change to 30XX from 282X in RAID mode
+ ///
+ if (SataConfig->RaidAlternateId == PCH_DEVICE_ENABLE) {
+ SataGcReg &= ~B_PCH_SATA_SCLKGC_AIES;
+ SataGcReg |= B_PCH_SATA_SCLKGC_AIE;
+ }
+#ifdef PCH_SVR_WS_SKU
+ SataGcReg &= ~B_PCH_SATA_SCLKGC_AIE;
+ SataGcReg |= B_PCH_SATA_SCLKGC_AIES;
+#endif
+ break;
+ }
+ ///
+ /// Unconditional write is necessary to lock the register
+ ///
+ MmioWrite16 (PciD31F2RegBase + R_PCH_SATA_SCLKGC, SataGcReg);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SCLKGC),
+ 1,
+ &SataGcReg
+ );
+
+ ///
+ /// Set legacy IDE decoding
+ /// These bits also effect with AHCI mode when PCH is using legacy mechanisms.
+ ///
+ MmioOr16 ((UINTN) (PciD31F2RegBase + R_PCH_SATA_TIMP), (UINT16) (B_PCH_SATA_TIM_IDE));
+ WordReg = MmioRead16 (PciD31F2RegBase + R_PCH_SATA_TIMP);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_TIMP),
+ 1,
+ &WordReg
+ );
+
+ MmioOr16 ((UINTN) (PciD31F2RegBase + R_PCH_SATA_TIMS), (UINT16) (B_PCH_SATA_TIM_IDE));
+ WordReg = MmioRead16 (PciD31F2RegBase + R_PCH_SATA_TIMS);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_TIMS),
+ 1,
+ &WordReg
+ );
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, section 19.10
+ /// Step 4.2
+ /// D31:F2 PCS: Enable the port in any of below condition:
+ /// Hot plug is enabled
+ /// A device is attached
+ /// Test mode is enabled
+ /// Configured as eSATA port
+ ///
+ SataPortsEnabled = 0;
+ WordReg = MmioRead16 (PciD31F2RegBase + R_PCH_SATA_PCS);
+ for (Index = 0; Index < GetPchMaxSataPortNum (); Index++) {
+ if ((SataConfig->PortSettings[Index].HotPlug == PCH_DEVICE_ENABLE) ||
+ (WordReg & (BIT0 << (8 + Index))) ||
+ (SataConfig->TestMode == PCH_DEVICE_ENABLE) ||
+ (SataConfig->PortSettings[Index].External == PCH_DEVICE_ENABLE)) {
+ SataPortsEnabled |= (SataConfig->PortSettings[Index].Enable << Index);
+ }
+ }
+ if (PchSeries == PchH) {
+ ///
+ /// D31:F5 PCS: Enable the port in any of below condition:
+ /// Hot plug is enabled
+ /// A device is attached
+ /// Test mode is enabled
+ ///
+ /// Note: In IDE mode, SATA Port 4/5 enable status needs to be checked before setting D31:F2 MAP[13:8].
+ /// It's because:
+ /// (1) SataPortsEnabled [5:4] will be set while it is configured as eSATA port that is not
+ /// supported in IDE mode.
+ /// (2) D31:F2 MAP[12] setting needs to sync up with D31:F5 MAP[8] setting.
+ /// D31:F2 MAP[13] setting needs to sync up with D31:F5 MAP[9] setting.
+ ///
+ if (SataModeSelect == V_PCH_SATA_MAP_SMS_IDE) {
+ ///
+ /// Clear SataPortsEnabled [5:4] before checking SATA Port 4/5 enable status
+ ///
+ SataPortsEnabled &= ~(BIT5 | BIT4);
+ WordReg = MmioRead16 (PciD31F5RegBase + R_PCH_SATA_PCS);
+ for (Index = 4; Index < GetPchMaxSataPortNum (); Index++) {
+ ///
+ /// D31:F5 PCS[9:8] = Port 4/5 Present bit
+ ///
+ if ((SataConfig->PortSettings[Index].HotPlug == PCH_DEVICE_ENABLE) ||
+ (WordReg & (BIT0 << (4 + Index))) ||
+ (SataConfig->TestMode == PCH_DEVICE_ENABLE)) {
+ ///
+ /// SataPortsEnabled [5:4] = Sata Port 4/5 enable status
+ ///
+ SataPortsEnabled |= (SataConfig->PortSettings[Index].Enable << Index);
+ }
+ }
+ }
+ }
+
+ ///
+ /// Set MAP register for PCH H
+ /// Set D31:F2 MAP[13:8] to 1b if SATA Port 0/1/2/3/4/5 is disabled
+ /// SataPortsEnabled [5:0] = Sata Port 0/1/2/3/4/5 enable status
+ /// MAP.SPD (D31:F2:Reg90h[13:8]) is Write Once
+ ///
+ /// Set MAP register for PCH LP
+ /// Set D31:F2 MAP[11:8] to 1b if SATA Port 0/1/2/3 is disabled
+ /// SataPortsEnabled [3:0] = Sata Port 0/1/2/3 enable status
+ /// MAP.SPD (D31:F2:Reg90h[11:8]) is Write Once
+ ///
+ switch (PchSeries) {
+ case PchLp:
+ MmioOr16 ((UINTN) (PciD31F2RegBase + R_PCH_SATA_MAP), ((~SataPortsEnabled << 8) & (UINT16) B_PCH_LP_SATA_MAP_SPD));
+ break;
+
+ case PchH:
+ MmioOr16 ((UINTN) (PciD31F2RegBase + R_PCH_SATA_MAP), ((~SataPortsEnabled << 8) & (UINT16) B_PCH_H_SATA_MAP_SPD));
+ break;
+
+ default:
+ break;
+ }
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_MAP),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_MAP)
+ );
+
+ //
+ // D31:F2 PCS[5:0] = Port 0~5 Enabled bit
+ // as per SataPortsEnabled value.
+ //
+ MmioOr16 ((UINTN) (PciD31F2RegBase + R_PCH_SATA_PCS), (UINT16) (SataPortsEnabled));
+
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_PCS),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_PCS)
+ );
+
+#ifdef TRAD_FLAG
+ if (PchSeries == PchH) {
+ ///
+ /// Set D31:F5 MAP[9:8] and D31:F5 PCS[1:0]
+ ///
+ if (SataModeSelect == V_PCH_SATA_MAP_SMS_IDE) {
+ ///
+ /// Set D31:F5 MAP[9:8] to 1b if SATA Port 4/5 is disabled
+ /// SataPortsEnabled [5:4] = Sata Port 4/5 enable status
+ /// MAP.SPD (D31:F5:Reg90h[9:8]) is Write Once
+ ///
+ MmioOr16 ((UINTN) (PciD31F5RegBase + R_PCH_SATA_MAP), ((~SataPortsEnabled << 4) & (UINT16) B_PCH_SATA2_MAP_SPD));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F5RegBase + R_PCH_SATA_MAP),
+ 1,
+ (VOID *) (UINTN) (PciD31F5RegBase + R_PCH_SATA_MAP)
+ );
+ ///
+ /// D31:F5 PCS[1:0] = Port 4/5 Enabled bit
+ ///
+ MmioAndThenOr16 (
+ (UINTN) (PciD31F5RegBase + R_PCH_SATA_PCS),
+ (UINT16) (~(B_PCH_SATA2_PCS_PORT5_EN | B_PCH_SATA2_PCS_PORT4_EN)),
+ (UINT16) (SataPortsEnabled >> 4)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F5RegBase + R_PCH_SATA_PCS),
+ 1,
+ (VOID *) (UINTN) (PciD31F5RegBase + R_PCH_SATA_PCS)
+ );
+ }
+ }
+#endif // TRAD_FLAG
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, section 19.10
+ /// Step 4.2
+ /// After configuring Port and Control Status (PCS) Register Port x Enabled (PxE) bits accordingly,
+ /// wait 1.4 micro second
+ ///
+ PchPmTimerStall (0x02);
+ SCRIPT_STALL (EFI_ACPI_S3_RESUME_SCRIPT_TABLE, 0x02);
+
+ ///
+ /// After programming the PCS.PxE, check if it is zero.
+ /// If no port enabled, terminate the SATA configuration and disable the SATA controller.
+ ///
+ WordReg = MmioRead16 ((UINTN) (PciD31F2RegBase + R_PCH_SATA_PCS));
+ WordReg &= (UINT16) ((1 << GetPchMaxSataPortNum ()) - 1);
+#ifdef TRAD_FLAG
+ if (WordReg == 0) {
+ if ((PchSeries == PchH) && (SataModeSelect == V_PCH_SATA_MAP_SMS_IDE)) {
+ WordReg = MmioRead16 ((UINTN) (PciD31F5RegBase + R_PCH_SATA_PCS));
+ WordReg &= (UINT16) (B_PCH_SATA2_PCS_PORT5_EN |
+ B_PCH_SATA2_PCS_PORT4_EN);
+ }
+ }
+#endif // TRAD_FLAG
+ if (WordReg == 0) {
+ Status = DisableSataController (PchPlatformPolicy, FuncDisableReg);
+ return Status;
+ }
+
+ if (PchSeries == PchLp) {
+ ///
+ /// If Listen Mode support is not required, program D31:F2:98h[24] to 1b.
+ ///
+ if ((SataConfig->PortSettings[0].HotPlug == PCH_DEVICE_DISABLE) &&
+ (SataConfig->PortSettings[1].HotPlug == PCH_DEVICE_DISABLE) &&
+ (SataConfig->PortSettings[2].HotPlug == PCH_DEVICE_DISABLE) &&
+ (SataConfig->PortSettings[3].HotPlug == PCH_DEVICE_DISABLE)) {
+ MmioOr32 ((UINTN) (PciD31F2RegBase + 0x98), (UINT32) (BIT24));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + 0x98),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + 0x98)
+ );
+ }
+ }
+
+ ///
+ /// Configure AHCI
+ ///
+ if (PchSeries == PchLp) {
+ if (SataModeSelect != V_PCH_SATA_MAP_SMS_LOOBACK_TESTMODE) {
+ Status = ConfigureSataAhci (PchPlatformPolicy, RootComplexBar, GpioBase);
+ }
+ } else if (PchSeries == PchH) {
+ if (SataModeSelect != V_PCH_SATA_MAP_SMS_IDE) {
+ Status = ConfigureSataAhci (PchPlatformPolicy, RootComplexBar, GpioBase);
+ } else {
+ ///
+ /// If it is IDE mode
+ ///
+ if(PchPlatformPolicy->SataConfig->SpeedSupport != PchSataSpeedSupportDefault){
+ PciDevFuncRegBase = 0;
+ MaxPorts = 0;
+ for (Index = 0; Index < GetPchMaxSataControllerNum (); Index++) {
+ switch (Index) {
+ case 0:
+ PciDevFuncRegBase = PciD31F2RegBase;
+ MaxPorts = PCH_IDE_1_MAX_PORTS;
+ break;
+
+ case 1:
+ PciDevFuncRegBase = PciD31F5RegBase;
+ MaxPorts = PCH_IDE_2_MAX_PORTS;
+ break;
+ }
+ Status = ConfigureSataSpeedIde (PchPlatformPolicy, PciDevFuncRegBase, MaxPorts);
+ }
+ }
+ }
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, section 19.10
+ /// Step 4.1
+ /// Set bits D31:F2:Reg 94h[29:24] to 3Fh as part of the chipset initialization and before disabling the
+ /// SATA function if the SATA interface is not supported. BIOS can also set PCD bits for the un-routed ports
+ /// on the platform to disable clocks for the unused ports
+ /// Set the PCD [port x] = 1 if the corresponding PCS.PxE = 0 (either have a device attached or have
+ /// hot plug enabled)
+ ///
+ for (Index = 0; Index < GetPchMaxSataPortNum (); Index++) {
+ if ((SataPortsEnabled & (B_PCH_SATA_PCS_PORT0_EN << Index)) == 0) {
+ MmioOr32 ((UINTN) (PciD31F2RegBase + R_PCH_SATA_SCLKCG), (UINT32) (B_PCH_SATA_SCLKCG_PORT0_PCD << Index));
+ }
+ }
+
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SCLKCG),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_SCLKCG)
+ );
+ ///
+ /// PCH BIOS Spec Rev 0.5.6, 14.1.6 Power Optimizer Configuration
+ /// System BIOS must execute the following steps as part of System BIOS initialization
+ /// of the PCH SATA controller on both cold boot (G3/S5) and S3/S4 resume path. Please
+ /// refer to the PCH EDS, section 14.1.35.1 for the SATA initialization settings and
+ /// the actual register indexes/values to be programmed.
+ ///
+ if (PchPlatformPolicy->PwrOptConfig->PchPwrOptSata == PCH_DEVICE_ENABLE) {
+ ///
+ /// Step 1
+ /// Set D31:F2 + SIR Index 64h[31:0] = 883C9001h
+ ///
+ MmioWrite8 (PciD31F2RegBase + R_PCH_SATA_SIRI, 0x64);
+ if (PchSeries == PchH) {
+ MmioWrite32 (PciD31F2RegBase + R_PCH_SATA_STRD, 0x883C9001);
+ }
+ if (PchSeries == PchLp) {
+ MmioWrite32 (PciD31F2RegBase + R_PCH_SATA_STRD, 0x883C9003);
+ }
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD)
+ );
+ ///
+ /// Step 2
+ /// Set D31:F2 + SIR Index 68h[15:0] = 880Ah
+ ///
+ MmioWrite8 (PciD31F2RegBase + R_PCH_SATA_SIRI, 0x68);
+ Data32And = 0xFFFF0000;
+ Data32Or = 0x0000880A;
+ MmioAndThenOr32 (
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD),
+ Data32And,
+ Data32Or
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD)
+ );
+ ///
+ /// Step 3
+ /// Set D31:F2 + SIR Index 60h[3] = 1b
+ ///
+ MmioWrite8 (PciD31F2RegBase + R_PCH_SATA_SIRI, 0x60);
+ Data32And = 0xFFFFFFF7;
+ Data32Or = 0x00000008;
+ MmioAndThenOr32 (
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD),
+ Data32And,
+ Data32Or
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD)
+ );
+ ///
+ /// Step 4
+ /// Set D31:F2 + SIR Index 60h[0] = 1b
+ ///
+ MmioWrite8 (PciD31F2RegBase + R_PCH_SATA_SIRI, 0x60);
+ Data32And = 0xFFFFFFFE;
+//for Denlow SVR, refer Inel doc 493798, c state communication
+#ifdef PCH_DENLOW_SERVER_SUPPORT
+ /// Set D31:F2 + SIR Index 60h[0] = 0b
+ Data32Or = 0x00000000;
+#else
+ Data32Or = 0x00000001;
+#endif
+ MmioAndThenOr32 (
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD),
+ Data32And,
+ Data32Or
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD)
+ );
+ ///
+ /// Step 5
+ /// Set D31:F2 + SIR Index 60h[1] = 1b
+ ///
+ MmioWrite8 (PciD31F2RegBase + R_PCH_SATA_SIRI, 0x60);
+ Data32And = 0xFFFFFFFD;
+ Data32Or = 0x00000002;
+ MmioAndThenOr32 (
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD),
+ Data32And,
+ Data32Or
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD)
+ );
+ }
+
+#ifdef TRAD_FLAG
+ ///
+ /// For dual controller IDE mode, disable the individual controller if no port enabled.
+ /// For SATA2, the SATA configuration should be done through SATA1.
+ /// Therefore, disabling the SATA1/SATA2 after finishing SATA configuration.
+ ///
+ if (PchSeries == PchH) {
+ if (SataModeSelect == V_PCH_SATA_MAP_SMS_IDE) {
+ WordReg = MmioRead16 (PciD31F5RegBase + R_PCH_SATA_PCS);
+ WordReg &= (UINT16) (B_PCH_SATA2_PCS_PORT5_EN |
+ B_PCH_SATA2_PCS_PORT4_EN);
+ if (WordReg == 0) {
+ *FuncDisableReg |= B_PCH_RCRB_FUNC_DIS_SATA2;
+ }
+ WordReg = MmioRead16 (PciD31F2RegBase + R_PCH_SATA_PCS);
+ WordReg &= (UINT16) (B_PCH_SATA_PCS_PORT3_EN |
+ B_PCH_SATA_PCS_PORT2_EN |
+ B_PCH_SATA_PCS_PORT1_EN |
+ B_PCH_SATA_PCS_PORT0_EN);
+ if (WordReg == 0) {
+ *FuncDisableReg |= B_PCH_RCRB_FUNC_DIS_SATA1;
+ }
+ }
+ }
+#endif // TRAD_FLAG
+
+ DEBUG ((EFI_D_INFO, "ConfigureSata() End\n"));
+
+ return Status;
+}
+
+/**
+ Program the Max speed suported in each ports while in IDE mode.
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance.
+ @param[in] PciDevFuncRegBase Pci B/D/F/Reg Base for the Sata controler.
+ @param[in] MaxPorts Max Sata ports supported in the Controller.
+
+ @retval EFI_SUCESS The function exited sucessfully
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources are available
+**/
+EFI_STATUS
+ConfigureSataSpeedIde (
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ UINTN PciDevFuncRegBase,
+ UINTN MaxPorts
+ )
+{
+ EFI_STATUS Status;
+#ifdef TRAD_FLAG
+ PCH_SATA_CONFIG *SataConfig;
+ EFI_PHYSICAL_ADDRESS IoBaseAddress;
+ UINT16 SidpBa;
+ UINT16 SidpBaSaveRestore;
+ UINT16 DevCmdSaveRestore;
+ UINT8 Data8;
+ UINT16 Data16;
+ UINTN PortIndex;
+
+ Data16 = 0;
+ Data8 = 0;
+
+ SataConfig = PchPlatformPolicy->SataConfig;
+
+ Status = gDS->AllocateIoSpace (
+ EfiGcdAllocateAnySearchBottomUp,
+ EfiGcdIoTypeIo,
+ N_PCH_SATA_SIDP_BAR_ALIGNMENT,
+ V_PCH_SATA_SIDP_BAR_LENGTH,
+ &IoBaseAddress,
+ mImageHandle,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ ///
+ /// Set the SIDP BAR
+ ///
+ SidpBa = (UINT16) IoBaseAddress;
+ SidpBaSaveRestore = MmioRead16 (PciDevFuncRegBase + R_PCH_SATA_SIDP_BAR);
+ MmioWrite16 (PciDevFuncRegBase + R_PCH_SATA_SIDP_BAR, SidpBa);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciDevFuncRegBase + R_PCH_SATA_SIDP_BAR),
+ 1,
+ &SidpBa
+ );
+ ///
+ /// Enable command register I/O space decoding
+ ///
+ DevCmdSaveRestore = MmioRead16 (PciDevFuncRegBase + R_PCH_SATA_COMMAND);
+ MmioOr16 ((UINTN) (PciDevFuncRegBase + R_PCH_SATA_COMMAND), (UINT16) B_PCH_SATA_COMMAND_IOSE);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciDevFuncRegBase + R_PCH_SATA_COMMAND),
+ 1,
+ (VOID *) (UINTN) (PciDevFuncRegBase + R_PCH_SATA_COMMAND)
+ );
+ ///
+ /// Configure for the max speed support 1.5Gb/s, 3.0Gb/s and 6.0Gb/s.
+ ///
+ for (PortIndex = 0; PortIndex < MaxPorts; PortIndex++) {
+ switch (PortIndex) {
+ case 0:
+ Data16 = V_PCH_SATA_AHCI_SINDX_RIDX_SCTL | V_PCH_SATA_AHCI_SINDX_PIDX_PORT0;
+ break;
+
+ case 1:
+ Data16 = V_PCH_SATA_AHCI_SINDX_RIDX_SCTL | V_PCH_SATA_AHCI_SINDX_PIDX_PORT1;
+ break;
+
+ case 2:
+ Data16 = V_PCH_SATA_AHCI_SINDX_RIDX_SCTL | V_PCH_SATA_AHCI_SINDX_PIDX_PORT2;
+ break;
+
+ case 3:
+ Data16 = V_PCH_SATA_AHCI_SINDX_RIDX_SCTL | V_PCH_SATA_AHCI_SINDX_PIDX_PORT3;
+ break;
+ }
+
+ IoWrite16 ((UINTN) (SidpBa + R_PCH_SATA_SIDPBA_SINDX), Data16);
+ SCRIPT_IO_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (SidpBa + R_PCH_SATA_SIDPBA_SINDX),
+ 1,
+ &Data16
+ );
+
+ switch (SataConfig->SpeedSupport) {
+ case PchSataSpeedSupportGen1:
+ Data8 = V_PCH_SATA_SIDPBA_SDATA_GEN1;
+ break;
+
+ case PchSataSpeedSupportGen2:
+ Data8 = V_PCH_SATA_SIDPBA_SDATA_GEN2;
+ break;
+
+ case PchSataSpeedSupportGen3:
+ Data8 = V_PCH_SATA_SIDPBA_SDATA_GEN3;
+ break;
+ }
+
+ IoWrite8 ((UINTN) (SidpBa + R_PCH_SATA_SIDPBA_SDATA), Data8);
+ SCRIPT_IO_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (SidpBa + R_PCH_SATA_SIDPBA_SDATA),
+ 1,
+ &Data8
+ );
+ Data16 = MmioRead16 ((UINTN) (PciDevFuncRegBase + R_PCH_SATA_PCS)) >> 8;
+ if(((Data16 >> PortIndex) & BIT0)){
+ Data8 = (IoRead8 (SidpBa + R_PCH_SATA_SIDPBA_SDATA) & ~B_PCH_SATA_SIDPBA_SCTL_DET) + V_PCH_SATA_SIDPBA_SCTL_DET_COMRST;
+ IoWrite8 ((UINTN) (SidpBa + R_PCH_SATA_SIDPBA_SDATA), Data8);
+ SCRIPT_IO_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (SidpBa + R_PCH_SATA_SIDPBA_SDATA),
+ 1,
+ &Data8
+ );
+ PchPmTimerStall (1000);
+ SCRIPT_STALL (EFI_ACPI_S3_RESUME_SCRIPT_TABLE, 1000);
+ Data8 = (IoRead8 (SidpBa + R_PCH_SATA_SIDPBA_SDATA) & ~B_PCH_SATA_SIDPBA_SCTL_DET) + V_PCH_SATA_SIDPBA_SCTL_DET_NOINT;
+ IoWrite8 ((UINTN) (SidpBa + R_PCH_SATA_SIDPBA_SDATA), Data8);
+ SCRIPT_IO_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (SidpBa + R_PCH_SATA_SIDPBA_SDATA),
+ 1,
+ &Data8
+ );
+ }
+ }
+ ///
+ /// Restore command register I/O space decoding
+ ///
+ MmioWrite16 (PciDevFuncRegBase + R_PCH_SATA_COMMAND, DevCmdSaveRestore);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciDevFuncRegBase + R_PCH_SATA_COMMAND),
+ 1,
+ &DevCmdSaveRestore
+ );
+ ///
+ /// Restore the SIDP BAR
+ ///
+ MmioWrite16 (PciDevFuncRegBase + R_PCH_SATA_SIDP_BAR, SidpBaSaveRestore);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciDevFuncRegBase + R_PCH_SATA_SIDP_BAR),
+ 1,
+ &SidpBaSaveRestore
+ );
+ ///
+ /// Free allocated resources
+ ///
+ gDS->FreeIoSpace (IoBaseAddress, (UINT64) V_PCH_SATA_SIDP_BAR_LENGTH);
+#else
+ Status = EFI_SUCCESS;
+#endif // TRAD_FLAG
+
+ return Status;
+}
+
+/**
+ Program AHCI PI register for Enabled ports
+ Handle hotplug, and interlock switch setting,
+ and config related GPIOs.
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in] GpioBase GPIO base address of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ConfigureSataAhci (
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ UINT32 RootComplexBar,
+ UINT16 GpioBase
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS MemBaseAddress;
+ UINT32 AhciBar;
+ UINT32 CapRegister;
+ UINT32 Data32And;
+ UINT32 Data32Or;
+ UINT32 DwordReg;
+ UINT32 PxCMDRegister;
+ UINT16 SataPortsEnabled;
+ UINT8 Index;
+ UINTN PciD31F2RegBase;
+ UINT16 WordReg;
+ UINT8 ByteReg;
+ PCH_SATA_CONFIG *SataConfig;
+ UINT16 SataModeSelect;
+ PCH_SERIES PchSeries;
+ UINT8 SataResetGpio[LPTH_AHCI_MAX_PORTS] = {
+ PCH_GPIO_SATA_PORT0_RESET,
+ PCH_GPIO_SATA_PORT1_RESET,
+ PCH_GPIO_SATA_PORT2_RESET,
+ PCH_GPIO_SATA_PORT3_RESET,
+ PCH_GPIO_SATA_PORT4_RESET,
+ PCH_GPIO_SATA_PORT5_RESET,
+ };
+
+ UINT16 SataResetLpGpio[LPTLP_AHCI_MAX_PORTS] = {
+ PCH_LP_GPIO_SATA_PORT0_RESET,
+ PCH_LP_GPIO_SATA_PORT1_RESET,
+ PCH_LP_GPIO_SATA_PORT2_RESET,
+ PCH_LP_GPIO_SATA_PORT3_RESET,
+ };
+
+ DEBUG ((EFI_D_INFO, "ConfigureSataAhci() Start\n"));
+ PchSeries = GetPchSeries();
+ SataConfig = PchPlatformPolicy->SataConfig;
+ PciD31F2RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 31, 2, 0);
+ SataModeSelect = MmioRead16 (PciD31F2RegBase + R_PCH_SATA_MAP) & B_PCH_SATA_MAP_SMS_MASK;
+ DwordReg = 0;
+
+ ///
+ /// Allocate the AHCI BAR
+ ///
+ MemBaseAddress = 0x0ffffffff;
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateMaxAddressSearchBottomUp,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ N_PCH_SATA_AHCI_BAR_ALIGNMENT, // 2^11: 2K Alignment
+ V_PCH_SATA_AHCI_BAR_LENGTH, // 2K Length
+ &MemBaseAddress,
+ mImageHandle,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ ///
+ /// Set the AHCI BAR
+ ///
+ AhciBar = (UINT32) MemBaseAddress;
+ MmioWrite32 (PciD31F2RegBase + R_PCH_SATA_AHCI_BAR, AhciBar);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_AHCI_BAR),
+ 1,
+ &AhciBar
+ );
+
+ ///
+ /// Enable command register memory space decoding
+ ///
+ MmioOr16 ((UINTN) (PciD31F2RegBase + R_PCH_SATA_COMMAND), (UINT16) B_PCH_SATA_COMMAND_MSE);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_COMMAND),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_COMMAND)
+ );
+
+ ///
+ /// Assert if the memory data of AhciBar is invalid.
+ ///
+ ASSERT (MmioRead32 (AhciBar) != 0xFFFFFFFF);
+
+ ///
+ /// Get Port Settings
+ ///
+ SataPortsEnabled = MmioRead16 ((UINTN) (PciD31F2RegBase + R_PCH_SATA_PCS));
+ if (PchSeries == PchH) {
+ SataPortsEnabled &= (UINT16) (B_PCH_SATA_PCS_PORT5_EN |
+ B_PCH_SATA_PCS_PORT4_EN |
+ B_PCH_SATA_PCS_PORT3_EN |
+ B_PCH_SATA_PCS_PORT2_EN |
+ B_PCH_SATA_PCS_PORT1_EN |
+ B_PCH_SATA_PCS_PORT0_EN );
+ } else if (PchSeries == PchLp) {
+ SataPortsEnabled &= (UINT16) (B_PCH_SATA_PCS_PORT3_EN |
+ B_PCH_SATA_PCS_PORT2_EN |
+ B_PCH_SATA_PCS_PORT1_EN |
+ B_PCH_SATA_PCS_PORT0_EN );
+ }
+
+ ///
+ /// Read the default value of the Host Capabilites Register
+ /// NOTE: many of the bits in this register are R/WO (Read/Write Once)
+ ///
+ CapRegister = MmioRead32 (AhciBar + R_PCH_SATA_AHCI_CAP);
+ CapRegister &= (UINT32)~(B_PCH_SATA_AHCI_CAP_SIS | B_PCH_SATA_AHCI_CAP_SSS | B_PCH_SATA_AHCI_CAP_SALP |
+ B_PCH_SATA_AHCI_CAP_PMS | B_PCH_SATA_AHCI_CAP_SSC | B_PCH_SATA_AHCI_CAP_PSC |
+ B_PCH_SATA_AHCI_CAP_SXS);
+ if (PchSeries == PchLp) {
+ CapRegister &= (UINT32)~(B_PCH_SATA_AHCI_CAP_SAM);
+ }
+
+ for (Index = 0; Index < GetPchMaxSataPortNum (); Index++) {
+ ///
+ /// Check PCS.PxE to know if the SATA Port x is disabled.
+ ///
+ if ((SataPortsEnabled & (B_PCH_SATA_PCS_PORT0_EN << Index)) == 0) {
+ continue;
+ }
+ if (PchSeries == PchLp) {
+ ///
+ /// Program AhciBar + 0h[18] = 1b
+ ///
+ CapRegister |= B_PCH_SATA_AHCI_CAP_SAM;
+ }
+
+ if (SataConfig->PortSettings[Index].InterlockSw == PCH_DEVICE_ENABLE) {
+ ///
+ /// Mechanical Presence Switch is Enabled for at least one of the ports
+ ///
+ CapRegister |= B_PCH_SATA_AHCI_CAP_SIS;
+ }
+
+ if ((SataConfig->PortSettings[Index].SpinUp == PCH_DEVICE_ENABLE) ||
+ (SataConfig->PortSettings[Index].External == PCH_DEVICE_ENABLE)) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 14.1.4 Initialize Registers in AHCI Memory-Mapped Space
+ /// Step 1.4
+ /// Set SSS (ABAR + 00h[27]) to enable SATA controller supports staggered
+ /// spin-up on its ports, for use in balancing power spikes
+ /// SATA Port Spin up is supported at least one of the ports
+ /// If this is an extra eSATA port. It needs to be hotpluggable but it's usually empty anyway
+ /// so LPM is not available but Listen Mode is available, so it will have good power management.
+ /// If Sata Test Mode enabled, then uncoditonally clear SSS (ABAR + 00h[27])
+ /// to resolve Spin-donw issue with the test equiepment
+ ///
+ if (SataConfig->TestMode == PCH_DEVICE_ENABLE ) {
+ CapRegister &= ~B_PCH_SATA_AHCI_CAP_SSS;
+ } else {
+ CapRegister |= B_PCH_SATA_AHCI_CAP_SSS;
+ }
+ }
+
+ if (SataConfig->PortSettings[Index].External == PCH_DEVICE_ENABLE) {
+ ///
+ /// External SATA is supported at least one of the ports
+ ///
+ CapRegister |= B_PCH_SATA_AHCI_CAP_SXS;
+ }
+ }
+ ///
+ /// Enable Enabled SATA ports,
+ /// If BIOS accesses any of the port specific AHCI address range before setting PI bit,
+ /// BIOS is required to read the PI register before the initial write to the PI register.
+ /// NOTE: many of the bits in this register are R/WO (Read/Write Once)
+ ///
+ Data32And = (UINT32) (~B_PCH_H_SATA_PORT_MASK);
+ if (PchSeries == PchLp) {
+ Data32And = (UINT32) (~B_PCH_LP_SATA_PORT_MASK);
+ }
+ Data32Or = (UINT32) (SataPortsEnabled);
+ MmioAndThenOr32 (
+ (UINTN) (AhciBar + R_PCH_SATA_AHCI_PI),
+ Data32And,
+ Data32Or
+ );
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AhciBar + R_PCH_SATA_AHCI_PI),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ ///
+ /// After BIOS issues initial write to this register, BIOS is requested to issue two
+ /// reads to this register.
+ ///
+ Data32Or = MmioRead32 (AhciBar + R_PCH_SATA_AHCI_PI);
+ SCRIPT_MEM_POLL (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AhciBar + R_PCH_SATA_AHCI_PI),
+ &Data32Or, // BitMask
+ &Data32Or, // BitValue
+ 1, // Duration
+ 1 // LoopTimes
+ );
+ SCRIPT_MEM_POLL (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AhciBar + R_PCH_SATA_AHCI_PI),
+ &Data32Or, // BitMask
+ &Data32Or, // BitValue
+ 1, // Duration
+ 1 // LoopTimes
+ );
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 14.1.4 Initialize Registers in AHCI Memory-Mapped Space
+ /// Step 1
+ /// For Lynx Point
+ /// Set PSC (ABAR + 00h[13]). This bit informs the Windows software driver that the AHCI
+ /// Controller supports the partial low-power state.
+ /// Set SSC (ABAR + 00h[14]). This bit informs the Windows software driver that the AHCI
+ /// Controller supports the slumber low-power state.
+ /// Set SALP (ABAR + 00h[26]) to enable Aggressive Link Power Management (LPM) support.
+ ///
+ CapRegister |= (B_PCH_SATA_AHCI_CAP_SSC | B_PCH_SATA_AHCI_CAP_PSC);
+
+ if (SataConfig->SalpSupport == PCH_DEVICE_ENABLE) {
+ CapRegister |= B_PCH_SATA_AHCI_CAP_SALP;
+ }
+ ///
+ /// Support Command List Override & PIO Multiple DRQ Block
+ ///
+ CapRegister |= (B_PCH_SATA_AHCI_CAP_SCLO | B_PCH_SATA_AHCI_CAP_PMD);
+
+ ///
+ /// Configure for the max speed support 1.5Gb/s, 3.0Gb/s and 6.0Gb/s.
+ ///
+ CapRegister &= ~B_PCH_SATA_AHCI_CAP_ISS_MASK;
+
+ switch (SataConfig->SpeedSupport) {
+ case PchSataSpeedSupportGen1:
+ CapRegister |= (V_PCH_SATA_AHCI_CAP_ISS_1_5_G << N_PCH_SATA_AHCI_CAP_ISS);
+ break;
+
+ case PchSataSpeedSupportGen2:
+ CapRegister |= (V_PCH_SATA_AHCI_CAP_ISS_3_0_G << N_PCH_SATA_AHCI_CAP_ISS);
+ break;
+
+ case PchSataSpeedSupportGen3:
+ case PchSataSpeedSupportDefault:
+ CapRegister |= (V_PCH_SATA_AHCI_CAP_ISS_6_0_G << N_PCH_SATA_AHCI_CAP_ISS);
+ break;
+ }
+ ///
+ /// Update the Host Capabilites Register and save for S3 resume
+ /// NOTE: Many of the bits in this register are R/WO (Read/Write Once)
+ ///
+ MmioWrite32 (AhciBar + R_PCH_SATA_AHCI_CAP, CapRegister);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AhciBar + R_PCH_SATA_AHCI_CAP),
+ 1,
+ &CapRegister
+ );
+
+ if (PchSeries == PchLp) {
+ ///
+ /// Set ABAR + 24h[5] to 1b
+ /// Set ABAR + 24h[4:2] to 111b
+ ///
+ Data32Or = B_PCH_SATA_AHCI_CAP2_DESO;
+ Data32Or |= B_PCH_SATA_AHCI_CAP2_SDS | B_PCH_SATA_AHCI_CAP2_SADM | B_PCH_SATA_AHCI_CAP2_APST;
+ MmioOr32 (AhciBar + R_PCH_SATA_AHCI_CAP2, Data32Or);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AhciBar + R_PCH_SATA_AHCI_CAP2),
+ 1,
+ (VOID *) (UINTN) (AhciBar + R_PCH_SATA_AHCI_CAP2)
+ );
+ }
+
+ ///
+ /// Port[Max:0] Command Register update
+ /// NOTE: this register must be updated after Port Implemented and Capabilities register,
+ /// Many of the bits in this register are R/WO (Read/Write Once)
+ ///
+ for (Index = 0; Index < GetPchMaxSataPortNum (); Index++) {
+ ///
+ /// Check PCS.PxE to know if the SATA Port x is disabled.
+ ///
+ if ((SataPortsEnabled & (B_PCH_SATA_PCS_PORT0_EN << Index)) == 0) {
+ continue;
+ }
+ ///
+ /// Initial to zero first
+ ///
+ PxCMDRegister = 0;
+
+ if (SataConfig->PortSettings[Index].HotPlug == PCH_DEVICE_ENABLE) {
+ if (SataConfig->PortSettings[Index].External == PCH_DEVICE_DISABLE) {
+ ///
+ /// Hot Plug of this port is enabled
+ ///
+ PxCMDRegister |= B_PCH_SATA_AHCI_PxCMD_HPCP;
+ if (SataConfig->PortSettings[Index].InterlockSw == PCH_DEVICE_ENABLE) {
+ ///
+ /// Mechanical Switch of this port is Attached
+ ///
+ PxCMDRegister |= B_PCH_SATA_AHCI_PxCMD_MPSP;
+ ///
+ /// Check the GPIO Pin is set as used for native function not a normal GPIO
+ ///
+ if (PchSeries == PchH) {
+ DwordReg = IoRead32 (
+ (UINTN)
+ (GpioBase + R_PCH_GPIO_USE_SEL +
+ (SataResetGpio[Index] / 32 * (R_PCH_GPIO_USE_SEL2 - R_PCH_GPIO_USE_SEL))));
+ DwordReg = (DwordReg & (1 << SataResetGpio[Index] % 32));
+ }
+
+ if (PchSeries == PchLp) {
+ DwordReg = IoRead32 (
+ (UINTN)
+ (GpioBase + SataResetLpGpio[Index]));
+ DwordReg = (DwordReg & B_PCH_GPIO_OWN0_GPIO_USE_SEL);
+ }
+
+ if(DwordReg != 0) {
+ if (PchSeries == PchH) {
+ DEBUG ((EFI_D_ERROR,
+ "BIOS must set the SATA%0xGP / GPIO%0d to native function if Inter Lock Switch is enabled!\n",
+ Index,
+ SataResetGpio[Index]));
+ ASSERT_EFI_ERROR (EFI_DEVICE_ERROR);
+ }
+
+ if (PchSeries == PchLp) {
+ DEBUG ((EFI_D_ERROR,
+ "BIOS must set the SATA%0xGP / GPIO%0d to native function if Inter Lock Switch is enabled!\n",
+ Index,
+ SataResetLpGpio[Index]));
+ ASSERT_EFI_ERROR (EFI_DEVICE_ERROR);
+ }
+ }
+ }
+ }
+ } else {
+ ///
+ /// When "Mechanical Switch Attached to Port" (PxCMD[19]) is set, it is expected that HPCP (PxCMD[18]) is also set.
+ ///
+ if (SataConfig->PortSettings[Index].InterlockSw == PCH_DEVICE_ENABLE) {
+ DEBUG ((EFI_D_ERROR, "Hot-Plug function of Port%d should be enabled while the Inter Lock Switch of it is enabled!\n",
+ Index));
+ }
+ }
+
+ if (SataConfig->PortSettings[Index].External == PCH_DEVICE_ENABLE) {
+ PxCMDRegister |= B_PCH_SATA_AHCI_PxCMD_ESP;
+ }
+
+ if (SataConfig->PortSettings[Index].SpinUp == PCH_DEVICE_ENABLE) {
+ PxCMDRegister |= B_PCH_SATA_AHCI_PxCMD_SUD;
+ }
+
+ ///
+ /// eSATA port support only up to Gen2
+ ///
+ if (SataConfig->PortSettings[Index].External == PCH_DEVICE_ENABLE) {
+ Data32And = (UINT32)~(B_PCH_SATA_AHCI_PXSCTL_SPD);
+ Data32Or = (V_PCH_SATA_AHCI_PXSCTL_SPD_2);
+ if (PchSeries == PchLp) {
+ Data32And = (UINT32)~(B_PCH_SATA_AHCI_PXSCTL_SPD | B_PCH_SATA_AHCI_PXSCTL_IPM);
+ Data32Or = (V_PCH_SATA_AHCI_PXSCTL_SPD_2);
+ }
+ MmioAndThenOr32 (
+ (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index))),
+ Data32And,
+ Data32Or
+ );
+
+ DwordReg = MmioRead32 (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index)));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index))),
+ 1,
+ &DwordReg
+ );
+ }
+
+ MmioAndThenOr32 (
+ (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index))),
+ (UINT32)~(B_PCH_SATA_AHCI_PxCMD_MASK),
+ (UINT32) PxCMDRegister
+ );
+ DwordReg = MmioRead32 (AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index)));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index))),
+ 1,
+ &DwordReg
+ );
+ if ((PchSeries == PchLp)) {
+ ///
+ /// Set ABAR + 144h[1], ABAR + 1C4h[1], ABAR + 244h[1], ABAR + 2C4[1] to 0b as default
+ /// Board rework is required to enable DevSlp.
+ /// POR settings are ABAR + 144h[1], ABAR + 1C4h[1], ABAR + 244h[1] = 1b, ABAR + 2C4[1] to 0b
+ ///
+ if (SataConfig->PortSettings[Index].DevSlp == PCH_DEVICE_ENABLE) {
+ Data32And = (UINT32)~(B_PCH_SATA_AHCI_PxDEVSLP_DITO_MASK | B_PCH_SATA_AHCI_PxDEVSLP_DM_MASK);
+ Data32Or = (B_PCH_SATA_AHCI_PxDEVSLP_DSP | V_PCH_SATA_AHCI_PxDEVSLP_DM_16 | V_PCH_SATA_AHCI_PxDEVSLP_DITO_625);
+ if (SataConfig->PortSettings[Index].EnableDitoConfig == PCH_DEVICE_ENABLE) {
+ Data32Or &= Data32And;
+ Data32Or |= ((SataConfig->PortSettings[Index].DitoVal << 15) | (SataConfig->PortSettings[Index].DmVal << 25));
+ }
+ MmioAndThenOr32 (
+ (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0DEVSLP + (0x80 * Index))),
+ Data32And,
+ Data32Or
+ );
+ } else {
+ MmioAnd32 (
+ (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0DEVSLP + (0x80 * Index))),
+ (UINT32) ~(B_PCH_SATA_AHCI_PxDEVSLP_DSP)
+ );
+ }
+ DwordReg = MmioRead32 (AhciBar + (R_PCH_SATA_AHCI_P0DEVSLP + (0x80 * Index)));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0DEVSLP + (0x80 * Index))),
+ 1,
+ &DwordReg
+ );
+ }
+
+ ///
+ /// eSATA port support only up to Gen2.
+ /// Save and restore Port Speed limitation
+ ///
+ if (SataConfig->PortSettings[Index].External == PCH_DEVICE_ENABLE) {
+ ByteReg = MmioRead8 (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index)));
+ ByteReg &= (UINT8) ~(B_PCH_SATA_AHCI_PXSCTL_SPD);
+ ByteReg |= (UINT8) V_PCH_SATA_AHCI_PXSCTL_SPD_2;
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index))),
+ 1,
+ &ByteReg
+ );
+ }
+ }
+ if ((PchSeries == PchLp)) {
+ ///
+ /// DevSlp on Port 0 and Port 3 are mutual exclusive. Assert if otherwise.
+ ///
+ ASSERT (!((SataConfig->PortSettings[0].DevSlp) && (SataConfig->PortSettings[3].DevSlp)));
+ if ((SataConfig->PortSettings[0].DevSlp == PCH_DEVICE_DISABLE) &&
+ (SataConfig->PortSettings[3].DevSlp == PCH_DEVICE_ENABLE)) {
+ MmioOr32 (
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SCLKCG),
+ (UINT32) B_PCH_SATA_SCLKCG_POP3_DEVSLP
+ );
+ DwordReg = MmioRead32 (PciD31F2RegBase + R_PCH_SATA_SCLKCG);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SCLKCG),
+ 1,
+ &DwordReg
+ );
+ }
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 14.1.5.2 Enable Flexible RAID OROM Features
+ /// Lynx Point with RAID capable sku is able to customize the RAID features through setting the
+ /// Intel RST Feature Capabilities (RSTF) register before loading the RAID Option ROM. The RAID
+ /// OROM will enable the desired features based on the setting in that register, please refer to
+ /// PCH EDS for more details.
+ /// For example, if the platform desired features are RAID0, RAID1, RAID5, RAID10 and
+ /// RST Smart Storage caching. System BIOS should set RSTF (ABAR + C8h [15:0]) to 022Fh before
+ /// loading RAID OROM.
+ ///
+ WordReg = 0;
+
+ if (SataConfig->HddUnlock == PCH_DEVICE_ENABLE) {
+ ///
+ /// If set to "1", indicates that the HDD password unlock in the OS is enabled
+ /// while SATA is configured as RAID mode.
+ ///
+ WordReg |= B_PCH_SATA_AHCI_RSTF_HDDLK;
+ }
+
+ if (SataConfig->LedLocate == PCH_DEVICE_ENABLE) {
+ ///
+ /// If set to "1", indicates that the LED/SGPIO hardware is attached and ping to
+ /// locate feature is enabled on the OS while SATA is configured as RAID mode.
+ ///
+ WordReg |= B_PCH_SATA_AHCI_RSTF_LEDL;
+ }
+
+ if (SataModeSelect == V_PCH_SATA_MAP_SMS_RAID) {
+ if (SataConfig->Raid0 == PCH_DEVICE_ENABLE) {
+ ///
+ /// If set to "1", then RAID0 is enabled in Flexible RAID Option ROM.
+ ///
+ WordReg |= B_PCH_SATA_AHCI_RSTF_R0E;
+ }
+
+ if (SataConfig->Raid1 == PCH_DEVICE_ENABLE) {
+ ///
+ /// If set to "1", then RAID1 is enabled in FD-OROM.
+ ///
+ WordReg |= B_PCH_SATA_AHCI_RSTF_R1E;
+ }
+
+ if (SataConfig->Raid10 == PCH_DEVICE_ENABLE) {
+ ///
+ /// If set to "1", then RAID10 is enabled in FD-OROM.
+ ///
+ WordReg |= B_PCH_SATA_AHCI_RSTF_R10E;
+ }
+
+ if (SataConfig->Raid5 == PCH_DEVICE_ENABLE) {
+ ///
+ /// If set to "1", then RAID5 is enabled in FD-OROM.
+ ///
+ WordReg |= B_PCH_SATA_AHCI_RSTF_R5E;
+ }
+
+ if (SataConfig->Irrt == PCH_DEVICE_ENABLE) {
+ ///
+ /// If set to "1", then Intel Rapid Recovery Technology is enabled.
+ ///
+ WordReg |= B_PCH_SATA_AHCI_RSTF_RSTE;
+ }
+
+ if (SataConfig->OromUiBanner == PCH_DEVICE_ENABLE) {
+ ///
+ /// If set to "1" then the OROM UI is shown. Otherwise, no OROM banner or information
+ /// will be displayed if all disks and RAID volumes are Normal.
+ ///
+ WordReg |= B_PCH_SATA_AHCI_RSTF_IRSTOROM;
+ }
+
+ if (SataConfig->IrrtOnly == PCH_DEVICE_ENABLE) {
+ ///
+ /// If set to "1", then only IRRT volumes can span internal and eSATA drives. If cleared
+ /// to "0", then any RAID volume can span internal and eSATA drives.
+ ///
+ WordReg |= B_PCH_SATA_AHCI_RSTF_IROES;
+ }
+ ///
+ /// Enable the RST Smart Storage caching bit to support Smart Storage caching.
+ ///
+ if (SataConfig->SmartStorage == PCH_DEVICE_ENABLE) {
+ WordReg |= B_PCH_SATA_AHCI_RSTF_SEREQ;
+ }
+ ///
+ /// Program the delay of the OROM UI Splash Screen in a normal status.
+ ///
+ WordReg |= (UINT16) (SataConfig->OromUiDelay << N_PCH_SATA_AHCI_RSTF_OUD);
+ }
+ ///
+ /// RSTF(RST Feature Capabilities) is a Write-Once register.
+ ///
+ MmioWrite16 ((UINTN) (AhciBar + R_PCH_SATA_AHCI_RSTF), WordReg);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (AhciBar + R_PCH_SATA_AHCI_RSTF),
+ 1,
+ &WordReg
+ );
+
+ ///
+ /// Set Ahci Bar to zero
+ ///
+ AhciBar = 0;
+ MmioWrite32 (PciD31F2RegBase + R_PCH_SATA_AHCI_BAR, AhciBar);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_AHCI_BAR),
+ 1,
+ &AhciBar
+ );
+
+ ///
+ /// Free the GCD pool
+ ///
+ gDS->FreeMemorySpace (
+ MemBaseAddress,
+ V_PCH_SATA_AHCI_BAR_LENGTH
+ );
+ DEBUG ((EFI_D_INFO, "ConfigureSataAhci() End\n"));
+ return EFI_SUCCESS;
+}
+
+/**
+ Disable Sata Controller
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in, out] FuncDisableReg Function Disable Register
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+DisableSataController (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN OUT UINT32 *FuncDisableReg
+ )
+{
+ UINTN PciD31F2RegBase;
+ UINTN PciD31F5RegBase;
+ UINT16 SataModeSelect;
+ PCH_SERIES PchSeries;
+
+ PciD31F2RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 31, 2, 0);
+ PciD31F5RegBase = 0;
+ SataModeSelect = MmioRead16 (PciD31F2RegBase + R_PCH_SATA_MAP) & B_PCH_SATA_MAP_SMS_MASK;
+ PchSeries = GetPchSeries();
+
+#ifdef ULT_FLAG
+ if (PchSeries == PchLp) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 14.2 SATA Controller Disabling
+ /// Step 1
+ /// Set D31:F2:92h [3:0] to 0000b
+ ///
+ MmioAnd16 (PciD31F2RegBase + R_PCH_SATA_PCS,
+ (UINT16) ~(B_PCH_SATA_PCS_PORT0_EN | B_PCH_SATA_PCS_PORT1_EN | B_PCH_SATA_PCS_PORT2_EN |
+ B_PCH_SATA_PCS_PORT3_EN));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_PCS),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_PCS)
+ );
+ ///
+ /// Step 3
+ /// Set Sata Port Clock Disable bits D31:F2:94h[27:24] to Fh
+ ///
+ MmioOr32 ((UINTN) (PciD31F2RegBase + R_PCH_SATA_SCLKCG),
+ (UINT32) (B_PCH_SATA_SCLKCG_PORT0_PCD | B_PCH_SATA_SCLKCG_PORT1_PCD | B_PCH_SATA_SCLKCG_PORT2_PCD |
+ B_PCH_SATA_SCLKCG_PORT3_PCD));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SCLKCG),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_SCLKCG)
+ );
+ ///
+ /// Step 4
+ /// Disabling SATA Device by programming RCBA + 3418h [2][25]
+ ///
+ *FuncDisableReg |= B_PCH_RCRB_FUNC_DIS_SATA1;
+ }
+#endif // ULT_FLAG
+#ifdef TRAD_FLAG
+ if (PchSeries == PchH) {
+ PciD31F5RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 31, 5, 0);
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 14.2 SATA Controller Disabling
+ /// Step 1
+ /// Set D31:F2:92h [5:0] to 000000b
+ ///
+ MmioAnd16 (PciD31F2RegBase + R_PCH_SATA_PCS,
+ (UINT16) ~(B_PCH_SATA_PCS_PORT0_EN | B_PCH_SATA_PCS_PORT1_EN | B_PCH_SATA_PCS_PORT2_EN |
+ B_PCH_SATA_PCS_PORT3_EN | B_PCH_SATA_PCS_PORT4_EN | B_PCH_SATA_PCS_PORT5_EN));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_PCS),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_PCS)
+ );
+ if (SataModeSelect == V_PCH_SATA_MAP_SMS_IDE) {
+ ///
+ /// Step 2
+ /// Set D31:F5:92h [1:0] to 00b if SATA is in IDE mode
+ ///
+ MmioAnd16 (PciD31F5RegBase + R_PCH_SATA_PCS,
+ (UINT16) ~(B_PCH_SATA_PCS_PORT0_EN | B_PCH_SATA_PCS_PORT1_EN));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F5RegBase + R_PCH_SATA_PCS),
+ 1,
+ (VOID *) (UINTN) (PciD31F5RegBase + R_PCH_SATA_PCS)
+ );
+ }
+ ///
+ /// Step 3
+ /// Set Sata Port Clock Disable bits D31:F2:94h[29:24] to 3Fh
+ ///
+ MmioOr32 ((UINTN) (PciD31F2RegBase + R_PCH_SATA_SCLKCG),
+ (UINT32) (B_PCH_SATA_SCLKCG_PORT0_PCD | B_PCH_SATA_SCLKCG_PORT1_PCD | B_PCH_SATA_SCLKCG_PORT2_PCD |
+ B_PCH_SATA_SCLKCG_PORT3_PCD | B_PCH_SATA_SCLKCG_PORT4_PCD | B_PCH_SATA_SCLKCG_PORT5_PCD));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SCLKCG),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_SCLKCG)
+ );
+ ///
+ /// Step 4
+ /// Disabling SATA Device by programming RCBA + 3418h [2][25]
+ ///
+ *FuncDisableReg |= B_PCH_RCRB_FUNC_DIS_SATA1;
+ *FuncDisableReg |= B_PCH_RCRB_FUNC_DIS_SATA2;
+ }
+#endif // TRAD_FLAG
+
+ return EFI_SUCCESS;
+}