| /* $NoKeywords:$ */ |
| /** |
| * @file |
| * |
| * mnmcttn.c |
| * |
| * Northbridge TN MCT supporting functions |
| * |
| * @xrefitem bom "File Content Label" "Release Content" |
| * @e project: AGESA |
| * @e sub-project: (Mem/NB/TN) |
| * @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 "amdlib.h" |
| #include "Ids.h" |
| #include "mport.h" |
| #include "GnbRegistersTN.h" |
| #include "GnbRegisterAccTN.h" |
| #include "mm.h" |
| #include "mn.h" |
| #include "OptionMemory.h" |
| #include "mntn.h" |
| #include "cpuFeatures.h" |
| #include "Filecode.h" |
| #include "mftds.h" |
| #include "mu.h" |
| CODE_GROUP (G3_DXE) |
| RDATA_GROUP (G3_DXE) |
| |
| |
| #define FILECODE PROC_MEM_NB_TN_MNMCTTN_FILECODE |
| /*---------------------------------------------------------------------------- |
| * DEFINITIONS AND MACROS |
| * |
| *---------------------------------------------------------------------------- |
| */ |
| #define _16MB_RJ16 0x0100 |
| /*---------------------------------------------------------------------------- |
| * TYPEDEFS AND STRUCTURES |
| * |
| *---------------------------------------------------------------------------- |
| */ |
| |
| /*---------------------------------------------------------------------------- |
| * PROTOTYPES OF LOCAL FUNCTIONS |
| * |
| *---------------------------------------------------------------------------- |
| */ |
| |
| |
| /*---------------------------------------------------------------------------- |
| * EXPORTED FUNCTIONS |
| * |
| *---------------------------------------------------------------------------- |
| */ |
| extern BUILD_OPT_CFG UserOptions; |
| |
| /* -----------------------------------------------------------------------------*/ |
| /** |
| * |
| * |
| * This function force memory Pstate to M0 |
| * |
| * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK |
| * |
| * @return TRUE - No fatal error occurs. |
| * @return FALSE - Fatal error occurs. |
| */ |
| |
| BOOLEAN |
| MemNInitializeMctTN ( |
| IN OUT MEM_NB_BLOCK *NBPtr |
| ) |
| { |
| MemNSetBitFieldNb (NBPtr, BFMemPsSel, 0); |
| MemNSetBitFieldNb (NBPtr, BFEnSplitMctDatBuffers, 1); |
| |
| MemUMFenceInstr (); |
| MemNSetBitFieldNb (NBPtr, BFMctEccDisLatOptEn, 1); |
| MemUMFenceInstr (); |
| |
| MemNBrdcstSetUnConditionalNb (NBPtr, BFPStateToAccess, 0); |
| |
| MemNForcePhyToM0Unb (NBPtr); |
| |
| return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL); |
| } |
| |
| /* -----------------------------------------------------------------------------*/ |
| /** |
| * |
| * |
| * This function sets final values for specific registers. |
| * |
| * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK |
| * |
| * @return TRUE - No fatal error occurs. |
| * @return FALSE - Fatal error occurs. |
| */ |
| |
| BOOLEAN |
| MemNFinalizeMctTN ( |
| IN OUT MEM_NB_BLOCK *NBPtr |
| ) |
| { |
| MEM_DATA_STRUCT *MemPtr; |
| MEM_PARAMETER_STRUCT *RefPtr; |
| DRAM_PREFETCH_MODE DramPrefetchMode; |
| UINT16 Speed; |
| UINT32 Value32; |
| UINT8 DcqBwThrotWm1; |
| UINT8 DcqBwThrotWm2; |
| UINT8 Dct; |
| |
| MemPtr = NBPtr->MemPtr; |
| RefPtr = MemPtr->ParameterListPtr; |
| DramPrefetchMode = MemPtr->PlatFormConfig->PlatformProfile.AdvancedPerformanceProfile.DramPrefetchMode; |
| Speed = NBPtr->DCTPtr->Timings.Speed; |
| |
| // |
| // F2x11C |
| // |
| MemNSetBitFieldNb (NBPtr, BFMctCfgHiReg, 0x0CE00F31); |
| if (DramPrefetchMode == DISABLE_DRAM_PREFETCH_FOR_IO || DramPrefetchMode == DISABLE_DRAM_PREFETCHER) { |
| MemNSetBitFieldNb (NBPtr, BFPrefIoDis, 1); |
| } |
| |
| if (DramPrefetchMode == DISABLE_DRAM_PREFETCH_FOR_CPU || DramPrefetchMode == DISABLE_DRAM_PREFETCHER) { |
| MemNSetBitFieldNb (NBPtr, BFPrefCpuDis, 1); |
| } |
| |
| |
| if (Speed == DDR667_FREQUENCY) { |
| DcqBwThrotWm1 = 3; |
| DcqBwThrotWm2 = 4; |
| } else if (Speed == DDR800_FREQUENCY) { |
| DcqBwThrotWm1 = 3; |
| DcqBwThrotWm2 = 5; |
| } else if (Speed == DDR1066_FREQUENCY) { |
| DcqBwThrotWm1 = 4; |
| DcqBwThrotWm2 = 6; |
| } else if (Speed == DDR1333_FREQUENCY) { |
| DcqBwThrotWm1 = 5; |
| DcqBwThrotWm2 = 8; |
| } else if (Speed == DDR1600_FREQUENCY) { |
| DcqBwThrotWm1 = 6; |
| DcqBwThrotWm2 = 9; |
| } else if (Speed == DDR1866_FREQUENCY) { |
| DcqBwThrotWm1 = 7; |
| DcqBwThrotWm2 = 10; |
| } else { |
| DcqBwThrotWm1 = 8; |
| DcqBwThrotWm2 = 12; |
| } |
| // |
| // F2x1B0 |
| // |
| Value32 = MemNGetBitFieldNb (NBPtr, BFExtMctCfgLoReg); |
| Value32 &= 0x003FE8C0; |
| Value32 |= 0x0FC01001; |
| MemNSetBitFieldNb (NBPtr, BFExtMctCfgLoReg, Value32); |
| |
| // |
| // F2x1B4 |
| // |
| Value32 = MemNGetBitFieldNb (NBPtr, BFExtMctCfgHiReg); |
| Value32 &= 0xFFFFFC00; |
| Value32 |= (((UINT32) DcqBwThrotWm2 << 5) | (UINT32) DcqBwThrotWm1); |
| MemNSetBitFieldNb (NBPtr, BFExtMctCfgHiReg, Value32); |
| |
| for (Dct = 0; Dct < MAX_DCTS_PER_NODE_TN; Dct++) { |
| MemNSwitchDCTNb (NBPtr, Dct); |
| |
| if (NBPtr->DCTPtr->Timings.DctMemSize != 0) { |
| // |
| // Phy Power Saving |
| // |
| MemNPhyPowerSavingMPstateUnb (NBPtr); |
| if (NBPtr->MemPstateStage == MEMORY_PSTATE_3RD_STAGE) { |
| MemNChangeMemPStateContextNb (NBPtr, 1); |
| MemNPhyPowerSavingMPstateUnb (NBPtr); |
| MemFInitTableDrive (NBPtr, MTAfterSettingMemoryPstate1); |
| MemNChangeMemPStateContextNb (NBPtr, 0); |
| } |
| // |
| // Power Down Enable |
| // |
| if (NBPtr->RefPtr->EnablePowerDown) { |
| MemNSetBitFieldNb (NBPtr, BFPowerDownEn, 1); |
| } |
| } |
| } |
| |
| // Set LockDramCfg |
| if (IsFeatureEnabled (C6Cstate, NBPtr->MemPtr->PlatFormConfig, &(NBPtr->MemPtr->StdHeader))) { |
| IDS_SKIP_HOOK (IDS_LOCK_DRAM_CFG, NBPtr, &NBPtr->MemPtr->StdHeader) { |
| MemNSetBitFieldNb (NBPtr, BFLockDramCfg, 1); |
| } |
| } |
| |
| return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL); |
| } |
| |
| /* -----------------------------------------------------------------------------*/ |
| /** |
| * |
| * This function create the HT memory map for TN |
| * |
| * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK |
| * |
| * @return TRUE - No fatal error occurs. |
| * @return FALSE - Fatal error occurs. |
| */ |
| |
| BOOLEAN |
| MemNHtMemMapInitTN ( |
| IN OUT MEM_NB_BLOCK *NBPtr |
| ) |
| { |
| UINT8 WeReMask; |
| UINT32 BottomIo; |
| UINT32 HoleOffset; |
| UINT32 DctSelBaseAddr; |
| UINT32 NodeSysBase; |
| UINT32 NodeSysLimit; |
| MEM_PARAMETER_STRUCT *RefPtr; |
| DIE_STRUCT *MCTPtr; |
| |
| RefPtr = NBPtr->RefPtr; |
| MCTPtr = NBPtr->MCTPtr; |
| // |
| // Physical addresses in this function are right adjusted by 16 bits ([47:16]) |
| // They are BottomIO, HoleOffset, DctSelBaseAddr, NodeSysBase, NodeSysLimit. |
| // |
| |
| // Enforce bottom of IO be be 128MB aligned |
| BottomIo = (RefPtr->BottomIo & 0xF8) << 8; |
| |
| if (MCTPtr->NodeMemSize != 0) { |
| NodeSysBase = 0; |
| NodeSysLimit = MCTPtr->NodeMemSize - 1; |
| DctSelBaseAddr = MCTPtr->DctData[0].Timings.DctMemSize; |
| |
| if (NodeSysLimit >= BottomIo) { |
| // HW Dram Remap |
| MCTPtr->Status[SbHWHole] = TRUE; |
| RefPtr->GStatus[GsbHWHole] = TRUE; |
| MCTPtr->NodeHoleBase = BottomIo; |
| RefPtr->HoleBase = BottomIo; |
| |
| HoleOffset = _4GB_RJ16 - BottomIo; |
| |
| NodeSysLimit += HoleOffset; |
| |
| if ((DctSelBaseAddr > 0) && (DctSelBaseAddr < BottomIo)) { |
| HoleOffset += DctSelBaseAddr; |
| } else { |
| if (DctSelBaseAddr >= BottomIo) { |
| DctSelBaseAddr += HoleOffset; |
| } |
| HoleOffset += NodeSysBase; |
| } |
| |
| MemNSetBitFieldNb (NBPtr, BFDramHoleBase, BottomIo >> 8); |
| MemNSetBitFieldNb (NBPtr, BFDramHoleOffset, HoleOffset >> 7); |
| MemNSetBitFieldNb (NBPtr, BFDramHoleValid, 1); |
| MemNSetBitFieldNb (NBPtr, BFDramMemHoistValid, 1); |
| } else { |
| // No Remapping. Normal Contiguous mapping |
| } |
| MCTPtr->NodeSysBase = NodeSysBase; |
| MCTPtr->NodeSysLimit = NodeSysLimit; |
| RefPtr->SysLimit = MCTPtr->NodeSysLimit; |
| |
| WeReMask = 3; |
| // Set the Dram base and set the WE and RE flags in the base. |
| MemNSetBitFieldNb (NBPtr, BFDramBaseReg0, (NodeSysBase << 8) | WeReMask); |
| MemNSetBitFieldNb (NBPtr, BFDramBaseHiReg0, NodeSysBase >> 24); |
| // Set the Dram limit and set DstNode. |
| MemNSetBitFieldNb (NBPtr, BFDramLimitReg0, ((NodeSysLimit << 8) & 0xFFFF0000)); |
| MemNSetBitFieldNb (NBPtr, BFDramLimitHiReg0, NodeSysLimit >> 24); |
| |
| MemNSetBitFieldNb (NBPtr, BFDramBaseAddr, NodeSysBase >> (27 - 16)); |
| MemNSetBitFieldNb (NBPtr, BFDramLimitAddr, NodeSysLimit >> (27 - 16)); |
| |
| if ((MCTPtr->DctData[1].Timings.DctMemSize != 0) && (!NBPtr->Ganged)) { |
| MemNSetBitFieldNb (NBPtr, BFDctSelBaseAddr, DctSelBaseAddr >> 11); |
| MemNSetBitFieldNb (NBPtr, BFDctSelHiRngEn, 1); |
| MemNSetBitFieldNb (NBPtr, BFDctSelHi, 1); |
| MemNSetBitFieldNb (NBPtr, BFDctSelBaseOffset, DctSelBaseAddr >> 10); |
| } |
| } |
| return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL); |
| } |
| |
| /* -----------------------------------------------------------------------------*/ |
| /** |
| * |
| * |
| * Report the Uma size that is going to be allocated. |
| * Total system memory UMASize |
| * >= 2G 512M |
| * >=1G 256M |
| * <1G 64M |
| * |
| * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK |
| * |
| * @return Uma size [31:0] = Addr [47:16] |
| */ |
| UINT32 |
| MemNGetUmaSizeTN ( |
| IN OUT MEM_NB_BLOCK *NBPtr |
| ) |
| { |
| UINT32 SysMemSize; |
| UINT32 SizeOfUma; |
| |
| SysMemSize = NBPtr->RefPtr->SysLimit + 1; |
| SysMemSize = (SysMemSize + 0x100) & 0xFFFFF000; // Ignore 16MB allocated for C6 when finding UMA size |
| if (SysMemSize >= 0x8000) { |
| SizeOfUma = 512 << (20 - 16); |
| } else if (SysMemSize >= 0x4000) { |
| SizeOfUma = 256 << (20 - 16); |
| } else { |
| SizeOfUma = 64 << (20 - 16); |
| } |
| |
| return SizeOfUma; |
| } |
| |
| /* -----------------------------------------------------------------------------*/ |
| /** |
| * |
| * This function allocates 16MB of memory for C6 storage when it is requested to be enabled |
| * |
| * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK |
| * |
| */ |
| VOID |
| MemNAllocateC6StorageTN ( |
| IN OUT MEM_NB_BLOCK *NBPtr |
| ) |
| { |
| UINT32 SysLimit; |
| UINT32 DramLimitReg; |
| |
| if (NBPtr->SharedPtr->C6Enabled || IsFeatureEnabled (C6Cstate, NBPtr->MemPtr->PlatFormConfig, &(NBPtr->MemPtr->StdHeader))) { |
| |
| SysLimit = NBPtr->RefPtr->SysLimit; |
| |
| // Calculate new SysLimit |
| if (!NBPtr->SharedPtr->C6Enabled) { |
| // System memory available is reduced by 16MB |
| SysLimit -= _16MB_RJ16; |
| |
| NBPtr->MCTPtr->NodeSysLimit = SysLimit; |
| NBPtr->RefPtr->SysLimit = SysLimit; |
| NBPtr->SharedPtr->C6Enabled = TRUE; |
| |
| // Set TOPMEM and MTRRs (only need to be done once for BSC) |
| MemNC6AdjustMSRs (NBPtr); |
| } |
| |
| // Set Dram Limit |
| DramLimitReg = MemNGetBitFieldNb (NBPtr, BFDramLimitReg0) & 0x0000FFFF; |
| MemNSetBitFieldNb (NBPtr, BFDramLimitReg0, ((SysLimit << 8) & 0xFFFF0000) | DramLimitReg); |
| MemNSetBitFieldNb (NBPtr, BFDramLimitHiReg0, SysLimit >> 24); |
| |
| MemNSetBitFieldNb (NBPtr, BFCoreStateSaveDestNode, 0); |
| |
| // Set BFCC6SaveEn |
| MemNSetBitFieldNb (NBPtr, BFCC6SaveEn, 1); |
| // LockDramCfg will be set in FinalizeMCT |
| } |
| } |
| |
| /* -----------------------------------------------------------------------------*/ |
| /** |
| * |
| * This function adjusts NB pstate norbridge voltage for TN |
| * |
| * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK |
| * |
| */ |
| VOID |
| MemNAdjustNBPstateVolTN ( |
| IN OUT MEM_NB_BLOCK *NBPtr |
| ) |
| { |
| |
| D0F0xBC_xE0104168_STRUCT D0F0xBC_xE0104168; |
| D0F0xBC_xE010416C_STRUCT D0F0xBC_xE010416C; |
| D0F0xBC_xE0104170_STRUCT D0F0xBC_xE0104170; |
| UINT8 MemClkVidHi; |
| UINT8 MemClkVidLo; |
| UINT8 MemPstate; |
| UINT8 NbVid; |
| UINT8 NbPs; |
| UINT8 NbPstateMaxVal; |
| |
| IDS_HDT_CONSOLE (MEM_FLOW, "\nStart NB Pstate voltage adjustment.\n"); |
| |
| GnbRegisterReadTN (TYPE_D0F0xBC, D0F0xBC_xE0104168_ADDRESS, &D0F0xBC_xE0104168.Value, 0, &(NBPtr->MemPtr->StdHeader)); |
| GnbRegisterReadTN (TYPE_D0F0xBC, D0F0xBC_xE010416C_ADDRESS, &D0F0xBC_xE010416C.Value, 0, &(NBPtr->MemPtr->StdHeader)); |
| GnbRegisterReadTN (TYPE_D0F0xBC, D0F0xBC_xE0104170_ADDRESS, &D0F0xBC_xE0104170.Value, 0, &(NBPtr->MemPtr->StdHeader)); |
| |
| IDS_HDT_CONSOLE (MEM_FLOW, "\t\tD0F0xBC_xE0104168: %08x\n", D0F0xBC_xE0104168.Value); |
| IDS_HDT_CONSOLE (MEM_FLOW, "\t\tD0F0xBC_xE010416C: %08x\n", D0F0xBC_xE010416C.Value); |
| IDS_HDT_CONSOLE (MEM_FLOW, "\t\tD0F0xBC_xE0104170: %08x\n", D0F0xBC_xE0104170.Value); |
| |
| // MemClkVidHi = read D0F0xBC_xE0104168 through D0F0xBC_xE0104170 to find the VID code corresponding |
| // to the M0 MEMCLK. If the M0 MEMCLK is not found, use the next higher defined MEMCLK as the target. |
| switch (NBPtr->DCTPtr->Timings.TargetSpeed) { |
| case DDR667_FREQUENCY: |
| MemClkVidHi = (UINT8) D0F0xBC_xE0104168.Field.MemClkVid0_7_0; |
| break; |
| case DDR800_FREQUENCY: |
| MemClkVidHi = (UINT8) D0F0xBC_xE0104168.Field.MemClkVid1_7_0; |
| break; |
| case DDR1066_FREQUENCY: |
| MemClkVidHi = (UINT8) D0F0xBC_xE0104168.Field.MemClkVid2_7_0; |
| break; |
| case DDR1333_FREQUENCY: |
| MemClkVidHi = (UINT8) D0F0xBC_xE0104168.Field.MemClkVid3_1_0 | ((UINT8) D0F0xBC_xE010416C.Field.MemClkVid3_7_2 << 2); |
| break; |
| case DDR1600_FREQUENCY: |
| MemClkVidHi = (UINT8) D0F0xBC_xE010416C.Field.MemClkVid4_7_0; |
| break; |
| case DDR1866_FREQUENCY: |
| MemClkVidHi = (UINT8) D0F0xBC_xE010416C.Field.MemClkVid5_7_0; |
| break; |
| case DDR2100_FREQUENCY: |
| MemClkVidHi = (UINT8) D0F0xBC_xE010416C.Field.MemClkVid6_7_0; |
| break; |
| case DDR2133_FREQUENCY: |
| MemClkVidHi = (UINT8) D0F0xBC_xE010416C.Field.MemClkVid7_1_0 | ((UINT8) D0F0xBC_xE0104170.Field.MemClkVid7_7_2 << 2); |
| break; |
| case DDR2400_FREQUENCY: |
| MemClkVidHi = (UINT8) D0F0xBC_xE0104170.Field.MemClkVid8_7_0; |
| break; |
| default: |
| // If the M0 MEMCLK is greater than MemClkVid8, use the MemClkVid8 VID as the target |
| MemClkVidHi = (UINT8) D0F0xBC_xE0104170.Field.MemClkVid8_7_0; |
| } |
| |
| // MemClkVidLo = read D0F0xBC_xE0104168 through D0F0xBC_xE0104170 to find the VID code corresponding |
| // to the M1 MEMCLK. If the M1 MEMCLK is not found, use the next higher defined MEMCLK as the target. |
| MemClkVidLo = (UINT8) D0F0xBC_xE0104168.Field.MemClkVid0_7_0; |
| |
| IDS_HDT_CONSOLE (MEM_FLOW, "\t\tOriginal MemClkVidLo: %02x\n", MemClkVidLo); |
| IDS_HDT_CONSOLE (MEM_FLOW, "\t\tOriginal MemClkVidHi: %02x\n", MemClkVidHi); |
| |
| // If D18F5x188[NbOffsetTrim] == 01b, MemClkVid = Fuse[MemClkVid] - 4 (-25mV offset so add 25mV to VID) |
| // Else if D18F5x188[NbOffsetTrim] == 11b, MemClkVid = Fuse[MemClkVid] + 4 (+25mV offset so decrease 25mV from VID) |
| // Else MemClkVid = Fuse[MemClkVid] |
| if (MemNGetBitFieldNb (NBPtr, BFNbOffsetTrim) == 1) { |
| MemClkVidLo -= 4; |
| MemClkVidHi -= 4; |
| IDS_HDT_CONSOLE (MEM_FLOW, "\t\tAdd 25mV\n"); |
| } else if (MemNGetBitFieldNb (NBPtr, BFNbOffsetTrim) == 3) { |
| MemClkVidLo += 4; |
| MemClkVidHi += 4; |
| IDS_HDT_CONSOLE (MEM_FLOW, "\t\tDecrease 25mV\n"); |
| } |
| IDS_HDT_CONSOLE (MEM_FLOW, "\t\tAdjusted MemClkVidLo: %02x\n", MemClkVidLo); |
| IDS_HDT_CONSOLE (MEM_FLOW, "\t\tAdjusted MemClkVidHi: %02x\n", MemClkVidHi); |
| |
| // For each NB P-state from NBP0 through D18F5x170[NbPstateMaxVal]: |
| // If ((D18F5x1[6C:60][MemPstate] == 0) && (MemClkVidHi voltage > D18F5x1[6C:60][NbVid] voltage)): |
| // Program D18F5x1[6C:60][NbVid] == MemClkVidHi. |
| // If ((D18F5x1[6C:60][MemPstate] == 1) && (MemClkVidLo voltage > D18F5x1[6C:60][NbVid] voltage)): |
| // Program D18F5x1[6C:60][NbVid] == MemClkVidLo. |
| IDS_HDT_CONSOLE (MEM_FLOW, "\t\tNBPs\tNbVid\tMemPstate\tOverride\n"); |
| NbPstateMaxVal = (UINT8) MemNGetBitFieldNb (NBPtr, BFNbPstateMaxVal); |
| for (NbPs = 0; NbPs <= NbPstateMaxVal; NbPs ++) { |
| NbVid = (UINT8) MemNGetBitFieldNb (NBPtr, BFNbVid0 + (NbPs << 1)); |
| MemPstate = (UINT8) MemNGetBitFieldNb (NBPtr, BFMemPstate0 + NbPs); |
| IDS_HDT_CONSOLE (MEM_FLOW, "\t\t %01d \t %02x \t %01d \t", NbPs, NbVid, MemPstate); |
| // higher voltage correspond to smaller VID |
| if ((MemPstate == 0) && (MemClkVidHi < NbVid)) { |
| MemNSetBitFieldNb (NBPtr, BFNbVid0 + (NbPs << 1), MemClkVidHi); |
| IDS_HDT_CONSOLE (MEM_FLOW, "MemClkVidHi\n"); |
| } else if ((MemPstate == 1) && (MemClkVidLo < NbVid)) { |
| MemNSetBitFieldNb (NBPtr, BFNbVid0 + (NbPs << 1), MemClkVidLo); |
| IDS_HDT_CONSOLE (MEM_FLOW, "MemClkVidLo\n"); |
| } else { |
| IDS_HDT_CONSOLE (MEM_FLOW, "No change\n"); |
| } |
| } |
| } |
| |
| /*---------------------------------------------------------------------------- |
| * LOCAL FUNCTIONS |
| * |
| *---------------------------------------------------------------------------- |
| */ |