diff options
author | zbao <fishbaozi@gmail.com> | 2012-07-02 14:19:14 +0800 |
---|---|---|
committer | Patrick Georgi <patrick@georgi-clan.de> | 2012-07-03 09:36:35 +0200 |
commit | 7d94cf93eec15dfb8eef9cd044fe39319d4ee9bc (patch) | |
tree | b0b385455992f0ad3ca6dbbd3266a7a386a80d4f /src/vendorcode/amd/agesa/f15tn/Proc/Mem/NB/mnfeat.c | |
parent | 78efc4c36c68b51b3e73acdb721a12ec23ed0369 (diff) | |
download | coreboot-7d94cf93eec15dfb8eef9cd044fe39319d4ee9bc.tar.xz |
AGESA F15tn: AMD family15 AGESA code for Trinity
AMD AGESA code for trinity.
Change-Id: I847a54b15e8ce03ad5dbc17b95ee6771a9da0592
Signed-off-by: Zheng Bao <zheng.bao@amd.com>
Signed-off-by: zbao <fishbaozi@gmail.com>
Reviewed-on: http://review.coreboot.org/1155
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
Diffstat (limited to 'src/vendorcode/amd/agesa/f15tn/Proc/Mem/NB/mnfeat.c')
-rw-r--r-- | src/vendorcode/amd/agesa/f15tn/Proc/Mem/NB/mnfeat.c | 1418 |
1 files changed, 1418 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f15tn/Proc/Mem/NB/mnfeat.c b/src/vendorcode/amd/agesa/f15tn/Proc/Mem/NB/mnfeat.c new file mode 100644 index 0000000000..2d9d23fac8 --- /dev/null +++ b/src/vendorcode/amd/agesa/f15tn/Proc/Mem/NB/mnfeat.c @@ -0,0 +1,1418 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * mnfeat.c + * + * Common Northbridge features + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/NB) + * @e \$Revision: 63425 $ @e \$Date: 2011-12-22 11:24:10 -0600 (Thu, 22 Dec 2011) $ + * + **/ +/***************************************************************************** +* +* Copyright 2008 - 2012 ADVANCED MICRO DEVICES, INC. All Rights Reserved. +* +* AMD is granting you permission to use this software (the Materials) +* pursuant to the terms and conditions of your Software License Agreement +* with AMD. This header does *NOT* give you permission to use the Materials +* or any rights under AMD's intellectual property. Your use of any portion +* of these Materials shall constitute your acceptance of those terms and +* conditions. If you do not agree to the terms and conditions of the Software +* License Agreement, please do not use any portion of these Materials. +* +* CONFIDENTIALITY: The Materials and all other information, identified as +* confidential and provided to you by AMD shall be kept confidential in +* accordance with the terms and conditions of the Software License Agreement. +* +* LIMITATION OF LIABILITY: THE MATERIALS AND ANY OTHER RELATED INFORMATION +* PROVIDED TO YOU BY AMD ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED +* WARRANTY OF ANY KIND, INCLUDING BUT NOT LIMITED TO WARRANTIES OF +* MERCHANTABILITY, NONINFRINGEMENT, TITLE, FITNESS FOR ANY PARTICULAR PURPOSE, +* OR WARRANTIES ARISING FROM CONDUCT, COURSE OF DEALING, OR USAGE OF TRADE. +* IN NO EVENT SHALL AMD OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES WHATSOEVER +* (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS +* INTERRUPTION, OR LOSS OF INFORMATION) ARISING OUT OF AMD'S NEGLIGENCE, +* GROSS NEGLIGENCE, THE USE OF OR INABILITY TO USE THE MATERIALS OR ANY OTHER +* RELATED INFORMATION PROVIDED TO YOU BY AMD, EVEN IF AMD HAS BEEN ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME JURISDICTIONS PROHIBIT THE +* EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, +* THE ABOVE LIMITATION MAY NOT APPLY TO YOU. +* +* AMD does not assume any responsibility for any errors which may appear in +* the Materials or any other related information provided to you by AMD, or +* result from use of the Materials or any related information. +* +* You agree that you will not reverse engineer or decompile the Materials. +* +* NO SUPPORT OBLIGATION: AMD is not obligated to furnish, support, or make any +* further information, software, technical information, know-how, or show-how +* available to you. Additionally, AMD retains the right to modify the +* Materials at any time, without notice, and is not obligated to provide such +* modified Materials to you. +* +* U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with +* "RESTRICTED RIGHTS." Use, duplication, or disclosure by the Government is +* subject to the restrictions as set forth in FAR 52.227-14 and +* DFAR252.227-7013, et seq., or its successor. Use of the Materials by the +* Government constitutes acknowledgement of AMD's proprietary rights in them. +* +* EXPORT ASSURANCE: You agree and certify that neither the Materials, nor any +* direct product thereof will be exported directly or indirectly, into any +* country prohibited by the United States Export Administration Act and the +* regulations thereunder, without the required authorization from the U.S. +* government nor will be used for any purpose prohibited by the same. +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + +#include "AGESA.h" +#include "AdvancedApi.h" +#include "amdlib.h" +#include "Ids.h" +#include "OptionMemory.h" +#include "mm.h" +#include "mn.h" +#include "mu.h" +#include "PlatformMemoryConfiguration.h" +#include "merrhdl.h" +#include "Filecode.h" +CODE_GROUP (G1_PEICC) +RDATA_GROUP (G1_PEICC) + +#define FILECODE PROC_MEM_NB_MNFEAT_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +#define MAX_CL_CONT_READ 32 +#define MAX_CL_CONT_WRITE 32 + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +VOID +STATIC +MemNContWritePatternNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT32 Address, + IN UINT8 Pattern[], + IN UINT16 ClCount + ); + +VOID +STATIC +MemNContReadPatternNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Buffer[], + IN UINT32 Address, + IN UINT16 ClCount + ); + +VOID +STATIC +MemNGenHwRcvEnReadsNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT32 Address + ); + +UINT16 +STATIC +MemNCompareTestPatternClientNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Buffer[], + IN UINT8 Pattern[], + IN UINT16 ByteCount + ); + +UINT16 +STATIC +MemNInsDlyCompareTestPatternClientNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Buffer[], + IN UINT8 Pattern[], + IN UINT16 ByteCount + ); + +VOID +STATIC +MemNContWritePatternClientNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT32 Address, + IN UINT8 Pattern[], + IN UINT16 ClCount + ); + +VOID +STATIC +MemNContReadPatternClientNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Buffer[], + IN UINT32 Address, + IN UINT16 ClCount + ); + +VOID +STATIC +MemNGenHwRcvEnReadsClientNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT32 Address + ); + +BOOLEAN +STATIC +MemNBeforeMemClrClientNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN VOID *UnUsed + ); + +VOID +STATIC +MemNGenHwRcvEnReadsUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT32 Address + ); + +VOID +STATIC +MemNEnableInfiniteWritePatternUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +STATIC +MemNDisableInfiniteWritePatternUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNInitCPGNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNInitDqsTrainRcvrEnHwNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNDisableDqsTrainRcvrEnHwNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNInitCPGClientNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +VOID +MemNInitCPGUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function assigns read/write function pointers to CPG read/write modules. + * + * @param[in,out] NBPtr - Pointer to the MEM_NB_BLOCK + * + */ +VOID +MemNInitCPGNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + NBPtr->WritePattern = MemNContWritePatternNb; + NBPtr->ReadPattern = MemNContReadPatternNb; + NBPtr->GenHwRcvEnReads = MemNGenHwRcvEnReadsNb; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function initializes member functions of HW Rx En Training. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNInitDqsTrainRcvrEnHwNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + NBPtr->MemNPrepareRcvrEnDlySeed = MemNPrepareRcvrEnDlySeedNb; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function disables member functions of Hw Rx En Training. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemNDisableDqsTrainRcvrEnHwNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + NBPtr->MemNPrepareRcvrEnDlySeed = (VOID (*) (MEM_NB_BLOCK *)) memDefRet; +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function writes 9 or 18 cache lines continuously using GH CPG engine + * + * @param[in,out] NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Pattern - Array of bytes that will be written to DRAM + * @param[in] Address - System Address [47:16] + * @param[in] ClCount - Number of cache lines + * + */ +VOID +STATIC +MemNContWritePatternNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT32 Address, + IN UINT8 Pattern[], + IN UINT16 ClCount + ) +{ + UINT16 ClDiff; + if (ClCount > MAX_CL_CONT_WRITE) { + ClDiff = ClCount - MAX_CL_CONT_WRITE; + ClCount = MAX_CL_CONT_WRITE; + } else { + ClDiff = 0; + } + + // Set F2x11C[MctWrLimit] to desired number of cachelines in the burst. + MemNSetBitFieldNb (NBPtr, BFMctWrLimit, MAX_CL_CONT_WRITE - ClCount); + + // Issue the stream of writes. When F2x11C[MctWrLimit] is reached (or when F2x11C[FlushWr] is set + // again), all the writes are written to DRAM. + Address = MemUSetUpperFSbase (Address, NBPtr->MemPtr); + MemUWriteCachelines (Address, Pattern, ClCount); + + // Flush out prior writes by setting F2x11C[FlushWr]. + MemNSetBitFieldNb (NBPtr, BFFlushWr, 1); + // Wait for F2x11C[FlushWr] to clear, indicating prior writes have been flushed. + while (MemNGetBitFieldNb (NBPtr, BFFlushWr) != 0) {} + + // Set F2x11C[MctWrLimit] to 1Fh to disable write bursting. + MemNSetBitFieldNb (NBPtr, BFMctWrLimit, 0x1F); + + if (ClDiff > 0) { + MemNContWritePatternNb (NBPtr, Address + (MAX_CL_CONT_WRITE * 64), Pattern + (MAX_CL_CONT_WRITE * 64), ClDiff); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function reads 9 or 18 cache lines continuously using GH CPG engine + * + * @param[in,out] NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] Buffer - Array of bytes to be filled with data read from DRAM + * @param[in] Address - System Address [47:16] + * @param[in] ClCount - Number of cache lines + * + */ + +VOID +STATIC +MemNContReadPatternNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Buffer[], + IN UINT32 Address, + IN UINT16 ClCount + ) +{ + BOOLEAN DisAutoRefresh; + UINT16 ClDiff; + if (ClCount > MAX_CL_CONT_READ) { + ClDiff = ClCount - MAX_CL_CONT_READ; + ClCount = MAX_CL_CONT_READ; + } else { + ClDiff = 0; + } + + Address = MemUSetUpperFSbase (Address, NBPtr->MemPtr); + + // 1. BIOS ensures that the only accesses outstanding to the MCT are training reads. + // 2. If F2x[1, 0]90[BurstLength32]=1, then BIOS ensures that the DCTs and DRAMs are configured for 64 + // byte bursts (8-beat burst length). This requires that BIOS issue MRS commands to the devices + // to change to an 8-beat burst length and then to restore the desired burst length after training + // is complete. + + if (MemNGetBitFieldNb (NBPtr, BFDisAutoRefresh) == 0) { + DisAutoRefresh = FALSE; + // 3. BIOS programs F2x[1, 0]90[ForceAutoPchg] = 0 and F2x[1, 0]8C[DisAutoRefresh] = 1. + // 4. If necessary, BIOS programs F2x[1, 0]78[EarlyArbEn] = 1 at this time. See register description. + MemNSetBitFieldNb (NBPtr, BFDisAutoRefresh, 1); + // MemNSetBitFieldNb (NBPtr, BFForceAutoPchg, 0); // ForceAutoPchg is 0 by default. + MemNSetBitFieldNb (NBPtr, BFZqcsInterval, 0); + } else { + DisAutoRefresh = TRUE; + } + + MemNSetBitFieldNb (NBPtr, BFPrefCpuDis, 0); + + // 5. BIOS sets F2x11C[MctPrefReqLimit] to the number of training reads (Ntrain) it wishes to generate in the + // training sequence. + MemNSetBitFieldNb (NBPtr, BFMctPrefReqLimit, ClCount - 1); + + // 6. BIOS sets F2x11C[PrefDramTrainMode] bit. + // 7. The act of setting F2x11C[PrefDramTrainMode] causes the MCT to flush out the prefetch stride predictor + // table (removing any existing prefetch stride patterns). + MemNSetBitFieldNb (NBPtr, BFPrefDramTrainMode, 1); + + // 8. BIOS issues an SFENCE (or other serializing instruction) to ensure that the prior write completes. + // 9. For revision C and earlier processors, BIOS generates two training reads. For revision D processors BIOS + // generates three training reads. Three are required to detect the stride with DCQ buddy enabled. These must + // be to consecutive cache lines (i.e. 64 bytes apart) and must not cross a naturally aligned 4 Kbyte boundary. + // 10. These reads set up a stride pattern which is detected by the prefetcher. The prefetcher then continues to + // issue prefetches until F2x11C[MctPrefReqLimit] is reached, at which point the MCT clears + // F2x11C[PrefDramTrainMode]. + MemUDummyCLRead (Address); + MemUDummyCLRead (Address + 0x40); + if (NBPtr->IsSupported[CheckDummyCLRead]) { + MemUDummyCLRead (Address + 0x80); + } + // 11. BIOS issues the remaining (Ntrain - 2 for revisions C and earlier or Ntrain - 3 for revision D) reads after + // checking that F2x11C[PrefDramTrainMode] is cleared. These reads must be to consecutive cache lines + // (i.e., 64 bytes apart) and must not cross a naturally aligned 4KB boundary. These reads hit the prefetches + // and read the data from the prefetch buffer. + while (MemNGetBitFieldNb (NBPtr, BFPrefDramTrainMode) != 0) {} + MemUReadCachelines (Buffer, Address, ClCount); + + // 14. BIOS restores the target values for F2x[1, 0]90[ForceAutoPchg], F2x[1, 0]8C[DisAutoRefresh] and + // F2x[1, 0]90[BurstLength32]. + if (!DisAutoRefresh) { + MemNSetBitFieldNb (NBPtr, BFDisAutoRefresh, 0); + MemNSetBitFieldNb (NBPtr, BFZqcsInterval, 2); + } + + if (ClDiff > 0) { + MemNContReadPatternNb (NBPtr, Buffer + (MAX_CL_CONT_READ * 64), Address + (MAX_CL_CONT_READ * 64), ClDiff); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function generates a continuous burst of reads during HW RcvEn training. + * + * @param[in,out] NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Address - System Address [47:16] + * + */ +VOID +STATIC +MemNGenHwRcvEnReadsNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT32 Address + ) +{ + UINT8 TempBuffer[12 * 64]; + UINT8 BurstCount; + + for (BurstCount = 0; BurstCount < 10; BurstCount++) { + NBPtr->ReadPattern (NBPtr, TempBuffer, Address, 12); + NBPtr->FlushPattern (NBPtr, Address, 12); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function writes cache lines continuously using TCB CPG engine + * + * @param[in,out] NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Pattern - Array of bytes that will be written to DRAM + * @param[in] Address - System Address [47:16] + * @param[in] ClCount - Number of cache lines + * + */ +VOID +STATIC +MemNContWritePatternClientNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT32 Address, + IN UINT8 Pattern[], + IN UINT16 ClCount + ) +{ + UINT32 PatternHash; + UINT32 *DwordPtr; + UINT16 i; + UINT16 j; + UINT16 Multiplier; + + Multiplier = 1; + + // 1. Program D18F2x1C0[WrDramTrainMode]=1. + MemNSetBitFieldNb (NBPtr, BFWrDramTrainMode, 1); + + PatternHash = ClCount << 24; + for (i = 0; i < 3; i ++) { + PatternHash |= (Pattern[i * ClCount * 24 + 9] << (8 * i)); + } + if (NBPtr->CPGInit != PatternHash) { + + if (ClCount == 3) { + // Double pattern length for MaxRdLat training + Multiplier = 2; + } + + // If write training buffer has not been initialized, initialize it + // 2. Program D18F2x1C0[TrainLength] to the appropriate number of cache lines. + MemNSetBitFieldNb (NBPtr, BFTrainLength, ClCount * Multiplier); + + // 3. Program D18F2x1D0[WrTrainBufAddr]=000h. + MemNSetBitFieldNb (NBPtr, BFWrTrainBufAddr, 0); + + // 4. Successively write each dword of the training pattern to D18F2x1D4. + DwordPtr = (UINT32 *) Pattern; + for (j = 0; j < Multiplier; j++) { + for (i = 0; i < (ClCount * 16); i++) { + MemNSetBitFieldNb (NBPtr, BFWrTrainBufDat, DwordPtr[i]); + } + } + + NBPtr->CPGInit = PatternHash; + } + + // 5. Program D18F2x1D0[WrTrainBufAddr]=000h + MemNSetBitFieldNb (NBPtr, BFWrTrainBufAddr, 0); + + // 6. Program the DRAM training address + MemNSetBitFieldNb (NBPtr, BFWrTrainAdrPtrLo, Address << (16 - 6)); + MemNSetBitFieldNb (NBPtr, BFWrTrainAdrPtrHi, (Address >> (38 - 16)) & 3); + + // 7. Program D18F2x1C0[WrTrainGo]=1. + MemNSetBitFieldNb (NBPtr, BFWrTrainGo, 1); + + // 8. Wait for D18F2x1C0[WrTrainGo]=0. + while (MemNGetBitFieldNb (NBPtr, BFWrTrainGo) != 0) {} + + // 9. Program D18F2x1C0[WrDramTrainMode]=0. + MemNSetBitFieldNb (NBPtr, BFWrDramTrainMode, 0); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function reads cache lines continuously using TCB CPG engine + * + * @param[in,out] NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] Buffer - Array of bytes to be filled with data read from DRAM + * @param[in] Address - System Address [47:16] + * @param[in] ClCount - Number of cache lines + * + */ + +VOID +STATIC +MemNContReadPatternClientNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Buffer[], + IN UINT32 Address, + IN UINT16 ClCount + ) +{ + UINT16 Multiplier; + + Multiplier = 1; + if (ClCount == 3) { + // Double pattern length for MaxRdLat training + Multiplier = 2; + } + + // 1. Program D18F2x1C0[RdDramTrainMode]=1. + MemNSetBitFieldNb (NBPtr, BFRdDramTrainMode, 1); + + // 2. Program D18F2x1C0[TrainLength] to the appropriate number of cache lines. + MemNSetBitFieldNb (NBPtr, BFTrainLength, ClCount * Multiplier); + + // 3. Program the DRAM training address as follows: + MemNSetBitFieldNb (NBPtr, BFWrTrainAdrPtrLo, Address << (16 - 6)); + MemNSetBitFieldNb (NBPtr, BFWrTrainAdrPtrHi, (Address >> (38 - 16)) & 3); + + // 4. Program D18F2x1D0[WrTrainBufAddr]=000h + MemNSetBitFieldNb (NBPtr, BFWrTrainBufAddr, 0); + + // 5. Program D18F2x1C0[RdTrainGo]=1. + MemNSetBitFieldNb (NBPtr, BFRdTrainGo, 1); + + // 6. Wait for D18F2x1C0[RdTrainGo]=0. + while (MemNGetBitFieldNb (NBPtr, BFRdTrainGo) != 0) {} + + // 7. Read D18F2x1E8[TrainCmpSts] and D18F2x1E8[TrainCmpSts2]. + // This step will be accomplished in Compare routine. + + // 8. Program D18F2x1C0[RdDramTrainMode]=0. + MemNSetBitFieldNb (NBPtr, BFRdDramTrainMode, 0); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function generates a continuous burst of reads during HW RcvEn training. + * + * @param[in,out] NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Address - System Address [47:16] + * + */ +VOID +STATIC +MemNGenHwRcvEnReadsClientNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT32 Address + ) +{ + UINT8 TempBuffer[64]; + UINT8 Count; + + for (Count = 0; Count < 3; Count++) { + NBPtr->ReadPattern (NBPtr, TempBuffer, Address, 64); + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function assigns read/write function pointers to CPG read/write modules. + * + * @param[in,out] NBPtr - Pointer to the MEM_NB_BLOCK + * + */ +VOID +MemNInitCPGClientNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + NBPtr->WritePattern = MemNContWritePatternClientNb; + NBPtr->ReadPattern = MemNContReadPatternClientNb; + NBPtr->GenHwRcvEnReads = MemNGenHwRcvEnReadsClientNb; + NBPtr->FlushPattern = (VOID (*) (MEM_NB_BLOCK *, UINT32, UINT16)) memDefRet; + NBPtr->CompareTestPattern = MemNCompareTestPatternClientNb; + NBPtr->InsDlyCompareTestPattern = MemNInsDlyCompareTestPatternClientNb; + NBPtr->FamilySpecificHook[BeforeMemClr] = MemNBeforeMemClrClientNb; + NBPtr->CPGInit = 0; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function compares test pattern with data in buffer and + * return a pass/fail bitmap for 8 bytelanes (upper 8 bits are reserved) + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Buffer[] - Buffer data from DRAM (Measured data from DRAM) to compare + * @param[in] Pattern[] - Pattern (Expected data in ROM/CACHE) to compare against + * @param[in] ByteCount - Byte count + * + * @return PASS - Bitmap of results of comparison + */ + +UINT16 +STATIC +MemNCompareTestPatternClientNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Buffer[], + IN UINT8 Pattern[], + IN UINT16 ByteCount + ) +{ + return ~((UINT16) MemNGetBitFieldNb (NBPtr, BFTrainCmpSts)); +} + +/*-----------------------------------------------------------------------------*/ +/** + * + * This function compares test pattern with data in buffer and + * return a pass/fail bitmap for 8 bytelanes (upper 8 bits are reserved) + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Buffer[] - Buffer data from DRAM (Measured data from DRAM) to compare + * @param[in] Pattern[] - Pattern (Expected data in ROM/CACHE) to compare against + * @param[in] ByteCount - Byte count + * + * @retval Bitmap of results of comparison + */ +UINT16 +STATIC +MemNInsDlyCompareTestPatternClientNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Buffer[], + IN UINT8 Pattern[], + IN UINT16 ByteCount + ) +{ + return ~((UINT16) MemNGetBitFieldNb (NBPtr, BFTrainCmpSts2)); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function calculates RcvEn seed value for each rank + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ +VOID +MemNPrepareRcvrEnDlySeedNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + MEM_TECH_BLOCK *TechPtr; + CH_DEF_STRUCT *ChannelPtr; + DIE_STRUCT *MCTPtr; + UINT16 SeedTotal; + UINT16 SeedFine; + UINT16 SeedGross; + UINT16 SeedPreGross; + UINT16 SeedTotalPreScaling; + UINT8 ByteLane; + UINT16 Speed; + UINT16 PlatEst; + UINT8 ChipSel; + UINT8 Pass; + UINT16 *PlatEstSeed; + UINT16 SeedValue[9]; + UINT16 SeedTtl[9]; + UINT16 SeedPre[9]; + + TechPtr = NBPtr->TechPtr; + MCTPtr = NBPtr->MCTPtr; + ChannelPtr = TechPtr->NBPtr->ChannelPtr; + Speed = NBPtr->DCTPtr->Timings.Speed; + SeedTotalPreScaling = 0; + ChipSel = TechPtr->ChipSel; + Pass = TechPtr->Pass; + + for (ByteLane = 0; ByteLane < (MCTPtr->Status[SbEccDimms] ? 9 : 8); ByteLane++) { + TechPtr->Bytelane = ByteLane; + if (Pass == 1) { + // Get platform override seed + PlatEstSeed = (UINT16 *) FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_RXEN_SEED, MCTPtr->SocketId, ChannelPtr->ChannelID, ChipSel >> 1, + &(NBPtr->MCTPtr->LogicalCpuid), &(NBPtr->MemPtr->StdHeader)); + // For Pass1, BIOS starts with the delay value obtained from the first pass of write + // levelization training that was done in DDR3 Training and add a delay value of 3Bh. + PlatEst = 0x3B; + NBPtr->FamilySpecificHook[OverrideRcvEnSeed] (NBPtr, &PlatEst); + PlatEst = ((PlatEstSeed != NULL) ? PlatEstSeed[ByteLane] : PlatEst); + SeedTotal = ChannelPtr->WrDqsDlys[(ChipSel / NBPtr->CsPerDelay) * TechPtr->DlyTableWidth () + ByteLane] + PlatEst; + SeedValue[ByteLane] = PlatEst; + } else { + // For Pass2 + // SeedTotalPreScaling = (the total delay values in D18F2x[1,0]9C_x0000_00[24:10] from pass 1 of + // DQS receiver enable training) - 20h. Subtract 1UI to get back to preamble left edge. + if ((((ChipSel & 1) == 0) || (NBPtr->CsPerDelay == 1)) && NBPtr->FamilySpecificHook[TrainingNibbleZero] (NBPtr, &ChipSel)) { + // Save Seed for odd CS SeedTotalPreScaling RxEn Value + TechPtr->PrevPassRcvEnDly[ByteLane] = ChannelPtr->RcvEnDlys[(ChipSel / NBPtr->CsPerDelay) * TechPtr->DlyTableWidth () + ByteLane]; + } + NBPtr->FamilySpecificHook[OverridePrevPassRcvEnDly] (NBPtr, &TechPtr->PrevPassRcvEnDly[ByteLane]); + SeedTotalPreScaling = TechPtr->PrevPassRcvEnDly[ByteLane] - 0x20; + // SeedTotal = SeedTotalPreScaling*target frequency/lowest supported frequency. + SeedTotal = (UINT16) (((UINT32) SeedTotalPreScaling * Speed) / TechPtr->PrevSpeed); + NBPtr->FamilySpecificHook[OverrideRcvEnSeedPassN] (NBPtr, &SeedTotal); + } + SeedTtl[ByteLane] = SeedTotal; + + // SeedGross = SeedTotal DIV 32. + SeedGross = SeedTotal >> 5; + // SeedFine = SeedTotal MOD 32. + SeedFine = SeedTotal & 0x1F; + // Next, determine the gross component of SeedTotal. SeedGrossPass1=SeedTotal DIV 32. + // Then, determine the fine delay component of SeedTotal. SeedFinePass1=SeedTotal MOD 32. + // Use SeedGrossPass1 to determine SeedPreGrossPass1: + + if ((SeedGross & 0x1) != 0) { + //if SeedGross is odd + SeedPreGross = 1; + } else { + //if SeedGross is even + SeedPreGross = 2; + } + // (SeedGross - SeedPreGross) + TechPtr->DiffSeedGrossSeedPreGross[ByteLane] = (SeedGross - SeedPreGross) << 5; + + //BIOS programs registers F2x[1, 0]9C_x[51:50] and F2x[1, 0]9C_x52 with SeedPreGrossPass1 + //and SeedFinePass1 from the preceding steps. + + NBPtr->SetTrainDly (NBPtr, AccessPhRecDly, DIMM_BYTE_ACCESS (ChipSel / NBPtr->CsPerDelay, ByteLane), (SeedPreGross << 5) | SeedFine); + SeedPre[ByteLane] = (SeedPreGross << 5) | SeedFine; + + NBPtr->SetTrainDly (NBPtr, AccessRcvEnDly, DIMM_BYTE_ACCESS (ChipSel / NBPtr->CsPerDelay, ByteLane), SeedGross << 5); + } + + IDS_HDT_CONSOLE_DEBUG_CODE ( + if (Pass == 1) { + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tSeedValue: "); + for (ByteLane = 0; ByteLane < (MCTPtr->Status[SbEccDimms] ? 9 : 8); ByteLane++) { + IDS_HDT_CONSOLE (MEM_FLOW, "%03x ", SeedValue[ByteLane]); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tSeedTotal: "); + for (ByteLane = 0; ByteLane < (MCTPtr->Status[SbEccDimms] ? 9 : 8); ByteLane++) { + IDS_HDT_CONSOLE (MEM_FLOW, "%03x ", SeedTtl[ByteLane]); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t\t SeedPRE: "); + for (ByteLane = 0; ByteLane < (MCTPtr->Status[SbEccDimms] ? 9 : 8); ByteLane++) { + IDS_HDT_CONSOLE (MEM_FLOW, "%03x ", SeedPre[ByteLane]); + } + IDS_HDT_CONSOLE (MEM_FLOW, "\n"); + ); + + NBPtr->FamilySpecificHook[RegAccessFence] (NBPtr, NULL); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Waits specified number of MEMCLKs + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] MemClkCount - Number of MEMCLKs + * + * ---------------------------------------------------------------------------- + */ +VOID +MemNWaitXMemClksNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT32 MemClkCount + ) +{ + MemUWait10ns ((MemClkCount * 100 + NBPtr->DCTPtr->Timings.Speed - 1) / NBPtr->DCTPtr->Timings.Speed, NBPtr->MemPtr); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * Issues dummy TCB write read to zero out CL that is used for MemClr + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *UnUsed - unused + * + * ---------------------------------------------------------------------------- + */ +BOOLEAN +STATIC +MemNBeforeMemClrClientNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN VOID *UnUsed + ) +{ + UINT8 Pattern[64]; + UINT8 i; + + for (i = 0; i < 64; i++) { + Pattern[i] = 0; + } + + MemNContWritePatternClientNb (NBPtr, 0x20, Pattern, 1); + MemNContReadPatternClientNb (NBPtr, Pattern, 0x20, 1); + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function uses the PRBS generator in the DCT to send a DDR Activate command + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] ChipSelect - Chip select 0-7 + * @param[in] Bank - Bank Address 0-7 + * @param[in] RowAddress - Row Address [17:0] + * + */ + +VOID +MemNRrwActivateCmd ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 ChipSelect, + IN UINT8 Bank, + IN UINT32 RowAddress + ) +{ + // Set Chip select + MemNSetBitFieldNb (NBPtr, BFCmdChipSelect, (1 << ChipSelect)); + // Set Bank Address + MemNSetBitFieldNb (NBPtr, BFCmdBank, Bank); + // Set Row Address + MemNSetBitFieldNb (NBPtr, BFCmdAddress, RowAddress); + // Send the command + MemNSetBitFieldNb (NBPtr, BFSendActCmd, 1); + // Wait for command complete + MemNPollBitFieldNb (NBPtr, BFSendActCmd, 0, PCI_ACCESS_TIMEOUT, FALSE); + // Wait 75 MEMCLKs + NBPtr->WaitXMemClks (NBPtr, 75); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function uses the PRBS generator in the DCT to send a DDR Precharge + * or Precharge All command + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] ChipSelect - Chip select 0-7 + * @param[in] Bank - Bank Address 0-7, PRECHARGE_ALL_BANKS = Precharge All + * + * + */ + +VOID +MemNRrwPrechargeCmd ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 ChipSelect, + IN UINT8 Bank + ) +{ + // Wait 25 MEMCLKs + NBPtr->WaitXMemClks (NBPtr, 25); + // Set Chip select + NBPtr->SetBitField (NBPtr, BFCmdChipSelect, (1 << ChipSelect)); + if (Bank == PRECHARGE_ALL_BANKS) { + // Set Row Address, bit 10 + NBPtr->SetBitField (NBPtr, BFCmdAddress, NBPtr->GetBitField (NBPtr, BFCmdAddress) | (1 << 10) ); + } else { + // Clear Row Address, bit 10 + NBPtr->SetBitField (NBPtr, BFCmdAddress, NBPtr->GetBitField (NBPtr, BFCmdAddress) & (~(1 << 10)) ); + // Set Bank Address + NBPtr->SetBitField (NBPtr, BFCmdBank, Bank); + } + // Send the command + NBPtr->SetBitField (NBPtr, BFSendPchgCmd, 1); + // Wait for command complete + NBPtr->PollBitField (NBPtr, BFSendPchgCmd, 0, PCI_ACCESS_TIMEOUT, FALSE); + // Wait 25 MEMCLKs + NBPtr->WaitXMemClks (NBPtr, 25); +} +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function generates a continuous burst of reads for HW RcvEn + * training using the Unified Northbridge Reliable Read/Write Engine. + * + * @param[in,out] NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Address - Unused by this function + * + */ +VOID +STATIC +MemNGenHwRcvEnReadsUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT32 Address + ) +{ + VOID *DummyPtr; + DummyPtr = NULL; + // + // Issue Stream of Reads from the Target Rank + // + NBPtr->ReadPattern (NBPtr, DummyPtr, 0, NBPtr->TechPtr->PatternLength); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function generates a continuous stream of reads from DRAM using the + * Unified Northbridge Reliable Read/Write Engine. + * + * @param[in,out] NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] Buffer - Unused by this function + * @param[in] Address - Unused by this function + * @param[in] ClCount - Number of cache lines to read + * + * Assumptions: + * + * + * + */ + +VOID +MemNContReadPatternUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Buffer[], + IN UINT32 Address, + IN UINT16 ClCount + ) +{ + MEM_TECH_BLOCK *TechPtr; + RRW_SETTINGS *Rrw; + UINT8 CmdTgt; + UINT8 ChipSel; + + TechPtr = NBPtr->TechPtr; + Rrw = &NBPtr->RrwSettings; + + ChipSel = TechPtr->ChipSel; + CmdTgt = Rrw->CmdTgt; + // + // Wait for RRW Engine to be ready and turn it on + // + NBPtr->PollBitField (NBPtr, BFCmdSendInProg, 0, PCI_ACCESS_TIMEOUT, FALSE); + NBPtr->SetBitField (NBPtr, BFCmdTestEnable, 1); + // + // Depending upon the Cmd Target, send Row Activate and set Chipselect + // for the Row or Rows that will be used + // + MemNRrwActivateCmd (NBPtr, ChipSel, Rrw->TgtBankAddressA, Rrw->TgtRowAddressA); + NBPtr->SetBitField (NBPtr, BFTgtChipSelectA, ChipSel); + if (CmdTgt == CMD_TGT_AB) { + MemNRrwActivateCmd (NBPtr, ChipSel, Rrw->TgtBankAddressB, Rrw->TgtRowAddressB); + NBPtr->SetBitField (NBPtr, BFTgtChipSelectB, ChipSel); + } + // Set Comparison Masks + NBPtr->SetBitField (NBPtr, BFDramDqMaskLow, Rrw->CompareMaskLow); + NBPtr->SetBitField (NBPtr, BFDramDqMaskHigh, Rrw->CompareMaskHigh); + // + // If All Dimms are ECC Capable Test ECC. Otherwise, mask it off + // + NBPtr->SetBitField (NBPtr, BFDramEccMask, (NBPtr->MCTPtr->Status[SbEccDimms] == TRUE) ? Rrw->CompareMaskEcc : 0xFF); + // + // Program the PRBS Seed + // + NBPtr->SetBitField (NBPtr, BFDataPrbsSeed, Rrw->DataPrbsSeed); + // + // Set the Command Count + // + NBPtr->SetBitField (NBPtr, BFCmdCount, ClCount); + // + // Program the Starting Address + // + NBPtr->SetBitField (NBPtr, BFTgtBankA, Rrw->TgtBankAddressA); + NBPtr->SetBitField (NBPtr, BFTgtAddressA, Rrw->TgtColAddressA); + if (CmdTgt == CMD_TGT_AB) { + NBPtr->SetBitField (NBPtr, BFTgtBankB, Rrw->TgtBankAddressB); + NBPtr->SetBitField (NBPtr, BFTgtAddressB, Rrw->TgtColAddressB); + } + // + // Reset All Errors and Disable StopOnErr + // + NBPtr->SetBitField (NBPtr, BFResetAllErr, 1); + NBPtr->SetBitField (NBPtr, BFStopOnErr, 0); + // + // Program the CmdTarget + // + NBPtr->SetBitField (NBPtr, BFCmdTgt, CmdTgt); + // + // Set CmdType to read + // + NBPtr->SetBitField (NBPtr, BFCmdType, CMD_TYPE_READ); + // + // Start the Commands + // + AGESA_TESTPOINT (TpProcMemContinPatternGenRead, &(NBPtr->MemPtr->StdHeader)); + NBPtr->SetBitField (NBPtr, BFSendCmd, 1); + // + // Commands have started, wait for the reads to complete then clear the command + // + NBPtr->PollBitField (NBPtr, BFTestStatus, 1, PCI_ACCESS_TIMEOUT, FALSE); + NBPtr->PollBitField (NBPtr, BFCmdSendInProg, 0, PCI_ACCESS_TIMEOUT, FALSE); + NBPtr->SetBitField (NBPtr, BFSendCmd, 0); + // + // Send the Precharge All Command + // + MemNRrwPrechargeCmd (NBPtr, ChipSel, PRECHARGE_ALL_BANKS); + // + // Turn Off the RRW Engine + // + NBPtr->SetBitField (NBPtr, BFCmdTestEnable, 0); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function generates a continuous stream of writes to DRAM using the + * Unified Northbridge Reliable Read/Write Engine. + * + * @param[in,out] NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] Address - Unused by this function + * @param[in] Pattern - Unused by this function + * @param[in] ClCount - Number of cache lines to write + * + */ + +VOID +MemNContWritePatternUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT32 Address, + IN UINT8 Pattern[], + IN UINT16 ClCount + ) +{ + MEM_TECH_BLOCK *TechPtr; + RRW_SETTINGS *Rrw; + UINT8 CmdTgt; + UINT8 ChipSel; + + TechPtr = NBPtr->TechPtr; + Rrw = &NBPtr->RrwSettings; + + ChipSel = TechPtr->ChipSel; + CmdTgt = Rrw->CmdTgt; + // + // Wait for RRW Engine to be ready and turn it on + // + NBPtr->PollBitField (NBPtr, BFCmdSendInProg, 0, PCI_ACCESS_TIMEOUT, FALSE); + NBPtr->SetBitField (NBPtr, BFCmdTestEnable, 1); + // + // Depending upon the Cmd Target, send Row Activate and set Chipselect + // for the Row or Rows that will be used + // + MemNRrwActivateCmd (NBPtr, ChipSel, Rrw->TgtBankAddressA, Rrw->TgtRowAddressA); + NBPtr->SetBitField (NBPtr, BFTgtChipSelectA, ChipSel); + if (CmdTgt == CMD_TGT_AB) { + MemNRrwActivateCmd (NBPtr, ChipSel, Rrw->TgtBankAddressB, Rrw->TgtRowAddressB); + NBPtr->SetBitField (NBPtr, BFTgtChipSelectB, ChipSel); + } + // + // Program the PRBS Seed + // + NBPtr->SetBitField (NBPtr, BFDataPrbsSeed, Rrw->DataPrbsSeed); + // + // Set the Command Count + // + NBPtr->SetBitField (NBPtr, BFCmdCount, ClCount); + // + // Program the Starting Address + // + NBPtr->SetBitField (NBPtr, BFTgtBankA, Rrw->TgtBankAddressA); + NBPtr->SetBitField (NBPtr, BFTgtAddressA, Rrw->TgtColAddressA); + if (CmdTgt == CMD_TGT_AB) { + NBPtr->SetBitField (NBPtr, BFTgtBankB, Rrw->TgtBankAddressB); + NBPtr->SetBitField (NBPtr, BFTgtAddressB, Rrw->TgtColAddressB); + } + // + // Program the CmdTarget + // + NBPtr->SetBitField (NBPtr, BFCmdTgt, CmdTgt); + // + // Set CmdType to Write + // + NBPtr->SetBitField (NBPtr, BFCmdType, CMD_TYPE_WRITE); + // + // Start the Commands + // + AGESA_TESTPOINT (TpProcMemContinPatternGenWrite, &(NBPtr->MemPtr->StdHeader)); + NBPtr->SetBitField (NBPtr, BFSendCmd, 1); + // + // Commands have started, wait for the writes to complete then clear the command + // + // Wait for TestStatus = 1 and CmdSendInProg = 0. + NBPtr->PollBitField (NBPtr, BFTestStatus, 1, PCI_ACCESS_TIMEOUT, FALSE); + NBPtr->PollBitField (NBPtr, BFCmdSendInProg, 0, PCI_ACCESS_TIMEOUT, FALSE); + NBPtr->SetBitField (NBPtr, BFSendCmd, 0); + // + // Send the Precharge All Command + // + MemNRrwPrechargeCmd (NBPtr, ChipSel, PRECHARGE_ALL_BANKS); + // + // Turn Off the RRW Engine + // + NBPtr->SetBitField (NBPtr, BFCmdTestEnable, 0); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function checks the Error status bits for comparison results + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Buffer[] - Not used in this implementation + * @param[in] Pattern[] - Not used in this implementation + * @param[in] ByteCount - Not used in this implementation + * + * @return PASS - Bitmap of results of comparison + */ + +UINT16 +MemNCompareTestPatternUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Buffer[], + IN UINT8 Pattern[], + IN UINT16 ByteCount + ) +{ + + + UINT16 i; + UINT16 Pass; + UINT8 ChipSel; + UINT8 ColumnCount; + UINT8* FailingBitMaskPtr; + UINT8 FailingBitMask[9]; + UINT32 NibbleErrSts; + + ChipSel = NBPtr->TechPtr->ChipSel; + ColumnCount = NBPtr->ChannelPtr->ColumnCount; + // Calculate Failing Bitmask pointer + FailingBitMaskPtr = &(NBPtr->ChannelPtr->FailingBitMask[(ColumnCount * NBPtr->TechPtr->ChipSel)]); + + // + // Get Failing bit data + // + *((UINT32*)FailingBitMask) = NBPtr->GetBitField (NBPtr, BFDQErrLow); + *((UINT32*)&FailingBitMask[4]) = NBPtr->GetBitField (NBPtr, BFDQErrHigh); + FailingBitMask[8] = (UINT8)NBPtr->GetBitField (NBPtr, BFEccErr); + + Pass = 0x0000; + // + // Get Comparison Results - Convert Nibble Masks to Byte Masks + // + NibbleErrSts = NBPtr->GetBitField (NBPtr, BFNibbleErrSts); + + for (i = 0; i < ColumnCount ; i++) { + Pass |= ((NibbleErrSts & 0x03) > 0 ) ? (1 << i) : 0; + NibbleErrSts >>= 2; + FailingBitMaskPtr[i] = FailingBitMask[i]; + } + Pass = ~Pass; + return Pass; +} + +/*-----------------------------------------------------------------------------*/ +/** + * + * This function checks the Error status bits for offset comparison results + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Buffer[] - Buffer data from DRAM (Measured data from DRAM) to compare + * @param[in] Pattern[] - Pattern (Expected data in ROM/CACHE) to compare against + * @param[in] ByteCount - Byte count + * + * @retval Bitmap of results of comparison + */ +UINT16 +STATIC +MemNInsDlyCompareTestPatternUnb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Buffer[], + IN UINT8 Pattern[], + IN UINT16 ByteCount + ) +{ + UINT16 i; + UINT16 Pass; + UINT8 ColumnCount; + UINT32 NibbleErr180Sts; + + ColumnCount = NBPtr->ChannelPtr->ColumnCount; + Pass = 0x0000; + // + // Get Comparison Results - Convert Nibble Masks to Byte Masks + // + NibbleErr180Sts = NBPtr->GetBitField (NBPtr, BFNibbleErr180Sts); + + for (i = 0; i < ColumnCount ; i++) { + Pass |= ((NibbleErr180Sts & 0x03) > 0 ) ? (1 << i) : 0; + NibbleErr180Sts >>= 2; + } + Pass = ~Pass; + + return Pass; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function assigns read/write function pointers to CPG read/write modules. + * + * @param[in,out] NBPtr - Pointer to the MEM_NB_BLOCK + * + */ +VOID +MemNInitCPGUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + NBPtr->WritePattern = MemNContWritePatternUnb; + NBPtr->ReadPattern = MemNContReadPatternUnb; + NBPtr->GenHwRcvEnReads = MemNGenHwRcvEnReadsUnb; + NBPtr->FlushPattern = (VOID (*) (MEM_NB_BLOCK *, UINT32, UINT16)) memDefRet; + NBPtr->TrainingPatternInit = (AGESA_STATUS (*) (MEM_NB_BLOCK *)) memDefRetSuccess; + NBPtr->TrainingPatternFinalize = (AGESA_STATUS (*) (MEM_NB_BLOCK *)) memDefRetSuccess; + NBPtr->CompareTestPattern = MemNCompareTestPatternUnb; + NBPtr->InsDlyCompareTestPattern = MemNInsDlyCompareTestPatternUnb; + NBPtr->FamilySpecificHook[SetupHwTrainingEngine] = MemNSetupHwTrainingEngineUnb; + NBPtr->EnableInfiniteWritePattern = MemNEnableInfiniteWritePatternUnb; + NBPtr->DisableInfiniteWritePattern = MemNDisableInfiniteWritePatternUnb; + NBPtr->CPGInit = 0; +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function generates a continuous stream of writes infinite writes to DRAM using the + * Unified Northbridge Reliable Read/Write Engine. + * + * @param[in,out] NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +STATIC +MemNEnableInfiniteWritePatternUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + MEM_TECH_BLOCK *TechPtr; + RRW_SETTINGS *Rrw; + UINT8 CmdTgt; + UINT8 ChipSel; + TechPtr = NBPtr->TechPtr; + Rrw = &NBPtr->RrwSettings; + ChipSel = TechPtr->ChipSel; + CmdTgt = Rrw->CmdTgt; + + // Ensure that DisAutoRefresh and ZqCals are disabled during the use of RRWM + if (MemNGetBitFieldNb (NBPtr, BFDisAutoRefresh) == 0) { + NBPtr->OrigDisAutoRefreshState = FALSE; + MemNSetBitFieldNb (NBPtr, BFDisAutoRefresh, 1); + MemNSetBitFieldNb (NBPtr, BFZqcsInterval, 0); + } else { + NBPtr->OrigDisAutoRefreshState = TRUE; + } + + + + // + // Enable PRBS + // + + // + // Wait for RRW Engine to be ready and turn it on + // + NBPtr->PollBitField (NBPtr, BFCmdSendInProg, 0, PCI_ACCESS_TIMEOUT, FALSE); + NBPtr->SetBitField (NBPtr, BFCmdTestEnable, 1); + // + // Depending upon the Cmd Target, send Row Activate and set Chipselect + // for the Row or Rows that will be used + // + MemNRrwActivateCmd (NBPtr, ChipSel, Rrw->TgtBankAddressA, Rrw->TgtRowAddressA); + NBPtr->SetBitField (NBPtr, BFTgtChipSelectA, ChipSel); + // + // Program the PRBS Seed + // + NBPtr->SetBitField (NBPtr, BFDataPrbsSeed, Rrw->DataPrbsSeed); + // + // Set the Command Count + // + NBPtr->SetBitField (NBPtr, BFCmdCount, 0); + // + // Program the Starting Address + // + NBPtr->SetBitField (NBPtr, BFTgtBankA, Rrw->TgtBankAddressA); + NBPtr->SetBitField (NBPtr, BFTgtAddressA, Rrw->TgtColAddressA); + // + // Program the CmdTarget + // + NBPtr->SetBitField (NBPtr, BFCmdTgt, CMD_TGT_A); + // + // Set CmdType to write + // + NBPtr->SetBitField (NBPtr, BFCmdType, CMD_TYPE_WRITE); + // + // Start the Commands + // + NBPtr->SetBitField (NBPtr, BFSendCmd, 1); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function disables the infinite stream of writes to DRAM using the + * Unified Northbridge Reliable Read/Write Engine. + * + * @param[in,out] NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +STATIC +MemNDisableInfiniteWritePatternUnb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + // + // Disable PRBS + NBPtr->SetBitField (NBPtr, BFCmdCount, 1); + //Wait for TestStatus = 1 and CmdSendInProg = 0 + NBPtr->PollBitField (NBPtr, BFCmdSendInProg, 0, PCI_ACCESS_TIMEOUT, FALSE); + NBPtr->SetBitField (NBPtr, BFSendCmd, 0); + // + // + // Turn Off the RRW Engine + // + MemNRrwPrechargeCmd (NBPtr, NBPtr->TechPtr->ChipSel, PRECHARGE_ALL_BANKS); + NBPtr->SetBitField (NBPtr, BFCmdTestEnable, 0); + // + // Restore DisAutoRefresh and ZQCals to original state + // + if (!NBPtr->OrigDisAutoRefreshState) { + MemNSetBitFieldNb (NBPtr, BFDisAutoRefresh, 0); + MemNSetBitFieldNb (NBPtr, BFZqcsInterval, 2); + } + +} +/*----------------------------------------------------------------------------- + * + * + * This function is an empty function used to intialize FamilySpecificHook array + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] OptParam - Optional parameter + * + * @return TRUE - always + * ---------------------------------------------------------------------------- + */ +BOOLEAN +MemNDefaultFamilyHookNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT VOID *OptParam + ) +{ + return TRUE; +} |