aboutsummaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/Family/Yangtze/YangtzeLpcResetService.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/Family/Yangtze/YangtzeLpcResetService.c')
-rw-r--r--src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/Family/Yangtze/YangtzeLpcResetService.c790
1 files changed, 790 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/Family/Yangtze/YangtzeLpcResetService.c b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/Family/Yangtze/YangtzeLpcResetService.c
new file mode 100644
index 0000000000..eb0f54f473
--- /dev/null
+++ b/src/vendorcode/amd/agesa/f16kb/Proc/Fch/Spi/Family/Yangtze/YangtzeLpcResetService.c
@@ -0,0 +1,790 @@
+/* $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);
+
+ RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REG6C, AccessWidth32, 0xFFFFFF00, 0, StdHeader);
+
+ ProgramPciByteTable ( (REG8_MASK*) (&FchInitYangtzeResetLpcPciTable[0]), sizeof (FchInitYangtzeResetLpcPciTable) / sizeof (REG8_MASK), 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)) {
+ 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;
+ UINT16 DummyValue16;
+ UINT16 CurrentDummyValue16;
+ UINT16 CurrentMode16;
+ AMD_CONFIG_PARAMS *StdHeader;
+
+ StdHeader = FchDataPtr->StdHeader;
+ Value16 = 0;
+ DummyValue16 = 8;
+
+ switch (DeviceID) {
+ case 0x17BA20:
+
+ 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
+ );
+ 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;
+}
+