/* $NoKeywords:$ */
/**
 * @file
 *
 * Config Fch LPC controller
 *
 * Init LPC Controller features.
 *
 * @xrefitem bom "File Content Label" "Release Content"
 * @e project:     AGESA
 * @e sub-project: FCH
 * @e \$Revision: 87493 $   @e \$Date: 2013-02-04 11:56:12 -0600 (Mon, 04 Feb 2013) $
 *
 */
/*
*****************************************************************************
*
 * Copyright (c) 2008 - 2013, 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.
****************************************************************************
*/
#include "FchPlatform.h"
#include "Filecode.h"

#define FILECODE PROC_FCH_SPI_FAMILY_YANGTZE_YANGTZELPCRESETSERVICE_FILECODE
#define SPI_BASE UserOptions.FchBldCfg->CfgSpiRomBaseAddress

SPI_CONTROLLER_PROFILE SpiControllerProfile[4] = {
  {128, 100, 100, 100, 100},
  {128,  66,  66,  66,  66},
  {128,  33,  33,  33,  33},
  {128,  16,  16,  16,  16},
  };
SPI_DEVICE_PROFILE DefaultSpiDeviceTable[] = {
  //JEDEC_ID,RomSize,SecSize;MaxNormal;MaxFast;MaxDual;MaxQuad;QeReadReg;QeWriteReg;QeRegSize;QeLocation;
  {0x001524C2, 2 << 20, 4096,  33, 108, 150, 300, 0x05, 0x01, 0x1, 0x0040}, //Macronix_MX25L1635D
  {0x001525C2, 2 << 20, 4096,  33, 108, 160, 432, 0x05, 0x01, 0x1, 0x0040}, //Macronix_MX25L1635E
  {0x00165EC2, 4 << 20, 4096,  33, 104, 208, 400, 0x05, 0x01, 0x1, 0x0040}, //Macronix_MX25L3235D
//  {0x003625C2, 4 << 20, 4096,  33, 104, 168, 432, 0x05, 0x01, 0x1, 0x0040}, //Macronix_MX25U3235F
  {0x001720C2, 8 << 20, 4096,  33, 104, 208, 400, 0x05, 0x01, 0x1, 0x0040}, //Macronix_MX25L6436E
  {0x003725C2, 8 << 20, 4096,  33, 104, 168, 432, 0x05, 0x01, 0x1, 0x0040}, //Macronix_MX25U6435F

  {0x0046159D, 4 << 20, 4096,  33, 104, 208, 400, 0x05, 0x01, 0x1, 0x0040}, //PFLASH Pm25LQ032C

  {0x001540EF, 2 << 20, 4096,  33, 104, 208, 416, 0x35, 0x01, 0x2, 0x0200}, //Wnbond_W25Q16CV
  {0x001640EF, 4 << 20, 4096,  33, 104, 208, 320, 0x35, 0x01, 0x2, 0x0200}, //Wnbond_W25Q32BV
  {0x001740EF, 8 << 20, 4096, 104, 104, 208, 416, 0x35, 0x01, 0x2, 0x0200}, //Wnbond_W25Q64

  {0x004326BF, 8 << 20, 4096,  40, 104, 160, 416, 0x35, 0x01, 0x2, 0x0200}, //SST26VF064BA

  {0x001640C8, 4 << 20, 4096,  33, 100, 160, 320, 0x35, 0x01, 0x2, 0x0200}, //GigaDecice GD25Q32BSIGR

  {0x00164037, 4 << 20, 4096,  33, 100, 200, 400, 0x35, 0x01, 0x2, 0x0200}, //AMIC A25LQ32B

  {0x00000000, 4 << 20, 4096,  33,  33,  33,  33, 0x05, 0x01, 0x1, 0x0040}
};


/**
 * FchInitYangtzeResetLpcPciTable - Lpc (Spi) device registers
 * initial during the power on stage.
 *
 *
 *
 *
 */
REG8_MASK FchInitYangtzeResetLpcPciTable[] =
{
  //
  // LPC Device (Bus 0, Dev 20, Func 3)
  //
  {0x00, LPC_BUS_DEV_FUN, 0},

  {FCH_LPC_REG48, 0x00, BIT0 + BIT1 + BIT2},
  {FCH_LPC_REG7C, 0x00, BIT0 + BIT2},
  {0x78, 0xF0, BIT2 + BIT3},                       /// Enable LDRQ pin
  {FCH_LPC_REGBA, 0x9F, BIT5 + BIT6},
  // Force EC_PortActive to 1 to fix possible IR non function issue when NO_EC_SUPPORT is defined
  {FCH_LPC_REGA4, (UINT8)~ BIT0, BIT0},
  {0xFF, 0xFF, 0xFF},
};

/**
 * FchInitResetLpcProgram - Config Lpc controller during Power-On
 *
 *
 *
 * @param[in] FchDataPtr Fch configuration structure pointer.
 *
 */
VOID
FchInitResetLpcProgram (
  IN       VOID     *FchDataPtr
  )
{
  FCH_RESET_DATA_BLOCK      *LocalCfgPtr;
  AMD_CONFIG_PARAMS         *StdHeader;

  LocalCfgPtr = (FCH_RESET_DATA_BLOCK *) FchDataPtr;
  StdHeader = LocalCfgPtr->StdHeader;
  //
  // enable prefetch on Host, set LPC cfg 0xBB bit 0 to 1
  //
  RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGBA, AccessWidth16, 0xFFFF, BIT8, StdHeader);

  ProgramPciByteTable ( (REG8_MASK*) (&FchInitYangtzeResetLpcPciTable[0]),
                       ARRAY_SIZE(FchInitYangtzeResetLpcPciTable), StdHeader);

  if ( LocalCfgPtr->Spi.LpcClk0 ) {
    RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGD0 + 1, AccessWidth8, 0xDF, 0x20, StdHeader);
  } else {
    RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGD0 + 1, AccessWidth8, 0xDF, 0, StdHeader);
  }
  if ( LocalCfgPtr->Spi.LpcClk1 ) {
    RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGD0 + 1, AccessWidth8, 0xBF, 0x40, StdHeader);
  } else {
    RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGD0 + 1, AccessWidth8, 0xBF, 0, StdHeader);
  }
  if ( LocalCfgPtr->LegacyFree ) {
    RwPci (((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REG44), AccessWidth32, 00, 0x0003C000, StdHeader);
  } else {
    RwPci (((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REG44), AccessWidth32, 00, 0xFF03FFD5, StdHeader);
  }
}

/**
 * FchWriteSpiExtReg - Write SPI Extension Register
 *
 *
 *
 * @param[in] SpiExtRegIndex - Extension Register Index.
 * @param[in] SpiExtRegData - Extension Register Data.
 *
 */
STATIC VOID
FchWriteSpiExtReg (
  IN       UINT8      SpiExtRegIndex,
  IN       UINT8      SpiExtRegData
  )
{
  ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG1E) = SpiExtRegIndex;
  ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG1F) = SpiExtRegData;
}
/**
 * FchSetSpiCounter - Set SPI RX/TX Counters
 *
 *
 *
 * @param[in] TxCounter - Transfer Counter.
 * @param[in] RxCounter - Receive Counter.
 *
 */
STATIC VOID
FchSetSpiCounter (
  IN       UINT8      TxCounter,
  IN       UINT8      RxCounter
  )
{
  FchWriteSpiExtReg (FCH_SPI_MMIO_REG1F_X05_TX_BYTE_COUNT, TxCounter);
  FchWriteSpiExtReg (FCH_SPI_MMIO_REG1F_X06_RX_BYTE_COUNT, RxCounter);
}
/**
 * FchSpiControllerNotBusy - SPI Conroller Not Busy
 *
 *
 *
 *
 */
STATIC VOID
FchSpiControllerNotBusy (
  VOID)
{
  UINT32 SpiReg00;
  SpiReg00 = FCH_SPI_BUSY + FCH_SPI_EXEC_OPCODE;
  do {
    SpiReg00 = ACPIMMIO32 (SPI_BASE + FCH_SPI_MMIO_REG00);
  } while ((SpiReg00 & (FCH_SPI_BUSY + FCH_SPI_EXEC_OPCODE)));
}
/**
 * FchResetFifo - Reset SPI FIFO
 *
 *
 *
 *
 */
STATIC VOID
FchResetFifo (
  VOID)
{
  ACPIMMIO32 (SPI_BASE + FCH_SPI_MMIO_REG00) |= BIT20;
}
/**
 * WaitForSpiDeviceWriteEnabled -
 *
 *
 *
 *
 */
STATIC BOOLEAN
WaitForSpiDeviceWriteEnabled (
  VOID)
{
  UINT8 bStatus;
  bStatus = 0;
  do
  {
    FchSpiTransfer (
      0, //IN       UINT8    PrefixCode,
      0x05,//IN       UINT8    Opcode,
      &bStatus,//IN       OUT UINT8    *DataPtr,
      NULL,//IN       UINT8    *AddressPtr,
      0,//IN       UINT8    Length,
      FALSE,//IN       BOOLEAN  WriteFlag,
      FALSE,//IN       BOOLEAN  AddressFlag,
      TRUE,//IN       BOOLEAN  DataFlag,
      FALSE //IN       BOOLEAN  FinishedFlag
    );
  } while ((bStatus & 2) == 0);
  return TRUE;
}
/**
 * WaitForSpiDeviceComplete -
 *
 *
 *
 *
 */
STATIC BOOLEAN
WaitForSpiDeviceComplete (
  VOID)
{
  UINT8 bStatus;
  bStatus = 1;
  do
  {
    FchSpiTransfer (
      0, //IN       UINT8    PrefixCode,
      0x05,//IN       UINT8    Opcode,
      &bStatus,//IN       OUT UINT8    *DataPtr,
      NULL,//IN       UINT8    *AddressPtr,
      0,//IN       UINT8    Length,
      FALSE,//IN       BOOLEAN  WriteFlag,
      FALSE,//IN       BOOLEAN  AddressFlag,
      TRUE,//IN       BOOLEAN  DataFlag,
      FALSE //IN       BOOLEAN  FinishedFlag
    );
  } while (bStatus & 1);
  return TRUE;
}
/**
 * FchSpiTransfer - FCH Spi Transfer
 *
 *
 *
 * @param[in] PrefixCode   - Prefix code.
 * @param[in] Opcode       - Opcode.
 * @param[in] DataPtr      - Data Pointer.
 * @param[in] AddressPtr   - Address Pointer.
 * @param[in] Length       - Read/Write Length.
 * @param[in] WriteFlag    - Write Flag.
 * @param[in] AddressFlag  - Address Flag.
 * @param[in] DataFlag     - Data Flag.
 * @param[in] FinishedFlag - Finished Flag.
 *
 */
//static
AGESA_STATUS
FchSpiTransfer (
  IN       UINT8    PrefixCode,
  IN       UINT8    Opcode,
  IN OUT   UINT8    *DataPtr,
  IN       UINT8    *AddressPtr,
  IN       UINT8    Length,
  IN       BOOLEAN  WriteFlag,
  IN       BOOLEAN  AddressFlag,
  IN       BOOLEAN  DataFlag,
  IN       BOOLEAN  FinishedFlag
  )
{
  UINTN  Addr;
  UINTN  Retry;
  UINTN  i;
  UINTN  index;
  UINT8  WriteCount;
  UINT8  ReadCount;
  //UINT8  Dummy;
  //UINT8  CurrFifoIndex;

  if (!((Opcode == 0x9f) && (!DataFlag))) {
    if (PrefixCode) {
      Retry = 0;
      do {
        ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG00 + 0) = PrefixCode;
        //ACPIMMIO8(SPI_BASE + FCH_SPI_MMIO_REG00 + 1) = 0;
        FchSetSpiCounter (0, 0);
        ACPIMMIO32 (SPI_BASE + FCH_SPI_MMIO_REG00) |= FCH_SPI_EXEC_OPCODE;
        FchSpiControllerNotBusy ();

        if (FinishedFlag) {
          if (WaitForSpiDeviceWriteEnabled ()) {
            Retry = 0;
          } else {
            Retry ++;
            if (Retry >= FCH_SPI_RETRY_TIMES) {
              return AGESA_ERROR;
            }
          }
        }
      } while (Retry);
    }
    Retry = 0;
    do {
      WriteCount = 0;
      ReadCount = 0;
      //
      // Reset Fifo Ptr
      //
      FchResetFifo ();
      //
      // Check Address Mode
      //
      index = 0;
      Addr = (UINTN) AddressPtr;
      if (AddressFlag) {
        //for (i = 16, Addr = (UINTN) AddressPtr; i >= 0; i -= 8) {
        for (i = 0; i < 3; i ++) {
          //ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG0C + 0) = (UINT8) ((Addr >> i) & 0xff);
          ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG80_FIFO + index) = (UINT8) ((Addr >> (16 - i * 8)) & 0xff);
          index ++;
        }
        WriteCount += 3;
      }
      if (DataFlag) {
        //
        // Check Read/Write Mode
        //
        if (WriteFlag) {
          WriteCount += Length + 1;
          for (i = 0; i < (UINTN) (Length + 1); i ++) {
            //ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG0C + 0) = DataPtr[i];
            ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG80_FIFO + index) = DataPtr[i];
            index ++;
          }
        } else {
          //
          // Read operation must plus extra 1 byte
          //
          ReadCount += Length + 2;
        }
      }
      ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG00 + 0) = Opcode;
      //ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG00 + 1) = (ReadCount << 4) + WriteCount;
      FchSetSpiCounter (WriteCount, ReadCount);
      ACPIMMIO32 (SPI_BASE + FCH_SPI_MMIO_REG00) |= FCH_SPI_EXEC_OPCODE;
      FchSpiControllerNotBusy ();

      if (FinishedFlag) {
        if (WaitForSpiDeviceComplete ()) {
          Retry = 0;
        } else {
          Retry ++;
          if (Retry >= FCH_SPI_RETRY_TIMES) {
            return AGESA_ERROR;
          }
        }
      }
    } while (Retry);
    if (DataFlag && ReadCount) {
      //
      // Reset Fifo Ptr
      //
      FchResetFifo ();
      //while (DataFlag && ReadCount) {
      //  CurrFifoIndex = ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG4E + 1) & 0x07;
      //  if (CurrFifoIndex != WriteCount) {
      //    Dummy = ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG0C + 0);
      //  } else break;
      //}
      for (i = 0; i < (UINTN) (Length + 1); i ++) {
        //DataPtr[i] = ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG0C + 0);
        DataPtr[i] = ACPIMMIO8 (SPI_BASE + FCH_SPI_MMIO_REG80_FIFO + WriteCount + i);
      }
    }
  }
  return AGESA_SUCCESS;
}

/**
 *
 *
 *
 * @param[in] SpiQualMode- Spi Qual Mode.
 * @param[in] StdHeader  - Standard Header.
 *
 */
STATIC VOID
FchSetQualMode (
  IN       UINT32      SpiQualMode,
  IN       AMD_CONFIG_PARAMS         *StdHeader
  )
{

  RwMem (ACPI_MMIO_BASE + GPIO_BASE + 0x69, AccessWidth8, (UINT32)~BIT3, BIT3);
  RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGBB, AccessWidth8, (UINT32)~ BIT0, BIT0, StdHeader);
  RwMem (SPI_BASE + FCH_SPI_MMIO_REG00, AccessWidth32, (UINT32)~( BIT18 + BIT29 + BIT30), ((SpiQualMode & 1) << 18) + ((SpiQualMode & 6) << 28));

}

/**
 * FchInitResetSpi - Config Spi controller during Power-On
 *
 *
 *
 * @param[in] FchDataPtr Fch configuration structure pointer.
 *
 */
VOID
FchInitResetSpi (
  IN       VOID     *FchDataPtr
  )
{
  UINT32                    SpiModeByte;
  FCH_RESET_DATA_BLOCK      *LocalCfgPtr;
  AMD_CONFIG_PARAMS         *StdHeader;

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

  //
  // Set Spi ROM Base Address
  //
  RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGA0, AccessWidth32, 0x001F, SPI_BASE, StdHeader);

  RwMem (SPI_BASE + FCH_SPI_MMIO_REG00, AccessWidth32, 0xFFFFFFFF, (BIT19 + BIT24 + BIT25 + BIT26));
  RwMem (SPI_BASE + FCH_SPI_MMIO_REG0C, AccessWidth32, 0xFFC0FFFF, 0 );

  RwMem (SPI_BASE + FCH_SPI_MMIO_REG20, AccessWidth8, 0xFE, (UINT8) ((LocalCfgPtr->SPI100_Enable) << 0));

  if (LocalCfgPtr->SpiSpeed) {
    RwMem (SPI_BASE + FCH_SPI_MMIO_REG22, AccessWidth32, ~((UINT32) (0xF << 12)), ((LocalCfgPtr->SpiSpeed - 1 ) << 12));
  }

  if (LocalCfgPtr->FastSpeed) {
    RwMem (SPI_BASE + FCH_SPI_MMIO_REG22, AccessWidth32, ~((UINT32) (0xF << 8)), ((LocalCfgPtr->FastSpeed - 1 ) << 8));
  }

  RwMem (SPI_BASE + FCH_SPI_MMIO_REG1C, AccessWidth32, (UINT32)~(BIT10), ((LocalCfgPtr->BurstWrite) << 10));

  SpiModeByte = LocalCfgPtr->Mode;
  if (LocalCfgPtr->Mode) {
    if ((SpiModeByte == FCH_SPI_MODE_QUAL_114) || (SpiModeByte == FCH_SPI_MODE_QUAL_144) || (SpiModeByte == FCH_SPI_MODE_QUAL_112) || (SpiModeByte == FCH_SPI_MODE_QUAL_122) || (SpiModeByte == FCH_SPI_MODE_FAST)) {
      if (FchPlatformSpiQe (FchDataPtr)) {
        FchSetQualMode (SpiModeByte, StdHeader);
      }
    } else {
      RwMem (SPI_BASE + FCH_SPI_MMIO_REG00, AccessWidth32, (UINT32)~( BIT18 + BIT29 + BIT30), ((LocalCfgPtr->Mode & 1) << 18) + ((LocalCfgPtr->Mode & 6) << 28));
    }
  } else {
    if (FchPlatformSpiQe (FchDataPtr)) {
      SpiModeByte = FCH_SPI_MODE_QUAL_144;
    }
  }
  RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGBA, AccessWidth16, 0xFFFF, BIT8, StdHeader);

  RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGBA, AccessWidth16, 0xFFFF, BIT7, StdHeader);
}



STATIC UINT32
FchReadSpiId (
  IN       BOOLEAN    Flag
  )
{
  UINT32 DeviceID;
  UINT8 *DeviceIdPtr;
  DeviceID = 0;
  DeviceIdPtr = (UINT8 *) (((UINTN) (&DeviceID)));
  if (Flag) {
    FchSpiTransfer (
      0, //IN       UINT8    PrefixCode,
      0x9F,//IN       UINT8    Opcode,
      DeviceIdPtr,//IN  OUT   UINT8    *DataPtr,
      (UINT8 *) (NULL),//IN       UINT8    *AddressPtr,
      2,//IN       UINT8    Length,
      FALSE,//IN       BOOLEAN  WriteFlag,
      FALSE,//IN       BOOLEAN  AddressFlag,
      TRUE,//IN       BOOLEAN  DataFlag,
      FALSE //IN       BOOLEAN  FinishedFlag
    );
  } else {
    FchSpiTransfer (
      0, //IN       UINT8    PrefixCode,
      0x9F,//IN       UINT8    Opcode,
      DeviceIdPtr,//IN  OUT   UINT8    *DataPtr,
      (UINT8 *) (NULL),//IN       UINT8    *AddressPtr,
      2,//IN       UINT8    Length,
      FALSE,//IN       BOOLEAN  WriteFlag,
      FALSE,//IN       BOOLEAN  AddressFlag,
      FALSE,//IN       BOOLEAN  DataFlag,
      FALSE //IN       BOOLEAN  FinishedFlag
    );
  }
  return DeviceID;
}
/**
 * FchReadSpiQe - Read SPI Qual Enable
 *
 *
 *
 * @param[in] SpiDeviceProfilePtr - Spi Device Profile Pointer
 * @param[in] SpiQeRegValue   - Spi QuadEnable Register Value
 *
 */
STATIC BOOLEAN
FchReadSpiQe (
  IN OUT   SPI_DEVICE_PROFILE    *SpiDeviceProfilePtr,
  IN       UINT16     SpiQeRegValue
  )
{
  UINT16     Value16;
  SpiQeRegValue = 0;
  Value16 = 0;

  FchSpiTransfer (
    0, //IN       UINT8    PrefixCode,
    SpiDeviceProfilePtr->QeReadRegister,//IN       UINT8    Opcode,
    (UINT8 *)(&SpiQeRegValue),//IN  OUT   UINT8    *DataPtr,
    NULL,//IN       UINT8    *AddressPtr,
    0,//IN       UINT8    Length,
    FALSE,//IN       BOOLEAN  WriteFlag,
    FALSE,//IN       BOOLEAN  AddressFlag,
    TRUE,//IN       BOOLEAN  DataFlag,
    FALSE //IN       BOOLEAN  FinishedFlag
  );
  if (SpiDeviceProfilePtr->QeOperateSize == 2) {
    FchSpiTransfer (
      0, //IN       UINT8    PrefixCode,
      0x05,//IN       UINT8    Opcode,
      (UINT8 *)(&SpiQeRegValue),//IN  OUT   UINT8    *DataPtr,
      NULL,//IN       UINT8    *AddressPtr,
      0,//IN       UINT8    Length,
      FALSE,//IN       BOOLEAN  WriteFlag,
      FALSE,//IN       BOOLEAN  AddressFlag,
      TRUE,//IN       BOOLEAN  DataFlag,
      FALSE //IN       BOOLEAN  FinishedFlag
    );
    FchSpiTransfer (
      0, //IN       UINT8    PrefixCode,
      SpiDeviceProfilePtr->QeReadRegister,//IN       UINT8    Opcode,
      (UINT8 *)(&Value16),//IN  OUT   UINT8    *DataPtr,
      NULL,//IN       UINT8    *AddressPtr,
      0,//IN       UINT8    Length,
      FALSE,//IN       BOOLEAN  WriteFlag,
      FALSE,//IN       BOOLEAN  AddressFlag,
      TRUE,//IN       BOOLEAN  DataFlag,
      FALSE //IN       BOOLEAN  FinishedFlag
    );
    SpiQeRegValue |= (Value16 << 8);
  }

  if (SpiDeviceProfilePtr->QeLocation & SpiQeRegValue) {
    return TRUE;
  }
  SpiQeRegValue |= SpiDeviceProfilePtr->QeLocation;
  return FALSE;
}
/**
 * FchWriteSpiQe - Write SPI Qual Enable
 *
 *
 *
 * @param[in] SpiDeviceProfilePtr - Spi Device Profile Pointer
 * @param[in] SpiQeRegValue   - Spi QuadEnable Register Value
 *
 */
STATIC VOID
FchWriteSpiQe (
  IN OUT   SPI_DEVICE_PROFILE    *SpiDeviceProfilePtr,
  IN       UINT16     SpiQeRegValue
  )
{

  SpiQeRegValue |= SpiDeviceProfilePtr->QeLocation;
  FchSpiTransfer (
    0x06, //IN       UINT8    PrefixCode,
    SpiDeviceProfilePtr->QeWriteRegister,//IN       UINT8    Opcode,
    (UINT8 *)(&SpiQeRegValue),//IN  OUT   UINT8    *DataPtr,
    NULL,//IN       UINT8    *AddressPtr,
    SpiDeviceProfilePtr->QeOperateSize - 1,//IN       UINT8    Length,
    TRUE,//IN       BOOLEAN  WriteFlag,
    FALSE,//IN       BOOLEAN  AddressFlag,
    TRUE,//IN       BOOLEAN  DataFlag,
    TRUE //IN       BOOLEAN  FinishedFlag
  );
}

/**
 * FchFindSpiDeviceProfile - Find SPI Device Profile
 *
 *
 *
 * @param[in] DeviceID   - Device ID
 * @param[in] SpiDeviceProfilePtr - Spi Device Profile Pointer
 *
 */
STATIC BOOLEAN
FchFindSpiDeviceProfile (
  IN       UINT32     DeviceID,
  IN OUT   SPI_DEVICE_PROFILE    *SpiDeviceProfilePtr
  )
{
  SPI_DEVICE_PROFILE   *CurrentSpiDeviceProfilePtr;
  UINT16     SpiQeRegValue;
  SpiQeRegValue = 0;
  CurrentSpiDeviceProfilePtr = SpiDeviceProfilePtr;
  do {
    if (CurrentSpiDeviceProfilePtr->JEDEC_ID == DeviceID) {
      SpiDeviceProfilePtr = CurrentSpiDeviceProfilePtr;
      if (!(FchReadSpiQe (SpiDeviceProfilePtr, SpiQeRegValue))) {
        FchWriteSpiQe (SpiDeviceProfilePtr, SpiQeRegValue);
        if (!(FchReadSpiQe (SpiDeviceProfilePtr, SpiQeRegValue))) {
          return FALSE;
        }
      }
      return TRUE;
    }
    CurrentSpiDeviceProfilePtr++;
  } while (CurrentSpiDeviceProfilePtr->JEDEC_ID != 0);
  return FALSE;
}

/**
 * FchConfigureSpiDeviceDummyCycle - Configure Spi Device Dummy
 * Cycle
 *
 *
 *
 * @param[in] DeviceID   - Device ID
 * @param[in] FchDataPtr  - FchData Pointer.
 *
 */
STATIC BOOLEAN
FchConfigureSpiDeviceDummyCycle (
  IN       UINT32     DeviceID,
  IN OUT   FCH_RESET_DATA_BLOCK    *FchDataPtr
  )
{
  UINT16     Mode16;
  UINT16     Value16;
  UINT8      Value8;
  UINT16     DummyValue16;
  UINT16     CurrentDummyValue16;
  UINT16     CurrentMode16;
  AMD_CONFIG_PARAMS         *StdHeader;

  StdHeader = FchDataPtr->StdHeader;
  Value16 = 0;
  DummyValue16 = 8;

  switch (DeviceID) {
  case 0x17BA20://N25Q064
  case 0x16BA20://N25Q032

    FchSpiTransfer (
      0, //IN       UINT8    PrefixCode,
      0xB5,//IN       UINT8    Opcode,
      (UINT8 *)(&Value16),//IN  OUT   UINT8    *DataPtr,
      NULL,//IN       UINT8    *AddressPtr,
      1,//IN       UINT8    Length,
      FALSE,//IN       BOOLEAN  WriteFlag,
      FALSE,//IN       BOOLEAN  AddressFlag,
      TRUE,//IN       BOOLEAN  DataFlag,
      FALSE //IN       BOOLEAN  FinishedFlag
    );
    CurrentDummyValue16 = Value16 >> 12;
    CurrentMode16 = (Value16 >> 9) & 7;

    switch (FchDataPtr->Mode) {
    case FCH_SPI_MODE_QUAL_144:
      DummyValue16 = 6;
      Mode16 = FCH_SPI_DEVICE_MODE_144;
      break;
    case FCH_SPI_MODE_QUAL_114:
      DummyValue16 = 8;
      Mode16 = FCH_SPI_DEVICE_MODE_114;
      Mode16 = 7;
      break;
    case FCH_SPI_MODE_QUAL_122:
      DummyValue16 = 4;
      Mode16 = FCH_SPI_DEVICE_MODE_122;
      break;
    case FCH_SPI_MODE_QUAL_112:
      DummyValue16 = 8;
      Mode16 = FCH_SPI_DEVICE_MODE_112;
      break;
    case FCH_SPI_MODE_FAST:
      DummyValue16 = 8;
      Mode16 = FCH_SPI_DEVICE_MODE_FAST;
      break;
    default:
      DummyValue16 = 15;
      Mode16 = 7;
      break;
    }
    if ((CurrentDummyValue16 != DummyValue16) || (CurrentMode16 != Mode16)) {
      //FCH_DEADLOOP();
      Value16 &= ~ (0x7f << 9);
      Value16 |= (DummyValue16 << 12);
      Value16 |= (Mode16 << 9);
      FchSpiTransfer (
        0x06, //IN       UINT8    PrefixCode,
        0xB1,//IN       UINT8    Opcode,
        (UINT8 *)(&Value16),//IN  OUT   UINT8    *DataPtr,
        NULL,//IN       UINT8    *AddressPtr,
        1,//IN       UINT8    Length,
        TRUE,//IN       BOOLEAN  WriteFlag,
        FALSE,//IN       BOOLEAN  AddressFlag,
        TRUE,//IN       BOOLEAN  DataFlag,
        TRUE //IN       BOOLEAN  FinishedFlag
      );

      FchSpiTransfer (
        0, //IN       UINT8    PrefixCode,
        0x85,//IN       UINT8    Opcode,
        (UINT8 *)(&Value8),//IN  OUT   UINT8    *DataPtr,
        NULL,//IN       UINT8    *AddressPtr,
        0,//IN       UINT8    Length,
        FALSE,//IN       BOOLEAN  WriteFlag,
        FALSE,//IN       BOOLEAN  AddressFlag,
        TRUE,//IN       BOOLEAN  DataFlag,
        FALSE //IN       BOOLEAN  FinishedFlag
      );

      Value8 &= ~ (0xf << 4);
      Value8 |= (UINT8) (DummyValue16 << 4);
      FchSpiTransfer (
        0x06, //IN       UINT8    PrefixCode,
        0x81,//IN       UINT8    Opcode,
        (UINT8 *)(&Value8),//IN  OUT   UINT8    *DataPtr,
        NULL,//IN       UINT8    *AddressPtr,
        0,//IN       UINT8    Length,
        TRUE,//IN       BOOLEAN  WriteFlag,
        FALSE,//IN       BOOLEAN  AddressFlag,
        TRUE,//IN       BOOLEAN  DataFlag,
        TRUE //IN       BOOLEAN  FinishedFlag
      );
      //      FchStall (1000, StdHeader);
//      WriteIo8 ((UINT16) (0xCF9), 0x0E);
    }
    return TRUE;
  default:
    return FALSE;
  }
}
/**
 * FchPlatformSpiQe - Platform SPI Qual Enable
 *
 *
 *
 * @param[in] FchDataPtr  - FchData Pointer.
 *
 */
BOOLEAN
FchPlatformSpiQe (
  IN       VOID     *FchDataPtr
  )
{
  UINT32 DeviceID;
  SPI_DEVICE_PROFILE        *LocalSpiDeviceProfilePtr;
  FCH_RESET_DATA_BLOCK      *LocalCfgPtr;
  AMD_CONFIG_PARAMS         *StdHeader;
  LocalCfgPtr = (FCH_RESET_DATA_BLOCK *) FchDataPtr;
  if (LocalCfgPtr->QeEnabled) {
    return TRUE;
  }
  StdHeader = LocalCfgPtr->StdHeader;
  FchReadSpiId (FALSE);
  DeviceID = FchReadSpiId (TRUE);
//  if (LocalCfgPtr->OemSpiDeviceTable != NULL) {
//    LocalSpiDeviceProfilePtr = LocalCfgPtr->OemSpiDeviceTable;
//    if (FchFindSpiDeviceProfile (DeviceID, LocalSpiDeviceProfilePtr)) {
//      return TRUE;
//    }
//  }
  LocalSpiDeviceProfilePtr = (SPI_DEVICE_PROFILE *) (&DefaultSpiDeviceTable);
  if (FchConfigureSpiDeviceDummyCycle (DeviceID, LocalCfgPtr)) {
    return TRUE;
  }
  if (FchFindSpiDeviceProfile (DeviceID, LocalSpiDeviceProfilePtr)) {
    return TRUE;
  }
  return FALSE;
}

