Example #1
0
/**
 * AbCfgTbl - Program ABCFG by input table.
 *
 *
 * @param[in] ABTbl  ABCFG config table.
 * @param[in] StdHeader
 *
 */
VOID
AbCfgTbl (
  IN  AB_TBL_ENTRY     *ABTbl,
  IN AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT32   AbValue;

  while ( (ABTbl->RegType) != 0xFF ) {
    if ( ABTbl->RegType == AXINDC ) {
      AbValue = 0x30 | (ABTbl->RegType << 29);
      WriteAlink (AbValue, (ABTbl->RegIndex & 0x00FFFFFF), StdHeader);
      AbValue = 0x34 | (ABTbl->RegType << 29);
      WriteAlink (AbValue, ((ReadAlink (AbValue, StdHeader)) & (0xFFFFFFFF^ (ABTbl->RegMask))) | ABTbl->RegData, StdHeader);
    } else if ( ABTbl->RegType == AXINDP ) {
      AbValue = 0x38 | (ABTbl->RegType << 29);
      WriteAlink (AbValue, (ABTbl->RegIndex & 0x00FFFFFF), StdHeader);
      AbValue = 0x3C | (ABTbl->RegType << 29);
      WriteAlink (AbValue, ((ReadAlink (AbValue, StdHeader)) & (0xFFFFFFFF^ (ABTbl->RegMask))) | ABTbl->RegData, StdHeader);
    } else {
      AbValue = ABTbl->RegIndex | (ABTbl->RegType << 29);
      WriteAlink (AbValue, ((ReadAlink (AbValue, StdHeader)) & (0xFFFFFFFF^ (ABTbl->RegMask))) | ABTbl->RegData, StdHeader);
    }

    ++ABTbl;
  }

  //
  //Clear ALink Access Index
  //
  AbValue = 0;
  LibAmdIoWrite (AccessWidth32, ALINK_ACCESS_INDEX, &AbValue, StdHeader);
}
Example #2
0
EFI_STATUS
EFIAPI
AmdSmiEinjChkErr (
  IN OUT   VOID
  )
{
  UINT8               Value8;
  UINT8               PortId;
  UINT32              Value32;
  EFI_STATUS          Status;
  AMD_CONFIG_PARAMS   StdHeader;

  Status = EFI_SUCCESS;
  PortId = 7;

  ReadMem (ACPI_MMIO_BASE + SMI_BASE + 0x3C, AccessWidth8, &Value8);

  if (Value8 & BIT2) {

    Value32 = ReadAlink (0x104C | (UINT32) (ABCFG << 29), &StdHeader);
    if (Value32 & BIT4) {
      PortId = 0;
      WriteAlink (0x104C | (UINT32) (ABCFG << 29), BIT4, &StdHeader);
    } else if (Value32 & BIT5) {
      PortId = 1;
      WriteAlink (0x104C | (UINT32) (ABCFG << 29), BIT5, &StdHeader);
    } else if (Value32 & BIT6) {
      PortId = 2;
      WriteAlink (0x104C | (UINT32) (ABCFG << 29), BIT6, &StdHeader);
    } else if (Value32 & BIT7) {
      PortId = 3;
      WriteAlink (0x104C | (UINT32) (ABCFG << 29), BIT7, &StdHeader);
    }
    Value8 = BIT2;
    WriteMem (ACPI_MMIO_BASE + SMI_BASE + 0x3C, AccessWidth8, &Value8);

    AmdFchWheaElogGpp (PortId);
  }

  return Status;
}
Example #3
0
/**
 * FchAbLateProgram - Set ABCFG registers during late POST
 *
 *
 * @param[in] FchDataPtr Fch configuration structure pointer.
 *
 */
VOID
FchAbLateProgram (
  IN  VOID     *FchDataPtr
  )
{
  UINT32                 AbValue;
  FCH_DATA_BLOCK         *LocalCfgPtr;
  AMD_CONFIG_PARAMS      *StdHeader;

  LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr;
  StdHeader = LocalCfgPtr->StdHeader;
  AbValue = ReadAlink (FCH_ABCFG_REGC0 | (UINT32) (ABCFG << 29), StdHeader);
  AbValue &= 0xf0;

  if ( LocalCfgPtr->Ab.PcieOrderRule && AbValue ) {
    AbValue = ReadAlink (FCH_RCINDXC_REG02, StdHeader);
    AbValue = AbValue | BIT9;
    WriteAlink (FCH_RCINDXC_REG02, AbValue, StdHeader);
  }
}
Example #4
0
/**
 * FchGppDynamicPowerSaving - GPP Dynamic Power Saving
 *
 *
 * @param[in] FchDataPtr
 *
 */
VOID
FchGppDynamicPowerSaving (
  IN  VOID     *FchDataPtr
  )
{
  FCH_GPP_PORT_CONFIG  *PortCfg;
  UINT8               FchGppLaneReversal;
  UINT8               FchAlinkPhyPllPowerDown;
  UINT8               FchGppPhyPllPowerDown;
  UINT32              GppData32;
  UINT32              HoldGppData32;
  UINT32              AbValue;
  FCH_DATA_BLOCK         *LocalCfgPtr;
  AMD_CONFIG_PARAMS      *StdHeader;

  LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr;
  StdHeader = LocalCfgPtr->StdHeader;

  if (!LocalCfgPtr->Gpp.GppDynamicPowerSaving || LocalCfgPtr->SerialDb.SerialDebugBusEnable) {
    return;
  }

  FchAlinkPhyPllPowerDown = (UINT8) LocalCfgPtr->Ab.UmiPhyPllPowerDown;
  FchGppLaneReversal =  (UINT8) LocalCfgPtr->Gpp.GppLaneReversal;
  FchGppPhyPllPowerDown =  (UINT8) LocalCfgPtr->Gpp.GppPhyPllPowerDown;

  if (LocalCfgPtr->Gpp.GppHardwareDownGrade) {
    PortCfg = &LocalCfgPtr->Gpp.PortCfg[LocalCfgPtr->Gpp.GppHardwareDownGrade - 1];
    PortCfg->PortDetected = TRUE;
  }

  GppData32 = 0;
  HoldGppData32 = 0;

  switch ( LocalCfgPtr->Gpp.GppLinkConfig ) {
  case PortA4:
    PortCfg = &LocalCfgPtr->Gpp.PortCfg[0];
    if ( PortCfg->PortDetected == FALSE ) {
      GppData32 |= 0x0f0f;
      HoldGppData32 |= 0x1000;
    }
    break;

  case PortA2B2:
    PortCfg = &LocalCfgPtr->Gpp.PortCfg[0];
    if ( PortCfg->PortDetected == FALSE ) {
      GppData32 |= ( FchGppLaneReversal )? 0x0c0c:0x0303;
      HoldGppData32 |= 0x1000;
    }

    PortCfg = &LocalCfgPtr->Gpp.PortCfg[1];
    if ( PortCfg->PortDetected == FALSE ) {
      GppData32 |= ( FchGppLaneReversal )? 0x0303:0x0c0c;
      HoldGppData32 |= 0x2000;
    }
    break;

  case PortA2B1C1:
    PortCfg = &LocalCfgPtr->Gpp.PortCfg[0];
    if ( PortCfg->PortDetected == FALSE ) {
      GppData32 |= ( FchGppLaneReversal )? 0x0c0c:0x0303;
      HoldGppData32 |= 0x1000;
    }

    PortCfg = &LocalCfgPtr->Gpp.PortCfg[1];
    if ( PortCfg->PortDetected == FALSE ) {
      GppData32 |= ( FchGppLaneReversal )? 0x0202:0x0404;
      HoldGppData32 |= 0x2000;
    }

    PortCfg = &LocalCfgPtr->Gpp.PortCfg[2];
    if ( PortCfg->PortDetected == FALSE ) {
      GppData32 |= ( FchGppLaneReversal )? 0x0101:0x0808;
      HoldGppData32 |= 0x4000;
    }
    break;

  case PortA1B1C1D1:
    PortCfg = &LocalCfgPtr->Gpp.PortCfg[0];
    if ( PortCfg->PortDetected == FALSE ) {
      GppData32 |= ( FchGppLaneReversal )? 0x0808:0x0101;
      HoldGppData32 |= 0x1000;
    }

    PortCfg = &LocalCfgPtr->Gpp.PortCfg[1];
    if ( PortCfg->PortDetected == FALSE ) {
      GppData32 |= ( FchGppLaneReversal )? 0x0404:0x0202;
      HoldGppData32 |= 0x2000;
    }

    PortCfg = &LocalCfgPtr->Gpp.PortCfg[2];
    if ( PortCfg->PortDetected == FALSE ) {
      GppData32 |= ( FchGppLaneReversal )? 0x0202:0x0404;
      HoldGppData32 |= 0x4000;
    }

    PortCfg = &LocalCfgPtr->Gpp.PortCfg[3];
    if ( PortCfg->PortDetected == FALSE ) {
      GppData32 |= ( FchGppLaneReversal )? 0x0101:0x0808;
      HoldGppData32 |= 0x8000;
    }
    break;

  default:
    ASSERT (FALSE);
    break;
  }

  //
  // Power Saving With GPP Disable
  // ABCFG 0xC0[8] = 0x0
  // ABCFG 0xC0[15:12] = 0xF
  // Enable "Power Saving Feature for A-Link Express Lanes"
  // Enable "Power Saving Feature for GPP Lanes"
  // ABCFG 0x90[19] = 1
  // ABCFG 0x90[6] = 1
  // RCINDC_Reg 0x65 [27:0] = 0xFFFFFFF
  // ABCFG 0xC0[7:4] = 0x0
  //
  if ( FchAlinkPhyPllPowerDown && FchGppPhyPllPowerDown ) {
    AbValue = ReadAlink (FCH_ABCFG_REGC0 | (UINT32) (ABCFG << 29), StdHeader);
    WriteAlink (FCH_ABCFG_REGC0 | (UINT32) (ABCFG << 29), (( AbValue | HoldGppData32 ) & (~ BIT8 )), StdHeader);
    RwAlink (FCH_AX_INDXC_REG40, ~(BIT9 + BIT4), (BIT0 + BIT3 + BIT12), StdHeader);
    RwAlink ((FCH_ABCFG_REG90 | (UINT32) (ABCFG << 29)), 0xFFFFFFFF, (BIT6 + BIT19), StdHeader);
    RwAlink (RC_INDXC_REG65, 0xFFFFFFFF, ((GppData32 & 0x0F) == 0x0F) ? GppData32 | 0x0CFF0000 : GppData32, StdHeader);
    RwAlink (RC_INDXC_REG40, ~(BIT9 + BIT4), (BIT0 + BIT3 + BIT12), StdHeader);
  }
}
Example #5
0
/**
 * FchInitLateGpp - Prepare Gpp controller to boot to OS.
 *
 *  PcieGppLateInit
 *
 * @param[in] FchDataPtr Fch configuration structure pointer.
 *
 */
VOID
FchInitLateGpp (
  IN  VOID     *FchDataPtr
  )
{
  UINT8               PortId;
  UINT8               BusNum;
  UINT8               AspmValue;
  UINT8               PortAspmValue;
  UINT8               AllowStrapControlByAB;
  UINT8               FchGppPhyPllPowerDown;
  FCH_GPP_PORT_CONFIG  *PortCfg;
  UINT32              PciAspmValue;
  UINT32              AbValue;
  FCH_DATA_BLOCK         *LocalCfgPtr;
  AMD_CONFIG_PARAMS      *StdHeader;

  LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr;
  StdHeader = LocalCfgPtr->StdHeader;

  //
  // Disable hidden register decode and serial number capability
  //
  AbValue = ReadAlink (FCH_ABCFG_REG330 | (UINT32) (ABCFG << 29), StdHeader);
  WriteAlink (FCH_ABCFG_REG330 | (UINT32) (ABCFG << 29), AbValue & ~(BIT26 + BIT10), StdHeader);

  if (ReadAlink (FCH_ABCFG_REGC0 | (UINT32) (ABCFG << 29), StdHeader) & BIT8) {
    return;
  }

  //
  // Configure ASPM
  //
  AspmValue = (UINT8)LocalCfgPtr->Gpp.GppPortAspm;
  FchGppPhyPllPowerDown = (UINT8) LocalCfgPtr->Gpp.GppPhyPllPowerDown;

  AllowStrapControlByAB = 0x01;

  for ( PortId = 0; PortId < MAX_GPP_PORTS; PortId++ ) {
    //
    // write pci_reg3d with 0x01 to fix yellow mark for GPP bridge under some OS
    // when native PCIE is enabled but MSI is not available
    // BIF/GPP allowing strap STRAP_BIF_INTERRUPT_PIN_SB controlled by AB reg
    //
    PortCfg = &LocalCfgPtr->Gpp.PortCfg[PortId];
    if (PortCfg->PortHotPlug) {
      RwPci (PCI_ADDRESS (0, 21, PortId, 0x04), AccessWidth8, 0xFE, 0x00, StdHeader);         ///clear IO enable to fix possible hotplug hang
    }

    WritePci (PCI_ADDRESS (0, 21, PortId, 0x3d), AccessWidth8, &AllowStrapControlByAB, StdHeader);
    ReadPci (PCI_ADDRESS (0, 21, PortId, 0x19), AccessWidth8, &BusNum, StdHeader);

    if (BusNum != 0xFF) {
      ReadPci (PCI_ADDRESS (BusNum, 0, 0, 0x00), AccessWidth32, &PciAspmValue, StdHeader);
      if (PciAspmValue != 0xffffffff) {
        PortAspmValue = AspmValue;
        //
        // Validate ASPM support on EP side
        //
        FchGppValidateAspm (PCI_ADDRESS (BusNum, 0, 0, 0), &PortAspmValue, StdHeader);
        //
        // Set ASPM on EP side
        //
        FchGppSetEpAspm (PCI_ADDRESS (BusNum, 0, 0, 0), PortAspmValue, StdHeader);
        //
        // Set ASPM on port side
        //
        FchGppSetAspm (PCI_ADDRESS (0, 21, PortId, 0), PortAspmValue, StdHeader);
      }
    }
    RwAlink ((FCH_RCINDXP_REG02 | (UINT32) (RCINDXP << 29) | (PortId << 24) ), ~(BIT15), (BIT15), StdHeader);
  }
  RwAlink ((FCH_RCINDXC_REG02 | (UINT32) (RCINDXC << 29)), ~(BIT0), (BIT0), StdHeader);

  //
  // Configure Lock HWInit registers
  //
  AbValue = ReadAlink (FCH_ABCFG_REGC0 | (UINT32) (ABCFG << 29), StdHeader);
  if (AbValue & 0xF0) {
    AbValue = ReadAlink (FCH_RCINDXC_REG10 | (UINT32) (RCINDXC << 29), StdHeader);
    WriteAlink (FCH_RCINDXC_REG10 | (UINT32) (RCINDXC << 29), AbValue | BIT0, StdHeader);    /// Set HWINIT_WR_LOCK

    if ( FchGppPhyPllPowerDown == TRUE ) {
      //
      // Power Saving Feature for GPP Lanes
      //
      // Set PCIE_P_CNTL in Alink PCIEIND space
      //
      AbValue = ReadAlink (RC_INDXC_REG40 | (UINT32) (RCINDXC << 29), StdHeader);
      AbValue |= BIT12 + BIT3 + BIT0;
      AbValue &= ~(BIT9 + BIT4);
      WriteAlink (RC_INDXC_REG40 | (UINT32) (RCINDXC << 29), AbValue, StdHeader);
      RwAlink (FCH_RCINDXC_REG02, ~(BIT8), (BIT8), StdHeader);
      RwAlink (FCH_RCINDXC_REG02, ~(BIT3), (BIT3), StdHeader);
    }
  }

  //
  // Restore strap0 via override
  //
  if (LocalCfgPtr->Gpp.PcieAer) {
    RwAlink (FCH_ABCFG_REG310 | (UINT32) (ABCFG << 29), 0xFFFFFFFF, BIT7, StdHeader);
    RwAlink (RC_INDXC_REGC0, 0xFFFFFFFF, BIT9, StdHeader);
  }
}