diff options
Diffstat (limited to 'src/northbridge/amd/amdmct/mct_ddr3/mct_d.c')
-rw-r--r-- | src/northbridge/amd/amdmct/mct_ddr3/mct_d.c | 8220 |
1 files changed, 0 insertions, 8220 deletions
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c deleted file mode 100644 index fa8c71447b..0000000000 --- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c +++ /dev/null @@ -1,8220 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2015-2017 Raptor Engineering, LLC - * Copyright (C) 2010 Advanced Micro Devices, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -/* Description: Main memory controller system configuration for DDR 3 */ - -/* KNOWN ISSUES - ERRATA - * - * Trtp is not calculated correctly when the controller is in 64-bit mode, it - * is 1 busclock off. No fix planned. The controller is not ordinarily in - * 64-bit mode. - * - * 32 Byte burst not supported. No fix planned. The controller is not - * ordinarily in 64-bit mode. - * - * Trc precision does not use extra Jedec defined fractional component. - * InsteadTrc (course) is rounded up to nearest 1 ns. - * - * Mini and Micro DIMM not supported. Only RDIMM, UDIMM, SO-DIMM defined types - * supported. - */ - -#include <console/console.h> -#include <northbridge/amd/amdfam10/debug.h> -#include <northbridge/amd/amdfam10/raminit.h> -#include <northbridge/amd/amdfam10/amdfam10.h> -#include <southbridge/amd/common/reset.h> -#include <cpu/x86/msr.h> -#include <cpu/amd/msr.h> -#include <cpu/x86/mtrr.h> -#include <device/pci_ops.h> -#include <arch/acpi.h> -#include <string.h> -#include <types.h> -#include <device/dram/ddr3.h> - -#include "s3utils.h" -#include "mct_d_gcc.h" -#include "mct_d.h" - -static u8 ReconfigureDIMMspare_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA); -static void DQSTiming_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA, - uint8_t allow_config_restore); -static void LoadDQSSigTmgRegs_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA); -static void HTMemMapInit_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA); -static void SyncDCTsReady_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA); -static void ClearDCT_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static u8 AutoCycTiming_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static void GetPresetmaxF_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -static void SPDGetTCL_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static u8 AutoConfig_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static void SPDSetBanks_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static void StitchMemory_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static u16 Get_Fk_D(u8 k); -static u8 Get_DIMMAddress_D(struct DCTStatStruc *pDCTstat, u8 i); -static void mct_preInitDCT(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -static void mct_initDCT(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -static void mct_DramInit(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static void mct_SyncDCTsReady(struct DCTStatStruc *pDCTstat); -static void Get_Trdrd(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static void mct_AfterGetCLT(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static u8 mct_SPDCalcWidth(struct MCTStatStruc *pMCTstat,\ - struct DCTStatStruc *pDCTstat, u8 dct); -static void mct_AfterStitchMemory(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static u8 mct_DIMMPresence(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static void Set_OtherTiming(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static void Get_Twrwr(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static void Get_Twrrd(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static void Get_TrwtTO(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static void Get_TrwtWB(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -static void Get_DqsRcvEnGross_Diff(struct DCTStatStruc *pDCTstat, - u32 dev, uint8_t dct, u32 index_reg); -static void Get_WrDatGross_Diff(struct DCTStatStruc *pDCTstat, u8 dct, - u32 dev, u32 index_reg); -static u16 Get_DqsRcvEnGross_MaxMin(struct DCTStatStruc *pDCTstat, - u32 dev, uint8_t dct, u32 index_reg, u32 index); -static void mct_FinalMCT_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -static u16 Get_WrDatGross_MaxMin(struct DCTStatStruc *pDCTstat, u8 dct, - u32 dev, u32 index_reg, u32 index); -static void mct_InitialMCT_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -static void mct_init(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -static void clear_legacy_Mode(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -static void mct_HTMemMapExt(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA); -static void SetCSTriState(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static void SetCKETriState(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static void SetODTTriState(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static void InitDDRPhy(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static u32 mct_NodePresent_D(void); -static void mct_OtherTiming(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA); -static void mct_ResetDataStruct_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA); -static void mct_EarlyArbEn_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static void mct_BeforeDramInit_Prod_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static void mct_ProgramODT_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -void mct_ClrClToNB_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -static u8 CheckNBCOFEarlyArbEn(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -void mct_ClrWbEnhWsbDis_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -static void mct_BeforeDQSTrain_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA); -static void AfterDramInit_D(struct DCTStatStruc *pDCTstat, u8 dct); -static void mct_ResetDLL_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static u32 mct_DisDllShutdownSR(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u32 DramConfigLo, u8 dct); -static void mct_EnDllShutdownSR(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -void ChangeMemClk(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); - -static u8 Get_Latency_Diff(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static void SyncSetting(struct DCTStatStruc *pDCTstat); -static uint8_t crcCheck(struct DCTStatStruc *pDCTstat, uint8_t dimm); - -uint8_t is_ecc_enabled(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat); - -/*See mctAutoInitMCT header for index relationships to CL and T*/ -static const u16 Table_F_k[] = {00,200,266,333,400,533 }; -static const u8 Tab_BankAddr[] = {0x3F,0x01,0x09,0x3F,0x3F,0x11,0x0A,0x19,0x12,0x1A,0x21,0x22,0x23}; -const u8 Table_DQSRcvEn_Offset[] = {0x00,0x01,0x10,0x11,0x2}; - -/**************************************************************************** - Describe how platform maps MemClk pins to logical DIMMs. The MemClk pins - are identified based on BKDG definition of Fn2x88[MemClkDis] bitmap. - AGESA will base on this value to disable unused MemClk to save power. - - If MEMCLK_MAPPING or MEMCLK_MAPPING contains all zeroes, AGESA will use - default MemClkDis setting based on package type. - - Example: - BKDG definition of Fn2x88[MemClkDis] bitmap for AM3 package is like below: - Bit AM3/S1g3 pin name - 0 M[B,A]_CLK_H/L[0] - 1 M[B,A]_CLK_H/L[1] - 2 M[B,A]_CLK_H/L[2] - 3 M[B,A]_CLK_H/L[3] - 4 M[B,A]_CLK_H/L[4] - 5 M[B,A]_CLK_H/L[5] - 6 M[B,A]_CLK_H/L[6] - 7 M[B,A]_CLK_H/L[7] - - And platform has the following routing: - CS0 M[B,A]_CLK_H/L[4] - CS1 M[B,A]_CLK_H/L[2] - CS2 M[B,A]_CLK_H/L[3] - CS3 M[B,A]_CLK_H/L[5] - - Then: - ; CS0 CS1 CS2 CS3 CS4 CS5 CS6 CS7 - MEMCLK_MAPPING EQU 00010000b, 00000100b, 00001000b, 00100000b, 00000000b, 00000000b, 00000000b, 00000000b -*/ - -/* ========================================================================================== - * Set up clock pin to DIMM mappings, - * NOTE: If you are not sure about the pin mappings, you can keep all MemClk signals active, - * just set all entries in the relevant table(s) to 0xff. - * ========================================================================================== - */ -static const u8 Tab_L1CLKDis[] = {0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04}; -static const u8 Tab_AM3CLKDis[] = {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00}; -static const u8 Tab_S1CLKDis[] = {0xA2, 0xA2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - -/* C32: Enable CS0 - CS3 clocks (DIMM0 - DIMM1) */ -static const u8 Tab_C32CLKDis[] = {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00}; - -/* G34: Enable CS0 - CS3 clocks (DIMM0 - DIMM1) */ -static const u8 Tab_G34CLKDis[] = {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00}; - -/* FM2: Enable all the clocks for the dimms */ -static const u8 Tab_FM2CLKDis[] = {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00}; - -static const u8 Tab_ManualCLKDis[]= {0x10, 0x04, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00}; -/* ========================================================================================== */ - -static const u8 Table_Comp_Rise_Slew_20x[] = {7, 3, 2, 2, 0xFF}; -static const u8 Table_Comp_Rise_Slew_15x[] = {7, 7, 3, 2, 0xFF}; -static const u8 Table_Comp_Fall_Slew_20x[] = {7, 5, 3, 2, 0xFF}; -static const u8 Table_Comp_Fall_Slew_15x[] = {7, 7, 5, 3, 0xFF}; - -uint8_t dct_ddr_voltage_index(struct DCTStatStruc *pDCTstat, uint8_t dct) -{ - uint8_t dimm; - uint8_t ddr_voltage_index = 0; - - /* If no DIMMs are present on this DCT, report 1.5V operation and skip checking the hardware */ - if (pDCTstat->DIMMValidDCT[dct] == 0) - return 0x1; - - /* Find current DDR supply voltage for this DCT */ - for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) { - if (pDCTstat->DIMMValidDCT[dct] & (1 << dimm)) - ddr_voltage_index |= pDCTstat->DimmConfiguredVoltage[dimm]; - } - if (ddr_voltage_index > 0x7) { - printk(BIOS_DEBUG, "%s: Insufficient DDR supply voltage indicated! Configuring processor for 1.25V operation, but this attempt may fail...\n", __func__); - ddr_voltage_index = 0x4; - } - if (ddr_voltage_index == 0x0) { - printk(BIOS_DEBUG, "%s: No DDR supply voltage indicated! Configuring processor for 1.5V operation, but this attempt may fail...\n", __func__); - ddr_voltage_index = 0x1; - } - - return ddr_voltage_index; -} - -static uint16_t fam15h_mhz_to_memclk_config(uint16_t freq) -{ - uint16_t fam15h_freq_tab[] = {0, 0, 0, 0, 333, 0, 400, 0, 0, 0, 533, 0, 0, 0, 667, 0, 0, 0, 800, 0, 0, 0, 933}; - uint16_t iter; - - /* Compute the index value for the given frequency */ - for (iter = 0; iter <= 0x16; iter++) { - if (fam15h_freq_tab[iter] == freq) { - freq = iter; - break; - } - } - if (freq == 0) - freq = 0x4; - - return freq; -} - -static uint16_t fam10h_mhz_to_memclk_config(uint16_t freq) -{ - uint16_t fam10h_freq_tab[] = {0, 0, 0, 400, 533, 667, 800}; - uint16_t iter; - - /* Compute the index value for the given frequency */ - for (iter = 0; iter <= 0x6; iter++) { - if (fam10h_freq_tab[iter] == freq) { - freq = iter; - break; - } - } - if (freq == 0) - freq = 0x3; - - return freq; -} - -static inline uint8_t is_model10_1f(void) -{ - uint8_t model101f = 0; - uint32_t family; - - family = cpuid_eax(0x80000001); - family = ((family & 0x0ff000) >> 12); - - if (family >= 0x10 && family <= 0x1f) - /* Model 0x10 to 0x1f */ - model101f = 1; - - return model101f; -} - -uint8_t is_ecc_enabled(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat) -{ - uint8_t ecc_enabled = 1; - - if (!pMCTstat->try_ecc) - ecc_enabled = 0; - - if (pDCTstat->NodePresent && (pDCTstat->DIMMValidDCT[0] || pDCTstat->DIMMValidDCT[1])) - if (!(pDCTstat->Status & (1 << SB_ECCDIMMs))) - ecc_enabled = 0; - - return !!ecc_enabled; -} - -uint8_t get_available_lane_count(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat) -{ - if (is_ecc_enabled(pMCTstat, pDCTstat)) - return 9; - else - return 8; -} - -uint16_t mhz_to_memclk_config(uint16_t freq) -{ - if (is_fam15h()) - return fam15h_mhz_to_memclk_config(freq); - else - return fam10h_mhz_to_memclk_config(freq) + 1; -} - -uint32_t fam10h_address_timing_compensation_code(struct DCTStatStruc *pDCTstat, uint8_t dct) -{ - uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH); - - uint8_t package_type; - uint32_t calibration_code = 0; - - package_type = mctGet_NVbits(NV_PACK_TYPE); - uint16_t MemClkFreq = (Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x94) & 0x7) + 1; - - /* Obtain number of DIMMs on channel */ - uint8_t dimm_count = pDCTstat->MAdimms[dct]; - uint8_t rank_count_dimm0; - uint8_t rank_count_dimm1; - - if (package_type == PT_GR) { - /* Socket G34 */ - if (pDCTstat->Status & (1 << SB_Registered)) { - /* RDIMM */ - /* Fam10h BKDG Rev. 3.62 section 2.8.9.5.8 Tables 60 - 61 */ - if (MaxDimmsInstallable == 1) { - if (MemClkFreq == 0x4) { - /* DDR3-800 */ - calibration_code = 0x00000000; - } else if (MemClkFreq == 0x5) { - /* DDR3-1066 */ - calibration_code = 0x003c3c3c; - } else if (MemClkFreq == 0x6) { - /* DDR3-1333 */ - calibration_code = 0x003a3a3a; - } - } else if (MaxDimmsInstallable == 2) { - if (dimm_count == 1) { - /* 1 DIMM detected */ - if (MemClkFreq == 0x4) { - /* DDR3-800 */ - calibration_code = 0x00000000; - } else if (MemClkFreq == 0x5) { - /* DDR3-1066 */ - calibration_code = 0x003c3c3c; - } else if (MemClkFreq == 0x6) { - /* DDR3-1333 */ - calibration_code = 0x003a3a3a; - } - } else if (dimm_count == 2) { - /* 2 DIMMs detected */ - if (MemClkFreq == 0x4) { - /* DDR3-800 */ - calibration_code = 0x00000000; - } else if (MemClkFreq == 0x5) { - /* DDR3-1066 */ - calibration_code = 0x003a3c3a; - } else if (MemClkFreq == 0x6) { - /* DDR3-1333 */ - calibration_code = 0x00383a38; - } - } - } else if (MaxDimmsInstallable == 3) { - /* TODO - * 3 DIMM/channel support unimplemented - */ - } - } else { - /* UDIMM */ - /* Fam10h BKDG Rev. 3.62 section 2.8.9.5.8 Table 56 */ - if (dimm_count == 1) { - /* 1 DIMM detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (MemClkFreq == 0x4) { - /* DDR3-800 */ - if (rank_count_dimm0 == 1) - calibration_code = 0x00000000; - else - calibration_code = 0x003b0000; - } else if (MemClkFreq == 0x5) { - /* DDR3-1066 */ - if (rank_count_dimm0 == 1) - calibration_code = 0x00000000; - else - calibration_code = 0x00380000; - } else if (MemClkFreq == 0x6) { - /* DDR3-1333 */ - if (rank_count_dimm0 == 1) - calibration_code = 0x00000000; - else - calibration_code = 0x00360000; - } - } else if (dimm_count == 2) { - /* 2 DIMMs detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (MemClkFreq == 0x4) { - /* DDR3-800 */ - calibration_code = 0x00390039; - } else if (MemClkFreq == 0x5) { - /* DDR3-1066 */ - calibration_code = 0x00350037; - } else if (MemClkFreq == 0x6) { - /* DDR3-1333 */ - calibration_code = 0x00000035; - } - } - } - } else { - /* TODO - * Other socket support unimplemented - */ - } - - return calibration_code; -} - -static uint32_t fam15h_phy_predriver_calibration_code(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t drive_strength) -{ - uint8_t lrdimm = 0; - uint8_t package_type; - uint8_t ddr_voltage_index; - uint32_t calibration_code = 0; - uint16_t MemClkFreq = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x94) & 0x1f; - - ddr_voltage_index = dct_ddr_voltage_index(pDCTstat, dct); - package_type = mctGet_NVbits(NV_PACK_TYPE); - - if (!lrdimm) { - /* Not an LRDIMM */ - if ((package_type == PT_M2) || (package_type == PT_GR)) { - /* Socket AM3 or G34 */ - if (ddr_voltage_index & 0x4) { - /* 1.25V */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 43 */ - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { - /* DDR3-667 - DDR3-800 */ - if (drive_strength == 0x0) - calibration_code = 0xfff; - else if (drive_strength == 0x1) - calibration_code = 0xb6d; - else if (drive_strength == 0x2) - calibration_code = 0x924; - else if (drive_strength == 0x3) - calibration_code = 0x6db; - } else if ((MemClkFreq == 0xa) || (MemClkFreq == 0xe)) { - /* DDR3-1066 - DDR3-1333 */ - if (drive_strength == 0x0) - calibration_code = 0xfff; - else if (drive_strength == 0x1) - calibration_code = 0xfff; - else if (drive_strength == 0x2) - calibration_code = 0xdb6; - else if (drive_strength == 0x3) - calibration_code = 0x924; - } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) { - /* DDR3-1600 - DDR3-1866 */ - if (drive_strength == 0x0) - calibration_code = 0xfff; - else if (drive_strength == 0x1) - calibration_code = 0xfff; - else if (drive_strength == 0x2) - calibration_code = 0xfff; - else if (drive_strength == 0x3) - calibration_code = 0xfff; - } - } else if (ddr_voltage_index & 0x2) { - /* 1.35V */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 42 */ - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { - /* DDR3-667 - DDR3-800 */ - if (drive_strength == 0x0) - calibration_code = 0xfff; - else if (drive_strength == 0x1) - calibration_code = 0x924; - else if (drive_strength == 0x2) - calibration_code = 0x6db; - else if (drive_strength == 0x3) - calibration_code = 0x492; - } else if ((MemClkFreq == 0xa) || (MemClkFreq == 0xe)) { - /* DDR3-1066 - DDR3-1333 */ - if (drive_strength == 0x0) - calibration_code = 0xfff; - else if (drive_strength == 0x1) - calibration_code = 0xdb6; - else if (drive_strength == 0x2) - calibration_code = 0xbd6; - else if (drive_strength == 0x3) - calibration_code = 0x6db; - } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) { - /* DDR3-1600 - DDR3-1866 */ - if (drive_strength == 0x0) - calibration_code = 0xfff; - else if (drive_strength == 0x1) - calibration_code = 0xfff; - else if (drive_strength == 0x2) - calibration_code = 0xfff; - else if (drive_strength == 0x3) - calibration_code = 0xdb6; - } - } else if (ddr_voltage_index & 0x1) { - /* 1.5V */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 41 */ - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { - /* DDR3-667 - DDR3-800 */ - if (drive_strength == 0x0) - calibration_code = 0xb6d; - else if (drive_strength == 0x1) - calibration_code = 0x6db; - else if (drive_strength == 0x2) - calibration_code = 0x492; - else if (drive_strength == 0x3) - calibration_code = 0x492; - } else if ((MemClkFreq == 0xa) || (MemClkFreq == 0xe)) { - /* DDR3-1066 - DDR3-1333 */ - if (drive_strength == 0x0) - calibration_code = 0xfff; - else if (drive_strength == 0x1) - calibration_code = 0x924; - else if (drive_strength == 0x2) - calibration_code = 0x6db; - else if (drive_strength == 0x3) - calibration_code = 0x6db; - } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) { - /* DDR3-1600 - DDR3-1866 */ - if (drive_strength == 0x0) - calibration_code = 0xfff; - else if (drive_strength == 0x1) - calibration_code = 0xfff; - else if (drive_strength == 0x2) - calibration_code = 0xfff; - else if (drive_strength == 0x3) - calibration_code = 0xb6d; - } - } - } else if (package_type == PT_C3) { - /* Socket C32 */ - if (ddr_voltage_index & 0x4) { - /* 1.25V */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 46 */ - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { - /* DDR3-667 - DDR3-800 */ - if (drive_strength == 0x0) - calibration_code = 0xfff; - else if (drive_strength == 0x1) - calibration_code = 0xb6d; - else if (drive_strength == 0x2) - calibration_code = 0x924; - else if (drive_strength == 0x3) - calibration_code = 0x6db; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - if (drive_strength == 0x0) - calibration_code = 0xfff; - else if (drive_strength == 0x1) - calibration_code = 0xfff; - else if (drive_strength == 0x2) - calibration_code = 0xdb6; - else if (drive_strength == 0x3) - calibration_code = 0x924; - } else if (MemClkFreq == 0xe) { - /* DDR3-1333 */ - if (drive_strength == 0x0) - calibration_code = 0xb6d; - else if (drive_strength == 0x1) - calibration_code = 0x6db; - else if (drive_strength == 0x2) - calibration_code = 0x492; - else if (drive_strength == 0x3) - calibration_code = 0x492; - } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) { - /* DDR3-1600 - DDR3-1866 */ - if (drive_strength == 0x0) - calibration_code = 0xfff; - else if (drive_strength == 0x1) - calibration_code = 0xfff; - else if (drive_strength == 0x2) - calibration_code = 0xfff; - else if (drive_strength == 0x3) - calibration_code = 0xfff; - } - } else if (ddr_voltage_index & 0x2) { - /* 1.35V */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 45 */ - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { - /* DDR3-667 - DDR3-800 */ - if (drive_strength == 0x0) - calibration_code = 0xfff; - else if (drive_strength == 0x1) - calibration_code = 0x924; - else if (drive_strength == 0x2) - calibration_code = 0x6db; - else if (drive_strength == 0x3) - calibration_code = 0x492; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - if (drive_strength == 0x0) - calibration_code = 0xfff; - else if (drive_strength == 0x1) - calibration_code = 0xdb6; - else if (drive_strength == 0x2) - calibration_code = 0xb6d; - else if (drive_strength == 0x3) - calibration_code = 0x6db; - } else if (MemClkFreq == 0xe) { - /* DDR3-1333 */ - if (drive_strength == 0x0) - calibration_code = 0xfff; - else if (drive_strength == 0x1) - calibration_code = 0x924; - else if (drive_strength == 0x2) - calibration_code = 0x6db; - else if (drive_strength == 0x3) - calibration_code = 0x492; - } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) { - /* DDR3-1600 - DDR3-1866 */ - if (drive_strength == 0x0) - calibration_code = 0xfff; - else if (drive_strength == 0x1) - calibration_code = 0xfff; - else if (drive_strength == 0x2) - calibration_code = 0xfff; - else if (drive_strength == 0x3) - calibration_code = 0xdb6; - } - } else if (ddr_voltage_index & 0x1) { - /* 1.5V */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 44 */ - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { - /* DDR3-667 - DDR3-800 */ - if (drive_strength == 0x0) - calibration_code = 0xb6d; - else if (drive_strength == 0x1) - calibration_code = 0x6db; - else if (drive_strength == 0x2) - calibration_code = 0x492; - else if (drive_strength == 0x3) - calibration_code = 0x492; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - if (drive_strength == 0x0) - calibration_code = 0xfff; - else if (drive_strength == 0x1) - calibration_code = 0x924; - else if (drive_strength == 0x2) - calibration_code = 0x6db; - else if (drive_strength == 0x3) - calibration_code = 0x6db; - } else if (MemClkFreq == 0xe) { - /* DDR3-1333 */ - if (drive_strength == 0x0) - calibration_code = 0xb6d; - else if (drive_strength == 0x1) - calibration_code = 0x6db; - else if (drive_strength == 0x2) - calibration_code = 0x492; - else if (drive_strength == 0x3) - calibration_code = 0x492; - } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) { - /* DDR3-1600 - DDR3-1866 */ - if (drive_strength == 0x0) - calibration_code = 0xfff; - else if (drive_strength == 0x1) - calibration_code = 0xfff; - else if (drive_strength == 0x2) - calibration_code = 0xfff; - else if (drive_strength == 0x3) - calibration_code = 0xb6d; - } - } - } else if (package_type == PT_FM2) { - /* Socket FM2 */ - if (ddr_voltage_index & 0x1) { - /* 1.5V */ - /* Fam15h BKDG Rev. 3.12 section 2.9.5.4.4 Table 22 */ - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { - /* DDR3-667 - DDR3-800 */ - calibration_code = 0xb24; - } else if (MemClkFreq >= 0xa) { - /* DDR3-1066 or higher */ - calibration_code = 0xff6; - } - } - } - } else { - /* LRDIMM */ - - /* TODO - * Implement LRDIMM support - * See Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Tables 47 - 49 - */ - } - - return calibration_code; -} - -static uint32_t fam15h_phy_predriver_cmd_addr_calibration_code(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t drive_strength) -{ - uint8_t ddr_voltage_index; - uint32_t calibration_code = 0; - uint16_t MemClkFreq = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x94) & 0x1f; - - ddr_voltage_index = dct_ddr_voltage_index(pDCTstat, dct); - - if (ddr_voltage_index & 0x4) { - /* 1.25V */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 52 */ - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { - /* DDR3-667 - DDR3-800 */ - if (drive_strength == 0x0) - calibration_code = 0x492; - else if (drive_strength == 0x1) - calibration_code = 0x492; - else if (drive_strength == 0x2) - calibration_code = 0x492; - else if (drive_strength == 0x3) - calibration_code = 0x492; - } else if ((MemClkFreq == 0xa) || (MemClkFreq == 0xe)) { - /* DDR3-1066 - DDR3-1333 */ - if (drive_strength == 0x0) - calibration_code = 0xdad; - else if (drive_strength == 0x1) - calibration_code = 0x924; - else if (drive_strength == 0x2) - calibration_code = 0x6db; - else if (drive_strength == 0x3) - calibration_code = 0x492; - } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) { - /* DDR3-1600 - DDR3-1866 */ - if (drive_strength == 0x0) - calibration_code = 0xff6; - else if (drive_strength == 0x1) - calibration_code = 0xdad; - else if (drive_strength == 0x2) - calibration_code = 0xb64; - else if (drive_strength == 0x3) - calibration_code = 0xb64; - } - } else if (ddr_voltage_index & 0x2) { - /* 1.35V */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 51 */ - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { - /* DDR3-667 - DDR3-800 */ - if (drive_strength == 0x0) - calibration_code = 0x492; - else if (drive_strength == 0x1) - calibration_code = 0x492; - else if (drive_strength == 0x2) - calibration_code = 0x492; - else if (drive_strength == 0x3) - calibration_code = 0x492; - } else if ((MemClkFreq == 0xa) || (MemClkFreq == 0xe)) { - /* DDR3-1066 - DDR3-1333 */ - if (drive_strength == 0x0) - calibration_code = 0x924; - else if (drive_strength == 0x1) - calibration_code = 0x6db; - else if (drive_strength == 0x2) - calibration_code = 0x6db; - else if (drive_strength == 0x3) - calibration_code = 0x6db; - } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) { - /* DDR3-1600 - DDR3-1866 */ - if (drive_strength == 0x0) - calibration_code = 0xb6d; - else if (drive_strength == 0x1) - calibration_code = 0xb6d; - else if (drive_strength == 0x2) - calibration_code = 0x924; - else if (drive_strength == 0x3) - calibration_code = 0x924; - } - } else if (ddr_voltage_index & 0x1) { - /* 1.5V */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 50 */ - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { - /* DDR3-667 - DDR3-800 */ - if (drive_strength == 0x0) - calibration_code = 0x492; - else if (drive_strength == 0x1) - calibration_code = 0x492; - else if (drive_strength == 0x2) - calibration_code = 0x492; - else if (drive_strength == 0x3) - calibration_code = 0x492; - } else if ((MemClkFreq == 0xa) || (MemClkFreq == 0xe)) { - /* DDR3-1066 - DDR3-1333 */ - if (drive_strength == 0x0) - calibration_code = 0x6db; - else if (drive_strength == 0x1) - calibration_code = 0x6db; - else if (drive_strength == 0x2) - calibration_code = 0x6db; - else if (drive_strength == 0x3) - calibration_code = 0x6db; - } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) { - /* DDR3-1600 - DDR3-1866 */ - if (drive_strength == 0x0) - calibration_code = 0xb6d; - else if (drive_strength == 0x1) - calibration_code = 0xb6d; - else if (drive_strength == 0x2) - calibration_code = 0xb6d; - else if (drive_strength == 0x3) - calibration_code = 0xb6d; - } - } - - return calibration_code; -} - -static uint32_t fam15h_phy_predriver_clk_calibration_code(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t drive_strength) -{ - uint8_t ddr_voltage_index; - uint32_t calibration_code = 0; - uint16_t MemClkFreq = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x94) & 0x1f; - - ddr_voltage_index = dct_ddr_voltage_index(pDCTstat, dct); - - if (ddr_voltage_index & 0x4) { - /* 1.25V */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 55 */ - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { - /* DDR3-667 - DDR3-800 */ - if (drive_strength == 0x0) - calibration_code = 0xdad; - else if (drive_strength == 0x1) - calibration_code = 0xdad; - else if (drive_strength == 0x2) - calibration_code = 0x924; - else if (drive_strength == 0x3) - calibration_code = 0x924; - } else if ((MemClkFreq == 0xa) || (MemClkFreq == 0xe)) { - /* DDR3-1066 - DDR3-1333 */ - if (drive_strength == 0x0) - calibration_code = 0xff6; - else if (drive_strength == 0x1) - calibration_code = 0xff6; - else if (drive_strength == 0x2) - calibration_code = 0xff6; - else if (drive_strength == 0x3) - calibration_code = 0xff6; - } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) { - /* DDR3-1600 - DDR3-1866 */ - if (drive_strength == 0x0) - calibration_code = 0xff6; - else if (drive_strength == 0x1) - calibration_code = 0xff6; - else if (drive_strength == 0x2) - calibration_code = 0xff6; - else if (drive_strength == 0x3) - calibration_code = 0xff6; - } - } else if (ddr_voltage_index & 0x2) { - /* 1.35V */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 54 */ - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { - /* DDR3-667 - DDR3-800 */ - if (drive_strength == 0x0) - calibration_code = 0xdad; - else if (drive_strength == 0x1) - calibration_code = 0xdad; - else if (drive_strength == 0x2) - calibration_code = 0x924; - else if (drive_strength == 0x3) - calibration_code = 0x924; - } else if ((MemClkFreq == 0xa) || (MemClkFreq == 0xe)) { - /* DDR3-1066 - DDR3-1333 */ - if (drive_strength == 0x0) - calibration_code = 0xff6; - else if (drive_strength == 0x1) - calibration_code = 0xff6; - else if (drive_strength == 0x2) - calibration_code = 0xff6; - else if (drive_strength == 0x3) - calibration_code = 0xdad; - } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) { - /* DDR3-1600 - DDR3-1866 */ - if (drive_strength == 0x0) - calibration_code = 0xff6; - else if (drive_strength == 0x1) - calibration_code = 0xff6; - else if (drive_strength == 0x2) - calibration_code = 0xff6; - else if (drive_strength == 0x3) - calibration_code = 0xdad; - } - } else if (ddr_voltage_index & 0x1) { - /* 1.5V */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 53 */ - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { - /* DDR3-667 - DDR3-800 */ - if (drive_strength == 0x0) - calibration_code = 0x924; - else if (drive_strength == 0x1) - calibration_code = 0x924; - else if (drive_strength == 0x2) - calibration_code = 0x924; - else if (drive_strength == 0x3) - calibration_code = 0x924; - } else if ((MemClkFreq == 0xa) || (MemClkFreq == 0xe)) { - /* DDR3-1066 - DDR3-1333 */ - if (drive_strength == 0x0) - calibration_code = 0xff6; - else if (drive_strength == 0x1) - calibration_code = 0xff6; - else if (drive_strength == 0x2) - calibration_code = 0xff6; - else if (drive_strength == 0x3) - calibration_code = 0xb6d; - } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) { - /* DDR3-1600 - DDR3-1866 */ - if (drive_strength == 0x0) - calibration_code = 0xff6; - else if (drive_strength == 0x1) - calibration_code = 0xff6; - else if (drive_strength == 0x2) - calibration_code = 0xff6; - else if (drive_strength == 0x3) - calibration_code = 0xff6; - } - } - - return calibration_code; -} - -uint32_t fam15h_output_driver_compensation_code(struct DCTStatStruc *pDCTstat, uint8_t dct) -{ - uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH); - - uint8_t package_type; - uint32_t calibration_code = 0; - - package_type = mctGet_NVbits(NV_PACK_TYPE); - uint16_t MemClkFreq = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x94) & 0x1f; - - /* Obtain number of DIMMs on channel */ - uint8_t dimm_count = pDCTstat->MAdimms[dct]; - uint8_t rank_count_dimm0; - uint8_t rank_count_dimm1; - - if (package_type == PT_GR) { - /* Socket G34 */ - if (pDCTstat->Status & (1 << SB_Registered)) { - /* RDIMM */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 74 */ - if (MaxDimmsInstallable == 1) { - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (MemClkFreq == 0x4) { - /* DDR3-667 */ - calibration_code = 0x00112222; - } else if (MemClkFreq == 0x6) { - /* DDR3-800 */ - calibration_code = 0x10112222; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x20112222; - } else if ((MemClkFreq == 0xe) || (MemClkFreq == 0x12)) { - /* DDR3-1333 - DDR3-1600 */ - calibration_code = 0x30112222; - } else if (MemClkFreq == 0x16) { - /* DDR3-1866 */ - calibration_code = 0x30332222; - } - - if (rank_count_dimm0 == 4) { - calibration_code &= ~(0xff << 16); - calibration_code |= 0x22 << 16; - } - } else if (MaxDimmsInstallable == 2) { - rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (dimm_count == 1) { - /* 1 DIMM detected */ - if (MemClkFreq == 0x4) { - /* DDR3-667 */ - calibration_code = 0x00112222; - } else if (MemClkFreq == 0x6) { - /* DDR3-800 */ - calibration_code = 0x10112222; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x20112222; - } else if ((MemClkFreq == 0xe) || (MemClkFreq == 0x12)) { - /* DDR3-1333 - DDR3-1600 */ - calibration_code = 0x30112222; - } - - if ((rank_count_dimm0 == 4) || (rank_count_dimm1 == 4)) { - calibration_code &= ~(0xff << 16); - calibration_code |= 0x22 << 16; - } - } else if (dimm_count == 2) { - /* 2 DIMMs detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (MemClkFreq == 0x4) { - /* DDR3-667 */ - calibration_code = 0x10222222; - } else if (MemClkFreq == 0x6) { - /* DDR3-800 */ - calibration_code = 0x20222222; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x30222222; - } else if (MemClkFreq == 0xe) { - /* DDR3-1333 */ - calibration_code = 0x30222222; - } else if (MemClkFreq == 0x12) { - /* DDR3-1600 */ - calibration_code = 0x30222222; - } - } - } else if (MaxDimmsInstallable == 3) { - /* TODO - * 3 DIMM/channel support unimplemented - */ - } - } else if (pDCTstat->Status & (1 << SB_LoadReduced)) { - /* LRDIMM */ - /* TODO - * LRDIMM support unimplemented - */ - } else { - /* UDIMM */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 73 */ - if (MaxDimmsInstallable == 1) { - if (MemClkFreq == 0x4) { - /* DDR3-667 */ - calibration_code = 0x00112222; - } else if (MemClkFreq == 0x6) { - /* DDR3-800 */ - calibration_code = 0x10112222; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x20112222; - } else if ((MemClkFreq == 0xe) || (MemClkFreq == 0x12)) { - /* DDR3-1333 - DDR3-1600 */ - calibration_code = 0x30112222; - } else if (MemClkFreq == 0x16) { - /* DDR3-1866 */ - calibration_code = 0x30332222; - } - } else if (MaxDimmsInstallable == 2) { - if (dimm_count == 1) { - /* 1 DIMM detected */ - if (MemClkFreq == 0x4) { - /* DDR3-667 */ - calibration_code = 0x00112222; - } else if (MemClkFreq == 0x6) { - /* DDR3-800 */ - calibration_code = 0x10112222; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x20112222; - } else if ((MemClkFreq == 0xe) || (MemClkFreq == 0x12)) { - /* DDR3-1333 - DDR3-1600 */ - calibration_code = 0x30112222; - } - } else if (dimm_count == 2) { - /* 2 DIMMs detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (MemClkFreq == 0x4) { - /* DDR3-667 */ - calibration_code = 0x10222222; - } else if (MemClkFreq == 0x6) { - /* DDR3-800 */ - calibration_code = 0x20222222; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x30222222; - } else if (MemClkFreq == 0xe) { - /* DDR3-1333 */ - calibration_code = 0x30222222; - } else if (MemClkFreq == 0x12) { - /* DDR3-1600 */ - if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1)) - calibration_code = 0x30222222; - else - calibration_code = 0x30112222; - } - } - } else if (MaxDimmsInstallable == 3) { - /* TODO - * 3 DIMM/channel support unimplemented - */ - } - } - } else if (package_type == PT_C3) { - /* Socket C32 */ - if (pDCTstat->Status & (1 << SB_Registered)) { - /* RDIMM */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 77 */ - if (MaxDimmsInstallable == 1) { - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (MemClkFreq == 0x4) { - /* DDR3-667 */ - calibration_code = 0x00112222; - } else if (MemClkFreq == 0x6) { - /* DDR3-800 */ - calibration_code = 0x10112222; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x20112222; - } else if ((MemClkFreq == 0xe) || (MemClkFreq == 0x12)) { - /* DDR3-1333 - DDR3-1600 */ - calibration_code = 0x30112222; - } - - if (rank_count_dimm0 == 4) { - calibration_code &= ~(0xff << 16); - calibration_code |= 0x22 << 16; - } - } else if (MaxDimmsInstallable == 2) { - rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (dimm_count == 1) { - /* 1 DIMM detected */ - if (MemClkFreq == 0x4) { - /* DDR3-667 */ - calibration_code = 0x00112222; - } else if (MemClkFreq == 0x6) { - /* DDR3-800 */ - calibration_code = 0x10112222; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x20112222; - } else if ((MemClkFreq == 0xe) || (MemClkFreq == 0x12)) { - /* DDR3-1333 - DDR3-1600 */ - calibration_code = 0x30112222; - } - - if ((rank_count_dimm0 == 4) || (rank_count_dimm1 == 4)) { - calibration_code &= ~(0xff << 16); - calibration_code |= 0x22 << 16; - } - } else if (dimm_count == 2) { - /* 2 DIMMs detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (MemClkFreq == 0x4) { - /* DDR3-667 */ - calibration_code = 0x10222222; - } else if (MemClkFreq == 0x6) { - /* DDR3-800 */ - calibration_code = 0x20222222; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x30222222; - } else if (MemClkFreq == 0xe) { - /* DDR3-1333 */ - calibration_code = 0x30222222; - } else if (MemClkFreq == 0x12) { - /* DDR3-1600 */ - calibration_code = 0x30222222; - } - } - } else if (MaxDimmsInstallable == 3) { - /* TODO - * 3 DIMM/channel support unimplemented - */ - } - } else if (pDCTstat->Status & (1 << SB_LoadReduced)) { - /* LRDIMM */ - /* TODO - * LRDIMM support unimplemented - */ - } else { - /* UDIMM */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 73 */ - if (MaxDimmsInstallable == 1) { - if (MemClkFreq == 0x4) { - /* DDR3-667 */ - calibration_code = 0x00112222; - } else if (MemClkFreq == 0x6) { - /* DDR3-800 */ - calibration_code = 0x10112222; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x20112222; - } else if ((MemClkFreq == 0xe) || (MemClkFreq == 0x12)) { - /* DDR3-1333 - DDR3-1600 */ - calibration_code = 0x30112222; - } - } else if (MaxDimmsInstallable == 2) { - if (dimm_count == 1) { - /* 1 DIMM detected */ - if (MemClkFreq == 0x4) { - /* DDR3-667 */ - calibration_code = 0x00112222; - } else if (MemClkFreq == 0x6) { - /* DDR3-800 */ - calibration_code = 0x10112222; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x20112222; - } else if ((MemClkFreq == 0xe) || (MemClkFreq == 0x12)) { - /* DDR3-1333 - DDR3-1600 */ - calibration_code = 0x30112222; - } - } else if (dimm_count == 2) { - /* 2 DIMMs detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (MemClkFreq == 0x4) { - /* DDR3-667 */ - calibration_code = 0x10222222; - } else if (MemClkFreq == 0x6) { - /* DDR3-800 */ - calibration_code = 0x20222222; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x30222222; - } else if (MemClkFreq == 0xe) { - /* DDR3-1333 */ - calibration_code = 0x30222222; - } else if (MemClkFreq == 0x12) { - /* DDR3-1600 */ - if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1)) - calibration_code = 0x30222222; - else - calibration_code = 0x30112222; - } - } - } else if (MaxDimmsInstallable == 3) { - /* TODO - * 3 DIMM/channel support unimplemented - */ - } - } - } else if (package_type == PT_FM2) { - /* Socket FM2 */ - /* Assume UDIMM */ - /* Fam15h Model10h BKDG Rev. 3.12 section 2.9.5.6.6 Table 32 */ - if (MaxDimmsInstallable == 1) { - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (MemClkFreq == 0x4) { - /* DDR3-667 */ - calibration_code = 0x00112222; - } else if (MemClkFreq == 0x6) { - /* DDR3-800 */ - calibration_code = 0x10112222; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x20112222; - } else if (MemClkFreq >= 0xe) { - /* DDR3-1333 or higher */ - calibration_code = 0x30112222; - } - } else if (MaxDimmsInstallable == 2) { - rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (dimm_count == 1) { - /* 1 DIMM detected */ - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { - /* DDR3-667 or DDR3-800 */ - calibration_code = 0x00112222; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x10112222; - } else if (MemClkFreq == 0xe) { - /* DDR3-1333 */ - calibration_code = 0x20112222; - } else if (MemClkFreq >= 0x12) { - /* DDR3-1600 or higher */ - calibration_code = 0x30112222; - } - } else if (dimm_count == 2) { - /* 2 DIMMs detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (MemClkFreq == 0x4) { - /* DDR3-667 */ - calibration_code = 0x10222322; - } else if (MemClkFreq == 0x6) { - /* DDR3-800 */ - calibration_code = 0x20222322; - } else if (MemClkFreq >= 0xa) { - /* DDR3-1066 or higher */ - calibration_code = 0x30222322; - } - } - } else if (MaxDimmsInstallable == 3) { - /* TODO - * 3 DIMM/channel support unimplemented - */ - } - } else { - /* TODO - * Other socket support unimplemented - */ - } - - return calibration_code; -} - -uint32_t fam15h_address_timing_compensation_code(struct DCTStatStruc *pDCTstat, uint8_t dct) -{ - uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH); - - uint8_t package_type; - uint32_t calibration_code = 0; - - package_type = mctGet_NVbits(NV_PACK_TYPE); - uint16_t MemClkFreq = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x94) & 0x1f; - - /* Obtain number of DIMMs on channel */ - uint8_t dimm_count = pDCTstat->MAdimms[dct]; - uint8_t rank_count_dimm0; - uint8_t rank_count_dimm1; - - if (package_type == PT_GR) { - /* Socket G34 */ - if (pDCTstat->Status & (1 << SB_Registered)) { - /* RDIMM */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 74 */ - if (MaxDimmsInstallable == 1) { - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { - /* DDR3-667 - DDR3-800 */ - calibration_code = 0x00000000; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x003c3c3c; - } else if (MemClkFreq == 0xe) { - /* DDR3-1333 */ - calibration_code = 0x003a3a3a; - } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) { - /* DDR3-1600 - DDR3-1866 */ - calibration_code = 0x00393939; - } - } else if (MaxDimmsInstallable == 2) { - if (dimm_count == 1) { - /* 1 DIMM detected */ - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { - /* DDR3-667 - DDR3-800 */ - calibration_code = 0x00000000; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x00393c39; - } else if (MemClkFreq == 0xe) { - /* DDR3-1333 */ - calibration_code = 0x00373a37; - } else if (MemClkFreq == 0x12) { - /* DDR3-1600 */ - calibration_code = 0x00363936; - } - } else if (dimm_count == 2) { - /* 2 DIMMs detected */ - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { - /* DDR3-667 - DDR3-800 */ - calibration_code = 0x00000000; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x003a3c3a; - } else if (MemClkFreq == 0xe) { - /* DDR3-1333 */ - calibration_code = 0x00383a38; - } else if (MemClkFreq == 0x12) { - /* DDR3-1600 */ - calibration_code = 0x00353935; - } - } - } else if (MaxDimmsInstallable == 3) { - /* TODO - * 3 DIMM/channel support unimplemented - */ - } - } else if (pDCTstat->Status & (1 << SB_LoadReduced)) { - /* LRDIMM */ - /* TODO - * LRDIMM support unimplemented - */ - } else { - /* UDIMM */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 76 */ - if (MaxDimmsInstallable == 1) { - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (MemClkFreq == 0x4) { - /* DDR3-667 */ - if (rank_count_dimm0 == 1) - calibration_code = 0x00000000; - else - calibration_code = 0x003b0000; - } else if (MemClkFreq == 0x6) { - /* DDR3-800 */ - if (rank_count_dimm0 == 1) - calibration_code = 0x00000000; - else - calibration_code = 0x003b0000; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x00383837; - } else if (MemClkFreq == 0xe) { - /* DDR3-1333 */ - calibration_code = 0x00363635; - } else if (MemClkFreq == 0x12) { - /* DDR3-1600 */ - if (rank_count_dimm0 == 1) - calibration_code = 0x00353533; - else - calibration_code = 0x00003533; - } else if (MemClkFreq == 0x16) { - /* DDR3-1866 */ - calibration_code = 0x00333330; - } - } else if (MaxDimmsInstallable == 2) { - if (dimm_count == 1) { - /* 1 DIMM detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (MemClkFreq == 0x4) { - /* DDR3-667 */ - if (rank_count_dimm0 == 1) - calibration_code = 0x00000000; - else - calibration_code = 0x003b0000; - } else if (MemClkFreq == 0x6) { - /* DDR3-800 */ - if (rank_count_dimm0 == 1) - calibration_code = 0x00000000; - else - calibration_code = 0x003b0000; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x00383837; - } else if (MemClkFreq == 0xe) { - /* DDR3-1333 */ - calibration_code = 0x00363635; - } else if (MemClkFreq == 0x12) { - /* DDR3-1600 */ - if (rank_count_dimm0 == 1) - calibration_code = 0x00353533; - else - calibration_code = 0x00003533; - } - } else if (dimm_count == 2) { - /* 2 DIMMs detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (MemClkFreq == 0x4) { - /* DDR3-667 */ - calibration_code = 0x00390039; - } else if (MemClkFreq == 0x6) { - /* DDR3-800 */ - calibration_code = 0x00390039; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x003a3a3a; - } else if (MemClkFreq == 0xe) { - /* DDR3-1333 */ - calibration_code = 0x00003939; - } else if (MemClkFreq == 0x12) { - /* DDR3-1600 */ - if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1)) - calibration_code = 0x00003738; - } - } - } else if (MaxDimmsInstallable == 3) { - /* TODO - * 3 DIMM/channel support unimplemented - */ - } - } - } else if (package_type == PT_C3) { - /* Socket C32 */ - if (pDCTstat->Status & (1 << SB_Registered)) { - /* RDIMM */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 77 */ - if (MaxDimmsInstallable == 1) { - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { - /* DDR3-667 - DDR3-800 */ - calibration_code = 0x00000000; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x003c3c3c; - } else if (MemClkFreq == 0xe) { - /* DDR3-1333 */ - calibration_code = 0x003a3a3a; - } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) { - /* DDR3-1600 - DDR3-1866 */ - calibration_code = 0x00393939; - } - } else if (MaxDimmsInstallable == 2) { - if (dimm_count == 1) { - /* 1 DIMM detected */ - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { - /* DDR3-667 - DDR3-800 */ - calibration_code = 0x00000000; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x00393c39; - } else if (MemClkFreq == 0xe) { - /* DDR3-1333 */ - calibration_code = 0x00373a37; - } else if (MemClkFreq == 0x12) { - /* DDR3-1600 */ - calibration_code = 0x00363936; - } - } else if (dimm_count == 2) { - /* 2 DIMMs detected */ - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { - /* DDR3-667 - DDR3-800 */ - calibration_code = 0x00000000; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x003a3c3a; - } else if (MemClkFreq == 0xe) { - /* DDR3-1333 */ - calibration_code = 0x00383a38; - } else if (MemClkFreq == 0x12) { - /* DDR3-1600 */ - calibration_code = 0x00353935; - } - } - } else if (MaxDimmsInstallable == 3) { - /* TODO - * 3 DIMM/channel support unimplemented - */ - } - } else if (pDCTstat->Status & (1 << SB_LoadReduced)) { - /* LRDIMM */ - /* TODO - * LRDIMM support unimplemented - */ - } else { - /* UDIMM */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 76 */ - if (MaxDimmsInstallable == 1) { - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (MemClkFreq == 0x4) { - /* DDR3-667 */ - if (rank_count_dimm0 == 1) - calibration_code = 0x00000000; - else - calibration_code = 0x003b0000; - } else if (MemClkFreq == 0x6) { - /* DDR3-800 */ - if (rank_count_dimm0 == 1) - calibration_code = 0x00000000; - else - calibration_code = 0x003b0000; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x00383837; - } else if (MemClkFreq == 0xe) { - /* DDR3-1333 */ - calibration_code = 0x00363635; - } else if (MemClkFreq == 0x12) { - /* DDR3-1600 */ - if (rank_count_dimm0 == 1) - calibration_code = 0x00353533; - else - calibration_code = 0x00003533; - } else if (MemClkFreq == 0x16) { - /* DDR3-1866 */ - calibration_code = 0x00333330; - } - } else if (MaxDimmsInstallable == 2) { - if (dimm_count == 1) { - /* 1 DIMM detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (MemClkFreq == 0x4) { - /* DDR3-667 */ - if (rank_count_dimm0 == 1) - calibration_code = 0x00000000; - else - calibration_code = 0x003b0000; - } else if (MemClkFreq == 0x6) { - /* DDR3-800 */ - if (rank_count_dimm0 == 1) - calibration_code = 0x00000000; - else - calibration_code = 0x003b0000; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x00383837; - } else if (MemClkFreq == 0xe) { - /* DDR3-1333 */ - calibration_code = 0x00363635; - } else if (MemClkFreq == 0x12) { - /* DDR3-1600 */ - if (rank_count_dimm0 == 1) - calibration_code = 0x00353533; - else - calibration_code = 0x00003533; - } - } else if (dimm_count == 2) { - /* 2 DIMMs detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (MemClkFreq == 0x4) { - /* DDR3-667 */ - calibration_code = 0x00390039; - } else if (MemClkFreq == 0x6) { - /* DDR3-800 */ - calibration_code = 0x00390039; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x003a3a3a; - } else if (MemClkFreq == 0xe) { - /* DDR3-1333 */ - calibration_code = 0x00003939; - } else if (MemClkFreq == 0x12) { - /* DDR3-1600 */ - if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1)) - calibration_code = 0x00003738; - } - } - } else if (MaxDimmsInstallable == 3) { - /* TODO - * 3 DIMM/channel support unimplemented - */ - } - } - } else if (package_type == PT_FM2) { - /* Socket FM2 */ - /* Assume UDIMM */ - /* Fam15h Model10h BKDG Rev. 3.12 section 2.9.5.6.6 Table 32 */ - if (dimm_count == 1) { - /* 1 DIMM detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { - /* DDR3-667 or DDR3-800 */ - if (rank_count_dimm0 == 1) - calibration_code = 0x00000000; - else - calibration_code = 0x003b0000; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - if (rank_count_dimm0 == 1) - calibration_code = 0x00000000; - else - calibration_code = 0x00380000; - } else if (MemClkFreq == 0xe) { - /* DDR3-1333 */ - if (rank_count_dimm0 == 1) - calibration_code = 0x00000000; - else - calibration_code = 0x00360000; - } else if (MemClkFreq >= 0x12) { - /* DDR3-1600 or higher */ - calibration_code = 0x00000000; - } - - } else if (dimm_count == 2) { - /* 2 DIMMs detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) { - /* DDR3-667 or DDR3-800 */ - calibration_code = 0x00390039; - } else if (MemClkFreq == 0xa) { - /* DDR3-1066 */ - calibration_code = 0x00350037; - } else if (MemClkFreq == 0xe) { - /* DDR3-1333 */ - calibration_code = 0x00000035; - } else if (MemClkFreq == 0x12) { - /* DDR3-1600 */ - calibration_code = 0x0000002b; - } else if (MemClkFreq > 0x12) { - /* DDR3-1866 or greater */ - calibration_code = 0x00000031; - } - } else if (MaxDimmsInstallable == 3) { - /* TODO - * 3 DIMM/channel support unimplemented - */ - } - } else { - /* TODO - * Other socket support unimplemented - */ - } - - return calibration_code; -} - -uint8_t fam15h_slow_access_mode(struct DCTStatStruc *pDCTstat, uint8_t dct) -{ - uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH); - - uint8_t package_type; - uint32_t slow_access = 0; - - package_type = mctGet_NVbits(NV_PACK_TYPE); - uint16_t MemClkFreq = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x94) & 0x1f; - - /* Obtain number of DIMMs on channel */ - uint8_t dimm_count = pDCTstat->MAdimms[dct]; - uint8_t rank_count_dimm0; - uint8_t rank_count_dimm1; - - if (package_type == PT_GR) { - /* Socket G34 */ - if (pDCTstat->Status & (1 << SB_Registered)) { - /* RDIMM */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 74 */ - slow_access = 0; - } else if (pDCTstat->Status & (1 << SB_LoadReduced)) { - /* LRDIMM */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 75 */ - slow_access = 0; - } else { - /* UDIMM */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 73 */ - if (MaxDimmsInstallable == 1) { - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6) - || (MemClkFreq == 0xa) | (MemClkFreq == 0xe)) { - /* DDR3-667 - DDR3-1333 */ - slow_access = 0; - } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) { - /* DDR3-1600 - DDR3-1866 */ - if (rank_count_dimm0 == 1) - slow_access = 0; - else - slow_access = 1; - } - } else if (MaxDimmsInstallable == 2) { - if (dimm_count == 1) { - /* 1 DIMM detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6) - || (MemClkFreq == 0xa) | (MemClkFreq == 0xe)) { - /* DDR3-667 - DDR3-1333 */ - slow_access = 0; - } else if (MemClkFreq == 0x12) { - /* DDR3-1600 */ - if (rank_count_dimm0 == 1) - slow_access = 0; - else - slow_access = 1; - } - } else if (dimm_count == 2) { - /* 2 DIMMs detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6) - || (MemClkFreq == 0xa)) { - /* DDR3-667 - DDR3-1066 */ - slow_access = 0; - } else if ((MemClkFreq == 0xe) || (MemClkFreq == 0x12)) { - /* DDR3-1333 - DDR3-1600 */ - slow_access = 1; - } - } - } else if (MaxDimmsInstallable == 3) { - /* TODO - * 3 DIMM/channel support unimplemented - */ - } - } - } else if (package_type == PT_C3) { - /* Socket C32 */ - if (pDCTstat->Status & (1 << SB_Registered)) { - /* RDIMM */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 77 */ - slow_access = 0; - } else if (pDCTstat->Status & (1 << SB_LoadReduced)) { - /* LRDIMM */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 78 */ - slow_access = 0; - } else { - /* UDIMM */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 Table 76 */ - if (MaxDimmsInstallable == 1) { - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6) - || (MemClkFreq == 0xa) | (MemClkFreq == 0xe)) { - /* DDR3-667 - DDR3-1333 */ - slow_access = 0; - } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) { - /* DDR3-1600 - DDR3-1866 */ - if (rank_count_dimm0 == 1) - slow_access = 0; - else - slow_access = 1; - } - } else if (MaxDimmsInstallable == 2) { - if (dimm_count == 1) { - /* 1 DIMM detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6) - || (MemClkFreq == 0xa) | (MemClkFreq == 0xe)) { - /* DDR3-667 - DDR3-1333 */ - slow_access = 0; - } else if (MemClkFreq == 0x12) { - /* DDR3-1600 */ - if (rank_count_dimm0 == 1) - slow_access = 0; - else - slow_access = 1; - } - } else if (dimm_count == 2) { - /* 2 DIMMs detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6) - || (MemClkFreq == 0xa)) { - /* DDR3-667 - DDR3-1066 */ - slow_access = 0; - } else if ((MemClkFreq == 0xe) || (MemClkFreq == 0x12)) { - /* DDR3-1333 - DDR3-1600 */ - slow_access = 1; - } - } - } else if (MaxDimmsInstallable == 3) { - /* TODO - * 3 DIMM/channel support unimplemented - */ - } - } - } else if (package_type == PT_FM2) { - /* Socket FM2 */ - /* UDIMM */ - /* Fam15h Model10 BKDG Rev. 3.12 section 2.9.5.6.6 Table 32 */ - if (MaxDimmsInstallable == 1) { - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6) - || (MemClkFreq == 0xa) | (MemClkFreq == 0xe)) { - /* DDR3-667 - DDR3-1333 */ - slow_access = 0; - } else if (MemClkFreq >= 0x12) { - /* DDR3-1600 or higher */ - if (rank_count_dimm0 == 1) - slow_access = 0; - else - slow_access = 1; - } - } else if (MaxDimmsInstallable == 2) { - if (dimm_count == 1) { - /* 1 DIMM detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6) - || (MemClkFreq == 0xa) | (MemClkFreq == 0xe)) { - /* DDR3-667 - DDR3-1333 */ - slow_access = 0; - } else if (MemClkFreq >= 0x12) { - /* DDR3-1600 or higher */ - if (rank_count_dimm0 == 1) - slow_access = 0; - else - slow_access = 1; - } - } else if (dimm_count == 2) { - /* 2 DIMMs detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6) - || (MemClkFreq == 0xa)) { - /* DDR3-667 - DDR3-1066 */ - slow_access = 0; - } else if (MemClkFreq >= 0xe) { - /* DDR3-1333 or higher */ - slow_access = 1; - } - } - } else if (MaxDimmsInstallable == 3) { - /* TODO - * 3 DIMM/channel support unimplemented - */ - } - } else { - /* TODO - * Other socket support unimplemented - */ - } - - return slow_access; -} - -static uint8_t fam15h_odt_tristate_enable_code(struct DCTStatStruc *pDCTstat, uint8_t dct) -{ - uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH); - - uint8_t package_type; - uint8_t odt_tristate_code = 0; - - package_type = mctGet_NVbits(NV_PACK_TYPE); - - /* Obtain number of DIMMs on channel */ - uint8_t dimm_count = pDCTstat->MAdimms[dct]; - uint8_t rank_count_dimm0; - uint8_t rank_count_dimm1; - - if (package_type == PT_GR) { - /* Socket G34 */ - if (pDCTstat->Status & (1 << SB_Registered)) { - /* RDIMM */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 104 */ - if (MaxDimmsInstallable == 1) { - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (rank_count_dimm0 == 1) - odt_tristate_code = 0xe; - else - odt_tristate_code = 0xa; - } else if (MaxDimmsInstallable == 2) { - if (dimm_count == 1) { - /* 1 DIMM detected */ - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (rank_count_dimm1 == 1) - odt_tristate_code = 0xd; - else - odt_tristate_code = 0x5; - } else if (dimm_count == 2) { - /* 2 DIMMs detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1)) - odt_tristate_code = 0xc; - else if ((rank_count_dimm0 == 1) && (rank_count_dimm1 >= 2)) - odt_tristate_code = 0x4; - else if ((rank_count_dimm0 >= 2) && (rank_count_dimm1 == 1)) - odt_tristate_code = 0x8; - else - odt_tristate_code = 0x0; - } - } else if (MaxDimmsInstallable == 3) { - /* TODO - * 3 DIMM/channel support unimplemented - */ - } - } else if (pDCTstat->Status & (1 << SB_LoadReduced)) { - /* LRDIMM */ - - /* TODO - * Implement LRDIMM support - * See Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 105 - */ - } else { - /* UDIMM */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 103 */ - if (MaxDimmsInstallable == 1) { - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (rank_count_dimm0 == 1) - odt_tristate_code = 0xe; - else - odt_tristate_code = 0xa; - } else if (MaxDimmsInstallable == 2) { - if (dimm_count == 1) { - /* 1 DIMM detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (rank_count_dimm0 == 1) - odt_tristate_code = 0xd; - else - odt_tristate_code = 0x5; - } else if (dimm_count == 2) { - /* 2 DIMMs detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1)) - odt_tristate_code = 0xc; - else if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 2)) - odt_tristate_code = 0x4; - else if ((rank_count_dimm0 == 2) && (rank_count_dimm1 == 1)) - odt_tristate_code = 0x8; - else - odt_tristate_code = 0x0; - } - } else if (MaxDimmsInstallable == 3) { - /* TODO - * 3 DIMM/channel support unimplemented - */ - } - } - } else if (package_type == PT_C3) { - /* Socket C32 */ - if (pDCTstat->Status & (1 << SB_Registered)) { - /* RDIMM */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 107 */ - if (MaxDimmsInstallable == 1) { - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (rank_count_dimm0 == 1) - odt_tristate_code = 0xe; - else - odt_tristate_code = 0xa; - } else if (MaxDimmsInstallable == 2) { - if (dimm_count == 1) { - /* 1 DIMM detected */ - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (rank_count_dimm1 == 1) - odt_tristate_code = 0xd; - else - odt_tristate_code = 0x5; - } else if (dimm_count == 2) { - /* 2 DIMMs detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1)) - odt_tristate_code = 0xc; - else if ((rank_count_dimm0 == 1) && (rank_count_dimm1 >= 2)) - odt_tristate_code = 0x4; - else if ((rank_count_dimm0 >= 2) && (rank_count_dimm1 == 1)) - odt_tristate_code = 0x8; - else - odt_tristate_code = 0x0; - } - } else if (MaxDimmsInstallable == 3) { - /* TODO - * 3 DIMM/channel support unimplemented - */ - } - } else if (pDCTstat->Status & (1 << SB_LoadReduced)) { - /* LRDIMM */ - - /* TODO - * Implement LRDIMM support - * See Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 108 - */ - } else { - /* UDIMM */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 106 */ - if (MaxDimmsInstallable == 1) { - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (rank_count_dimm0 == 1) - odt_tristate_code = 0xe; - else - odt_tristate_code = 0xa; - } else if (MaxDimmsInstallable == 2) { - if (dimm_count == 1) { - /* 1 DIMM detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (rank_count_dimm0 == 1) - odt_tristate_code = 0xd; - else - odt_tristate_code = 0x5; - } else if (dimm_count == 2) { - /* 2 DIMMs detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1)) - odt_tristate_code = 0xc; - else if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 2)) - odt_tristate_code = 0x4; - else if ((rank_count_dimm0 == 2) && (rank_count_dimm1 == 1)) - odt_tristate_code = 0x8; - else - odt_tristate_code = 0x0; - } - } else if (MaxDimmsInstallable == 3) { - /* TODO - * 3 DIMM/channel support unimplemented - */ - } - } - } else if (package_type == PT_FM2) { - /* Socket FM2 */ - /* UDIMM */ - odt_tristate_code = 0x0; - } else { - /* TODO - * Other socket support unimplemented - */ - } - - return odt_tristate_code; -} - -static uint8_t fam15h_cs_tristate_enable_code(struct DCTStatStruc *pDCTstat, uint8_t dct) -{ - uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH); - - uint8_t package_type; - uint8_t cs_tristate_code = 0; - - package_type = mctGet_NVbits(NV_PACK_TYPE); - - /* Obtain number of DIMMs on channel */ - uint8_t dimm_count = pDCTstat->MAdimms[dct]; - uint8_t rank_count_dimm0; - uint8_t rank_count_dimm1; - - if (package_type == PT_GR) { - /* Socket G34 */ - if (pDCTstat->Status & (1 << SB_Registered)) { - /* RDIMM */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 104 */ - if (MaxDimmsInstallable == 1) { - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (rank_count_dimm0 < 4) - cs_tristate_code = 0xfc; - else - cs_tristate_code = 0xcc; - } else if (MaxDimmsInstallable == 2) { - if (dimm_count == 1) { - /* 1 DIMM detected */ - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (rank_count_dimm1 < 4) - cs_tristate_code = 0xf3; - else - cs_tristate_code = 0x33; - } else if (dimm_count == 2) { - /* 2 DIMMs detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4)) - cs_tristate_code = 0xf0; - else if ((rank_count_dimm0 < 4) && (rank_count_dimm1 == 4)) - cs_tristate_code = 0x30; - else if ((rank_count_dimm0 == 4) && (rank_count_dimm1 < 4)) - cs_tristate_code = 0xc0; - else - cs_tristate_code = 0x0; - } - } else if (MaxDimmsInstallable == 3) { - /* TODO - * 3 DIMM/channel support unimplemented - */ - } - } else if (pDCTstat->Status & (1 << SB_LoadReduced)) { - /* LRDIMM */ - - /* TODO - * Implement LRDIMM support - * See Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 105 - */ - } else { - /* UDIMM */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 103 */ - if (MaxDimmsInstallable == 1) { - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (rank_count_dimm0 == 1) - cs_tristate_code = 0xfe; - else - cs_tristate_code = 0xfc; - } else if (MaxDimmsInstallable == 2) { - if (dimm_count == 1) { - /* 1 DIMM detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (rank_count_dimm0 == 1) - cs_tristate_code = 0xfb; - else - cs_tristate_code = 0xf3; - } else if (dimm_count == 2) { - /* 2 DIMMs detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1)) - cs_tristate_code = 0xfa; - else if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 2)) - cs_tristate_code = 0xf2; - else if ((rank_count_dimm0 == 2) && (rank_count_dimm1 == 1)) - cs_tristate_code = 0xf8; - else - cs_tristate_code = 0xf0; - } - } else if (MaxDimmsInstallable == 3) { - /* TODO - * 3 DIMM/channel support unimplemented - */ - } - } - } else if (package_type == PT_C3) { - /* Socket C32 */ - if (pDCTstat->Status & (1 << SB_Registered)) { - /* RDIMM */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 107 */ - if (MaxDimmsInstallable == 1) { - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (rank_count_dimm0 < 4) - cs_tristate_code = 0xfc; - else - cs_tristate_code = 0xcc; - } else if (MaxDimmsInstallable == 2) { - if (dimm_count == 1) { - /* 1 DIMM detected */ - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (rank_count_dimm1 < 4) - cs_tristate_code = 0xf3; - else - cs_tristate_code = 0x33; - } else if (dimm_count == 2) { - /* 2 DIMMs detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4)) - cs_tristate_code = 0xf0; - else if ((rank_count_dimm0 < 4) && (rank_count_dimm1 == 4)) - cs_tristate_code = 0x30; - else if ((rank_count_dimm0 == 4) && (rank_count_dimm1 < 4)) - cs_tristate_code = 0xc0; - else - cs_tristate_code = 0x0; - } - } else if (MaxDimmsInstallable == 3) { - /* TODO - * 3 DIMM/channel support unimplemented - */ - } - } else if (pDCTstat->Status & (1 << SB_LoadReduced)) { - /* LRDIMM */ - - /* TODO - * Implement LRDIMM support - * See Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 108 - */ - } else { - /* UDIMM */ - /* Fam15h BKDG Rev. 3.14 section 2.10.5.10.1 Table 106 */ - if (MaxDimmsInstallable == 1) { - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (rank_count_dimm0 == 1) - cs_tristate_code = 0xfe; - else - cs_tristate_code = 0xfc; - } else if (MaxDimmsInstallable == 2) { - if (dimm_count == 1) { - /* 1 DIMM detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if (rank_count_dimm0 == 1) - cs_tristate_code = 0xfb; - else - cs_tristate_code = 0xf3; - } else if (dimm_count == 2) { - /* 2 DIMMs detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - - if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 1)) - cs_tristate_code = 0xfa; - else if ((rank_count_dimm0 == 1) && (rank_count_dimm1 == 2)) - cs_tristate_code = 0xf2; - else if ((rank_count_dimm0 == 2) && (rank_count_dimm1 == 1)) - cs_tristate_code = 0xf8; - else - cs_tristate_code = 0xf0; - } - } else if (MaxDimmsInstallable == 3) { - /* TODO - * 3 DIMM/channel support unimplemented - */ - } - } - } else if (package_type == PT_FM2) { - /* Socket FM2 */ - /* UDIMM */ - cs_tristate_code = 0x0; - } else { - /* TODO - * Other socket support unimplemented - */ - } - - return cs_tristate_code; -} - -void set_2t_configuration(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - printk(BIOS_DEBUG, "%s: Start\n", __func__); - - uint32_t dev; - uint32_t reg; - uint32_t dword; - - uint8_t enable_slow_access_mode = 0; - dev = pDCTstat->dev_dct; - - if (is_fam15h()) { - if (pDCTstat->_2Tmode) - enable_slow_access_mode = 1; - } else { - if (pDCTstat->_2Tmode == 2) - enable_slow_access_mode = 1; - } - - reg = 0x94; /* DRAM Configuration High */ - dword = Get_NB32_DCT(dev, dct, reg); - if (enable_slow_access_mode) - dword |= (0x1 << 20); /* Set 2T CMD mode */ - else - dword &= ~(0x1 << 20); /* Clear 2T CMD mode */ - Set_NB32_DCT(dev, dct, reg, dword); - - printk(BIOS_DEBUG, "%s: Done\n", __func__); -} - -void precise_ndelay_fam15(struct MCTStatStruc *pMCTstat, uint32_t nanoseconds) { - msr_t tsc_msr; - uint64_t cycle_count = (((uint64_t)pMCTstat->TSCFreq) * nanoseconds) / 1000; - uint64_t start_timestamp; - uint64_t current_timestamp; - - tsc_msr = rdmsr(TSC_MSR); - start_timestamp = (((uint64_t)tsc_msr.hi) << 32) | tsc_msr.lo; - do { - tsc_msr = rdmsr(TSC_MSR); - current_timestamp = (((uint64_t)tsc_msr.hi) << 32) | tsc_msr.lo; - } while ((current_timestamp - start_timestamp) < cycle_count); -} - -void precise_memclk_delay_fam15(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, uint8_t dct, uint32_t clocks) { - uint16_t memclk_freq; - uint32_t delay_ns; - uint16_t fam15h_freq_tab[] = {0, 0, 0, 0, 333, 0, 400, 0, 0, 0, 533, 0, 0, 0, 667, 0, 0, 0, 800, 0, 0, 0, 933}; - - memclk_freq = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x94) & 0x1f; - - if (fam15h_freq_tab[memclk_freq] == 0) { - printk(BIOS_DEBUG, "ERROR: precise_memclk_delay_fam15 for DCT %d (delay %d clocks) failed to obtain valid memory frequency!" - " (pDCTstat: %p pDCTstat->dev_dct: %08x memclk_freq: %02x)\n", dct, clocks, pDCTstat, pDCTstat->dev_dct, memclk_freq); - } - delay_ns = (((uint64_t)clocks * 1000) / fam15h_freq_tab[memclk_freq]); - precise_ndelay_fam15(pMCTstat, delay_ns); -} - -static void read_spd_bytes(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, uint8_t dimm) -{ - uint8_t addr; - uint16_t byte; - - addr = Get_DIMMAddress_D(pDCTstat, dimm); - pDCTstat->spd_data.spd_address[dimm] = addr; - - for (byte = 0; byte < 256; byte++) { - pDCTstat->spd_data.spd_bytes[dimm][byte] = mctRead_SPD(addr, byte); - } -} - -#ifdef DEBUG_DIMM_SPD -static void dump_spd_bytes(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, uint8_t dimm) -{ - uint16_t byte; - - printk(BIOS_DEBUG, "SPD dump for DIMM %d\n ", dimm); - for (byte = 0; byte < 16; byte++) { - printk(BIOS_DEBUG, "%02x ", byte); - } - for (byte = 0; byte < 256; byte++) { - if ((byte & 0xf) == 0x0) { - printk(BIOS_DEBUG, "\n%02x ", byte >> 4); - } - printk(BIOS_DEBUG, "%02x ", pDCTstat->spd_data.spd_bytes[dimm][byte]); - } - printk(BIOS_DEBUG, "\n"); -} -#endif - -static void set_up_cc6_storage_fam15(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, uint8_t num_nodes) -{ - uint8_t interleaved; - uint8_t destination_node; - int8_t range; - int8_t max_range; - uint8_t max_node; - uint64_t max_range_limit; - uint8_t byte; - uint32_t dword; - uint32_t dword2; - uint64_t qword; - - interleaved = 0; - if (pMCTstat->GStatus & (1 << GSB_NodeIntlv)) - interleaved = 1; - - printk(BIOS_INFO, - "%s: Initializing CC6 DRAM storage area for node %d" - " (interleaved: %d)\n", - __func__, pDCTstat->Node_ID, interleaved); - - /* Find highest DRAM range (DramLimitAddr) */ - max_node = 0; - max_range = -1; - max_range_limit = 0; - for (range = 0; range < 8; range++) { - dword = Get_NB32(pDCTstat->dev_map, 0x40 + (range * 0x8)); - if (!(dword & 0x3)) - continue; - - dword = Get_NB32(pDCTstat->dev_map, 0x44 + (range * 0x8)); - dword2 = Get_NB32(pDCTstat->dev_map, 0x144 + (range * 0x8)); - qword = 0xffffff; - qword |= ((((uint64_t)dword) >> 16) & 0xffff) << 24; - qword |= (((uint64_t)dword2) & 0xff) << 40; - - if (qword > max_range_limit) { - max_range = range; - max_range_limit = qword; - max_node = dword & 0x7; - } - } - - if (max_range >= 0) { - printk(BIOS_INFO, - "%s:\toriginal (node %d) max_range_limit: %16llx DRAM" - " limit: %16llx\n", - __func__, max_node, max_range_limit, - (((uint64_t)(Get_NB32(pDCTstat->dev_map, 0x124) - & 0x1fffff)) << 27) | 0x7ffffff); - - if (interleaved) - /* Move upper limit down by 16M * the number of nodes */ - max_range_limit -= (0x1000000ULL * num_nodes); - else - /* Move upper limit down by 16M */ - max_range_limit -= 0x1000000ULL; - - printk(BIOS_INFO, "%s:\tnew max_range_limit: %16llx\n", - __func__, max_range_limit); - - /* Disable the range */ - dword = Get_NB32(pDCTstat->dev_map, 0x40 + (max_range * 0x8)); - byte = dword & 0x3; - dword &= ~(0x3); - Set_NB32(pDCTstat->dev_map, 0x40 + (max_range * 0x8), dword); - - /* Store modified range */ - dword = Get_NB32(pDCTstat->dev_map, 0x44 + (max_range * 0x8)); - dword &= ~(0xffff << 16); /* DramLimit[39:24] = max_range_limit[39:24] */ - dword |= ((max_range_limit >> 24) & 0xffff) << 16; - Set_NB32(pDCTstat->dev_map, 0x44 + (max_range * 0x8), dword); - - dword = Get_NB32(pDCTstat->dev_map, 0x144 + (max_range * 0x8)); - dword &= ~0xff; /* DramLimit[47:40] = max_range_limit[47:40] */ - dword |= (max_range_limit >> 40) & 0xff; - Set_NB32(pDCTstat->dev_map, 0x144 + (max_range * 0x8), dword); - - /* Reenable the range */ - dword = Get_NB32(pDCTstat->dev_map, 0x40 + (max_range * 0x8)); - dword |= byte; - Set_NB32(pDCTstat->dev_map, 0x40 + (max_range * 0x8), dword); - } - - /* Determine save state destination node */ - if (interleaved) - destination_node = Get_NB32(pDCTstat->dev_host, 0x60) & 0x7; - else - destination_node = max_node; - - /* Set save state destination node */ - dword = Get_NB32(pDCTstat->dev_link, 0x128); - dword &= ~(0x3f << 12); /* CoreSaveStateDestNode = destination_node */ - dword |= (destination_node & 0x3f) << 12; - Set_NB32(pDCTstat->dev_link, 0x128, dword); - - printk(BIOS_INFO, "%s:\tTarget node: %d\n", __func__, destination_node); - - printk(BIOS_INFO, "%s:\tDone\n", __func__); -} - -static void lock_dram_config(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - uint32_t dword; - - dword = Get_NB32(pDCTstat->dev_dct, 0x118); - dword |= 0x1 << 19; /* LockDramCfg = 1 */ - Set_NB32(pDCTstat->dev_dct, 0x118, dword); -} - -static void set_cc6_save_enable(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, uint8_t enable) -{ - uint32_t dword; - - dword = Get_NB32(pDCTstat->dev_dct, 0x118); - dword &= ~(0x1 << 18); /* CC6SaveEn = enable */ - dword |= (enable & 0x1) << 18; - Set_NB32(pDCTstat->dev_dct, 0x118, dword); -} - -void mctAutoInitMCT_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - /* - * Memory may be mapped contiguously all the way up to 4GB (depending on setup - * options). It is the responsibility of PCI subsystem to create an uncacheable - * IO region below 4GB and to adjust TOP_MEM downward prior to any IO mapping or - * accesses. It is the same responsibility of the CPU sub-system prior to - * accessing LAPIC. - * - * Slot Number is an external convention, and is determined by OEM with accompanying - * silk screening. OEM may choose to use Slot number convention which is consistent - * with DIMM number conventions. All AMD engineering platforms do. - * - * Build Requirements: - * 1. MCT_SEG0_START and MCT_SEG0_END macros to begin and end the code segment, - * defined in mcti.inc. - * - * Run-Time Requirements: - * 1. Complete Hypertransport Bus Configuration - * 2. SMBus Controller Initialized - * 1. BSP in Big Real Mode - * 2. Stack at SS:SP, located somewhere between A000:0000 and F000:FFFF - * 3. Checksummed or Valid NVRAM bits - * 4. MCG_CTL = -1, MC4_CTL_EN = 0 for all CPUs - * 5. MCi_STS from shutdown/warm reset recorded (if desired) prior to entry - * 6. All var MTRRs reset to zero - * 7. State of NB_CFG.DisDatMsk set properly on all CPUs - * 8. All CPUs at 2GHz Speed (unless DQS training is not installed). - * 9. All cHT links at max Speed/Width (unless DQS training is not installed). - * - * - * Global relationship between index values and item values: - * - * pDCTstat.CASL pDCTstat.Speed - * j CL(j) k F(k) - * -------------------------- - * 0 2.0 - - - * 1 3.0 1 200 MHz - * 2 4.0 2 266 MHz - * 3 5.0 3 333 MHz - * 4 6.0 4 400 MHz - * 5 7.0 5 533 MHz - * 6 8.0 6 667 MHz - * 7 9.0 7 800 MHz - */ - u8 Node, NodesWmem; - u32 node_sys_base; - uint8_t dimm; - uint8_t nvram; - uint8_t enable_cc6; - uint8_t ecc_enabled; - uint8_t allow_config_restore; - - uint8_t s3resume = acpi_is_wakeup_s3(); - -restartinit: - - if (!mctGet_NVbits(NV_ECC_CAP) || !mctGet_NVbits(NV_ECC)) - pMCTstat->try_ecc = 0; - else - pMCTstat->try_ecc = 1; - - mctInitMemGPIOs_A_D(); /* Set any required GPIOs*/ - if (s3resume) { - printk(BIOS_DEBUG, "mctAutoInitMCT_D: mct_ForceNBPState0_En_Fam15\n"); - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - - mct_ForceNBPState0_En_Fam15(pMCTstat, pDCTstat); - } - -#if CONFIG(HAVE_ACPI_RESUME) - printk(BIOS_DEBUG, "mctAutoInitMCT_D: Restoring DCT configuration from NVRAM\n"); - if (restore_mct_information_from_nvram(0) != 0) - printk(BIOS_CRIT, "%s: ERROR: Unable to restore DCT configuration from NVRAM\n", __func__); - pMCTstat->GStatus |= 1 << GSB_ConfigRestored; -#endif - - if (is_fam15h()) { - printk(BIOS_DEBUG, "mctAutoInitMCT_D: mct_ForceNBPState0_Dis_Fam15\n"); - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - - mct_ForceNBPState0_Dis_Fam15(pMCTstat, pDCTstat); - } - } - } else { - NodesWmem = 0; - node_sys_base = 0; - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - - /* Zero out data structures to avoid false detection of DIMMs */ - memset(pDCTstat, 0, sizeof(struct DCTStatStruc)); - - /* Initialize data structures */ - pDCTstat->Node_ID = Node; - pDCTstat->dev_host = PA_HOST(Node); - pDCTstat->dev_map = PA_MAP(Node); - pDCTstat->dev_dct = PA_DCT(Node); - pDCTstat->dev_nbmisc = PA_NBMISC(Node); - pDCTstat->dev_link = PA_LINK(Node); - pDCTstat->dev_nbctl = PA_NBCTL(Node); - pDCTstat->NodeSysBase = node_sys_base; - - if (mctGet_NVbits(NV_PACK_TYPE) == PT_GR) { - uint32_t dword; - pDCTstat->Dual_Node_Package = 1; - - /* Get the internal node number */ - dword = Get_NB32(pDCTstat->dev_nbmisc, 0xe8); - dword = (dword >> 30) & 0x3; - pDCTstat->Internal_Node_ID = dword; - } else { - pDCTstat->Dual_Node_Package = 0; - } - - printk(BIOS_DEBUG, "%s: mct_init Node %d\n", __func__, Node); - mct_init(pMCTstat, pDCTstat); - mctNodeIDDebugPort_D(); - pDCTstat->NodePresent = NodePresent_D(Node); - if (pDCTstat->NodePresent) { - pDCTstat->LogicalCPUID = mctGetLogicalCPUID_D(Node); - - printk(BIOS_DEBUG, "%s: mct_InitialMCT_D\n", __func__); - mct_InitialMCT_D(pMCTstat, pDCTstat); - - printk(BIOS_DEBUG, "%s: mctSMBhub_Init\n", __func__); - mctSMBhub_Init(Node); /* Switch SMBUS crossbar to proper node */ - - printk(BIOS_DEBUG, "%s: mct_preInitDCT\n", __func__); - mct_preInitDCT(pMCTstat, pDCTstat); - } - node_sys_base = pDCTstat->NodeSysBase; - node_sys_base += (pDCTstat->NodeSysLimit + 2) & ~0x0F; - } - - /* If the boot fails make sure training is attempted after reset */ - nvram = 0; - set_option("allow_spd_nvram_cache_restore", &nvram); - -#if CONFIG(DIMM_VOLTAGE_SET_SUPPORT) - printk(BIOS_DEBUG, "%s: DIMMSetVoltage\n", __func__); - DIMMSetVoltages(pMCTstat, pDCTstatA); /* Set the DIMM voltages (mainboard specific) */ -#endif - if (!CONFIG(DIMM_VOLTAGE_SET_SUPPORT)) { - /* Assume 1.5V operation */ - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - - if (!pDCTstat->NodePresent) - continue; - - for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) { - if (pDCTstat->DIMMValid & (1 << dimm)) - pDCTstat->DimmConfiguredVoltage[dimm] = 0x1; - } - } - } - - /* If DIMM configuration has not changed since last boot restore training values */ - allow_config_restore = 1; - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - - if (pDCTstat->NodePresent) - if (!pDCTstat->spd_data.nvram_spd_match) - allow_config_restore = 0; - } - - /* FIXME - * Stability issues have arisen on multiple Family 15h systems - * when configuration restoration is enabled. In all cases these - * stability issues resolved by allowing the RAM to go through a - * full training cycle. - * - * Debug and reenable this! - */ - allow_config_restore = 0; - - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - - if (pDCTstat->NodePresent) { - printk(BIOS_DEBUG, "%s: mctSMBhub_Init\n", __func__); - mctSMBhub_Init(Node); /* Switch SMBUS crossbar to proper node*/ - - printk(BIOS_DEBUG, "%s: mct_initDCT\n", __func__); - mct_initDCT(pMCTstat, pDCTstat); - if (pDCTstat->ErrCode == SC_FatalErr) { - goto fatalexit; /* any fatal errors?*/ - } else if (pDCTstat->ErrCode < SC_StopError) { - NodesWmem++; - } - } - } - if (NodesWmem == 0) { - printk(BIOS_ALERT, "Unable to detect valid memory on any nodes. Halting!\n"); - goto fatalexit; - } - - printk(BIOS_DEBUG, "mctAutoInitMCT_D: SyncDCTsReady_D\n"); - SyncDCTsReady_D(pMCTstat, pDCTstatA); /* Make sure DCTs are ready for accesses.*/ - - printk(BIOS_DEBUG, "mctAutoInitMCT_D: HTMemMapInit_D\n"); - HTMemMapInit_D(pMCTstat, pDCTstatA); /* Map local memory into system address space.*/ - mctHookAfterHTMap(); - - if (!is_fam15h()) { - printk(BIOS_DEBUG, "mctAutoInitMCT_D: CPUMemTyping_D\n"); - CPUMemTyping_D(pMCTstat, pDCTstatA); /* Map dram into WB/UC CPU cacheability */ - } - - printk(BIOS_DEBUG, "mctAutoInitMCT_D: mctHookAfterCPU\n"); - mctHookAfterCPU(); /* Setup external northbridge(s) */ - - /* FIXME - * Previous training values should only be used if the current desired - * speed is the same as the speed used in the previous boot. - * How to get the desired speed at this point in the code? - */ - - printk(BIOS_DEBUG, "mctAutoInitMCT_D: DQSTiming_D\n"); - DQSTiming_D(pMCTstat, pDCTstatA, allow_config_restore); /* Get Receiver Enable and DQS signal timing*/ - - if (!is_fam15h()) { - printk(BIOS_DEBUG, "mctAutoInitMCT_D: UMAMemTyping_D\n"); - UMAMemTyping_D(pMCTstat, pDCTstatA); /* Fix up for UMA sizing */ - } - - if (!allow_config_restore) { - printk(BIOS_DEBUG, "mctAutoInitMCT_D: :OtherTiming\n"); - mct_OtherTiming(pMCTstat, pDCTstatA); - } - - if (ReconfigureDIMMspare_D(pMCTstat, pDCTstatA)) { /* RESET# if 1st pass of DIMM spare enabled*/ - goto restartinit; - } - - InterleaveNodes_D(pMCTstat, pDCTstatA); - InterleaveChannels_D(pMCTstat, pDCTstatA); - - ecc_enabled = 1; - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - - if (pDCTstat->NodePresent) - if (!is_ecc_enabled(pMCTstat, pDCTstat)) - ecc_enabled = 0; - } - - if (ecc_enabled) { - printk(BIOS_DEBUG, "mctAutoInitMCT_D: ECCInit_D\n"); - if (!ECCInit_D(pMCTstat, pDCTstatA)) { /* Setup ECC control and ECC check-bits*/ - /* Memory was not cleared during ECC setup */ - /* mctDoWarmResetMemClr_D(); */ - printk(BIOS_DEBUG, "mctAutoInitMCT_D: MCTMemClr_D\n"); - MCTMemClr_D(pMCTstat,pDCTstatA); - } - } - - if (is_fam15h()) { - printk(BIOS_DEBUG, "mctAutoInitMCT_D: CPUMemTyping_D\n"); - CPUMemTyping_D(pMCTstat, pDCTstatA); /* Map dram into WB/UC CPU cacheability */ - - printk(BIOS_DEBUG, "mctAutoInitMCT_D: UMAMemTyping_D\n"); - UMAMemTyping_D(pMCTstat, pDCTstatA); /* Fix up for UMA sizing */ - - printk(BIOS_DEBUG, "mctAutoInitMCT_D: mct_ForceNBPState0_Dis_Fam15\n"); - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - - mct_ForceNBPState0_Dis_Fam15(pMCTstat, pDCTstat); - } - } - - if (is_fam15h()) { - enable_cc6 = 0; - if (get_option(&nvram, "cpu_cc6_state") == CB_SUCCESS) - enable_cc6 = !!nvram; - - if (enable_cc6) { - uint8_t num_nodes; - - num_nodes = 0; - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - - if (pDCTstat->NodePresent) - num_nodes++; - } - - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - - if (pDCTstat->NodePresent) - set_up_cc6_storage_fam15(pMCTstat, pDCTstat, num_nodes); - } - - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - - if (pDCTstat->NodePresent) { - set_cc6_save_enable(pMCTstat, pDCTstat, 1); - lock_dram_config(pMCTstat, pDCTstat); - } - } - } - } - - mct_FinalMCT_D(pMCTstat, pDCTstatA); - printk(BIOS_DEBUG, "mctAutoInitMCT_D Done: Global Status: %x\n", pMCTstat->GStatus); - } - - return; - -fatalexit: - die("mct_d: fatalexit"); -} - -void initialize_mca(uint8_t bsp, uint8_t suppress_errors) { - uint8_t node; - uint32_t mc4_status_high; - uint32_t mc4_status_low; - - for (node = 0; node < MAX_NODES_SUPPORTED; node++) { - if (bsp && (node > 0)) - break; - - mc4_status_high = pci_read_config32(PCI_DEV(0, 0x18 + node, 3), 0x4c); - mc4_status_low = pci_read_config32(PCI_DEV(0, 0x18 + node, 3), 0x48); - if ((mc4_status_high & (0x1 << 31)) && (mc4_status_high != 0xffffffff)) { - if (!suppress_errors) - printk(BIOS_WARNING, "WARNING: MC4 Machine Check Exception detected on node %d!\n" - "Signature: %08x%08x\n", node, mc4_status_high, mc4_status_low); - - /* Clear MC4 error status */ - pci_write_config32(PCI_DEV(0, 0x18 + node, 3), 0x48, 0x0); - pci_write_config32(PCI_DEV(0, 0x18 + node, 3), 0x4c, 0x0); - } - } -} - -static u8 ReconfigureDIMMspare_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - u8 ret; - - if (mctGet_NVbits(NV_CS_SpareCTL)) { - if (MCT_DIMM_SPARE_NO_WARM) { - /* Do no warm-reset DIMM spare */ - if (pMCTstat->GStatus & (1 << GSB_EnDIMMSpareNW)) { - LoadDQSSigTmgRegs_D(pMCTstat, pDCTstatA); - ret = 0; - } else { - mct_ResetDataStruct_D(pMCTstat, pDCTstatA); - pMCTstat->GStatus |= 1 << GSB_EnDIMMSpareNW; - ret = 1; - } - } else { - /* Do warm-reset DIMM spare */ - if (mctGet_NVbits(NV_DQSTrainCTL)) - mctWarmReset_D(); - ret = 0; - } - } else { - ret = 0; - } - - return ret; -} - -/* Enable or disable phy-assisted training mode - * Phy-assisted training mode applies to the follow DRAM training procedures: - * Write Levelization Training (2.10.5.8.1) - * DQS Receiver Enable Training (2.10.5.8.2) - */ -void fam15EnableTrainingMode(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t enable) -{ - uint8_t index; - uint32_t dword; - uint32_t index_reg = 0x98; - uint32_t dev = pDCTstat->dev_dct; - - if (enable) { - /* Enable training mode */ - dword = Get_NB32_DCT(dev, dct, 0x78); /* DRAM Control */ - dword &= ~(0x1 << 17); /* AddrCmdTriEn = 0 */ - Set_NB32_DCT(dev, dct, 0x78, dword); /* DRAM Control */ - - dword = Get_NB32_DCT(dev, dct, 0x8c); /* DRAM Timing High */ - dword |= (0x1 << 18); /* DisAutoRefresh = 1 */ - Set_NB32_DCT(dev, dct, 0x8c, dword); /* DRAM Timing High */ - - dword = Get_NB32_DCT(dev, dct, 0x94); /* DRAM Configuration High */ - dword &= ~(0xf << 24); /* DcqBypassMax = 0 */ - dword &= ~(0x1 << 22); /* BankSwizzleMode = 0 */ - dword &= ~(0x1 << 15); /* PowerDownEn = 0 */ - dword &= ~(0x3 << 10); /* ZqcsInterval = 0 */ - Set_NB32_DCT(dev, dct, 0x94, dword); /* DRAM Configuration High */ - - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000d); - dword &= ~(0xf << 16); /* RxMaxDurDllNoLock = 0 */ - dword &= ~(0xf); /* TxMaxDurDllNoLock = 0 */ - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000d, dword); - - for (index = 0; index < 0x9; index++) { - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0010 | (index << 8)); - dword &= ~(0x1 << 12); /* EnRxPadStandby = 0 */ - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0010 | (index << 8), dword); - } - - dword = Get_NB32_DCT(dev, dct, 0xa4); /* DRAM Controller Temperature Throttle */ - dword &= ~(0x1 << 11); /* BwCapEn = 0 */ - dword &= ~(0x1 << 8); /* ODTSEn = 0 */ - Set_NB32_DCT(dev, dct, 0xa4, dword); /* DRAM Controller Temperature Throttle */ - - dword = Get_NB32_DCT(dev, dct, 0x110); /* DRAM Controller Select Low */ - dword &= ~(0x1 << 2); /* DctSelIntLvEn = 0 */ - Set_NB32_DCT(dev, dct, 0x110, dword); /* DRAM Controller Select Low */ - - dword = Get_NB32_DCT(pDCTstat->dev_nbmisc, dct, 0x58); /* Scrub Rate Control */ - dword &= ~(0x1f << 24); /* L3Scrub = 0 */ - dword &= ~(0x1f); /* DramScrub = 0 */ - Set_NB32_DCT(pDCTstat->dev_nbmisc, dct, 0x58, dword); /* Scrub Rate Control */ - - dword = Get_NB32_DCT(pDCTstat->dev_nbmisc, dct, 0x5c); /* DRAM Scrub Address Low */ - dword &= ~(0x1); /* ScrubReDirEn = 0 */ - Set_NB32_DCT(pDCTstat->dev_nbmisc, dct, 0x5c, dword); /* DRAM Scrub Address Low */ - - dword = Get_NB32_DCT(pDCTstat->dev_nbmisc, dct, 0x1b8); /* L3 Control 1 */ - dword |= (0x1 << 4); /* L3ScrbRedirDis = 1 */ - Set_NB32_DCT(pDCTstat->dev_nbmisc, dct, 0x1b8, dword); /* L3 Control 1 */ - - /* Fam15h BKDG section 2.10.5.5.1 */ - dword = Get_NB32_DCT(dev, dct, 0x218); /* DRAM Timing 5 */ - dword &= ~(0xf << 24); /* TrdrdSdSc = 0xb */ - dword |= (0xb << 24); - dword &= ~(0xf << 16); /* TrdrdSdDc = 0xb */ - dword |= (0xb << 16); - dword &= ~(0xf); /* TrdrdDd = 0xb */ - dword |= 0xb; - Set_NB32_DCT(dev, dct, 0x218, dword); /* DRAM Timing 5 */ - - /* Fam15h BKDG section 2.10.5.5.2 */ - dword = Get_NB32_DCT(dev, dct, 0x214); /* DRAM Timing 4 */ - dword &= ~(0xf << 16); /* TwrwrSdSc = 0xb */ - dword |= (0xb << 16); - dword &= ~(0xf << 8); /* TwrwrSdDc = 0xb */ - dword |= (0xb << 8); - dword &= ~(0xf); /* TwrwrDd = 0xb */ - dword |= 0xb; - Set_NB32_DCT(dev, dct, 0x214, dword); /* DRAM Timing 4 */ - - /* Fam15h BKDG section 2.10.5.5.3 */ - dword = Get_NB32_DCT(dev, dct, 0x218); /* DRAM Timing 5 */ - dword &= ~(0xf << 8); /* Twrrd = 0xb */ - dword |= (0xb << 8); - Set_NB32_DCT(dev, dct, 0x218, dword); /* DRAM Timing 5 */ - - /* Fam15h BKDG section 2.10.5.5.4 */ - dword = Get_NB32_DCT(dev, dct, 0x21c); /* DRAM Timing 6 */ - dword &= ~(0x1f << 8); /* TrwtTO = 0x16 */ - dword |= (0x16 << 8); - dword &= ~(0x1f << 16); /* TrwtWB = TrwtTO + 1 */ - dword |= ((((dword >> 8) & 0x1f) + 1) << 16); - Set_NB32_DCT(dev, dct, 0x21c, dword); /* DRAM Timing 6 */ - } else { - /* Disable training mode */ - uint8_t lane; - uint8_t dimm; - int16_t max_cdd_we_delta; - int16_t cdd_trwtto_we_delta; - uint8_t receiver; - uint8_t lane_count; - uint8_t x4_present = 0; - uint8_t x8_present = 0; - uint8_t memclk_index; - uint8_t interleave_channels = 0; - uint16_t trdrdsddc; - uint16_t trdrddd; - uint16_t cdd_trdrddd; - uint16_t twrwrsddc; - uint16_t twrwrdd; - uint16_t cdd_twrwrdd; - uint16_t twrrd; - uint16_t cdd_twrrd; - uint16_t cdd_trwtto; - uint16_t trwtto; - uint8_t first_dimm; - uint16_t delay; - uint16_t delay2; - uint8_t min_value; - uint8_t write_early; - uint8_t read_odt_delay; - uint8_t write_odt_delay; - uint8_t buffer_data_delay; - int16_t latency_difference; - uint16_t difference; - uint16_t current_total_delay_1[MAX_BYTE_LANES]; - uint16_t current_total_delay_2[MAX_BYTE_LANES]; - uint8_t ddr_voltage_index; - uint8_t max_dimms_installable; - - /* FIXME - * This should be platform configurable - */ - uint8_t dimm_event_l_pin_support = 0; - - ddr_voltage_index = dct_ddr_voltage_index(pDCTstat, dct); - max_dimms_installable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH); - - lane_count = get_available_lane_count(pMCTstat, pDCTstat); - - if (pDCTstat->Dimmx4Present & ((dct)?0xaa:0x55)) - x4_present = 1; - if (pDCTstat->Dimmx8Present & ((dct)?0xaa:0x55)) - x8_present = 1; - memclk_index = Get_NB32_DCT(dev, dct, 0x94) & 0x1f; - - if (pDCTstat->DIMMValidDCT[0] && pDCTstat->DIMMValidDCT[1] && mctGet_NVbits(NV_Unganged)) - interleave_channels = 1; - - dword = Get_NB32_DCT(dev, dct, 0x240); - delay = (dword >> 4) & 0xf; - if (delay > 6) - read_odt_delay = delay - 6; - else - read_odt_delay = 0; - delay = (dword >> 12) & 0x7; - if (delay > 6) - write_odt_delay = delay - 6; - else - write_odt_delay = 0; - - dword = (Get_NB32_DCT(dev, dct, 0xa8) >> 24) & 0x3; - write_early = dword / 2; - - latency_difference = Get_NB32_DCT(dev, dct, 0x200) & 0x1f; - dword = Get_NB32_DCT(dev, dct, 0x20c) & 0x1f; - latency_difference -= dword; - - if (pDCTstat->Status & (1 << SB_LoadReduced)) { - /* LRDIMM */ - - /* TODO - * Implement LRDIMM support - * See Fam15h BKDG Rev. 3.14 section 2.10.5.5 - */ - } else { - buffer_data_delay = 0; - } - - /* TODO: - * Adjust trdrdsddc if four-rank DIMMs are installed per - * section 2.10.5.5.1 of the Family 15h BKDG. - * cdd_trdrdsddc will also need to be calculated in that process. - */ - trdrdsddc = 3; - - /* Calculate the Critical Delay Difference for TrdrdDd */ - cdd_trdrddd = 0; - first_dimm = 1; - for (receiver = 0; receiver < 8; receiver += 2) { - dimm = (receiver >> 1); - - if (!mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, dct, receiver)) - continue; - - read_dqs_receiver_enable_control_registers(current_total_delay_2, dev, dct, dimm, index_reg); - - if (first_dimm) { - memcpy(current_total_delay_1, current_total_delay_2, sizeof(current_total_delay_1)); - first_dimm = 0; - } - - for (lane = 0; lane < lane_count; lane++) { - if (current_total_delay_1[lane] > current_total_delay_2[lane]) - difference = current_total_delay_1[lane] - current_total_delay_2[lane]; - else - difference = current_total_delay_2[lane] - current_total_delay_1[lane]; - - if (difference > cdd_trdrddd) - cdd_trdrddd = difference; - } - } - - /* Convert the difference to MEMCLKs */ - cdd_trdrddd = (((cdd_trdrddd + (1 << 6) - 1) >> 6) & 0xf); - - /* Calculate Trdrddd */ - delay = (read_odt_delay + 3) * 2; - delay2 = cdd_trdrddd + 7; - if (delay2 > delay) - delay = delay2; - trdrddd = (delay + 1) / 2; /* + 1 is equivalent to ceiling function here */ - if (trdrdsddc > trdrddd) - trdrddd = trdrdsddc; - - /* TODO: - * Adjust twrwrsddc if four-rank DIMMs are installed per - * section 2.10.5.5.1 of the Family 15h BKDG. - * cdd_twrwrsddc will also need to be calculated in that process. - */ - twrwrsddc = 4; - - /* Calculate the Critical Delay Difference for TwrwrDd */ - cdd_twrwrdd = 0; - first_dimm = 1; - for (receiver = 0; receiver < 8; receiver += 2) { - dimm = (receiver >> 1); - - if (!mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, dct, receiver)) - continue; - - read_dqs_write_timing_control_registers(current_total_delay_2, dev, dct, dimm, index_reg); - - if (first_dimm) { - memcpy(current_total_delay_1, current_total_delay_2, sizeof(current_total_delay_1)); - first_dimm = 0; - } - - for (lane = 0; lane < lane_count; lane++) { - if (current_total_delay_1[lane] > current_total_delay_2[lane]) - difference = current_total_delay_1[lane] - current_total_delay_2[lane]; - else - difference = current_total_delay_2[lane] - current_total_delay_1[lane]; - - if (difference > cdd_twrwrdd) - cdd_twrwrdd = difference; - } - } - - /* Convert the difference to MEMCLKs */ - cdd_twrwrdd = (((cdd_twrwrdd + (1 << 6) - 1) >> 6) & 0xf); - - /* Calculate Twrwrdd */ - delay = (write_odt_delay + 3) * 2; - delay2 = cdd_twrwrdd + 7; - if (delay2 > delay) - delay = delay2; - twrwrdd = (delay + 1) / 2; /* + 1 is equivalent to ceiling function here */ - if (twrwrsddc > twrwrdd) - twrwrdd = twrwrsddc; - - dword = Get_NB32_DCT(dev, dct, 0x78); /* DRAM Control */ - dword |= (0x1 << 17); /* AddrCmdTriEn = 1 */ - Set_NB32_DCT(dev, dct, 0x78, dword); /* DRAM Control */ - - dword = Get_NB32_DCT(dev, dct, 0x8c); /* DRAM Timing High */ - dword &= ~(0x1 << 18); /* DisAutoRefresh = 0 */ - Set_NB32_DCT(dev, dct, 0x8c, dword); /* DRAM Timing High */ - - /* Configure power saving options */ - dword = Get_NB32_DCT(dev, dct, 0xa8); /* Dram Miscellaneous 2 */ - dword |= (0x1 << 22); /* PrtlChPDEnhEn = 0x1 */ - dword |= (0x1 << 21); /* AggrPDEn = 0x1 */ - Set_NB32_DCT(dev, dct, 0xa8, dword); /* Dram Miscellaneous 2 */ - - /* Configure partial power down delay */ - dword = Get_NB32(dev, 0x244); /* DRAM Controller Miscellaneous 3 */ - dword &= ~0xf; /* PrtlChPDDynDly = 0x2 */ - dword |= 0x2; - Set_NB32(dev, 0x244, dword); /* DRAM Controller Miscellaneous 3 */ - - /* Configure power save delays */ - delay = 0xa; - delay2 = 0x3; - - /* Family 15h BKDG Table 214 */ - if ((pDCTstat->Status & (1 << SB_Registered)) - || (pDCTstat->Status & (1 << SB_LoadReduced))) { - if (memclk_index <= 0x6) { - if (ddr_voltage_index < 0x4) - /* 1.5 or 1.35V */ - delay2 = 0x3; - else - /* 1.25V */ - delay2 = 0x4; - } - else if ((memclk_index == 0xa) - || (memclk_index == 0xe)) - delay2 = 0x4; - else if (memclk_index == 0x12) - delay2 = 0x5; - else if (memclk_index == 0x16) - delay2 = 0x6; - } else { - if (memclk_index <= 0x6) - delay2 = 0x3; - else if ((memclk_index == 0xa) - || (memclk_index == 0xe)) - delay2 = 0x4; - else if (memclk_index == 0x12) - delay2 = 0x5; - else if (memclk_index == 0x16) - delay2 = 0x6; - } - - /* Family 15h BKDG Table 215 */ - if (memclk_index <= 0x6) - delay = 0xa; - else if (memclk_index == 0xa) - delay = 0xd; - else if (memclk_index == 0xe) - delay = 0x10; - else if (memclk_index == 0x12) - delay = 0x14; - else if (memclk_index == 0x16) - delay = 0x17; - - dword = Get_NB32_DCT(dev, dct, 0x248); /* Dram Power Management 0 */ - dword &= ~(0x3f << 24); /* AggrPDDelay = 0x0 */ - dword &= ~(0x3f << 16); /* PchgPDEnDelay = 0x1 */ - dword |= (0x1 << 16); - dword &= ~(0x1f << 8); /* Txpdll = delay */ - dword |= ((delay & 0x1f) << 8); - dword &= ~0xf; /* Txp = delay2 */ - dword |= delay2 & 0xf; - Set_NB32_DCT(dev, dct, 0x248, dword); /* Dram Power Management 0 */ - - /* Family 15h BKDG Table 216 */ - if (memclk_index <= 0x6) { - delay = 0x5; - delay2 = 0x3; - } else if (memclk_index == 0xa) { - delay = 0x6; - delay2 = 0x3; - } else if (memclk_index == 0xe) { - delay = 0x7; - delay2 = 0x4; - } else if (memclk_index == 0x12) { - delay = 0x8; - delay2 = 0x4; - } else if (memclk_index == 0x16) { - delay = 0xa; - delay2 = 0x5; - } - - dword = Get_NB32_DCT(dev, dct, 0x24c); /* Dram Power Management 1 */ - dword &= ~(0x3f << 24); /* Tcksrx = delay */ - dword |= ((delay & 0x3f) << 24); - dword &= ~(0x3f << 16); /* Tcksre = delay */ - dword |= ((delay & 0x3f) << 16); - dword &= ~(0x3f << 8); /* Tckesr = delay2 + 1 */ - dword |= (((delay2 + 1) & 0x3f) << 8); - dword &= ~0xf; /* Tpd = delay2 */ - dword |= delay2 & 0xf; - Set_NB32_DCT(dev, dct, 0x24c, dword); /* Dram Power Management 1 */ - - dword = Get_NB32_DCT(dev, dct, 0x94); /* DRAM Configuration High */ - dword |= (0xf << 24); /* DcqBypassMax = 0xf */ - dword |= (0x1 << 22); /* BankSwizzleMode = 1 */ - dword |= (0x1 << 15); /* PowerDownEn = 1 */ - dword &= ~(0x3 << 10); /* ZqcsInterval = 0x2 */ - dword |= (0x2 << 10); - Set_NB32_DCT(dev, dct, 0x94, dword); /* DRAM Configuration High */ - - if (x4_present && x8_present) { - /* Mixed channel of 4x and 8x DIMMs */ - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000d); - dword &= ~(0x3 << 24); /* RxDLLWakeupTime = 0 */ - dword &= ~(0x7 << 20); /* RxCPUpdPeriod = 0 */ - dword &= ~(0xf << 16); /* RxMaxDurDllNoLock = 0 */ - dword &= ~(0x3 << 8); /* TxDLLWakeupTime = 0 */ - dword &= ~(0x7 << 4); /* TxCPUpdPeriod = 0 */ - dword &= ~(0xf); /* TxMaxDurDllNoLock = 0 */ - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000d, dword); - } else { - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000d); - dword &= ~(0x3 << 24); /* RxDLLWakeupTime = 3 */ - dword |= (0x3 << 24); - dword &= ~(0x7 << 20); /* RxCPUpdPeriod = 3 */ - dword |= (0x3 << 20); - dword &= ~(0xf << 16); /* RxMaxDurDllNoLock = 7 */ - dword |= (0x7 << 16); - dword &= ~(0x3 << 8); /* TxDLLWakeupTime = 3 */ - dword |= (0x3 << 8); - dword &= ~(0x7 << 4); /* TxCPUpdPeriod = 3 */ - dword |= (0x3 << 4); - dword &= ~(0xf); /* TxMaxDurDllNoLock = 7 */ - dword |= 0x7; - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000d, dword); - } - - if ((memclk_index <= 0x12) && (x4_present != x8_present)) { - /* MemClkFreq <= 800MHz - * Not a mixed channel of x4 and x8 DIMMs - */ - for (index = 0; index < 0x9; index++) { - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0010 | (index << 8)); - dword |= (0x1 << 12); /* EnRxPadStandby = 1 */ - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0010 | (index << 8), dword); - } - } else { - for (index = 0; index < 0x9; index++) { - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0010 | (index << 8)); - dword &= ~(0x1 << 12); /* EnRxPadStandby = 0 */ - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0010 | (index << 8), dword); - } - } - - /* Calculate the Critical Delay Difference for Twrrd */ - cdd_twrrd = 0; - for (receiver = 0; receiver < 8; receiver += 2) { - dimm = (receiver >> 1); - - if (!mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, dct, receiver)) - continue; - - read_dqs_write_timing_control_registers(current_total_delay_1, dev, dct, dimm, index_reg); - read_dqs_receiver_enable_control_registers(current_total_delay_2, dev, dct, dimm, index_reg); - - for (lane = 0; lane < lane_count; lane++) { - if (current_total_delay_1[lane] > current_total_delay_2[lane]) - difference = current_total_delay_1[lane] - current_total_delay_2[lane]; - else - difference = current_total_delay_2[lane] - current_total_delay_1[lane]; - - if (difference > cdd_twrrd) - cdd_twrrd = difference; - } - } - - /* Convert the difference to MEMCLKs */ - cdd_twrrd = (((cdd_twrrd + (1 << 6) - 1) >> 6) & 0xf); - - /* Fam15h BKDG section 2.10.5.5.3 */ - if (pDCTstat->Status & (1 << SB_LoadReduced)) { - /* LRDIMM */ - - /* TODO - * Implement LRDIMM support - * See Fam15h BKDG Rev. 3.14 section 2.10.5.5 - */ - twrrd = 0xb; - } else { - max_cdd_we_delta = (((int16_t)cdd_twrrd + 1 - ((int16_t)write_early * 2)) + 1) / 2; - if (max_cdd_we_delta < 0) - max_cdd_we_delta = 0; - if (((uint16_t)max_cdd_we_delta) > write_odt_delay) - dword = max_cdd_we_delta; - else - dword = write_odt_delay; - dword += 3; - if (latency_difference < dword) { - dword -= latency_difference; - if (dword < 1) - twrrd = 1; - else - twrrd = dword; - } else { - twrrd = 1; - } - } - - /* Calculate the Critical Delay Difference for TrwtTO */ - cdd_trwtto = 0; - for (receiver = 0; receiver < 8; receiver += 2) { - dimm = (receiver >> 1); - - if (!mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, dct, receiver)) - continue; - - read_dqs_receiver_enable_control_registers(current_total_delay_1, dev, dct, dimm, index_reg); - read_dqs_write_timing_control_registers(current_total_delay_2, dev, dct, dimm, index_reg); - - for (lane = 0; lane < lane_count; lane++) { - if (current_total_delay_1[lane] > current_total_delay_2[lane]) - difference = current_total_delay_1[lane] - current_total_delay_2[lane]; - else - difference = current_total_delay_2[lane] - current_total_delay_1[lane]; - - if (difference > cdd_trwtto) - cdd_trwtto = difference; - } - } - - /* Convert the difference to MEMCLKs */ - cdd_trwtto = (((cdd_trwtto + (1 << 6) - 1) >> 6) & 0xf); - - /* Fam15h BKDG section 2.10.5.5.4 */ - if (max_dimms_installable == 1) - min_value = 0; - else - min_value = read_odt_delay + buffer_data_delay; - cdd_trwtto_we_delta = (((int16_t)cdd_trwtto - 1 + ((int16_t)write_early * 2)) + 1) / 2; - cdd_trwtto_we_delta += latency_difference + 3; - if (cdd_trwtto_we_delta < 0) - cdd_trwtto_we_delta = 0; - if ((cdd_trwtto_we_delta) > min_value) - trwtto = cdd_trwtto_we_delta; - else - trwtto = min_value; - - dword = Get_NB32_DCT(dev, dct, 0xa4); /* DRAM Controller Temperature Throttle */ - dword &= ~(0x1 << 11); /* BwCapEn = 0 */ - dword &= ~(0x1 << 8); /* ODTSEn = dimm_event_l_pin_support */ - dword |= (dimm_event_l_pin_support & 0x1) << 8; - Set_NB32_DCT(dev, dct, 0xa4, dword); /* DRAM Controller Temperature Throttle */ - - dword = Get_NB32_DCT(dev, dct, 0x110); /* DRAM Controller Select Low */ - dword &= ~(0x1 << 2); /* DctSelIntLvEn = interleave_channels */ - dword |= (interleave_channels & 0x1) << 2; - dword |= (0x3 << 6); /* DctSelIntLvAddr = 0x3 */ - Set_NB32_DCT(dev, dct, 0x110, dword); /* DRAM Controller Select Low */ - - /* NOTE - * ECC-related setup is performed as part of ECCInit_D and must not be located here, - * otherwise semi-random lockups will occur due to misconfigured scrubbing hardware! - */ - - /* Fam15h BKDG section 2.10.5.5.2 */ - dword = Get_NB32_DCT(dev, dct, 0x214); /* DRAM Timing 4 */ - dword &= ~(0xf << 16); /* TwrwrSdSc = 0x1 */ - dword |= (0x1 << 16); - dword &= ~(0xf << 8); /* TwrwrSdDc = twrwrsddc */ - dword |= ((twrwrsddc & 0xf) << 8); - dword &= ~(0xf); /* TwrwrDd = twrwrdd */ - dword |= (twrwrdd & 0xf); - Set_NB32_DCT(dev, dct, 0x214, dword); /* DRAM Timing 4 */ - - /* Fam15h BKDG section 2.10.5.5.3 */ - dword = Get_NB32_DCT(dev, dct, 0x218); /* DRAM Timing 5 */ - dword &= ~(0xf << 24); /* TrdrdSdSc = 0x1 */ - dword |= (0x1 << 24); - dword &= ~(0xf << 16); /* TrdrdSdDc = trdrdsddc */ - dword |= ((trdrdsddc & 0xf) << 16); - dword &= ~(0xf << 8); /* Twrrd = twrrd */ - dword |= ((twrrd & 0xf) << 8); - dword &= ~(0xf); /* TrdrdDd = trdrddd */ - dword |= (trdrddd & 0xf); - Set_NB32_DCT(dev, dct, 0x218, dword); /* DRAM Timing 5 */ - - /* Fam15h BKDG section 2.10.5.5.4 */ - dword = Get_NB32_DCT(dev, dct, 0x21c); /* DRAM Timing 6 */ - dword &= ~(0x1f << 8); /* TrwtTO = trwtto */ - dword |= ((trwtto & 0x1f) << 8); - dword &= ~(0x1f << 16); /* TrwtWB = TrwtTO + 1 */ - dword |= ((((dword >> 8) & 0x1f) + 1) << 16); - Set_NB32_DCT(dev, dct, 0x21c, dword); /* DRAM Timing 6 */ - - /* Enable prefetchers */ - dword = Get_NB32(dev, 0x11c); /* Memory Controller Configuration High */ - dword &= ~(0x1 << 13); /* PrefIoDis = 0 */ - dword &= ~(0x1 << 12); /* PrefCpuDis = 0 */ - Set_NB32(dev, 0x11c, dword); /* Memory Controller Configuration High */ - } -} - -static void exit_training_mode_fam15(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - uint8_t node; - uint8_t dct; - - for (node = 0; node < MAX_NODES_SUPPORTED; node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + node; - - if (pDCTstat->NodePresent) - for (dct = 0; dct < 2; dct++) - fam15EnableTrainingMode(pMCTstat, pDCTstat, dct, 0); - } -} - -static void DQSTiming_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA, uint8_t allow_config_restore) -{ - uint8_t Node; - u8 nv_DQSTrainCTL; - uint8_t retry_requested; - - if (pMCTstat->GStatus & (1 << GSB_EnDIMMSpareNW)) { - return; - } - - /* Set initial TCWL offset to zero */ - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - uint8_t dct; - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - for (dct = 0; dct < 2; dct++) - pDCTstat->tcwl_delay[dct] = 0; - } - -retry_dqs_training_and_levelization: - nv_DQSTrainCTL = !allow_config_restore; - - mct_BeforeDQSTrain_D(pMCTstat, pDCTstatA); - phyAssistedMemFnceTraining(pMCTstat, pDCTstatA, -1); - - if (is_fam15h()) { - struct DCTStatStruc *pDCTstat; - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - pDCTstat = pDCTstatA + Node; - if (pDCTstat->NodePresent) { - if (pDCTstat->DIMMValidDCT[0]) - InitPhyCompensation(pMCTstat, pDCTstat, 0); - if (pDCTstat->DIMMValidDCT[1]) - InitPhyCompensation(pMCTstat, pDCTstat, 1); - } - } - } - - mctHookBeforeAnyTraining(pMCTstat, pDCTstatA); - if (!is_fam15h()) { - /* TODO: should be in mctHookBeforeAnyTraining */ - _WRMSR(MTRR_FIX_4K_E0000, 0x04040404, 0x04040404); - _WRMSR(MTRR_FIX_4K_E8000, 0x04040404, 0x04040404); - _WRMSR(MTRR_FIX_4K_F0000, 0x04040404, 0x04040404); - _WRMSR(MTRR_FIX_4K_F8000, 0x04040404, 0x04040404); - } - - if (nv_DQSTrainCTL) { - mct_WriteLevelization_HW(pMCTstat, pDCTstatA, FirstPass); - - if (is_fam15h()) { - /* Receiver Enable Training Pass 1 */ - TrainReceiverEn_D(pMCTstat, pDCTstatA, FirstPass); - } - - mct_WriteLevelization_HW(pMCTstat, pDCTstatA, SecondPass); - - if (is_fam15h()) { - - /* TODO: - * Determine why running TrainReceiverEn_D in SecondPass - * mode yields less stable training values than when run - * in FirstPass mode as in the HACK below. - */ - TrainReceiverEn_D(pMCTstat, pDCTstatA, FirstPass); - } else { - TrainReceiverEn_D(pMCTstat, pDCTstatA, FirstPass); - } - - mct_TrainDQSPos_D(pMCTstat, pDCTstatA); - - /* Determine if DQS training requested a retrain attempt */ - retry_requested = 0; - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - - if (pDCTstat->NodePresent) { - if (pDCTstat->TrainErrors & (1 << SB_FatalError)) { - printk(BIOS_ERR, "DIMM training FAILED! Restarting system..."); - soft_reset(); - } - if (pDCTstat->TrainErrors & (1 << SB_RetryConfigTrain)) { - retry_requested = 1; - - /* Clear previous errors */ - pDCTstat->TrainErrors &= ~(1 << SB_RetryConfigTrain); - pDCTstat->TrainErrors &= ~(1 << SB_NODQSPOS); - pDCTstat->ErrStatus &= ~(1 << SB_RetryConfigTrain); - pDCTstat->ErrStatus &= ~(1 << SB_NODQSPOS); - } - } - } - - /* Retry training and levelization if requested */ - if (retry_requested) { - printk(BIOS_DEBUG, "%s: Restarting training on algorithm request\n", __func__); - /* Reset frequency to minimum */ - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - if (pDCTstat->NodePresent) { - uint8_t original_target_freq = pDCTstat->TargetFreq; - uint8_t original_auto_speed = pDCTstat->DIMMAutoSpeed; - pDCTstat->TargetFreq = mhz_to_memclk_config(mctGet_NVbits(NV_MIN_MEMCLK)); - pDCTstat->Speed = pDCTstat->DIMMAutoSpeed = pDCTstat->TargetFreq; - SetTargetFreq(pMCTstat, pDCTstatA, Node); - pDCTstat->TargetFreq = original_target_freq; - pDCTstat->DIMMAutoSpeed = original_auto_speed; - } - } - /* Apply any DIMM timing changes */ - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - if (pDCTstat->NodePresent) { - AutoCycTiming_D(pMCTstat, pDCTstat, 0); - if (!pDCTstat->GangedMode) - if (pDCTstat->DIMMValidDCT[1] > 0) - AutoCycTiming_D(pMCTstat, pDCTstat, 1); - } - } - goto retry_dqs_training_and_levelization; - } - - TrainMaxRdLatency_En_D(pMCTstat, pDCTstatA); - - if (is_fam15h()) - exit_training_mode_fam15(pMCTstat, pDCTstatA); - else - mctSetEccDQSRcvrEn_D(pMCTstat, pDCTstatA); - } else { - mct_WriteLevelization_HW(pMCTstat, pDCTstatA, FirstPass); - - mct_WriteLevelization_HW(pMCTstat, pDCTstatA, SecondPass); - -#if CONFIG(HAVE_ACPI_RESUME) - printk(BIOS_DEBUG, "mctAutoInitMCT_D: Restoring DIMM training configuration from NVRAM\n"); - if (restore_mct_information_from_nvram(1) != 0) - printk(BIOS_CRIT, "%s: ERROR: Unable to restore DCT configuration from NVRAM\n", __func__); -#endif - - if (is_fam15h()) - exit_training_mode_fam15(pMCTstat, pDCTstatA); - - pMCTstat->GStatus |= 1 << GSB_ConfigRestored; - } - - if (is_fam15h()) { - struct DCTStatStruc *pDCTstat; - - /* Switch DCT control register to DCT 0 per Erratum 505 */ - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - pDCTstat = pDCTstatA + Node; - if (pDCTstat->NodePresent) { - fam15h_switch_dct(pDCTstat->dev_map, 0); - } - } - } - - /* FIXME - currently uses calculated value TrainMaxReadLatency_D(pMCTstat, pDCTstatA); */ - mctHookAfterAnyTraining(); -} - -static void LoadDQSSigTmgRegs_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - u8 Node, Receiver, Channel, Dir, DIMM; - u32 dev; - u32 index_reg; - u32 reg; - u32 index; - u32 val; - u8 ByteLane; - u8 txdqs; - - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - - if (pDCTstat->DCTSysLimit) { - dev = pDCTstat->dev_dct; - for (Channel = 0;Channel < 2; Channel++) { - /* there are four receiver pairs, - loosely associated with chipselects.*/ - index_reg = 0x98; - for (Receiver = 0; Receiver < 8; Receiver += 2) { - /* Set Receiver Enable Values */ - mct_SetRcvrEnDly_D(pDCTstat, - 0, /* RcvrEnDly */ - 1, /* FinalValue, From stack */ - Channel, - Receiver, - dev, index_reg, - (Receiver >> 1) * 3 + 0x10, /* Addl_Index */ - 2); /* Pass Second Pass ? */ - /* Restore Write levelization training data */ - for (ByteLane = 0; ByteLane < 9; ByteLane ++) { - txdqs = pDCTstat->persistentData.CH_D_B_TxDqs[Channel][Receiver >> 1][ByteLane]; - index = Table_DQSRcvEn_Offset[ByteLane >> 1]; - index += (Receiver >> 1) * 3 + 0x10 + 0x20; /* Addl_Index */ - val = Get_NB32_index_wait_DCT(dev, Channel, 0x98, index); - if (ByteLane & 1) { /* odd byte lane */ - val &= ~(0xFF << 16); - val |= txdqs << 16; - } else { - val &= ~0xFF; - val |= txdqs; - } - Set_NB32_index_wait_DCT(dev, Channel, 0x98, index, val); - } - } - } - for (Channel = 0; Channel < 2; Channel++) { - SetEccDQSRcvrEn_D(pDCTstat, Channel); - } - - for (Channel = 0; Channel < 2; Channel++) { - u8 *p; - index_reg = 0x98; - - /* NOTE: - * when 400, 533, 667, it will support dimm0/1/2/3, - * and set conf for dimm0, hw will copy to dimm1/2/3 - * set for dimm1, hw will copy to dimm3 - * Rev A/B only support DIMM0/1 when 800MHz and above - * + 0x100 to next dimm - * Rev C support DIMM0/1/2/3 when 800MHz and above - * + 0x100 to next dimm - */ - for (DIMM = 0; DIMM < 4; DIMM++) { - if (DIMM == 0) { - index = 0; /* CHA Write Data Timing Low */ - } else { - if (pDCTstat->Speed >= mhz_to_memclk_config(mctGet_NVbits(NV_MIN_MEMCLK))) { - index = 0x100 * DIMM; - } else { - break; - } - } - for (Dir = 0; Dir < 2; Dir++) {/* RD/WR */ - p = pDCTstat->CH_D_DIR_B_DQS[Channel][DIMM][Dir]; - val = stream_to_int(p); /* CHA Read Data Timing High */ - Set_NB32_index_wait_DCT(dev, Channel, index_reg, index+1, val); - val = stream_to_int(p+4); /* CHA Write Data Timing High */ - Set_NB32_index_wait_DCT(dev, Channel, index_reg, index+2, val); - val = *(p+8); /* CHA Write ECC Timing */ - Set_NB32_index_wait_DCT(dev, Channel, index_reg, index+3, val); - index += 4; - } - } - } - - for (Channel = 0; Channel < 2; Channel++) { - reg = 0x78; - val = Get_NB32_DCT(dev, Channel, reg); - val &= ~(0x3ff<<22); - val |= ((u32) pDCTstat->CH_MaxRdLat[Channel][0] << 22); - val &= ~(1<<DqsRcvEnTrain); - Set_NB32_DCT(dev, Channel, reg, val); /* program MaxRdLatency to correspond with current delay*/ - } - } - } -} - -static void HTMemMapInit_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - u8 Node; - u32 NextBase, BottomIO; - u8 _MemHoleRemap, DramHoleBase; - u32 HoleSize, DramSelBaseAddr; - - u32 val; - u32 base; - u32 limit; - u32 dev, devx; - struct DCTStatStruc *pDCTstat; - - _MemHoleRemap = mctGet_NVbits(NV_MemHole); - - if (pMCTstat->HoleBase == 0) { - DramHoleBase = mctGet_NVbits(NV_BottomIO); - } else { - DramHoleBase = pMCTstat->HoleBase >> (24-8); - } - - BottomIO = DramHoleBase << (24-8); - - NextBase = 0; - pDCTstat = pDCTstatA + 0; - dev = pDCTstat->dev_map; - - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - pDCTstat = pDCTstatA + Node; - devx = pDCTstat->dev_map; - DramSelBaseAddr = 0; - if (!pDCTstat->GangedMode) { - DramSelBaseAddr = pDCTstat->NodeSysLimit - pDCTstat->DCTSysLimit; - /*In unganged mode, we must add DCT0 and DCT1 to DCTSysLimit */ - val = pDCTstat->NodeSysLimit; - if ((val & 0xFF) == 0xFE) { - DramSelBaseAddr++; - val++; - } - pDCTstat->DCTSysLimit = val; - } - - base = pDCTstat->DCTSysBase; - limit = pDCTstat->DCTSysLimit; - if (limit > base) { - base += NextBase; - limit += NextBase; - DramSelBaseAddr += NextBase; - printk(BIOS_DEBUG, " Node: %02x base: %02x limit: %02x BottomIO: %02x\n", Node, base, limit, BottomIO); - - if (_MemHoleRemap) { - if ((base < BottomIO) && (limit >= BottomIO)) { - /* HW Dram Remap */ - pDCTstat->Status |= 1 << SB_HWHole; - pMCTstat->GStatus |= 1 << GSB_HWHole; - pDCTstat->DCTSysBase = base; - pDCTstat->DCTSysLimit = limit; - pDCTstat->DCTHoleBase = BottomIO; - pMCTstat->HoleBase = BottomIO; - HoleSize = _4GB_RJ8 - BottomIO; /* HoleSize[39:8] */ - if ((DramSelBaseAddr > 0) && (DramSelBaseAddr < BottomIO)) - base = DramSelBaseAddr; - val = ((base + HoleSize) >> (24-8)) & 0xFF; - val <<= 8; /* shl 16, rol 24 */ - val |= DramHoleBase << 24; - val |= 1 << DramHoleValid; - Set_NB32(devx, 0xF0, val); /* Dram Hole Address Reg */ - pDCTstat->DCTSysLimit += HoleSize; - base = pDCTstat->DCTSysBase; - limit = pDCTstat->DCTSysLimit; - } else if (base == BottomIO) { - /* SW Node Hoist */ - pMCTstat->GStatus |= 1<<GSB_SpIntRemapHole; - pDCTstat->Status |= 1<<SB_SWNodeHole; - pMCTstat->GStatus |= 1<<GSB_SoftHole; - pMCTstat->HoleBase = base; - limit -= base; - base = _4GB_RJ8; - limit += base; - pDCTstat->DCTSysBase = base; - pDCTstat->DCTSysLimit = limit; - } else { - /* No Remapping. Normal Contiguous mapping */ - pDCTstat->DCTSysBase = base; - pDCTstat->DCTSysLimit = limit; - } - } else { - /*No Remapping. Normal Contiguous mapping*/ - pDCTstat->DCTSysBase = base; - pDCTstat->DCTSysLimit = limit; - } - base |= 3; /* set WE,RE fields*/ - pMCTstat->SysLimit = limit; - } - Set_NB32(dev, 0x40 + (Node << 3), base); /* [Node] + Dram Base 0 */ - - val = limit & 0xFFFF0000; - val |= Node; - Set_NB32(dev, 0x44 + (Node << 3), val); /* set DstNode */ - - printk(BIOS_DEBUG, " Node: %02x base: %02x limit: %02x\n", Node, base, limit); - limit = pDCTstat->DCTSysLimit; - if (limit) { - NextBase = (limit & 0xFFFF0000) + 0x10000; - } - } - - /* Copy dram map from Node 0 to Node 1-7 */ - for (Node = 1; Node < MAX_NODES_SUPPORTED; Node++) { - u32 reg; - pDCTstat = pDCTstatA + Node; - devx = pDCTstat->dev_map; - - if (pDCTstat->NodePresent) { - printk(BIOS_DEBUG, " Copy dram map from Node 0 to Node %02x\n", Node); - reg = 0x40; /*Dram Base 0*/ - do { - val = Get_NB32(dev, reg); - Set_NB32(devx, reg, val); - reg += 4; - } while (reg < 0x80); - } else { - break; /* stop at first absent Node */ - } - } - - /*Copy dram map to F1x120/124*/ - mct_HTMemMapExt(pMCTstat, pDCTstatA); -} - -void MCTMemClr_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - - /* Initiates a memory clear operation for all node. The mem clr - * is done in parallel. After the memclr is complete, all processors - * status are checked to ensure that memclr has completed. - */ - u8 Node; - uint32_t dword; - struct DCTStatStruc *pDCTstat; - - if (!mctGet_NVbits(NV_DQSTrainCTL)) { - /* FIXME: callback to wrapper: mctDoWarmResetMemClr_D */ - } else { /* NV_DQSTrainCTL == 1 */ - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - pDCTstat = pDCTstatA + Node; - - if (pDCTstat->NodePresent) { - DCTMemClr_Init_D(pMCTstat, pDCTstat); - } - } - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - pDCTstat = pDCTstatA + Node; - - if (pDCTstat->NodePresent) { - DCTMemClr_Sync_D(pMCTstat, pDCTstat); - } - } - } - - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - pDCTstat = pDCTstatA + Node; - - /* Enable prefetchers */ - dword = Get_NB32(pDCTstat->dev_dct, 0x11c); /* Memory Controller Configuration High */ - dword &= ~(0x1 << 13); /* PrefIoDis = 0 */ - dword &= ~(0x1 << 12); /* PrefCpuDis = 0 */ - Set_NB32(pDCTstat->dev_dct, 0x11c, dword); /* Memory Controller Configuration High */ - } -} - -void DCTMemClr_Init_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u32 val; - u32 dev; - uint32_t dword; - - /* Initiates a memory clear operation on one node */ - if (pDCTstat->DCTSysLimit) { - dev = pDCTstat->dev_dct; - - /* Disable prefetchers */ - dword = Get_NB32(dev, 0x11c); /* Memory Controller Configuration High */ - dword |= 0x1 << 13; /* PrefIoDis = 1 */ - dword |= 0x1 << 12; /* PrefCpuDis = 1 */ - Set_NB32(dev, 0x11c, dword); /* Memory Controller Configuration High */ - - do { - val = Get_NB32(dev, 0x110); - } while (val & (1 << MemClrBusy)); - - val |= (1 << MemClrInit); - Set_NB32(dev, 0x110, val); - } -} - -void DCTMemClr_Sync_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - uint32_t dword; - uint32_t dev = pDCTstat->dev_dct; - - printk(BIOS_DEBUG, "%s: Start\n", __func__); - - /* Ensure that a memory clear operation has completed on one node */ - if (pDCTstat->DCTSysLimit) { - printk(BIOS_DEBUG, "%s: Waiting for memory clear to complete", __func__); - do { - dword = Get_NB32(dev, 0x110); - - printk(BIOS_DEBUG, "."); - } while (dword & (1 << MemClrBusy)); - - printk(BIOS_DEBUG, "\n"); - do { - printk(BIOS_DEBUG, "."); - dword = Get_NB32(dev, 0x110); - } while (!(dword & (1 << Dr_MemClrStatus))); - printk(BIOS_DEBUG, "\n"); - } - - /* Enable prefetchers */ - dword = Get_NB32(dev, 0x11c); /* Memory Controller Configuration High */ - dword &= ~(0x1 << 13); /* PrefIoDis = 0 */ - dword &= ~(0x1 << 12); /* PrefCpuDis = 0 */ - Set_NB32(dev, 0x11c, dword); /* Memory Controller Configuration High */ - - printk(BIOS_DEBUG, "%s: Done\n", __func__); -} - -u8 NodePresent_D(u8 Node) -{ - /* - * Determine if a single Hammer Node exists within the network. - */ - u32 dev; - u32 val; - u32 dword; - u8 ret = 0; - - dev = PA_HOST(Node); /*test device/vendor id at host bridge */ - val = Get_NB32(dev, 0); - dword = mct_NodePresent_D(); /* FIXME: BOZO -11001022h rev for F */ - if (val == dword) { /* AMD Hammer Family CPU HT Configuration */ - if (oemNodePresent_D(Node, &ret)) - goto finish; - /* Node ID register */ - val = Get_NB32(dev, 0x60); - val &= 0x07; - dword = Node; - if (val == dword) /* current nodeID = requested nodeID ? */ - ret = 1; - } -finish: - return ret; -} - -static void DCTPreInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct) -{ - /* - * Run DCT pre-initialization tasks - */ - uint32_t dword; - - /* Reset DCT registers */ - ClearDCT_D(pMCTstat, pDCTstat, dct); - pDCTstat->stopDCT[dct] = 1; /* preload flag with 'disable' */ - - if (!is_fam15h()) { - /* Enable DDR3 support */ - dword = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x94); - dword |= 1 << Ddr3Mode; - Set_NB32_DCT(pDCTstat->dev_dct, dct, 0x94, dword); - } - - /* Read the SPD information into the data structures */ - if (mct_DIMMPresence(pMCTstat, pDCTstat, dct) < SC_StopError) { - printk(BIOS_DEBUG, "\t\tDCTPreInit_D: mct_DIMMPresence Done\n"); - } -} - -static void DCTInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct) -{ - /* - * Initialize DRAM on single Athlon 64/Opteron Node. - */ - uint32_t dword; - - if (!is_fam15h()) { - /* (Re)-enable DDR3 support */ - dword = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x94); - dword |= 1 << Ddr3Mode; - Set_NB32_DCT(pDCTstat->dev_dct, dct, 0x94, dword); - } - - if (mct_SPDCalcWidth(pMCTstat, pDCTstat, dct) < SC_StopError) { - printk(BIOS_DEBUG, "\t\tDCTInit_D: mct_SPDCalcWidth Done\n"); - if (AutoCycTiming_D(pMCTstat, pDCTstat, dct) < SC_StopError) { - printk(BIOS_DEBUG, "\t\tDCTInit_D: AutoCycTiming_D Done\n"); - - /* SkewMemClk must be set before MemClkFreqVal is set - * This relies on DCTInit_D being called for DCT 1 after - * it has already been called for DCT 0... - */ - if (is_fam15h()) { - /* Set memory clock skew if needed */ - if (dct == 1) { - if (!pDCTstat->stopDCT[0]) { - printk(BIOS_DEBUG, "\t\tDCTInit_D: enabling intra-channel clock skew\n"); - dword = Get_NB32_index_wait_DCT(pDCTstat->dev_dct, 0, 0x98, 0x0d0fe00a); - dword |= (0x1 << 4); /* SkewMemClk = 1 */ - Set_NB32_index_wait_DCT(pDCTstat->dev_dct, 0, 0x98, 0x0d0fe00a, dword); - } - } - } - - if (AutoConfig_D(pMCTstat, pDCTstat, dct) < SC_StopError) { - printk(BIOS_DEBUG, "\t\tDCTInit_D: AutoConfig_D Done\n"); - if (PlatformSpec_D(pMCTstat, pDCTstat, dct) < SC_StopError) { - printk(BIOS_DEBUG, "\t\tDCTInit_D: PlatformSpec_D Done\n"); - pDCTstat->stopDCT[dct] = 0; - } - } - } - } -} - -static void DCTFinalInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct) -{ - uint32_t dword; - - /* Finalize DRAM init on a single node */ - if (!pDCTstat->stopDCT[dct]) { - if (!(pMCTstat->GStatus & (1 << GSB_EnDIMMSpareNW))) { - printk(BIOS_DEBUG, "\t\tDCTFinalInit_D: StartupDCT_D Start\n"); - StartupDCT_D(pMCTstat, pDCTstat, dct); - printk(BIOS_DEBUG, "\t\tDCTFinalInit_D: StartupDCT_D Done\n"); - } - } - - if (pDCTstat->stopDCT[dct]) { - dword = 1 << DisDramInterface; - Set_NB32_DCT(pDCTstat->dev_dct, dct, 0x94, dword); - - dword = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x90); - dword &= ~(1 << ParEn); - Set_NB32_DCT(pDCTstat->dev_dct, dct, 0x90, dword); - - /* To maximize power savings when DisDramInterface = 1b, - * all of the MemClkDis bits should also be set. - */ - Set_NB32_DCT(pDCTstat->dev_dct, dct, 0x88, 0xff000000); - } else { - mct_EnDllShutdownSR(pMCTstat, pDCTstat, dct); - } -} - -static void SyncDCTsReady_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - /* Wait (and block further access to dram) for all DCTs to be ready, - * by polling all InitDram bits and waiting for possible memory clear - * operations to be complete. Read MemClkFreqVal bit to see if - * the DIMMs are present in this node. - */ - u8 Node; - u32 val; - - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - mct_SyncDCTsReady(pDCTstat); - } - - if (!is_fam15h()) { - /* v6.1.3 */ - /* re-enable phy compensation engine when dram init is completed on all nodes. */ - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - if (pDCTstat->NodePresent) { - if (pDCTstat->DIMMValidDCT[0] > 0 || pDCTstat->DIMMValidDCT[1] > 0) { - /* re-enable phy compensation engine when dram init on both DCTs is completed. */ - val = Get_NB32_index_wait(pDCTstat->dev_dct, 0x98, 0x8); - val &= ~(1 << DisAutoComp); - Set_NB32_index_wait(pDCTstat->dev_dct, 0x98, 0x8, val); - } - } - } - } - - /* wait 750us before any memory access can be made. */ - mct_Wait(15000); -} - -void StartupDCT_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - /* Read MemClkFreqVal bit to see if the DIMMs are present in this node. - * If the DIMMs are present then set the DRAM Enable bit for this node. - * - * Setting dram init starts up the DCT state machine, initializes the - * dram devices with MRS commands, and kicks off any - * HW memory clear process that the chip is capable of. The sooner - * that dram init is set for all nodes, the faster the memory system - * initialization can complete. Thus, the init loop is unrolled into - * two loops so as to start the processes for non BSP nodes sooner. - * This procedure will not wait for the process to finish. - * Synchronization is handled elsewhere. - */ - u32 val; - u32 dev; - - dev = pDCTstat->dev_dct; - val = Get_NB32_DCT(dev, dct, 0x94); - if (val & (1<<MemClkFreqVal)) { - mctHookBeforeDramInit(); /* generalized Hook */ - if (!(pMCTstat->GStatus & (1 << GSB_EnDIMMSpareNW))) - mct_DramInit(pMCTstat, pDCTstat, dct); - AfterDramInit_D(pDCTstat, dct); - mctHookAfterDramInit(); /* generalized Hook*/ - } -} - -static void ClearDCT_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u32 reg_end; - u32 dev = pDCTstat->dev_dct; - u32 reg = 0x40; - u32 val = 0; - - if (pMCTstat->GStatus & (1 << GSB_EnDIMMSpareNW)) { - reg_end = 0x78; - } else { - reg_end = 0xA4; - } - - while (reg < reg_end) { - if ((reg & 0xFF) == 0x84) { - if (is_fam15h()) { - val = Get_NB32_DCT(dev, dct, reg); - val &= ~(0x1 << 23); /* Clear PchgPDModeSel */ - val &= ~0x3; /* Clear BurstCtrl */ - } - } - if ((reg & 0xFF) == 0x90) { - if (pDCTstat->LogicalCPUID & AMD_DR_Dx) { - val = Get_NB32_DCT(dev, dct, reg); /* get DRAMConfigLow */ - val |= 0x08000000; /* preserve value of DisDllShutdownSR for only Rev.D */ - } - } - Set_NB32_DCT(dev, dct, reg, val); - val = 0; - reg += 4; - } - - val = 0; - dev = pDCTstat->dev_map; - reg = 0xF0; - Set_NB32(dev, reg, val); -} - -void SPD2ndTiming(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u8 i; - u16 Twr, Trtp; - u16 Trp, Trrd, Trcd, Tras, Trc; - u8 Trfc[4]; - u16 Tfaw; - u16 Tcwl; /* Fam15h only */ - u32 DramTimingLo, DramTimingHi; - u8 tCK16x; - u16 Twtr; - uint8_t Etr[2]; - u8 LDIMM; - u8 MTB16x; - u8 byte; - u32 dword; - u32 dev; - u32 val; - - printk(BIOS_DEBUG, "%s: Start\n", __func__); - - /* Gather all DIMM mini-max values for cycle timing data */ - Trp = 0; - Trrd = 0; - Trcd = 0; - Trtp = 0; - Tras = 0; - Trc = 0; - Twr = 0; - Twtr = 0; - for (i = 0; i < 2; i++) - Etr[i] = 0; - for (i = 0; i < 4; i++) - Trfc[i] = 0; - Tfaw = 0; - - for (i = 0; i< MAX_DIMMS_SUPPORTED; i++) { - LDIMM = i >> 1; - if (pDCTstat->DIMMValid & (1 << i)) { - val = pDCTstat->spd_data.spd_bytes[dct + i][SPD_MTBDivisor]; /* MTB = Dividend/Divisor */ - MTB16x = ((pDCTstat->spd_data.spd_bytes[dct + i][SPD_MTBDividend] & 0xff) << 4); - MTB16x /= val; /* transfer to MTB*16 */ - - byte = pDCTstat->spd_data.spd_bytes[dct + i][SPD_tRPmin]; - val = byte * MTB16x; - if (Trp < val) - Trp = val; - - byte = pDCTstat->spd_data.spd_bytes[dct + i][SPD_tRRDmin]; - val = byte * MTB16x; - if (Trrd < val) - Trrd = val; - - byte = pDCTstat->spd_data.spd_bytes[dct + i][SPD_tRCDmin]; - val = byte * MTB16x; - if (Trcd < val) - Trcd = val; - - byte = pDCTstat->spd_data.spd_bytes[dct + i][SPD_tRTPmin]; - val = byte * MTB16x; - if (Trtp < val) - Trtp = val; - - byte = pDCTstat->spd_data.spd_bytes[dct + i][SPD_tWRmin]; - val = byte * MTB16x; - if (Twr < val) - Twr = val; - - byte = pDCTstat->spd_data.spd_bytes[dct + i][SPD_tWTRmin]; - val = byte * MTB16x; - if (Twtr < val) - Twtr = val; - - val = pDCTstat->spd_data.spd_bytes[dct + i][SPD_Upper_tRAS_tRC] & 0xff; - val >>= 4; - val <<= 8; - val |= pDCTstat->spd_data.spd_bytes[dct + i][SPD_tRCmin] & 0xff; - val *= MTB16x; - if (Trc < val) - Trc = val; - - byte = pDCTstat->spd_data.spd_bytes[dct + i][SPD_Density] & 0xf; - if (Trfc[LDIMM] < byte) - Trfc[LDIMM] = byte; - - val = pDCTstat->spd_data.spd_bytes[dct + i][SPD_Upper_tRAS_tRC] & 0xf; - val <<= 8; - val |= (pDCTstat->spd_data.spd_bytes[dct + i][SPD_tRASmin] & 0xff); - val *= MTB16x; - if (Tras < val) - Tras = val; - - val = pDCTstat->spd_data.spd_bytes[dct + i][SPD_Upper_tFAW] & 0xf; - val <<= 8; - val |= pDCTstat->spd_data.spd_bytes[dct + i][SPD_tFAWmin] & 0xff; - val *= MTB16x; - if (Tfaw < val) - Tfaw = val; - - /* Determine if the DIMMs on this channel support 95°C ETR */ - if (pDCTstat->spd_data.spd_bytes[dct + i][SPD_Thermal] & 0x1) - Etr[dct] = 1; - } /* Dimm Present */ - } - - /* Convert DRAM CycleTiming values and store into DCT structure */ - byte = pDCTstat->DIMMAutoSpeed; - if (is_fam15h()) { - if (byte == 0x16) - tCK16x = 17; - else if (byte == 0x12) - tCK16x = 20; - else if (byte == 0xe) - tCK16x = 24; - else if (byte == 0xa) - tCK16x = 30; - else if (byte == 0x6) - tCK16x = 40; - else - tCK16x = 48; - } else { - if (byte == 7) - tCK16x = 20; - else if (byte == 6) - tCK16x = 24; - else if (byte == 5) - tCK16x = 30; - else - tCK16x = 40; - } - - /* Notes: - 1. All secondary time values given in SPDs are in binary with units of ns. - 2. Some time values are scaled by 16, in order to have least count of 0.25 ns - (more accuracy). JEDEC SPD spec. shows which ones are x1 and x4. - 3. Internally to this SW, cycle time, tCK16x, is scaled by 16 to match time values - */ - - /* Tras */ - pDCTstat->DIMMTras = (u16)Tras; - val = Tras / tCK16x; - if (Tras % tCK16x) { /* round up number of busclocks */ - val++; - } - if (val < Min_TrasT) - val = Min_TrasT; - else if (val > Max_TrasT) - val = Max_TrasT; - pDCTstat->Tras = val; - - /* Trp */ - pDCTstat->DIMMTrp = Trp; - val = Trp / tCK16x; - if (Trp % tCK16x) { /* round up number of busclocks */ - val++; - } - if (val < Min_TrpT) - val = Min_TrpT; - else if (val > Max_TrpT) - val = Max_TrpT; - pDCTstat->Trp = val; - - /* Trrd */ - pDCTstat->DIMMTrrd = Trrd; - val = Trrd / tCK16x; - if (Trrd % tCK16x) { /* round up number of busclocks */ - val++; - } - if (val < Min_TrrdT) - val = Min_TrrdT; - else if (val > Max_TrrdT) - val = Max_TrrdT; - pDCTstat->Trrd = val; - - /* Trcd */ - pDCTstat->DIMMTrcd = Trcd; - val = Trcd / tCK16x; - if (Trcd % tCK16x) { /* round up number of busclocks */ - val++; - } - if (val < Min_TrcdT) - val = Min_TrcdT; - else if (val > Max_TrcdT) - val = Max_TrcdT; - pDCTstat->Trcd = val; - - /* Trc */ - pDCTstat->DIMMTrc = Trc; - val = Trc / tCK16x; - if (Trc % tCK16x) { /* round up number of busclocks */ - val++; - } - if (val < Min_TrcT) - val = Min_TrcT; - else if (val > Max_TrcT) - val = Max_TrcT; - pDCTstat->Trc = val; - - /* Trtp */ - pDCTstat->DIMMTrtp = Trtp; - val = Trtp / tCK16x; - if (Trtp % tCK16x) { - val ++; - } - if (val < Min_TrtpT) - val = Min_TrtpT; - else if (val > Max_TrtpT) - val = Max_TrtpT; - pDCTstat->Trtp = val; - - /* Twr */ - pDCTstat->DIMMTwr = Twr; - val = Twr / tCK16x; - if (Twr % tCK16x) { /* round up number of busclocks */ - val++; - } - if (val < Min_TwrT) - val = Min_TwrT; - else if (val > Max_TwrT) - val = Max_TwrT; - pDCTstat->Twr = val; - - /* Twtr */ - pDCTstat->DIMMTwtr = Twtr; - val = Twtr / tCK16x; - if (Twtr % tCK16x) { /* round up number of busclocks */ - val++; - } - if (val < Min_TwtrT) - val = Min_TwtrT; - else if (val > Max_TwtrT) - val = Max_TwtrT; - pDCTstat->Twtr = val; - - /* Trfc0-Trfc3 */ - for (i = 0; i < 4; i++) - pDCTstat->Trfc[i] = Trfc[i]; - - /* Tfaw */ - pDCTstat->DIMMTfaw = Tfaw; - val = Tfaw / tCK16x; - if (Tfaw % tCK16x) { /* round up number of busclocks */ - val++; - } - if (val < Min_TfawT) - val = Min_TfawT; - else if (val > Max_TfawT) - val = Max_TfawT; - pDCTstat->Tfaw = val; - - mctAdjustAutoCycTmg_D(); - - if (is_fam15h()) { - /* Compute Tcwl (Fam15h BKDG v3.14 Table 203) */ - if (pDCTstat->Speed <= 0x6) - Tcwl = 0x5; - else if (pDCTstat->Speed == 0xa) - Tcwl = 0x6; - else if (pDCTstat->Speed == 0xe) - Tcwl = 0x7; - else if (pDCTstat->Speed == 0x12) - Tcwl = 0x8; - else if (pDCTstat->Speed == 0x16) - Tcwl = 0x9; - else - Tcwl = 0x5; /* Power-on default */ - - /* Apply offset */ - Tcwl += pDCTstat->tcwl_delay[dct]; - } - - /* Program DRAM Timing values */ - if (is_fam15h()) { - dev = pDCTstat->dev_dct; - - dword = Get_NB32_DCT(dev, dct, 0x8c); /* DRAM Timing High */ - if (Etr[dct]) - val = 3; /* Tref = 3.9us */ - else - val = 2; /* Tref = 7.8us */ - dword &= ~(0x3 << 16); - dword |= (val & 0x3) << 16; - Set_NB32_DCT(dev, dct, 0x8c, dword); /* DRAM Timing High */ - - dword = Get_NB32_DCT(dev, dct, 0x200); /* DRAM Timing 0 */ - dword &= ~(0x3f1f1f1f); - dword |= (pDCTstat->Tras & 0x3f) << 24; /* Tras */ - val = pDCTstat->Trp; - val = mct_AdjustSPDTimings(pMCTstat, pDCTstat, val); - dword |= (val & 0x1f) << 16; /* Trp */ - dword |= (pDCTstat->Trcd & 0x1f) << 8; /* Trcd */ - dword |= (pDCTstat->CASL & 0x1f); /* Tcl */ - Set_NB32_DCT(dev, dct, 0x200, dword); /* DRAM Timing 0 */ - - dword = Get_NB32_DCT(dev, dct, 0x204); /* DRAM Timing 1 */ - dword &= ~(0x0f3f0f3f); - dword |= (pDCTstat->Trtp & 0xf) << 24; /* Trtp */ - if (pDCTstat->Tfaw != 0) { - val = pDCTstat->Tfaw; - val = mct_AdjustSPDTimings(pMCTstat, pDCTstat, val); - if ((val > 0x5) && (val < 0x2b)) - dword |= (val & 0x3f) << 16; /* FourActWindow */ - } - dword |= (pDCTstat->Trrd & 0xf) << 8; /* Trrd */ - dword |= (pDCTstat->Trc & 0x3f); /* Trc */ - Set_NB32_DCT(dev, dct, 0x204, dword); /* DRAM Timing 1 */ - - /* Trfc0-Trfc3 */ - for (i = 0; i < 4; i++) - if (pDCTstat->Trfc[i] == 0x0) - pDCTstat->Trfc[i] = 0x1; - dword = Get_NB32_DCT(dev, dct, 0x208); /* DRAM Timing 2 */ - dword &= ~(0x07070707); - dword |= (pDCTstat->Trfc[3] & 0x7) << 24; /* Trfc3 */ - dword |= (pDCTstat->Trfc[2] & 0x7) << 16; /* Trfc2 */ - dword |= (pDCTstat->Trfc[1] & 0x7) << 8; /* Trfc1 */ - dword |= (pDCTstat->Trfc[0] & 0x7); /* Trfc0 */ - Set_NB32_DCT(dev, dct, 0x208, dword); /* DRAM Timing 2 */ - - dword = Get_NB32_DCT(dev, dct, 0x20c); /* DRAM Timing 3 */ - dword &= ~(0x00000f00); - dword |= (pDCTstat->Twtr & 0xf) << 8; /* Twtr */ - dword &= ~(0x0000001f); - dword |= (Tcwl & 0x1f); /* Tcwl */ - Set_NB32_DCT(dev, dct, 0x20c, dword); /* DRAM Timing 3 */ - - dword = Get_NB32_DCT(dev, dct, 0x22c); /* DRAM Timing 10 */ - dword &= ~(0x0000001f); - dword |= (pDCTstat->Twr & 0x1f); /* Twr */ - Set_NB32_DCT(dev, dct, 0x22c, dword); /* DRAM Timing 10 */ - - if (pDCTstat->Speed > mhz_to_memclk_config(mctGet_NVbits(NV_MIN_MEMCLK))) { - /* Enable phy-assisted training mode */ - fam15EnableTrainingMode(pMCTstat, pDCTstat, dct, 1); - } - - /* Other setup (not training specific) */ - dword = Get_NB32_DCT(dev, dct, 0x90); /* DRAM Configuration Low */ - dword &= ~(0x1 << 23); /* ForceAutoPchg = 0 */ - dword &= ~(0x1 << 20); /* DynPageCloseEn = 0 */ - Set_NB32_DCT(dev, dct, 0x90, dword); /* DRAM Configuration Low */ - - Set_NB32_DCT(dev, dct, 0x228, 0x14141414); /* DRAM Timing 9 */ - } else { - DramTimingLo = 0; /* Dram Timing Low init */ - val = pDCTstat->CASL - 4; /* pDCTstat.CASL to reg. definition */ - DramTimingLo |= val; - - val = pDCTstat->Trcd - Bias_TrcdT; - DramTimingLo |= val<<4; - - val = pDCTstat->Trp - Bias_TrpT; - val = mct_AdjustSPDTimings(pMCTstat, pDCTstat, val); - DramTimingLo |= val<<7; - - val = pDCTstat->Trtp - Bias_TrtpT; - DramTimingLo |= val<<10; - - val = pDCTstat->Tras - Bias_TrasT; - DramTimingLo |= val<<12; - - val = pDCTstat->Trc - Bias_TrcT; - DramTimingLo |= val<<16; - - val = pDCTstat->Trrd - Bias_TrrdT; - DramTimingLo |= val<<22; - - DramTimingHi = 0; /* Dram Timing High init */ - val = pDCTstat->Twtr - Bias_TwtrT; - DramTimingHi |= val<<8; - - val = 2; /* Tref = 7.8us */ - DramTimingHi |= val<<16; - - val = 0; - for (i = 4; i > 0; i--) { - val <<= 3; - val |= Trfc[i-1]; - } - DramTimingHi |= val << 20; - - dev = pDCTstat->dev_dct; - /* Twr */ - val = pDCTstat->Twr; - if (val == 10) - val = 9; - else if (val == 12) - val = 10; - val = mct_AdjustSPDTimings(pMCTstat, pDCTstat, val); - val -= Bias_TwrT; - val <<= 4; - dword = Get_NB32_DCT(dev, dct, 0x84); - dword &= ~0x70; - dword |= val; - Set_NB32_DCT(dev, dct, 0x84, dword); - - /* Tfaw */ - val = pDCTstat->Tfaw; - val = mct_AdjustSPDTimings(pMCTstat, pDCTstat, val); - val -= Bias_TfawT; - val >>= 1; - val <<= 28; - dword = Get_NB32_DCT(dev, dct, 0x94); - dword &= ~0xf0000000; - dword |= val; - Set_NB32_DCT(dev, dct, 0x94, dword); - - /* dev = pDCTstat->dev_dct; */ - - if (pDCTstat->Speed > mhz_to_memclk_config(mctGet_NVbits(NV_MIN_MEMCLK))) { - val = Get_NB32_DCT(dev, dct, 0x88); - val &= 0xFF000000; - DramTimingLo |= val; - } - Set_NB32_DCT(dev, dct, 0x88, DramTimingLo); /*DCT Timing Low*/ - - if (pDCTstat->Speed > mhz_to_memclk_config(mctGet_NVbits(NV_MIN_MEMCLK))) { - DramTimingHi |= 1 << DisAutoRefresh; - } - DramTimingHi |= 0x000018FF; - Set_NB32_DCT(dev, dct, 0x8c, DramTimingHi); /*DCT Timing Hi*/ - } - - /* dump_pci_device(PCI_DEV(0, 0x18+pDCTstat->Node_ID, 2)); */ - - printk(BIOS_DEBUG, "%s: Done\n", __func__); -} - -static u8 AutoCycTiming_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, uint8_t dct) -{ - /* Initialize DCT Timing registers as per DIMM SPD. - * For primary timing (T, CL) use best case T value. - * For secondary timing params., use most aggressive settings - * of slowest DIMM. - * - * There are three components to determining "maximum frequency": - * SPD component, Bus load component, and "Preset" max frequency - * component. - * - * The SPD component is a function of the min cycle time specified - * by each DIMM, and the interaction of cycle times from all DIMMs - * in conjunction with CAS latency. The SPD component only applies - * when user timing mode is 'Auto'. - * - * The Bus load component is a limiting factor determined by electrical - * characteristics on the bus as a result of varying number of device - * loads. The Bus load component is specific to each platform but may - * also be a function of other factors. The bus load component only - * applies when user timing mode is 'Auto'. - * - * The Preset component is subdivided into three items and is - * the minimum of the set: Silicon revision, user limit - * setting when user timing mode is 'Auto' and memclock mode - * is 'Limit', OEM build specification of the maximum - * frequency. The Preset component is only applies when user - * timing mode is 'Auto'. - */ - - printk(BIOS_DEBUG, "%s: Start\n", __func__); - - /* Get primary timing (CAS Latency and Cycle Time) */ - if (pDCTstat->Speed == 0) { - mctGet_MaxLoadFreq(pDCTstat); - - /* and Factor in presets (setup options, Si cap, etc.) */ - GetPresetmaxF_D(pMCTstat, pDCTstat); - - /* Go get best T and CL as specified by DIMM mfgs. and OEM */ - SPDGetTCL_D(pMCTstat, pDCTstat, dct); - - /* skip callback mctForce800to1067_D */ - pDCTstat->Speed = pDCTstat->DIMMAutoSpeed; - pDCTstat->CASL = pDCTstat->DIMMCASL; - - } - mct_AfterGetCLT(pMCTstat, pDCTstat, dct); - - SPD2ndTiming(pMCTstat, pDCTstat, dct); - - printk(BIOS_DEBUG, "AutoCycTiming: Status %x\n", pDCTstat->Status); - printk(BIOS_DEBUG, "AutoCycTiming: ErrStatus %x\n", pDCTstat->ErrStatus); - printk(BIOS_DEBUG, "AutoCycTiming: ErrCode %x\n", pDCTstat->ErrCode); - printk(BIOS_DEBUG, "AutoCycTiming: Done\n\n"); - - mctHookAfterAutoCycTmg(); - - return pDCTstat->ErrCode; -} - -static void GetPresetmaxF_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - /* Get max frequency from OEM platform definition, from any user - * override (limiting) of max frequency, and from any Si Revision - * Specific information. Return the least of these three in - * DCTStatStruc.PresetmaxFreq. - */ - /* TODO: Set the proper max frequency in wrappers/mcti_d.c. */ - u16 proposedFreq; - u16 word; - - printk(BIOS_DEBUG, "%s: Start\n", __func__); - - /* Get CPU Si Revision defined limit (NPT) */ - if (is_fam15h()) - proposedFreq = 933; - else - proposedFreq = 800; /* Rev F0 programmable max memclock is */ - - /*Get User defined limit if "limit" mode */ - if (mctGet_NVbits(NV_MCTUSRTMGMODE) == 1) { - word = Get_Fk_D(mctGet_NVbits(NV_MemCkVal) + 1); - if (word < proposedFreq) - proposedFreq = word; - - /* Get Platform defined limit */ - word = mctGet_NVbits(NV_MAX_MEMCLK); - if (word < proposedFreq) - proposedFreq = word; - - word = pDCTstat->PresetmaxFreq; - if (word > proposedFreq) - word = proposedFreq; - - pDCTstat->PresetmaxFreq = word; - } - /* Check F3xE8[DdrMaxRate] for maximum DRAM data rate support */ - - printk(BIOS_DEBUG, "%s: Done\n", __func__); -} - -static void SPDGetTCL_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, uint8_t dct) -{ - /* Find the best T and CL primary timing parameter pair, per Mfg., - * for the given set of DIMMs, and store into DCTStatStruc - * (.DIMMAutoSpeed and .DIMMCASL). See "Global relationship between - * index values and item values" for definition of CAS latency - * index (j) and Frequency index (k). - */ - u8 i, CASLatLow, CASLatHigh; - u16 tAAmin16x; - u8 MTB16x; - u16 tCKmin16x; - u16 tCKproposed16x; - u8 CLactual, CLdesired, CLT_Fail; - uint16_t min_frequency_tck16x; - - u8 byte = 0, bytex = 0; - - CASLatLow = 0xFF; - CASLatHigh = 0xFF; - tAAmin16x = 0; - tCKmin16x = 0; - CLT_Fail = 0; - - printk(BIOS_DEBUG, "%s: Start\n", __func__); - - if (is_fam15h()) { - uint16_t minimum_frequency_mhz = mctGet_NVbits(NV_MIN_MEMCLK); - if (minimum_frequency_mhz == 0) - minimum_frequency_mhz = 333; - min_frequency_tck16x = 16000 / minimum_frequency_mhz; - } else { - min_frequency_tck16x = 40; - } - - for (i = 0; i < MAX_DIMMS_SUPPORTED; i++) { - if (pDCTstat->DIMMValid & (1 << i)) { - /* Step 1: Determine the common set of supported CAS Latency - * values for all modules on the memory channel using the CAS - * Latencies Supported in SPD bytes 14 and 15. - */ - byte = pDCTstat->spd_data.spd_bytes[dct + i][SPD_CASLow]; - CASLatLow &= byte; - byte = pDCTstat->spd_data.spd_bytes[dct + i][SPD_CASHigh]; - CASLatHigh &= byte; - /* Step 2: Determine tAAmin(all) which is the largest tAAmin - value for all modules on the memory channel (SPD byte 16). */ - byte = pDCTstat->spd_data.spd_bytes[dct + i][SPD_MTBDivisor]; - - MTB16x = ((pDCTstat->spd_data.spd_bytes[dct + i][SPD_MTBDividend] & 0xFF)<<4); - MTB16x /= byte; /* transfer to MTB*16 */ - - byte = pDCTstat->spd_data.spd_bytes[dct + i][SPD_tAAmin]; - if (tAAmin16x < byte * MTB16x) - tAAmin16x = byte * MTB16x; - /* Step 3: Determine tCKmin(all) which is the largest tCKmin - value for all modules on the memory channel (SPD byte 12). */ - byte = pDCTstat->spd_data.spd_bytes[dct + i][SPD_tCKmin]; - - if (tCKmin16x < byte * MTB16x) - tCKmin16x = byte * MTB16x; - } - } - /* calculate tCKproposed16x (proposed clock period in ns * 16) */ - tCKproposed16x = 16000 / pDCTstat->PresetmaxFreq; - if (tCKmin16x > tCKproposed16x) - tCKproposed16x = tCKmin16x; - - /* TODO: get user manual tCK16x(Freq.) and overwrite current tCKproposed16x if manual. */ - if (is_fam15h()) { - if (tCKproposed16x == 17) - pDCTstat->TargetFreq = 0x16; - else if (tCKproposed16x <= 20) { - pDCTstat->TargetFreq = 0x12; - tCKproposed16x = 20; - } else if (tCKproposed16x <= 24) { - pDCTstat->TargetFreq = 0xe; - tCKproposed16x = 24; - } else if (tCKproposed16x <= 30) { - pDCTstat->TargetFreq = 0xa; - tCKproposed16x = 30; - } else if (tCKproposed16x <= 40) { - pDCTstat->TargetFreq = 0x6; - tCKproposed16x = 40; - } else { - pDCTstat->TargetFreq = 0x4; - tCKproposed16x = 48; - } - } else { - if (tCKproposed16x == 20) - pDCTstat->TargetFreq = 7; - else if (tCKproposed16x <= 24) { - pDCTstat->TargetFreq = 6; - tCKproposed16x = 24; - } else if (tCKproposed16x <= 30) { - pDCTstat->TargetFreq = 5; - tCKproposed16x = 30; - } else { - pDCTstat->TargetFreq = 4; - tCKproposed16x = 40; - } - } - /* Running through this loop twice: - - First time find tCL at target frequency - - Second time find tCL at 400MHz */ - - for (;;) { - CLT_Fail = 0; - /* Step 4: For a proposed tCK value (tCKproposed) between tCKmin(all) and tCKmax, - determine the desired CAS Latency. If tCKproposed is not a standard JEDEC - value (2.5, 1.875, 1.5, or 1.25 ns) then tCKproposed must be adjusted to the - next lower standard tCK value for calculating CLdesired. - CLdesired = ceiling (tAAmin(all) / tCKproposed) - where tAAmin is defined in Byte 16. The ceiling function requires that the - quotient be rounded up always. */ - CLdesired = tAAmin16x / tCKproposed16x; - if (tAAmin16x % tCKproposed16x) - CLdesired ++; - /* Step 5: Chose an actual CAS Latency (CLactual) that is greather than or equal - to CLdesired and is supported by all modules on the memory channel as - determined in step 1. If no such value exists, choose a higher tCKproposed - value and repeat steps 4 and 5 until a solution is found. */ - for (i = 0, CLactual = 4; i < 15; i++, CLactual++) { - if ((CASLatHigh << 8 | CASLatLow) & (1 << i)) { - if (CLdesired <= CLactual) - break; - } - } - if (i == 15) - CLT_Fail = 1; - /* Step 6: Once the calculation of CLactual is completed, the BIOS must also - verify that this CAS Latency value does not exceed tAAmax, which is 20 ns - for all DDR3 speed grades, by multiplying CLactual times tCKproposed. If - not, choose a lower CL value and repeat steps 5 and 6 until a solution is found. */ - if (CLactual * tCKproposed16x > 320) - CLT_Fail = 1; - /* get CL and T */ - if (!CLT_Fail) { - bytex = CLactual; - if (is_fam15h()) { - if (tCKproposed16x == 17) - byte = 0x16; - else if (tCKproposed16x == 20) - byte = 0x12; - else if (tCKproposed16x == 24) - byte = 0xe; - else if (tCKproposed16x == 30) - byte = 0xa; - else if (tCKproposed16x == 40) - byte = 0x6; - else - byte = 0x4; - } else { - if (tCKproposed16x == 20) - byte = 7; - else if (tCKproposed16x == 24) - byte = 6; - else if (tCKproposed16x == 30) - byte = 5; - else - byte = 4; - } - } else { - /* mctHookManualCLOverride */ - /* TODO: */ - } - - if (tCKproposed16x != min_frequency_tck16x) { - if (pMCTstat->GStatus & (1 << GSB_EnDIMMSpareNW)) { - pDCTstat->DIMMAutoSpeed = byte; - pDCTstat->DIMMCASL = bytex; - break; - } else { - pDCTstat->TargetCASL = bytex; - tCKproposed16x = min_frequency_tck16x; - } - } else { - pDCTstat->DIMMAutoSpeed = byte; - pDCTstat->DIMMCASL = bytex; - break; - } - } - - printk(BIOS_DEBUG, "SPDGetTCL_D: DIMMCASL %x\n", pDCTstat->DIMMCASL); - printk(BIOS_DEBUG, "SPDGetTCL_D: DIMMAutoSpeed %x\n", pDCTstat->DIMMAutoSpeed); - - printk(BIOS_DEBUG, "SPDGetTCL_D: Status %x\n", pDCTstat->Status); - printk(BIOS_DEBUG, "SPDGetTCL_D: ErrStatus %x\n", pDCTstat->ErrStatus); - printk(BIOS_DEBUG, "SPDGetTCL_D: ErrCode %x\n", pDCTstat->ErrCode); - printk(BIOS_DEBUG, "SPDGetTCL_D: Done\n\n"); -} - -u8 PlatformSpec_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - if (!is_fam15h()) { - mctGet_PS_Cfg_D(pMCTstat, pDCTstat, dct); - - if (pDCTstat->GangedMode == 1) { - mctGet_PS_Cfg_D(pMCTstat, pDCTstat, 1); - mct_BeforePlatformSpec(pMCTstat, pDCTstat, 1); - } - - set_2t_configuration(pMCTstat, pDCTstat, dct); - - mct_BeforePlatformSpec(pMCTstat, pDCTstat, dct); - mct_PlatformSpec(pMCTstat, pDCTstat, dct); - if (pDCTstat->DIMMAutoSpeed == mhz_to_memclk_config(mctGet_NVbits(NV_MIN_MEMCLK))) - InitPhyCompensation(pMCTstat, pDCTstat, dct); - } - mctHookAfterPSCfg(); - - return pDCTstat->ErrCode; -} - -static u8 AutoConfig_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u32 DramControl, DramTimingLo, Status; - u32 DramConfigLo, DramConfigHi, DramConfigMisc, DramConfigMisc2; - u32 val; - u32 dev; - u16 word; - u32 dword; - u8 byte; - uint32_t offset; - - DramConfigLo = 0; - DramConfigHi = 0; - DramConfigMisc = 0; - DramConfigMisc2 = 0; - - /* set bank addressing and Masks, plus CS pops */ - SPDSetBanks_D(pMCTstat, pDCTstat, dct); - if (pDCTstat->ErrCode == SC_StopError) - goto AutoConfig_exit; - - /* map chip-selects into local address space */ - StitchMemory_D(pMCTstat, pDCTstat, dct); - InterleaveBanks_D(pMCTstat, pDCTstat, dct); - - /* temp image of status (for convenience). RO usage! */ - Status = pDCTstat->Status; - - dev = pDCTstat->dev_dct; - - /* Build Dram Control Register Value */ - DramConfigMisc2 = Get_NB32_DCT(dev, dct, 0xa8); /* Dram Miscellaneous 2 */ - DramControl = Get_NB32_DCT(dev, dct, 0x78); /* Dram Control */ - - /* FIXME: Skip mct_checkForDxSupport */ - /* REV_CALL mct_DoRdPtrInit if not Dx */ - if (pDCTstat->LogicalCPUID & AMD_DR_Bx) - val = 5; - else - val = 6; - DramControl &= ~0xFF; - DramControl |= val; /* RdPtrInit = 6 for Cx CPU */ - - if (mctGet_NVbits(NV_CLKHZAltVidC3)) - DramControl |= 1<<16; /* check */ - - DramControl |= 0x00002A00; - - /* FIXME: Skip for Ax versions */ - /* callback not required - if (!mctParityControl_D()) */ - if (Status & (1 << SB_128bitmode)) - DramConfigLo |= 1 << Width128; /* 128-bit mode (normal) */ - - word = dct; - dword = X4Dimm; - while (word < 8) { - if (pDCTstat->Dimmx4Present & (1 << word)) - DramConfigLo |= 1 << dword; /* X4Dimm[3:0] */ - word++; - word++; - dword++; - } - - if (Status & (1 << SB_Registered)) { - /* Registered DIMMs */ - if (!is_fam15h()) { - DramConfigLo |= 1 << ParEn; - } - } else { - /* Unbuffered DIMMs */ - DramConfigLo |= 1 << UnBuffDimm; - } - - if (mctGet_NVbits(NV_ECC_CAP)) - if (Status & (1 << SB_ECCDIMMs)) - if (mctGet_NVbits(NV_ECC)) - DramConfigLo |= 1 << DimmEcEn; - - DramConfigLo = mct_DisDllShutdownSR(pMCTstat, pDCTstat, DramConfigLo, dct); - - /* Build Dram Config Hi Register Value */ - if (is_fam15h()) - offset = 0x0; - else - offset = 0x1; - dword = pDCTstat->Speed; - DramConfigHi |= dword - offset; /* get MemClk encoding */ - DramConfigHi |= 1 << MemClkFreqVal; - - if (!is_fam15h()) - if (Status & (1 << SB_Registered)) - if ((pDCTstat->Dimmx4Present != 0) && (pDCTstat->Dimmx8Present != 0)) - /* set only if x8 Registered DIMMs in System*/ - DramConfigHi |= 1 << RDqsEn; - - if (pDCTstat->LogicalCPUID & AMD_FAM15_ALL) { - DramConfigLo |= 1 << 25; /* PendRefPaybackS3En = 1 */ - DramConfigLo |= 1 << 24; /* StagRefEn = 1 */ - DramConfigHi |= 1 << 16; /* PowerDownMode = 1 */ - } else { - if (mctGet_NVbits(NV_CKE_CTL)) - /*Chip Select control of CKE*/ - DramConfigHi |= 1 << 16; - } - - if (!is_fam15h()) { - /* Control Bank Swizzle */ - if (0) /* call back not needed mctBankSwizzleControl_D()) */ - DramConfigHi &= ~(1 << BankSwizzleMode); - else - DramConfigHi |= 1 << BankSwizzleMode; /* recommended setting (default) */ - } - - /* Check for Quadrank DIMM presence */ - if (pDCTstat->DimmQRPresent != 0) { - byte = mctGet_NVbits(NV_4RANKType); - if (byte == 2) - DramConfigHi |= 1 << 17; /* S4 (4-Rank SO-DIMMs) */ - else if (byte == 1) - DramConfigHi |= 1 << 18; /* R4 (4-Rank Registered DIMMs) */ - } - - if (0) /* call back not needed mctOverrideDcqBypMax_D) */ - val = mctGet_NVbits(NV_BYPMAX); - else - val = 0x0f; /* recommended setting (default) */ - DramConfigHi |= val << 24; - - if (pDCTstat->LogicalCPUID & (AMD_DR_Dx | AMD_DR_Cx | AMD_DR_Bx | AMD_FAM15_ALL)) - DramConfigHi |= 1 << DcqArbBypassEn; - - /* Build MemClkDis Value from Dram Timing Lo and - Dram Config Misc Registers - 1. We will assume that MemClkDis field has been preset prior to this - point. - 2. We will only set MemClkDis bits if a DIMM is NOT present AND if: - NV_AllMemClks <>0 AND SB_DiagClks == 0 */ - - /* Dram Timing Low (owns Clock Enable bits) */ - DramTimingLo = Get_NB32_DCT(dev, dct, 0x88); - if (mctGet_NVbits(NV_AllMemClks) == 0) { - /* Special Jedec SPD diagnostic bit - "enable all clocks" */ - if (!(pDCTstat->Status & (1<<SB_DiagClks))) { - const u8 *p; - p = Tab_ManualCLKDis; - - byte = mctGet_NVbits(NV_PACK_TYPE); - if (byte == PT_L1) - p = Tab_L1CLKDis; - else if (byte == PT_M2 || byte == PT_AS) - p = Tab_AM3CLKDis; - else if (byte == PT_C3) - p = Tab_C32CLKDis; - else if (byte == PT_GR) - p = Tab_G34CLKDis; - else if (byte == PT_FM2) - p = Tab_FM2CLKDis; - else - p = Tab_S1CLKDis; - - dword = 0; - byte = 0xFF; - while (dword < MAX_CS_SUPPORTED) { - if (pDCTstat->CSPresent & (1<<dword)) { - /* re-enable clocks for the enabled CS */ - val = p[dword]; - byte &= ~val; - } - dword++; - } - DramTimingLo &= ~(0xff << 24); - DramTimingLo |= byte << 24; - } - } - - DramConfigMisc2 = mct_SetDramConfigMisc2(pDCTstat, dct, DramConfigMisc2, DramControl); - - printk(BIOS_DEBUG, "AutoConfig_D: DramControl: %08x\n", DramControl); - printk(BIOS_DEBUG, "AutoConfig_D: DramTimingLo: %08x\n", DramTimingLo); - printk(BIOS_DEBUG, "AutoConfig_D: DramConfigMisc: %08x\n", DramConfigMisc); - printk(BIOS_DEBUG, "AutoConfig_D: DramConfigMisc2: %08x\n", DramConfigMisc2); - printk(BIOS_DEBUG, "AutoConfig_D: DramConfigLo: %08x\n", DramConfigLo); - printk(BIOS_DEBUG, "AutoConfig_D: DramConfigHi: %08x\n", DramConfigHi); - - /* Write Values to the registers */ - Set_NB32_DCT(dev, dct, 0x78, DramControl); - Set_NB32_DCT(dev, dct, 0x88, DramTimingLo); - Set_NB32_DCT(dev, dct, 0xa0, DramConfigMisc); - Set_NB32_DCT(dev, dct, 0xa8, DramConfigMisc2); - Set_NB32_DCT(dev, dct, 0x90, DramConfigLo); - ProgDramMRSReg_D(pMCTstat, pDCTstat, dct); - - if (is_fam15h()) - InitDDRPhy(pMCTstat, pDCTstat, dct); - - /* Write the DRAM Configuration High register, including memory frequency change */ - dword = Get_NB32_DCT(dev, dct, 0x94); - DramConfigHi |= dword; - mct_SetDramConfigHi_D(pMCTstat, pDCTstat, dct, DramConfigHi); - mct_EarlyArbEn_D(pMCTstat, pDCTstat, dct); - mctHookAfterAutoCfg(); - - /* dump_pci_device(PCI_DEV(0, 0x18+pDCTstat->Node_ID, 2)); */ - - printk(BIOS_DEBUG, "AutoConfig: Status %x\n", pDCTstat->Status); - printk(BIOS_DEBUG, "AutoConfig: ErrStatus %x\n", pDCTstat->ErrStatus); - printk(BIOS_DEBUG, "AutoConfig: ErrCode %x\n", pDCTstat->ErrCode); - printk(BIOS_DEBUG, "AutoConfig: Done\n\n"); - -AutoConfig_exit: - return pDCTstat->ErrCode; -} - -static void SPDSetBanks_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - /* Set bank addressing, program Mask values and build a chip-select - * population map. This routine programs PCI 0:24N:2x80 config register - * and PCI 0:24N:2x60,64,68,6C config registers (CS Mask 0-3). - */ - u8 ChipSel, Rows, Cols, Ranks, Banks; - u32 BankAddrReg, csMask; - - u32 val; - u32 reg; - u32 dev; - u8 byte; - u16 word; - u32 dword; - - dev = pDCTstat->dev_dct; - - BankAddrReg = 0; - for (ChipSel = 0; ChipSel < MAX_CS_SUPPORTED; ChipSel+=2) { - byte = ChipSel; - if ((pDCTstat->Status & (1 << SB_64MuxedMode)) && ChipSel >=4) - byte -= 3; - - if (pDCTstat->DIMMValid & (1<<byte)) { - byte = pDCTstat->spd_data.spd_bytes[ChipSel + dct][SPD_Addressing]; - Rows = (byte >> 3) & 0x7; /* Rows:0b = 12-bit,... */ - Cols = byte & 0x7; /* Cols:0b = 9-bit,... */ - - byte = pDCTstat->spd_data.spd_bytes[ChipSel + dct][SPD_Density]; - Banks = (byte >> 4) & 7; /* Banks:0b = 3-bit,... */ - - byte = pDCTstat->spd_data.spd_bytes[ChipSel + dct][SPD_Organization]; - Ranks = ((byte >> 3) & 7) + 1; - - /* Configure Bank encoding - * Use a 6-bit key into a lookup table. - * Key (index) = RRRBCC, where CC is the number of Columns minus 9, - * RRR is the number of Rows minus 12, and B is the number of banks - * minus 3. - */ - byte = Cols; - if (Banks == 1) - byte |= 4; - - byte |= Rows << 3; /* RRRBCC internal encode */ - - for (dword = 0; dword < 13; dword++) { - if (byte == Tab_BankAddr[dword]) - break; - } - - if (dword > 12) - continue; - - /* bit no. of CS field in address mapping reg.*/ - dword <<= (ChipSel<<1); - BankAddrReg |= dword; - - /* Mask value=(2pow(rows+cols+banks+3)-1)>>8, - or 2pow(rows+cols+banks-5)-1*/ - csMask = 0; - - byte = Rows + Cols; /* cl = rows+cols*/ - byte += 21; /* row:12+col:9 */ - byte -= 2; /* 3 banks - 5 */ - - if (pDCTstat->Status & (1 << SB_128bitmode)) - byte++; /* double mask size if in 128-bit mode*/ - - csMask |= 1 << byte; - csMask--; - - /*set ChipSelect population indicator even bits*/ - pDCTstat->CSPresent |= (1<<ChipSel); - if (Ranks >= 2) - /*set ChipSelect population indicator odd bits*/ - pDCTstat->CSPresent |= 1 << (ChipSel + 1); - - reg = 0x60+(ChipSel<<1); /*Dram CS Mask Register */ - val = csMask; - val &= 0x1FF83FE0; /* Mask out reserved bits.*/ - Set_NB32_DCT(dev, dct, reg, val); - } else { - if (pDCTstat->DIMMSPDCSE & (1<<ChipSel)) - pDCTstat->CSTestFail |= (1<<ChipSel); - } /* if DIMMValid*/ - } /* while ChipSel*/ - - SetCSTriState(pMCTstat, pDCTstat, dct); - SetCKETriState(pMCTstat, pDCTstat, dct); - SetODTTriState(pMCTstat, pDCTstat, dct); - - if (pDCTstat->Status & (1 << SB_128bitmode)) { - SetCSTriState(pMCTstat, pDCTstat, 1); /* force dct1) */ - SetCKETriState(pMCTstat, pDCTstat, 1); /* force dct1) */ - SetODTTriState(pMCTstat, pDCTstat, 1); /* force dct1) */ - } - - word = pDCTstat->CSPresent; - mctGetCS_ExcludeMap(); /* mask out specified chip-selects */ - word ^= pDCTstat->CSPresent; - pDCTstat->CSTestFail |= word; /* enable ODT to disabled DIMMs */ - if (!pDCTstat->CSPresent) - pDCTstat->ErrCode = SC_StopError; - - reg = 0x80; /* Bank Addressing Register */ - Set_NB32_DCT(dev, dct, reg, BankAddrReg); - - pDCTstat->CSPresent_DCT[dct] = pDCTstat->CSPresent; - /* dump_pci_device(PCI_DEV(0, 0x18+pDCTstat->Node_ID, 2)); */ - - printk(BIOS_DEBUG, "SPDSetBanks: CSPresent %x\n", pDCTstat->CSPresent_DCT[dct]); - printk(BIOS_DEBUG, "SPDSetBanks: Status %x\n", pDCTstat->Status); - printk(BIOS_DEBUG, "SPDSetBanks: ErrStatus %x\n", pDCTstat->ErrStatus); - printk(BIOS_DEBUG, "SPDSetBanks: ErrCode %x\n", pDCTstat->ErrCode); - printk(BIOS_DEBUG, "SPDSetBanks: Done\n\n"); -} - -static void SPDCalcWidth_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - /* Per SPDs, check the symmetry of DIMM pairs (DIMM on Channel A - * matching with DIMM on Channel B), the overall DIMM population, - * and determine the width mode: 64-bit, 64-bit muxed, 128-bit. - */ - u8 i; - u8 byte, byte1; - - /* Check Symmetry of Channel A and Channel B DIMMs - (must be matched for 128-bit mode).*/ - for (i = 0; i < MAX_DIMMS_SUPPORTED; i += 2) { - if ((pDCTstat->DIMMValid & (1 << i)) && (pDCTstat->DIMMValid & (1<<(i+1)))) { - byte = pDCTstat->spd_data.spd_bytes[i][SPD_Addressing] & 0x7; - byte1 = pDCTstat->spd_data.spd_bytes[i + 1][SPD_Addressing] & 0x7; - if (byte != byte1) { - pDCTstat->ErrStatus |= (1<<SB_DimmMismatchO); - break; - } - - byte = pDCTstat->spd_data.spd_bytes[i][SPD_Density] & 0x0f; - byte1 = pDCTstat->spd_data.spd_bytes[i + 1][SPD_Density] & 0x0f; - if (byte != byte1) { - pDCTstat->ErrStatus |= (1<<SB_DimmMismatchO); - break; - } - - byte = pDCTstat->spd_data.spd_bytes[i][SPD_Organization] & 0x7; - byte1 = pDCTstat->spd_data.spd_bytes[i + 1][SPD_Organization] & 0x7; - if (byte != byte1) { - pDCTstat->ErrStatus |= (1<<SB_DimmMismatchO); - break; - } - - byte = (pDCTstat->spd_data.spd_bytes[i][SPD_Organization] >> 3) & 0x7; - byte1 = (pDCTstat->spd_data.spd_bytes[i + 1][SPD_Organization] >> 3) & 0x7; - if (byte != byte1) { - pDCTstat->ErrStatus |= (1<<SB_DimmMismatchO); - break; - } - - byte = pDCTstat->spd_data.spd_bytes[i][SPD_DMBANKS] & 7; /* #ranks-1 */ - byte1 = pDCTstat->spd_data.spd_bytes[i + 1][SPD_DMBANKS] & 7; /* #ranks-1 */ - if (byte != byte1) { - pDCTstat->ErrStatus |= (1<<SB_DimmMismatchO); - break; - } - - } - } - -} - -static void StitchMemory_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - /* Requires that Mask values for each bank be programmed first and that - * the chip-select population indicator is correctly set. - */ - u8 b = 0; - u32 nxtcsBase, curcsBase; - u8 p, q; - u32 BiggestBank; - u8 _DSpareEn; - - u16 word; - u32 dev; - u32 reg; - u32 val; - - dev = pDCTstat->dev_dct; - - _DSpareEn = 0; - - /* CS Sparing 1 = enabled, 0 = disabled */ - if (mctGet_NVbits(NV_CS_SpareCTL) & 1) { - if (MCT_DIMM_SPARE_NO_WARM) { - /* Do no warm-reset DIMM spare */ - if (pMCTstat->GStatus & 1 << GSB_EnDIMMSpareNW) { - word = pDCTstat->CSPresent; - val = bsf(word); - word &= ~(1<<val); - if (word) - /* Make sure at least two chip-selects are available */ - _DSpareEn = 1; - else - pDCTstat->ErrStatus |= 1 << SB_SpareDis; - } - } else { - if (!mctGet_NVbits(NV_DQSTrainCTL)) { /*DQS Training 1 = enabled, 0 = disabled */ - word = pDCTstat->CSPresent; - val = bsf(word); - word &= ~(1 << val); - if (word) - /* Make sure at least two chip-selects are available */ - _DSpareEn = 1; - else - pDCTstat->ErrStatus |= 1 << SB_SpareDis; - } - } - } - - nxtcsBase = 0; /* Next available cs base ADDR[39:8] */ - for (p = 0; p < MAX_DIMMS_SUPPORTED; p++) { - BiggestBank = 0; - for (q = 0; q < MAX_CS_SUPPORTED; q++) { /* from DIMMS to CS */ - if (pDCTstat->CSPresent & (1 << q)) { /* bank present? */ - reg = 0x40 + (q << 2); /* Base[q] reg.*/ - val = Get_NB32_DCT(dev, dct, reg); - if (!(val & 3)) { /* (CSEnable|Spare == 1)bank is enabled already? */ - reg = 0x60 + (q << 1); /*Mask[q] reg.*/ - val = Get_NB32_DCT(dev, dct, reg); - val >>= 19; - val++; - val <<= 19; - if (val > BiggestBank) { - /*Bingo! possibly Map this chip-select next! */ - BiggestBank = val; - b = q; - } - } - } /*if bank present */ - } /* while q */ - if (BiggestBank !=0) { - curcsBase = nxtcsBase; /* curcsBase = nxtcsBase*/ - /* DRAM CS Base b Address Register offset */ - reg = 0x40 + (b << 2); - if (_DSpareEn) { - BiggestBank = 0; - val = 1 << Spare; /* Spare Enable*/ - } else { - val = curcsBase; - val |= 1 << CSEnable; /* Bank Enable */ - } - if (((reg - 0x40) >> 2) & 1) { - if (!(pDCTstat->Status & (1 << SB_Registered))) { - u16 dimValid; - dimValid = pDCTstat->DIMMValid; - if (dct & 1) - dimValid <<= 1; - if ((dimValid & pDCTstat->MirrPresU_NumRegR) != 0) { - val |= 1 << onDimmMirror; - } - } - } - Set_NB32_DCT(dev, dct, reg, val); - if (_DSpareEn) - _DSpareEn = 0; - else - /* let nxtcsBase+=Size[b] */ - nxtcsBase += BiggestBank; - } - - /* bank present but disabled?*/ - if (pDCTstat->CSTestFail & (1 << p)) { - /* DRAM CS Base b Address Register offset */ - reg = (p << 2) + 0x40; - val = 1 << TestFail; - Set_NB32_DCT(dev, dct, reg, val); - } - } - - if (nxtcsBase) { - pDCTstat->DCTSysLimit = nxtcsBase - 1; - mct_AfterStitchMemory(pMCTstat, pDCTstat, dct); - } - - /* dump_pci_device(PCI_DEV(0, 0x18+pDCTstat->Node_ID, 2)); */ - - printk(BIOS_DEBUG, "StitchMemory: Status %x\n", pDCTstat->Status); - printk(BIOS_DEBUG, "StitchMemory: ErrStatus %x\n", pDCTstat->ErrStatus); - printk(BIOS_DEBUG, "StitchMemory: ErrCode %x\n", pDCTstat->ErrCode); - printk(BIOS_DEBUG, "StitchMemory: Done\n\n"); -} - -static u16 Get_Fk_D(u8 k) -{ - return Table_F_k[k]; /* FIXME: k or k<<1 ? */ -} - -static u8 DIMMPresence_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - /* Check DIMMs present, verify checksum, flag SDRAM type, - * build population indicator bitmaps, and preload bus loading - * of DIMMs into DCTStatStruc. - * MAAload = number of devices on the "A" bus. - * MABload = number of devices on the "B" bus. - * MAAdimms = number of DIMMs on the "A" bus slots. - * MABdimms = number of DIMMs on the "B" bus slots. - * DATAAload = number of ranks on the "A" bus slots. - * DATABload = number of ranks on the "B" bus slots. - */ - u16 i, j, k; - u8 smbaddr; - u8 SPDCtrl; - u16 RegDIMMPresent, LRDIMMPresent, MaxDimms; - u8 devwidth; - u16 DimmSlots; - u8 byte = 0, bytex; - uint8_t crc_status; - - /* preload data structure with addrs */ - mctGet_DIMMAddr(pDCTstat, pDCTstat->Node_ID); - - DimmSlots = MaxDimms = mctGet_NVbits(NV_MAX_DIMMS); - - SPDCtrl = mctGet_NVbits(NV_SPDCHK_RESTRT); - - RegDIMMPresent = 0; - LRDIMMPresent = 0; - pDCTstat->DimmQRPresent = 0; - - for (i = 0; i < MAX_DIMMS_SUPPORTED; i++) { - if (i >= MaxDimms) - break; - - if ((pDCTstat->DimmQRPresent & (1 << i)) || (i < DimmSlots)) { - int status; - smbaddr = Get_DIMMAddress_D(pDCTstat, i); - status = mctRead_SPD(smbaddr, SPD_ByteUse); - if (status >= 0) { - /* Verify result */ - status = mctRead_SPD(smbaddr, SPD_ByteUse); - } - if (status >= 0) { /* SPD access is ok */ - pDCTstat->DIMMPresent |= 1 << i; - read_spd_bytes(pMCTstat, pDCTstat, i); -#ifdef DEBUG_DIMM_SPD - dump_spd_bytes(pMCTstat, pDCTstat, i); -#endif - crc_status = crcCheck(pDCTstat, i); - if (!crc_status) { - /* Try again in case there was a transient glitch */ - read_spd_bytes(pMCTstat, pDCTstat, i); - crc_status = crcCheck(pDCTstat, i); - } - if ((crc_status) || (SPDCtrl == 2)) { /* CRC is OK */ - byte = pDCTstat->spd_data.spd_bytes[i][SPD_TYPE]; - if (byte == JED_DDR3SDRAM) { - /*Dimm is 'Present'*/ - pDCTstat->DIMMValid |= 1 << i; - } - } else { - printk(BIOS_WARNING, "Node %d DIMM %d: SPD checksum invalid\n", pDCTstat->Node_ID, i); - pDCTstat->DIMMSPDCSE = 1 << i; - if (SPDCtrl == 0) { - pDCTstat->ErrStatus |= 1 << SB_DIMMChkSum; - pDCTstat->ErrCode = SC_StopError; - } else { - /*if NV_SPDCHK_RESTRT is set to 1, ignore faulty SPD checksum*/ - pDCTstat->ErrStatus |= 1<<SB_DIMMChkSum; - byte = pDCTstat->spd_data.spd_bytes[i][SPD_TYPE]; - if (byte == JED_DDR3SDRAM) - pDCTstat->DIMMValid |= 1 << i; - } - } - - /* Zero DIMM SPD data cache if DIMM not present / valid */ - if (!(pDCTstat->DIMMValid & (1 << i))) - memset(pDCTstat->spd_data.spd_bytes[i], 0, sizeof(pDCTstat->spd_data.spd_bytes[i])); - - /* Get module information for SMBIOS */ - if (pDCTstat->DIMMValid & (1 << i)) { - pDCTstat->DimmManufacturerID[i] = 0; - for (k = 0; k < 8; k++) - pDCTstat->DimmManufacturerID[i] |= ((uint64_t)pDCTstat->spd_data.spd_bytes[i][SPD_MANID_START + k]) << (k * 8); - for (k = 0; k < SPD_PARTN_LENGTH; k++) - pDCTstat->DimmPartNumber[i][k] = pDCTstat->spd_data.spd_bytes[i][SPD_PARTN_START + k]; - pDCTstat->DimmPartNumber[i][SPD_PARTN_LENGTH] = 0; - pDCTstat->DimmRevisionNumber[i] = 0; - for (k = 0; k < 2; k++) - pDCTstat->DimmRevisionNumber[i] |= ((uint16_t)pDCTstat->spd_data.spd_bytes[i][SPD_REVNO_START + k]) << (k * 8); - pDCTstat->DimmSerialNumber[i] = 0; - for (k = 0; k < 4; k++) - pDCTstat->DimmSerialNumber[i] |= ((uint32_t)pDCTstat->spd_data.spd_bytes[i][SPD_SERIAL_START + k]) << (k * 8); - pDCTstat->DimmRows[i] = (pDCTstat->spd_data.spd_bytes[i][SPD_Addressing] & 0x38) >> 3; - pDCTstat->DimmCols[i] = pDCTstat->spd_data.spd_bytes[i][SPD_Addressing] & 0x7; - pDCTstat->DimmRanks[i] = ((pDCTstat->spd_data.spd_bytes[i][SPD_Organization] & 0x38) >> 3) + 1; - pDCTstat->DimmBanks[i] = 1ULL << (((pDCTstat->spd_data.spd_bytes[i][SPD_Density] & 0x70) >> 4) + 3); - pDCTstat->DimmWidth[i] = 1ULL << ((pDCTstat->spd_data.spd_bytes[i][SPD_BusWidth] & 0x7) + 3); - pDCTstat->DimmChipSize[i] = 1ULL << ((pDCTstat->spd_data.spd_bytes[i][SPD_Density] & 0xf) + 28); - pDCTstat->DimmChipWidth[i] = 1ULL << ((pDCTstat->spd_data.spd_bytes[i][SPD_Organization] & 0x7) + 2); - } - /* Check supported voltage(s) */ - pDCTstat->DimmSupportedVoltages[i] = pDCTstat->spd_data.spd_bytes[i][SPD_Voltage] & 0x7; - pDCTstat->DimmSupportedVoltages[i] ^= 0x1; /* Invert LSB to convert from SPD format to internal bitmap format */ - /* Check module type */ - byte = pDCTstat->spd_data.spd_bytes[i][SPD_DIMMTYPE] & 0x7; - if (byte == JED_RDIMM || byte == JED_MiniRDIMM) { - RegDIMMPresent |= 1 << i; - pDCTstat->DimmRegistered[i] = 1; - } else { - pDCTstat->DimmRegistered[i] = 0; - } - if (byte == JED_LRDIMM) { - LRDIMMPresent |= 1 << i; - pDCTstat->DimmLoadReduced[i] = 1; - } else { - pDCTstat->DimmLoadReduced[i] = 0; - } - /* Check ECC capable */ - byte = pDCTstat->spd_data.spd_bytes[i][SPD_BusWidth]; - if (byte & JED_ECC) { - /* DIMM is ECC capable */ - pDCTstat->DimmECCPresent |= 1 << i; - } - /* Check if x4 device */ - devwidth = pDCTstat->spd_data.spd_bytes[i][SPD_Organization] & 0x7; /* 0:x4,1:x8,2:x16 */ - if (devwidth == 0) { - /* DIMM is made with x4 or x16 drams */ - pDCTstat->Dimmx4Present |= 1 << i; - } else if (devwidth == 1) { - pDCTstat->Dimmx8Present |= 1 << i; - } else if (devwidth == 2) { - pDCTstat->Dimmx16Present |= 1 << i; - } - - byte = (pDCTstat->spd_data.spd_bytes[i][SPD_Organization] >> 3); - byte &= 7; - if (byte == 3) { /* 4ranks */ - /* if any DIMMs are QR, we have to make two passes through DIMMs*/ - if (pDCTstat->DimmQRPresent == 0) { - MaxDimms <<= 1; - } - if (i < DimmSlots) { - pDCTstat->DimmQRPresent |= (1 << i) | (1 << (i+4)); - } else { - pDCTstat->MAdimms[i & 1] --; - } - byte = 1; /* upper two ranks of QR DIMM will be counted on another DIMM number iteration*/ - } else if (byte == 1) { /* 2ranks */ - pDCTstat->DimmDRPresent |= 1 << i; - } - bytex = devwidth; - if (devwidth == 0) - bytex = 16; - else if (devwidth == 1) - bytex = 8; - else if (devwidth == 2) - bytex = 4; - - byte++; /* al+1 = rank# */ - if (byte == 2) - bytex <<= 1; /*double Addr bus load value for dual rank DIMMs*/ - - j = i & (1<<0); - pDCTstat->DATAload[j] += byte; /*number of ranks on DATA bus*/ - pDCTstat->MAload[j] += bytex; /*number of devices on CMD/ADDR bus*/ - pDCTstat->MAdimms[j]++; /*number of DIMMs on A bus */ - - /* check address mirror support for unbuffered dimm */ - /* check number of registers on a dimm for registered dimm */ - byte = pDCTstat->spd_data.spd_bytes[i][SPD_AddressMirror]; - if (RegDIMMPresent & (1 << i)) { - if ((byte & 3) > 1) - pDCTstat->MirrPresU_NumRegR |= 1 << i; - } else { - if ((byte & 1) == 1) - pDCTstat->MirrPresU_NumRegR |= 1 << i; - } - /* Get byte62: Reference Raw Card information. We dont need it now. */ - /* byte = pDCTstat->spd_data.spd_bytes[i][SPD_RefRawCard]; */ - /* Get Byte65/66 for register manufacture ID code */ - if ((0x97 == pDCTstat->spd_data.spd_bytes[i][SPD_RegManufactureID_H]) && - (0x80 == pDCTstat->spd_data.spd_bytes[i][SPD_RegManufactureID_L])) { - if (0x16 == pDCTstat->spd_data.spd_bytes[i][SPD_RegManRevID]) - pDCTstat->RegMan2Present |= 1 << i; - else - pDCTstat->RegMan1Present |= 1 << i; - } - /* Get control word value for RC3 */ - byte = pDCTstat->spd_data.spd_bytes[i][70]; - pDCTstat->CtrlWrd3 |= ((byte >> 4) & 0xf) << (i << 2); /* RC3 = SPD byte 70 [7:4] */ - /* Get control word values for RC4 and RC5 */ - byte = pDCTstat->spd_data.spd_bytes[i][71]; - pDCTstat->CtrlWrd4 |= (byte & 0xf) << (i << 2); /* RC4 = SPD byte 71 [3:0] */ - pDCTstat->CtrlWrd5 |= ((byte >> 4) & 0xf) << (i << 2); /* RC5 = SPD byte 71 [7:4] */ - } - } - } - printk(BIOS_DEBUG, "\t DIMMPresence: DIMMValid=%x\n", pDCTstat->DIMMValid); - printk(BIOS_DEBUG, "\t DIMMPresence: DIMMPresent=%x\n", pDCTstat->DIMMPresent); - printk(BIOS_DEBUG, "\t DIMMPresence: RegDIMMPresent=%x\n", RegDIMMPresent); - printk(BIOS_DEBUG, "\t DIMMPresence: LRDIMMPresent=%x\n", LRDIMMPresent); - printk(BIOS_DEBUG, "\t DIMMPresence: DimmECCPresent=%x\n", pDCTstat->DimmECCPresent); - printk(BIOS_DEBUG, "\t DIMMPresence: DimmPARPresent=%x\n", pDCTstat->DimmPARPresent); - printk(BIOS_DEBUG, "\t DIMMPresence: Dimmx4Present=%x\n", pDCTstat->Dimmx4Present); - printk(BIOS_DEBUG, "\t DIMMPresence: Dimmx8Present=%x\n", pDCTstat->Dimmx8Present); - printk(BIOS_DEBUG, "\t DIMMPresence: Dimmx16Present=%x\n", pDCTstat->Dimmx16Present); - printk(BIOS_DEBUG, "\t DIMMPresence: DimmPlPresent=%x\n", pDCTstat->DimmPlPresent); - printk(BIOS_DEBUG, "\t DIMMPresence: DimmDRPresent=%x\n", pDCTstat->DimmDRPresent); - printk(BIOS_DEBUG, "\t DIMMPresence: DimmQRPresent=%x\n", pDCTstat->DimmQRPresent); - printk(BIOS_DEBUG, "\t DIMMPresence: DATAload[0]=%x\n", pDCTstat->DATAload[0]); - printk(BIOS_DEBUG, "\t DIMMPresence: MAload[0]=%x\n", pDCTstat->MAload[0]); - printk(BIOS_DEBUG, "\t DIMMPresence: MAdimms[0]=%x\n", pDCTstat->MAdimms[0]); - printk(BIOS_DEBUG, "\t DIMMPresence: DATAload[1]=%x\n", pDCTstat->DATAload[1]); - printk(BIOS_DEBUG, "\t DIMMPresence: MAload[1]=%x\n", pDCTstat->MAload[1]); - printk(BIOS_DEBUG, "\t DIMMPresence: MAdimms[1]=%x\n", pDCTstat->MAdimms[1]); - - if (pDCTstat->DIMMValid != 0) { /* If any DIMMs are present...*/ - if (RegDIMMPresent != 0) { - if ((RegDIMMPresent ^ pDCTstat->DIMMValid) !=0) { - /* module type DIMM mismatch (reg'ed, unbuffered) */ - pDCTstat->ErrStatus |= 1<<SB_DimmMismatchM; - pDCTstat->ErrCode = SC_StopError; - } else{ - /* all DIMMs are registered */ - pDCTstat->Status |= 1<<SB_Registered; - } - } - if (LRDIMMPresent != 0) { - if ((LRDIMMPresent ^ pDCTstat->DIMMValid) !=0) { - /* module type DIMM mismatch (reg'ed, unbuffered) */ - pDCTstat->ErrStatus |= 1<<SB_DimmMismatchM; - pDCTstat->ErrCode = SC_StopError; - } else{ - /* all DIMMs are registered */ - pDCTstat->Status |= 1<<SB_LoadReduced; - } - } - if (pDCTstat->DimmECCPresent != 0) { - if ((pDCTstat->DimmECCPresent ^ pDCTstat->DIMMValid) == 0) { - /* all DIMMs are ECC capable */ - pDCTstat->Status |= 1<<SB_ECCDIMMs; - } - } - if (pDCTstat->DimmPARPresent != 0) { - if ((pDCTstat->DimmPARPresent ^ pDCTstat->DIMMValid) == 0) { - /*all DIMMs are Parity capable */ - pDCTstat->Status |= 1<<SB_PARDIMMs; - } - } - } else { - /* no DIMMs present or no DIMMs that qualified. */ - pDCTstat->ErrStatus |= 1<<SB_NoDimms; - pDCTstat->ErrCode = SC_StopError; - } - - printk(BIOS_DEBUG, "\t DIMMPresence: Status %x\n", pDCTstat->Status); - printk(BIOS_DEBUG, "\t DIMMPresence: ErrStatus %x\n", pDCTstat->ErrStatus); - printk(BIOS_DEBUG, "\t DIMMPresence: ErrCode %x\n", pDCTstat->ErrCode); - printk(BIOS_DEBUG, "\t DIMMPresence: Done\n\n"); - - mctHookAfterDIMMpre(); - - return pDCTstat->ErrCode; -} - -static u8 Get_DIMMAddress_D(struct DCTStatStruc *pDCTstat, u8 i) -{ - u8 *p; - - p = pDCTstat->DIMMAddr; - /* mct_BeforeGetDIMMAddress(); */ - return p[i]; -} - -static void mct_preInitDCT(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u8 err_code; - uint8_t nvram; - uint8_t allow_config_restore; - - /* Preconfigure DCT0 */ - DCTPreInit_D(pMCTstat, pDCTstat, 0); - - /* Configure DCT1 if unganged and enabled*/ - if (!pDCTstat->GangedMode) { - if (pDCTstat->DIMMValidDCT[1] > 0) { - err_code = pDCTstat->ErrCode; /* save DCT0 errors */ - pDCTstat->ErrCode = 0; - DCTPreInit_D(pMCTstat, pDCTstat, 1); - if (pDCTstat->ErrCode == 2) /* DCT1 is not Running */ - pDCTstat->ErrCode = err_code; /* Using DCT0 Error code to update pDCTstat.ErrCode */ - } - } - -#if CONFIG(HAVE_ACPI_RESUME) - calculate_and_store_spd_hashes(pMCTstat, pDCTstat); - - if (load_spd_hashes_from_nvram(pMCTstat, pDCTstat) < 0) { - pDCTstat->spd_data.nvram_spd_match = 0; - } else { - compare_nvram_spd_hashes(pMCTstat, pDCTstat); - } -#else - pDCTstat->spd_data.nvram_spd_match = 0; -#endif - - /* Check to see if restoration of SPD data from NVRAM is allowed */ - allow_config_restore = 0; - if (get_option(&nvram, "allow_spd_nvram_cache_restore") == CB_SUCCESS) - allow_config_restore = !!nvram; - -#if CONFIG(HAVE_ACPI_RESUME) - if (pMCTstat->nvram_checksum != calculate_nvram_mct_hash()) - allow_config_restore = 0; -#else - allow_config_restore = 0; -#endif - - if (!allow_config_restore) - pDCTstat->spd_data.nvram_spd_match = 0; -} - -static void mct_initDCT(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u32 val; - u8 err_code; - - /* Config. DCT0 for Ganged or unganged mode */ - DCTInit_D(pMCTstat, pDCTstat, 0); - DCTFinalInit_D(pMCTstat, pDCTstat, 0); - if (pDCTstat->ErrCode == SC_FatalErr) { - /* Do nothing goto exitDCTInit; any fatal errors? */ - } else { - /* Configure DCT1 if unganged and enabled */ - if (!pDCTstat->GangedMode) { - if (pDCTstat->DIMMValidDCT[1] > 0) { - err_code = pDCTstat->ErrCode; /* save DCT0 errors */ - pDCTstat->ErrCode = 0; - DCTInit_D(pMCTstat, pDCTstat, 1); - DCTFinalInit_D(pMCTstat, pDCTstat, 1); - if (pDCTstat->ErrCode == 2) /* DCT1 is not Running */ - pDCTstat->ErrCode = err_code; /* Using DCT0 Error code to update pDCTstat.ErrCode */ - } else { - val = 1 << DisDramInterface; - Set_NB32_DCT(pDCTstat->dev_dct, 1, 0x94, val); - - val = Get_NB32_DCT(pDCTstat->dev_dct, 1, 0x90); - val &= ~(1 << ParEn); - Set_NB32_DCT(pDCTstat->dev_dct, 1, 0x90, val); - - /* To maximize power savings when DisDramInterface = 1b, - * all of the MemClkDis bits should also be set. - */ - Set_NB32_DCT(pDCTstat->dev_dct, 1, 0x88, 0xff000000); - } - } - } -} - -static void mct_DramInit(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - mct_BeforeDramInit_Prod_D(pMCTstat, pDCTstat, dct); - mct_DramInit_Sw_D(pMCTstat, pDCTstat, dct); - /* mct_DramInit_Hw_D(pMCTstat, pDCTstat, dct); */ -} - -static u8 mct_setMode(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u8 byte; - u8 bytex; - u32 val; - u32 reg; - - byte = bytex = pDCTstat->DIMMValid; - bytex &= 0x55; /* CHA DIMM pop */ - pDCTstat->DIMMValidDCT[0] = bytex; - - byte &= 0xAA; /* CHB DIMM popa */ - byte >>= 1; - pDCTstat->DIMMValidDCT[1] = byte; - - if (byte != bytex) { - pDCTstat->ErrStatus &= ~(1 << SB_DimmMismatchO); - } else { - byte = mctGet_NVbits(NV_Unganged); - if (byte) - pDCTstat->ErrStatus |= (1 << SB_DimmMismatchO); /* Set temp. to avoid setting of ganged mode */ - - if ((!(pDCTstat->ErrStatus & (1 << SB_DimmMismatchO))) && (pDCTstat->LogicalCPUID & AMD_FAM10_ALL)) { - /* Ganged channel mode not supported on Family 15h or higher */ - pDCTstat->GangedMode = 1; - /* valid 128-bit mode population. */ - pDCTstat->Status |= 1 << SB_128bitmode; - reg = 0x110; - val = Get_NB32(pDCTstat->dev_dct, reg); - val |= 1 << DctGangEn; - Set_NB32(pDCTstat->dev_dct, reg, val); - } - if (byte) /* NV_Unganged */ - pDCTstat->ErrStatus &= ~(1 << SB_DimmMismatchO); /* Clear so that there is no DIMM mismatch error */ - } - - return pDCTstat->ErrCode; -} - -u32 Get_NB32(u32 dev, u32 reg) -{ - return pci_read_config32(dev, reg); -} - -void Set_NB32(u32 dev, u32 reg, u32 val) -{ - pci_write_config32(dev, reg, val); -} - - -u32 Get_NB32_index(u32 dev, u32 index_reg, u32 index) -{ - u32 dword; - - Set_NB32(dev, index_reg, index); - dword = Get_NB32(dev, index_reg+0x4); - - return dword; -} - -void Set_NB32_index(u32 dev, u32 index_reg, u32 index, u32 data) -{ - Set_NB32(dev, index_reg, index); - Set_NB32(dev, index_reg + 0x4, data); -} - -u32 Get_NB32_index_wait(u32 dev, u32 index_reg, u32 index) -{ - u32 dword; - - index &= ~(1 << DctAccessWrite); - Set_NB32(dev, index_reg, index); - do { - dword = Get_NB32(dev, index_reg); - } while (!(dword & (1 << DctAccessDone))); - dword = Get_NB32(dev, index_reg + 0x4); - - return dword; -} - -void Set_NB32_index_wait(u32 dev, u32 index_reg, u32 index, u32 data) -{ - u32 dword; - - Set_NB32(dev, index_reg + 0x4, data); - index |= (1 << DctAccessWrite); - Set_NB32(dev, index_reg, index); - do { - dword = Get_NB32(dev, index_reg); - } while (!(dword & (1 << DctAccessDone))); - -} - -u8 mct_BeforePlatformSpec(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - printk(BIOS_DEBUG, "%s: Start\n", __func__); - - /* mct_checkForCxDxSupport_D */ - if (pDCTstat->LogicalCPUID & AMD_DR_GT_Bx) { - /* Family 10h Errata 322: Address and Command Fine Delay Values May Be Incorrect */ - /* 1. Write 00000000h to F2x[1,0]9C_xD08E000 */ - Set_NB32_index_wait_DCT(pDCTstat->dev_dct, dct, 0x98, 0x0D08E000, 0); - /* 2. If DRAM Configuration Register[MemClkFreq] (F2x[1,0]94[2:0]) is - greater than or equal to 011b (DDR-800 and higher), - then write 00000080h to F2x[1,0]9C_xD02E001, - else write 00000090h to F2x[1,0]9C_xD02E001. */ - if (pDCTstat->Speed >= mhz_to_memclk_config(mctGet_NVbits(NV_MIN_MEMCLK))) - Set_NB32_index_wait_DCT(pDCTstat->dev_dct, dct, 0x98, 0x0D02E001, 0x80); - else - Set_NB32_index_wait_DCT(pDCTstat->dev_dct, dct, 0x98, 0x0D02E001, 0x90); - } - - printk(BIOS_DEBUG, "%s: Done\n", __func__); - - return pDCTstat->ErrCode; -} - -u8 mct_PlatformSpec(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - /* Get platform specific config/timing values from the interface layer - * and program them into DCT. - */ - - printk(BIOS_DEBUG, "%s: Start\n", __func__); - - u32 dev = pDCTstat->dev_dct; - u32 index_reg; - u8 i, i_start, i_end; - - if (pDCTstat->GangedMode) { - SyncSetting(pDCTstat); - /* mct_SetupSync_D */ - i_start = 0; - i_end = 2; - } else { - i_start = dct; - i_end = dct + 1; - } - for (i = i_start; i < i_end; i++) { - index_reg = 0x98; - Set_NB32_index_wait_DCT(dev, i, index_reg, 0x00, pDCTstat->CH_ODC_CTL[i]); /* Channel A/B Output Driver Compensation Control */ - Set_NB32_index_wait_DCT(dev, i, index_reg, 0x04, pDCTstat->CH_ADDR_TMG[i]); /* Channel A/B Output Driver Compensation Control */ - printk(BIOS_SPEW, "Programmed DCT %d timing/termination pattern %08x %08x\n", dct, pDCTstat->CH_ADDR_TMG[i], pDCTstat->CH_ODC_CTL[i]); - } - - printk(BIOS_DEBUG, "%s: Done\n", __func__); - - return pDCTstat->ErrCode; -} - -static void mct_SyncDCTsReady(struct DCTStatStruc *pDCTstat) -{ - u32 dev; - u32 val; - - if (pDCTstat->NodePresent) { - dev = pDCTstat->dev_dct; - - if ((pDCTstat->DIMMValidDCT[0]) || (pDCTstat->DIMMValidDCT[1])) { - /* This Node has DRAM */ - do { - val = Get_NB32(dev, 0x110); - } while (!(val & (1 << DramEnabled))); - } - } /* Node is present */ -} - -static void mct_AfterGetCLT(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - if (!pDCTstat->GangedMode) { - if (dct == 0) { - pDCTstat->DIMMValid = pDCTstat->DIMMValidDCT[dct]; - if (pDCTstat->DIMMValidDCT[dct] == 0) - pDCTstat->ErrCode = SC_StopError; - } else { - pDCTstat->CSPresent = 0; - pDCTstat->CSTestFail = 0; - pDCTstat->DIMMValid = pDCTstat->DIMMValidDCT[dct]; - if (pDCTstat->DIMMValidDCT[dct] == 0) - pDCTstat->ErrCode = SC_StopError; - } - } -} - -static u8 mct_SPDCalcWidth(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u8 ret; - u32 val; - - if (dct == 0) { - SPDCalcWidth_D(pMCTstat, pDCTstat); - ret = mct_setMode(pMCTstat, pDCTstat); - } else { - ret = pDCTstat->ErrCode; - } - - if (pDCTstat->DIMMValidDCT[0] == 0) { - val = Get_NB32_DCT(pDCTstat->dev_dct, 0, 0x94); - val |= 1 << DisDramInterface; - Set_NB32_DCT(pDCTstat->dev_dct, 0, 0x94, val); - - val = Get_NB32_DCT(pDCTstat->dev_dct, 0, 0x90); - val &= ~(1 << ParEn); - Set_NB32_DCT(pDCTstat->dev_dct, 0, 0x90, val); - } - if (pDCTstat->DIMMValidDCT[1] == 0) { - val = Get_NB32_DCT(pDCTstat->dev_dct, 1, 0x94); - val |= 1 << DisDramInterface; - Set_NB32_DCT(pDCTstat->dev_dct, 1, 0x94, val); - - val = Get_NB32_DCT(pDCTstat->dev_dct, 1, 0x90); - val &= ~(1 << ParEn); - Set_NB32_DCT(pDCTstat->dev_dct, 1, 0x90, val); - } - - printk(BIOS_DEBUG, "SPDCalcWidth: Status %x\n", pDCTstat->Status); - printk(BIOS_DEBUG, "SPDCalcWidth: ErrStatus %x\n", pDCTstat->ErrStatus); - printk(BIOS_DEBUG, "SPDCalcWidth: ErrCode %x\n", pDCTstat->ErrCode); - printk(BIOS_DEBUG, "SPDCalcWidth: Done\n"); - /* Disable dram interface before DRAM init */ - - return ret; -} - -static void mct_AfterStitchMemory(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u32 val; - u32 dword; - u32 dev; - u32 reg; - u8 _MemHoleRemap; - u32 DramHoleBase; - - _MemHoleRemap = mctGet_NVbits(NV_MemHole); - DramHoleBase = mctGet_NVbits(NV_BottomIO); - DramHoleBase <<= 8; - /* Increase hole size so;[31:24]to[31:16] - * it has granularity of 128MB shl eax,8 - * Set 'effective' bottom IOmov DramHoleBase,eax - */ - pMCTstat->HoleBase = (DramHoleBase & 0xFFFFF800) << 8; - - /* In unganged mode, we must add DCT0 and DCT1 to DCTSysLimit */ - if (!pDCTstat->GangedMode) { - dev = pDCTstat->dev_dct; - pDCTstat->NodeSysLimit += pDCTstat->DCTSysLimit; - /* if DCT0 and DCT1 both exist, set DctSelBaseAddr[47:27] to the top of DCT0 */ - if (dct == 0) { - if (pDCTstat->DIMMValidDCT[1] > 0) { - dword = pDCTstat->DCTSysLimit + 1; - dword += pDCTstat->NodeSysBase; - dword >>= 8; /* scale [39:8] to [47:27],and to F2x110[31:11] */ - if ((dword >= DramHoleBase) && _MemHoleRemap) { - pMCTstat->HoleBase = (DramHoleBase & 0xFFFFF800) << 8; - val = pMCTstat->HoleBase; - val >>= 16; - val = (((~val) & 0xFF) + 1); - val <<= 8; - dword += val; - } - reg = 0x110; - val = Get_NB32(dev, reg); - val &= 0x7F; - val |= dword; - val |= 3; /* Set F2x110[DctSelHiRngEn], F2x110[DctSelHi] */ - Set_NB32(dev, reg, val); - - reg = 0x114; - val = dword; - Set_NB32(dev, reg, val); - } - } else { - /* Program the DctSelBaseAddr value to 0 - if DCT 0 is disabled */ - if (pDCTstat->DIMMValidDCT[0] == 0) { - dword = pDCTstat->NodeSysBase; - dword >>= 8; - if ((dword >= DramHoleBase) && _MemHoleRemap) { - pMCTstat->HoleBase = (DramHoleBase & 0xFFFFF800) << 8; - val = pMCTstat->HoleBase; - val >>= 8; - val &= ~(0xFFFF); - val |= (((~val) & 0xFFFF) + 1); - dword += val; - } - reg = 0x114; - val = dword; - Set_NB32(dev, reg, val); - - reg = 0x110; - val |= 3; /* Set F2x110[DctSelHiRngEn], F2x110[DctSelHi] */ - Set_NB32(dev, reg, val); - } - } - } else { - pDCTstat->NodeSysLimit += pDCTstat->DCTSysLimit; - } - printk(BIOS_DEBUG, "AfterStitch pDCTstat->NodeSysBase = %x\n", pDCTstat->NodeSysBase); - printk(BIOS_DEBUG, "mct_AfterStitchMemory: pDCTstat->NodeSysLimit = %x\n", pDCTstat->NodeSysLimit); -} - -static u8 mct_DIMMPresence(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u8 ret; - - if (dct == 0) - ret = DIMMPresence_D(pMCTstat, pDCTstat); - else - ret = pDCTstat->ErrCode; - - return ret; -} - -/* mct_BeforeGetDIMMAddress inline in C */ - -static void mct_OtherTiming(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - u8 Node; - - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - if (pDCTstat->NodePresent) { - if (pDCTstat->DIMMValidDCT[0]) { - pDCTstat->DIMMValid = pDCTstat->DIMMValidDCT[0]; - Set_OtherTiming(pMCTstat, pDCTstat, 0); - } - if (pDCTstat->DIMMValidDCT[1] && !pDCTstat->GangedMode) { - pDCTstat->DIMMValid = pDCTstat->DIMMValidDCT[1]; - Set_OtherTiming(pMCTstat, pDCTstat, 1); - } - } /* Node is present*/ - } /* while Node */ -} - -static void Set_OtherTiming(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u32 reg; - u32 val; - u32 dword; - u32 dev = pDCTstat->dev_dct; - - Get_DqsRcvEnGross_Diff(pDCTstat, dev, dct, 0x98); - Get_WrDatGross_Diff(pDCTstat, dct, dev, 0x98); - Get_Trdrd(pMCTstat, pDCTstat, dct); - Get_Twrwr(pMCTstat, pDCTstat, dct); - Get_Twrrd(pMCTstat, pDCTstat, dct); - Get_TrwtTO(pMCTstat, pDCTstat, dct); - Get_TrwtWB(pMCTstat, pDCTstat); - - if (!is_fam15h()) { - reg = 0x8c; /* Dram Timing Hi */ - val = Get_NB32_DCT(dev, dct, reg); - val &= 0xffff0300; - dword = pDCTstat->TrwtTO; - val |= dword << 4; - dword = pDCTstat->Twrrd & 3; - val |= dword << 10; - dword = pDCTstat->Twrwr & 3; - val |= dword << 12; - dword = (pDCTstat->Trdrd - 0x3) & 3; - val |= dword << 14; - dword = pDCTstat->TrwtWB; - val |= dword; - Set_NB32_DCT(dev, dct, reg, val); - - reg = 0x78; - val = Get_NB32_DCT(dev, dct, reg); - val &= 0xffffc0ff; - dword = pDCTstat->Twrrd >> 2; - val |= dword << 8; - dword = pDCTstat->Twrwr >> 2; - val |= dword << 10; - dword = (pDCTstat->Trdrd - 0x3) >> 2; - val |= dword << 12; - Set_NB32_DCT(dev, dct, reg, val); - } -} - -static void Get_Trdrd(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - int8_t Trdrd; - - Trdrd = ((int8_t)(pDCTstat->DqsRcvEnGrossMax - pDCTstat->DqsRcvEnGrossMin) >> 1) + 1; - if (Trdrd > 8) - Trdrd = 8; - if (Trdrd < 3) - Trdrd = 3; - pDCTstat->Trdrd = Trdrd; -} - -static void Get_Twrwr(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - int8_t Twrwr = 0; - - Twrwr = ((int8_t)(pDCTstat->WrDatGrossMax - pDCTstat->WrDatGrossMin) >> 1) + 2; - - if (Twrwr < 2) - Twrwr = 2; - else if (Twrwr > 9) - Twrwr = 9; - - pDCTstat->Twrwr = Twrwr; -} - -static void Get_Twrrd(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u8 LDplus1; - int8_t Twrrd; - - LDplus1 = Get_Latency_Diff(pMCTstat, pDCTstat, dct); - - Twrrd = ((int8_t)(pDCTstat->WrDatGrossMax - pDCTstat->DqsRcvEnGrossMin) >> 1) + 4 - LDplus1; - - if (Twrrd < 2) - Twrrd = 2; - else if (Twrrd > 10) - Twrrd = 10; - pDCTstat->Twrrd = Twrrd; -} - -static void Get_TrwtTO(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u8 LDplus1; - int8_t TrwtTO; - - LDplus1 = Get_Latency_Diff(pMCTstat, pDCTstat, dct); - - TrwtTO = ((int8_t)(pDCTstat->DqsRcvEnGrossMax - pDCTstat->WrDatGrossMin) >> 1) + LDplus1; - - pDCTstat->TrwtTO = TrwtTO; -} - -static void Get_TrwtWB(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - /* TrwtWB ensures read-to-write data-bus turnaround. - This value should be one more than the programmed TrwtTO.*/ - pDCTstat->TrwtWB = pDCTstat->TrwtTO; -} - -static u8 Get_Latency_Diff(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u32 dev = pDCTstat->dev_dct; - u32 val1, val2; - - val1 = Get_NB32_DCT(dev, dct, 0x88) & 0xF; - val2 = (Get_NB32_DCT(dev, dct, 0x84) >> 20) & 7; - - return val1 - val2; -} - -static void Get_DqsRcvEnGross_Diff(struct DCTStatStruc *pDCTstat, - u32 dev, uint8_t dct, u32 index_reg) -{ - u8 Smallest, Largest; - u32 val; - u8 byte, bytex; - - /* The largest DqsRcvEnGrossDelay of any DIMM minus the - DqsRcvEnGrossDelay of any other DIMM is equal to the Critical - Gross Delay Difference (CGDD) */ - /* DqsRcvEn byte 1,0 */ - val = Get_DqsRcvEnGross_MaxMin(pDCTstat, dev, dct, index_reg, 0x10); - Largest = val & 0xFF; - Smallest = (val >> 8) & 0xFF; - - /* DqsRcvEn byte 3,2 */ - val = Get_DqsRcvEnGross_MaxMin(pDCTstat, dev, dct, index_reg, 0x11); - byte = val & 0xFF; - bytex = (val >> 8) & 0xFF; - if (bytex < Smallest) - Smallest = bytex; - if (byte > Largest) - Largest = byte; - - /* DqsRcvEn byte 5,4 */ - val = Get_DqsRcvEnGross_MaxMin(pDCTstat, dev, dct, index_reg, 0x20); - byte = val & 0xFF; - bytex = (val >> 8) & 0xFF; - if (bytex < Smallest) - Smallest = bytex; - if (byte > Largest) - Largest = byte; - - /* DqsRcvEn byte 7,6 */ - val = Get_DqsRcvEnGross_MaxMin(pDCTstat, dev, dct, index_reg, 0x21); - byte = val & 0xFF; - bytex = (val >> 8) & 0xFF; - if (bytex < Smallest) - Smallest = bytex; - if (byte > Largest) - Largest = byte; - - if (pDCTstat->DimmECCPresent> 0) { - /*DqsRcvEn Ecc */ - val = Get_DqsRcvEnGross_MaxMin(pDCTstat, dev, dct, index_reg, 0x12); - byte = val & 0xFF; - bytex = (val >> 8) & 0xFF; - if (bytex < Smallest) - Smallest = bytex; - if (byte > Largest) - Largest = byte; - } - - pDCTstat->DqsRcvEnGrossMax = Largest; - pDCTstat->DqsRcvEnGrossMin = Smallest; -} - -static void Get_WrDatGross_Diff(struct DCTStatStruc *pDCTstat, - u8 dct, u32 dev, u32 index_reg) -{ - u8 Smallest = 0, Largest = 0; - u32 val; - u8 byte, bytex; - - /* The largest WrDatGrossDlyByte of any DIMM minus the - WrDatGrossDlyByte of any other DIMM is equal to CGDD */ - if (pDCTstat->DIMMValid & (1 << 0)) { - val = Get_WrDatGross_MaxMin(pDCTstat, dct, dev, index_reg, 0x01); /* WrDatGrossDlyByte byte 0,1,2,3 for DIMM0 */ - Largest = val & 0xFF; - Smallest = (val >> 8) & 0xFF; - } - if (pDCTstat->DIMMValid & (1 << 2)) { - val = Get_WrDatGross_MaxMin(pDCTstat, dct, dev, index_reg, 0x101); /* WrDatGrossDlyByte byte 0,1,2,3 for DIMM1 */ - byte = val & 0xFF; - bytex = (val >> 8) & 0xFF; - if (bytex < Smallest) - Smallest = bytex; - if (byte > Largest) - Largest = byte; - } - - /* If Cx, 2 more dimm need to be checked to find out the largest and smallest */ - if (pDCTstat->LogicalCPUID & AMD_DR_Cx) { - if (pDCTstat->DIMMValid & (1 << 4)) { - val = Get_WrDatGross_MaxMin(pDCTstat, dct, dev, index_reg, 0x201); /* WrDatGrossDlyByte byte 0,1,2,3 for DIMM2 */ - byte = val & 0xFF; - bytex = (val >> 8) & 0xFF; - if (bytex < Smallest) - Smallest = bytex; - if (byte > Largest) - Largest = byte; - } - if (pDCTstat->DIMMValid & (1 << 6)) { - val = Get_WrDatGross_MaxMin(pDCTstat, dct, dev, index_reg, 0x301); /* WrDatGrossDlyByte byte 0,1,2,3 for DIMM2 */ - byte = val & 0xFF; - bytex = (val >> 8) & 0xFF; - if (bytex < Smallest) - Smallest = bytex; - if (byte > Largest) - Largest = byte; - } - } - - pDCTstat->WrDatGrossMax = Largest; - pDCTstat->WrDatGrossMin = Smallest; -} - -static u16 Get_DqsRcvEnGross_MaxMin(struct DCTStatStruc *pDCTstat, - u32 dev, uint8_t dct, u32 index_reg, - u32 index) -{ - u8 Smallest, Largest; - u8 i; - u8 byte; - u32 val; - u16 word; - u8 ecc_reg = 0; - - Smallest = 7; - Largest = 0; - - if (index == 0x12) - ecc_reg = 1; - - for (i = 0; i < 8; i+=2) { - if (pDCTstat->DIMMValid & (1 << i)) { - val = Get_NB32_index_wait_DCT(dev, dct, index_reg, index); - val &= 0x00E000E0; - byte = (val >> 5) & 0xFF; - if (byte < Smallest) - Smallest = byte; - if (byte > Largest) - Largest = byte; - if (!(ecc_reg)) { - byte = (val >> (16 + 5)) & 0xFF; - if (byte < Smallest) - Smallest = byte; - if (byte > Largest) - Largest = byte; - } - } - index += 3; - } /* while ++i */ - - word = Smallest; - word <<= 8; - word |= Largest; - - return word; -} - -static u16 Get_WrDatGross_MaxMin(struct DCTStatStruc *pDCTstat, - u8 dct, u32 dev, u32 index_reg, - u32 index) -{ - u8 Smallest, Largest; - u8 i, j; - u32 val; - u8 byte; - u16 word; - - Smallest = 3; - Largest = 0; - for (i = 0; i < 2; i++) { - val = Get_NB32_index_wait_DCT(dev, dct, index_reg, index); - val &= 0x60606060; - val >>= 5; - for (j = 0; j < 4; j++) { - byte = val & 0xFF; - if (byte < Smallest) - Smallest = byte; - if (byte > Largest) - Largest = byte; - val >>= 8; - } /* while ++j */ - index++; - } /*while ++i*/ - - if (pDCTstat->DimmECCPresent > 0) { - index++; - val = Get_NB32_index_wait_DCT(dev, dct, index_reg, index); - val &= 0x00000060; - val >>= 5; - byte = val & 0xFF; - if (byte < Smallest) - Smallest = byte; - if (byte > Largest) - Largest = byte; - } - - word = Smallest; - word <<= 8; - word |= Largest; - - return word; -} - -static void mct_PhyController_Config(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - uint8_t index; - uint32_t dword; - u32 index_reg = 0x98; - u32 dev = pDCTstat->dev_dct; - - if (pDCTstat->LogicalCPUID & (AMD_DR_DAC2_OR_C3 | AMD_RB_C3 | AMD_FAM15_ALL)) { - if (is_fam15h()) { - /* Set F2x[1, 0]98_x0D0F0F13 DllDisEarlyU and DllDisEarlyL to save power */ - for (index = 0; index < 0x9; index++) { - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0013 | (index << 8)); - dword |= (0x1 << 1); /* DllDisEarlyU = 1 */ - dword |= 0x1; /* DllDisEarlyL = 1 */ - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0013 | (index << 8), dword); - } - } - - if (pDCTstat->Dimmx4Present == 0) { - /* Set bit7 RxDqsUDllPowerDown to register F2x[1, 0]98_x0D0F0F13 for - * additional power saving when x4 DIMMs are not present. - */ - for (index = 0; index < 0x9; index++) { - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0013 | (index << 8)); - dword |= (0x1 << 7); /* RxDqsUDllPowerDown = 1 */ - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0013 | (index << 8), dword); - } - } - } - - if (pDCTstat->LogicalCPUID & (AMD_DR_DAC2_OR_C3 | AMD_FAM15_ALL)) { - if (pDCTstat->DimmECCPresent == 0) { - /* Set bit4 PwrDn to register F2x[1, 0]98_x0D0F0830 for power saving */ - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0830); - dword |= 1 << 4; /* BIOS should set this bit if ECC DIMMs are not present */ - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0830, dword); - } - } - -} - -static void mct_FinalMCT_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - u8 Node; - struct DCTStatStruc *pDCTstat; - u32 val; - - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - pDCTstat = pDCTstatA + Node; - - if (pDCTstat->NodePresent) { - mct_PhyController_Config(pMCTstat, pDCTstat, 0); - mct_PhyController_Config(pMCTstat, pDCTstat, 1); - - if (!is_fam15h()) { - /* Family 10h CPUs */ - mct_ExtMCTConfig_Cx(pDCTstat); - mct_ExtMCTConfig_Bx(pDCTstat); - mct_ExtMCTConfig_Dx(pDCTstat); - } else { - /* Family 15h CPUs */ - uint8_t nvram; - uint8_t enable_experimental_memory_speed_boost; - - /* Check to see if cache partitioning is allowed */ - enable_experimental_memory_speed_boost = 0; - if (get_option(&nvram, "experimental_memory_speed_boost") == CB_SUCCESS) - enable_experimental_memory_speed_boost = !!nvram; - - val = 0x0ce00f00; /* FlushWrOnStpGnt = 0x0 */ - val |= 0x10 << 2; /* MctWrLimit = 0x10 */ - val |= 0x1; /* DctWrLimit = 0x1 */ - Set_NB32(pDCTstat->dev_dct, 0x11c, val); - - val = Get_NB32(pDCTstat->dev_dct, 0x1b0); - val &= ~0x3; /* AdapPrefMissRatio = 0x1 */ - val |= 0x1; - val &= ~(0x3 << 2); /* AdapPrefPositiveStep = 0x0 */ - val &= ~(0x3 << 4); /* AdapPrefNegativeStep = 0x0 */ - val &= ~(0x7 << 8); /* CohPrefPrbLmt = 0x1 */ - val |= (0x1 << 8); - val |= (0x1 << 12); /* EnSplitDctLimits = 0x1 */ - if (enable_experimental_memory_speed_boost) - val |= (0x1 << 20); /* DblPrefEn = 0x1 */ - val |= (0x7 << 22); /* PrefFourConf = 0x7 */ - val |= (0x7 << 25); /* PrefFiveConf = 0x7 */ - val &= ~(0xf << 28); /* DcqBwThrotWm = 0x0 */ - Set_NB32(pDCTstat->dev_dct, 0x1b0, val); - - uint8_t wm1; - uint8_t wm2; - - switch (pDCTstat->Speed) { - case 0x4: - wm1 = 0x3; - wm2 = 0x4; - break; - case 0x6: - wm1 = 0x3; - wm2 = 0x5; - break; - case 0xa: - wm1 = 0x4; - wm2 = 0x6; - break; - case 0xe: - wm1 = 0x5; - wm2 = 0x8; - break; - case 0x12: - wm1 = 0x6; - wm2 = 0x9; - break; - default: - wm1 = 0x7; - wm2 = 0xa; - break; - } - - val = Get_NB32(pDCTstat->dev_dct, 0x1b4); - val &= ~(0x3ff); - val |= ((wm2 & 0x1f) << 5); - val |= (wm1 & 0x1f); - Set_NB32(pDCTstat->dev_dct, 0x1b4, val); - } - } - } - - /* ClrClToNB_D postponed until we're done executing from ROM */ - mct_ClrWbEnhWsbDis_D(pMCTstat, pDCTstat); - - /* set F3x8C[DisFastTprWr] on all DR, if L3Size = 0 */ - if (pDCTstat->LogicalCPUID & AMD_DR_ALL) { - if (!(cpuid_edx(0x80000006) & 0xFFFC0000)) { - val = Get_NB32(pDCTstat->dev_nbmisc, 0x8C); - val |= 1 << 24; - Set_NB32(pDCTstat->dev_nbmisc, 0x8C, val); - } - } -} - -void mct_ForceNBPState0_En_Fam15(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - /* Force the NB P-state to P0 */ - uint32_t dword; - uint32_t dword2; - - dword = Get_NB32(pDCTstat->dev_nbctl, 0x174); - if (!(dword & 0x1)) { - dword = Get_NB32(pDCTstat->dev_nbctl, 0x170); - pDCTstat->SwNbPstateLoDis = (dword >> 14) & 0x1; - pDCTstat->NbPstateDisOnP0 = (dword >> 13) & 0x1; - pDCTstat->NbPstateThreshold = (dword >> 9) & 0x7; - pDCTstat->NbPstateHi = (dword >> 6) & 0x3; - dword &= ~(0x1 << 14); /* SwNbPstateLoDis = 0 */ - dword &= ~(0x1 << 13); /* NbPstateDisOnP0 = 0 */ - dword &= ~(0x7 << 9); /* NbPstateThreshold = 0 */ - dword &= ~(0x3 << 3); /* NbPstateLo = NbPstateMaxVal */ - dword |= ((dword & 0x3) << 3); - Set_NB32(pDCTstat->dev_nbctl, 0x170, dword); - - if (!is_model10_1f()) { - /* Wait until CurNbPState == NbPstateLo */ - do { - dword2 = Get_NB32(pDCTstat->dev_nbctl, 0x174); - } while (((dword2 >> 19) & 0x7) != (dword & 0x3)); - } - dword = Get_NB32(pDCTstat->dev_nbctl, 0x170); - dword &= ~(0x3 << 6); /* NbPstateHi = 0 */ - dword |= (0x3 << 14); /* SwNbPstateLoDis = 1 */ - Set_NB32(pDCTstat->dev_nbctl, 0x170, dword); - - if (!is_model10_1f()) { - /* Wait until CurNbPState == 0 */ - do { - dword2 = Get_NB32(pDCTstat->dev_nbctl, 0x174); - } while (((dword2 >> 19) & 0x7) != 0); - } - } -} - -void mct_ForceNBPState0_Dis_Fam15(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - /* Restore normal NB P-state functionailty */ - uint32_t dword; - - dword = Get_NB32(pDCTstat->dev_nbctl, 0x174); - if (!(dword & 0x1)) { - dword = Get_NB32(pDCTstat->dev_nbctl, 0x170); - dword &= ~(0x1 << 14); /* SwNbPstateLoDis*/ - dword |= ((pDCTstat->SwNbPstateLoDis & 0x1) << 14); - dword &= ~(0x1 << 13); /* NbPstateDisOnP0 */ - dword |= ((pDCTstat->NbPstateDisOnP0 & 0x1) << 13); - dword &= ~(0x7 << 9); /* NbPstateThreshold */ - dword |= ((pDCTstat->NbPstateThreshold & 0x7) << 9); - dword &= ~(0x3 << 6); /* NbPstateHi */ - dword |= ((pDCTstat->NbPstateHi & 0x3) << 3); - Set_NB32(pDCTstat->dev_nbctl, 0x170, dword); - } -} - -static void mct_InitialMCT_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat) -{ - if (is_fam15h()) { - msr_t p0_state_msr; - uint8_t cpu_fid; - uint8_t cpu_did; - uint32_t cpu_divisor; - uint8_t boost_states; - - /* Retrieve the number of boost states */ - boost_states = (Get_NB32(pDCTstat->dev_link, 0x15c) >> 2) & 0x7; - - /* Retrieve and store the TSC frequency (P0 COF) */ - p0_state_msr = rdmsr(PSTATE_0_MSR + boost_states); - cpu_fid = p0_state_msr.lo & 0x3f; - cpu_did = (p0_state_msr.lo >> 6) & 0x7; - cpu_divisor = (0x1 << cpu_did); - pMCTstat->TSCFreq = (100 * (cpu_fid + 0x10)) / cpu_divisor; - - printk(BIOS_DEBUG, "mct_InitialMCT_D: mct_ForceNBPState0_En_Fam15\n"); - mct_ForceNBPState0_En_Fam15(pMCTstat, pDCTstat); - } else { - /* K10 BKDG v3.62 section 2.8.9.2 */ - printk(BIOS_DEBUG, "mct_InitialMCT_D: clear_legacy_Mode\n"); - clear_legacy_Mode(pMCTstat, pDCTstat); - - /* Northbridge configuration */ - mct_SetClToNB_D(pMCTstat, pDCTstat); - mct_SetWbEnhWsbDis_D(pMCTstat, pDCTstat); - } -} - -static u32 mct_NodePresent_D(void) -{ - u32 val; - if (is_fam15h()) { - if (is_model10_1f()) { - val = 0x14001022; - } else { - val = 0x16001022; - } - } else { - val = 0x12001022; - } - return val; -} - -static void mct_init(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u32 lo, hi; - u32 addr; - - pDCTstat->GangedMode = 0; - pDCTstat->DRPresent = 1; - - /* enable extend PCI configuration access */ - addr = NB_CFG_MSR; - _RDMSR(addr, &lo, &hi); - if (hi & (1 << (46-32))) { - pDCTstat->Status |= 1 << SB_ExtConfig; - } else { - hi |= 1 << (46-32); - _WRMSR(addr, lo, hi); - } -} - -static void clear_legacy_Mode(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u32 reg; - u32 val; - u32 dev = pDCTstat->dev_dct; - - /* Clear Legacy BIOS Mode bit */ - reg = 0x94; - val = Get_NB32_DCT(dev, 0, reg); - val &= ~(1<<LegacyBiosMode); - Set_NB32_DCT(dev, 0, reg, val); - - val = Get_NB32_DCT(dev, 1, reg); - val &= ~(1<<LegacyBiosMode); - Set_NB32_DCT(dev, 1, reg, val); -} - -static void mct_HTMemMapExt(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - u8 Node; - u32 Drambase, Dramlimit; - u32 val; - u32 reg; - u32 dev; - u32 devx; - u32 dword; - struct DCTStatStruc *pDCTstat; - - pDCTstat = pDCTstatA + 0; - dev = pDCTstat->dev_map; - - /* Copy dram map from F1x40/44,F1x48/4c, - to F1x120/124(Node0),F1x120/124(Node1),...*/ - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - pDCTstat = pDCTstatA + Node; - devx = pDCTstat->dev_map; - - /* get base/limit from Node0 */ - reg = 0x40 + (Node << 3); /* Node0/Dram Base 0 */ - val = Get_NB32(dev, reg); - Drambase = val >> (16 + 3); - - reg = 0x44 + (Node << 3); /* Node0/Dram Base 0 */ - val = Get_NB32(dev, reg); - Dramlimit = val >> (16 + 3); - - /* set base/limit to F1x120/124 per Node */ - if (pDCTstat->NodePresent) { - reg = 0x120; /* F1x120,DramBase[47:27] */ - val = Get_NB32(devx, reg); - val &= 0xFFE00000; - val |= Drambase; - Set_NB32(devx, reg, val); - - reg = 0x124; - val = Get_NB32(devx, reg); - val &= 0xFFE00000; - val |= Dramlimit; - Set_NB32(devx, reg, val); - - if (pMCTstat->GStatus & (1 << GSB_HWHole)) { - reg = 0xF0; - val = Get_NB32(devx, reg); - val |= (1 << DramMemHoistValid); - val &= ~(0xFF << 24); - dword = (pMCTstat->HoleBase >> (24 - 8)) & 0xFF; - dword <<= 24; - val |= dword; - Set_NB32(devx, reg, val); - } - - } - } -} - -static void SetCSTriState(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u32 val; - u32 dev = pDCTstat->dev_dct; - u32 index_reg = 0x98; - u16 word; - - if (is_fam15h()) { - word = fam15h_cs_tristate_enable_code(pDCTstat, dct); - } else { - /* Tri-state unused chipselects when motherboard - termination is available */ - - /* FIXME: skip for Ax */ - - word = pDCTstat->CSPresent; - if (pDCTstat->Status & (1 << SB_Registered)) { - word |= (word & 0x55) << 1; - } - word = (~word) & 0xff; - } - - val = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000c); - val &= ~0xff; - val |= word; - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000c, val); -} - -static void SetCKETriState(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u32 val; - u32 dev; - u32 index_reg = 0x98; - u16 word; - - /* Tri-state unused CKEs when motherboard termination is available */ - - /* FIXME: skip for Ax */ - - dev = pDCTstat->dev_dct; - word = pDCTstat->CSPresent; - - val = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000c); - val &= ~(0x3 << 12); - if ((word & 0x55) == 0) - val |= 1 << 12; - if ((word & 0xaa) == 0) - val |= 1 << 13; - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000c, val); -} - -static void SetODTTriState(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u32 val; - u32 dev; - u32 index_reg = 0x98; - u8 cs; - u8 odt; - - dev = pDCTstat->dev_dct; - - if (is_fam15h()) { - odt = fam15h_odt_tristate_enable_code(pDCTstat, dct); - } else { - /* FIXME: skip for Ax */ - - /* Tri-state unused ODTs when motherboard termination is available */ - odt = 0x0f; /* ODT tri-state setting */ - - if (pDCTstat->Status & (1 <<SB_Registered)) { - for (cs = 0; cs < 8; cs += 2) { - if (pDCTstat->CSPresent & (1 << cs)) { - odt &= ~(1 << (cs / 2)); - if (mctGet_NVbits(NV_4RANKType) != 0) { /* quad-rank capable platform */ - if (pDCTstat->CSPresent & (1 << (cs + 1))) - odt &= ~(4 << (cs / 2)); - } - } - } - } else { /* AM3 package */ - val = ~(pDCTstat->CSPresent); - odt = val & 9; /* swap bits 1 and 2 */ - if (val & (1 << 1)) - odt |= 1 << 2; - if (val & (1 << 2)) - odt |= 1 << 1; - } - } - - val = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000c); - val &= ~(0xf << 8); /* ODTTri = odt */ - val |= (odt & 0xf) << 8; - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000c, val); -} - -/* Family 15h */ -static void InitDDRPhy(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - uint8_t index; - uint32_t dword; - uint8_t ddr_voltage_index; - uint8_t amd_voltage_level_index = 0; - uint32_t index_reg = 0x98; - uint32_t dev = pDCTstat->dev_dct; - - printk(BIOS_DEBUG, "%s: Start\n", __func__); - - /* Find current DDR supply voltage for this DCT */ - ddr_voltage_index = dct_ddr_voltage_index(pDCTstat, dct); - - /* Fam15h BKDG v3.14 section 2.10.5.3 - * The remainder of the Phy Initialization algorithm picks up in phyAssistedMemFnceTraining - */ - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000b, 0x80000000); - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fe013, 0x00000118); - - /* Program desired VDDIO level */ - if (ddr_voltage_index & 0x4) { - /* 1.25V */ - amd_voltage_level_index = 0x2; - } else if (ddr_voltage_index & 0x2) { - /* 1.35V */ - amd_voltage_level_index = 0x1; - } else if (ddr_voltage_index & 0x1) { - /* 1.50V */ - amd_voltage_level_index = 0x0; - } - - /* D18F2x9C_x0D0F_0[F,8:0]1F_dct[1:0][RxVioLvl] */ - for (index = 0; index < 0x9; index++) { - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f001f | (index << 8)); - dword &= ~(0x3 << 3); - dword |= (amd_voltage_level_index << 3); - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f001f | (index << 8), dword); - } - - /* D18F2x9C_x0D0F_[C,8,2][2:0]1F_dct[1:0][RxVioLvl] */ - for (index = 0; index < 0x3; index++) { - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f201f | (index << 8)); - dword &= ~(0x3 << 3); - dword |= (amd_voltage_level_index << 3); - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f201f | (index << 8), dword); - } - for (index = 0; index < 0x2; index++) { - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f801f | (index << 8)); - dword &= ~(0x3 << 3); - dword |= (amd_voltage_level_index << 3); - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f801f | (index << 8), dword); - } - for (index = 0; index < 0x1; index++) { - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc01f | (index << 8)); - dword &= ~(0x3 << 3); - dword |= (amd_voltage_level_index << 3); - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc01f | (index << 8), dword); - } - - /* D18F2x9C_x0D0F_4009_dct[1:0][CmpVioLvl, ComparatorAdjust] */ - /* NOTE: CmpVioLvl and ComparatorAdjust only take effect when set on DCT 0 */ - dword = Get_NB32_index_wait_DCT(dev, 0, index_reg, 0x0d0f4009); - dword &= ~(0x0000c00c); - dword |= (amd_voltage_level_index << 14); - dword |= (amd_voltage_level_index << 2); - Set_NB32_index_wait_DCT(dev, 0, index_reg, 0x0d0f4009, dword); - - printk(BIOS_DEBUG, "%s: Done\n", __func__); -} - -void InitPhyCompensation(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u8 i; - u32 index_reg = 0x98; - u32 dev = pDCTstat->dev_dct; - u32 valx = 0; - uint8_t index; - uint32_t dword; - const u8 *p; - - printk(BIOS_DEBUG, "%s: DCT %d: Start\n", __func__, dct); - - if (is_fam15h()) { - /* Algorithm detailed in the Fam15h BKDG Rev. 3.14 section 2.10.5.3.4 */ - uint32_t tx_pre; - uint32_t drive_strength; - - /* Program D18F2x9C_x0D0F_E003_dct[1:0][DisAutoComp] */ - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fe003); - dword |= (0x1 << 14); - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fe003, dword); - - /* Program D18F2x9C_x0D0F_E003_dct[1:0][DisablePredriverCal] */ - /* NOTE: DisablePredriverCal only takes effect when set on DCT 0 */ - dword = Get_NB32_index_wait_DCT(dev, 0, index_reg, 0x0d0fe003); - dword |= (0x1 << 13); - Set_NB32_index_wait_DCT(dev, 0, index_reg, 0x0d0fe003, dword); - - /* Determine TxPreP/TxPreN for data lanes (Stage 1) */ - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x00000000); - drive_strength = (dword >> 20) & 0x7; /* DqsDrvStren */ - tx_pre = fam15h_phy_predriver_calibration_code(pDCTstat, dct, drive_strength); - - /* Program TxPreP/TxPreN for data lanes (Stage 1) */ - for (index = 0; index < 0x9; index++) { - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0006 | (index << 8)); - dword &= ~(0xffff); - dword |= tx_pre; - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0006 | (index << 8), dword); - } - - /* Determine TxPreP/TxPreN for data lanes (Stage 2) */ - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x00000000); - drive_strength = (dword >> 16) & 0x7; /* DataDrvStren */ - tx_pre = fam15h_phy_predriver_calibration_code(pDCTstat, dct, drive_strength); - - /* Program TxPreP/TxPreN for data lanes (Stage 2) */ - for (index = 0; index < 0x9; index++) { - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f000a | (index << 8)); - dword &= ~(0xffff); - dword |= tx_pre; - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f000a | (index << 8), dword); - } - for (index = 0; index < 0x9; index++) { - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0002 | (index << 8)); - dword &= ~(0xffff); - dword |= (0x8000 | tx_pre); - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0002 | (index << 8), dword); - } - - /* Determine TxPreP/TxPreN for command/address lines (Stage 1) */ - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x00000000); - drive_strength = (dword >> 4) & 0x7; /* CsOdtDrvStren */ - tx_pre = fam15h_phy_predriver_cmd_addr_calibration_code(pDCTstat, dct, drive_strength); - - /* Program TxPreP/TxPreN for command/address lines (Stage 1) */ - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8006); - dword &= ~(0xffff); - dword |= tx_pre; - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8006, dword); - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f800a); - dword &= ~(0xffff); - dword |= tx_pre; - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f800a, dword); - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8002); - dword &= ~(0xffff); - dword |= (0x8000 | tx_pre); - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8002, dword); - - /* Determine TxPreP/TxPreN for command/address lines (Stage 2) */ - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x00000000); - drive_strength = (dword >> 8) & 0x7; /* AddrCmdDrvStren */ - tx_pre = fam15h_phy_predriver_cmd_addr_calibration_code(pDCTstat, dct, drive_strength); - - /* Program TxPreP/TxPreN for command/address lines (Stage 2) */ - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8106); - dword &= ~(0xffff); - dword |= tx_pre; - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8106, dword); - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f810a); - dword &= ~(0xffff); - dword |= tx_pre; - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f810a, dword); - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc006); - dword &= ~(0xffff); - dword |= tx_pre; - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc006, dword); - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc00a); - dword &= ~(0xffff); - dword |= tx_pre; - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc00a, dword); - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc00e); - dword &= ~(0xffff); - dword |= tx_pre; - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc00e, dword); - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc012); - dword &= ~(0xffff); - dword |= tx_pre; - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc012, dword); - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8102); - dword &= ~(0xffff); - dword |= (0x8000 | tx_pre); - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8102, dword); - - /* Determine TxPreP/TxPreN for command/address lines (Stage 3) */ - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x00000000); - drive_strength = (dword >> 0) & 0x7; /* CkeDrvStren */ - tx_pre = fam15h_phy_predriver_cmd_addr_calibration_code(pDCTstat, dct, drive_strength); - - /* Program TxPreP/TxPreN for command/address lines (Stage 3) */ - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc002); - dword &= ~(0xffff); - dword |= (0x8000 | tx_pre); - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc002, dword); - - /* Determine TxPreP/TxPreN for clock lines */ - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x00000000); - drive_strength = (dword >> 12) & 0x7; /* ClkDrvStren */ - tx_pre = fam15h_phy_predriver_clk_calibration_code(pDCTstat, dct, drive_strength); - - /* Program TxPreP/TxPreN for clock lines */ - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2002); - dword &= ~(0xffff); - dword |= (0x8000 | tx_pre); - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2002, dword); - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2102); - dword &= ~(0xffff); - dword |= (0x8000 | tx_pre); - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2102, dword); - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2202); - dword &= ~(0xffff); - dword |= (0x8000 | tx_pre); - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2202, dword); - - if (!is_model10_1f()) { - /* Be extra safe and wait for the predriver calibration - * to be applied to the hardware. The BKDG does not - * require this, but it does take some time for the - * data to propagate, so it's probably a good idea. - */ - uint8_t predriver_cal_pending = 1; - printk(BIOS_DEBUG, "Waiting for predriver calibration to be applied..."); - while (predriver_cal_pending) { - predriver_cal_pending = 0; - for (index = 0; index < 0x9; index++) { - if (Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0002 | (index << 8)) & 0x8000) - predriver_cal_pending = 1; - } - } - printk(BIOS_DEBUG, "done!\n"); - } - } else { - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x00); - dword = 0; - for (i = 0; i < 6; i++) { - switch (i) { - case 0: - case 4: - p = Table_Comp_Rise_Slew_15x; - valx = p[(dword >> 16) & 3]; - break; - case 1: - case 5: - p = Table_Comp_Fall_Slew_15x; - valx = p[(dword >> 16) & 3]; - break; - case 2: - p = Table_Comp_Rise_Slew_20x; - valx = p[(dword >> 8) & 3]; - break; - case 3: - p = Table_Comp_Fall_Slew_20x; - valx = p[(dword >> 8) & 3]; - break; - } - dword |= valx << (5 * i); - } - - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0a, dword); - } - - printk(BIOS_DEBUG, "%s: DCT %d: Done\n", __func__, dct); -} - -static void mct_EarlyArbEn_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - printk(BIOS_DEBUG, "%s: Start\n", __func__); - - if (!is_fam15h()) { - u32 reg; - u32 val; - u32 dev = pDCTstat->dev_dct; - - /* GhEnhancement #18429 modified by askar: For low NB CLK : - * Memclk ratio, the DCT may need to arbitrate early to avoid - * unnecessary bubbles. - * bit 19 of F2x[1,0]78 Dram Control Register, set this bit only when - * NB CLK : Memclk ratio is between 3:1 (inclusive) to 4:5 (inclusive) - */ - reg = 0x78; - val = Get_NB32_DCT(dev, dct, reg); - - if (pDCTstat->LogicalCPUID & (AMD_DR_Cx | AMD_DR_Dx)) - val |= (1 << EarlyArbEn); - else if (CheckNBCOFEarlyArbEn(pMCTstat, pDCTstat)) - val |= (1 << EarlyArbEn); - - Set_NB32_DCT(dev, dct, reg, val); - } - - printk(BIOS_DEBUG, "%s: Done\n", __func__); -} - -static u8 CheckNBCOFEarlyArbEn(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u32 reg; - u32 val; - u32 tmp; - u32 rem; - u32 dev = pDCTstat->dev_dct; - u32 hi, lo; - u8 NbDid = 0; - - /* Check if NB COF >= 4*Memclk, if it is not, return a fatal error - */ - - /* 3*(Fn2xD4[NBFid]+4)/(2^NbDid)/(3+Fn2x94[MemClkFreq]) */ - _RDMSR(MSR_COFVID_STS, &lo, &hi); - if (lo & (1 << 22)) - NbDid |= 1; - - reg = 0x94; - val = Get_NB32_DCT(dev, 0, reg); - if (!(val & (1 << MemClkFreqVal))) - val = Get_NB32_DCT(dev, 1, reg); /* get the DCT1 value */ - - val &= 0x07; - val += 3; - if (NbDid) - val <<= 1; - tmp = val; - - dev = pDCTstat->dev_nbmisc; - reg = 0xD4; - val = Get_NB32(dev, reg); - val &= 0x1F; - val += 3; - val *= 3; - val = val / tmp; - rem = val % tmp; - tmp >>= 1; - - /* Yes this could be nicer but this was how the asm was.... */ - if (val < 3) { /* NClk:MemClk < 3:1 */ - return 0; - } else if (val > 4) { /* NClk:MemClk >= 5:1 */ - return 0; - } else if ((val == 4) && (rem > tmp)) { /* NClk:MemClk > 4.5:1 */ - return 0; - } else { - return 1; /* 3:1 <= NClk:MemClk <= 4.5:1*/ - } -} - -static void mct_ResetDataStruct_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - uint8_t Node; - struct DCTStatStruc *pDCTstat; - - /* Initialize Data structures by clearing all entries to 0 */ - memset(pMCTstat, 0, sizeof(*pMCTstat)); - - for (Node = 0; Node < 8; Node++) { - pDCTstat = pDCTstatA + Node; - memset(pDCTstat, 0, sizeof(*pDCTstat) - sizeof(pDCTstat->persistentData)); - } -} - -static void mct_BeforeDramInit_Prod_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - printk(BIOS_DEBUG, "%s: Start\n", __func__); - - mct_ProgramODT_D(pMCTstat, pDCTstat, dct); - - printk(BIOS_DEBUG, "%s: Done\n", __func__); -} - -static void mct_ProgramODT_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u8 i; - u32 dword; - u32 dev = pDCTstat->dev_dct; - - printk(BIOS_DEBUG, "%s: Start\n", __func__); - - uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH); - - if (is_fam15h()) { - /* Obtain number of DIMMs on channel */ - uint8_t dimm_count = pDCTstat->MAdimms[dct]; - uint8_t rank_count_dimm0; - uint8_t rank_count_dimm1; - uint32_t odt_pattern_0; - uint32_t odt_pattern_1; - uint32_t odt_pattern_2; - uint32_t odt_pattern_3; - uint8_t write_odt_duration; - uint8_t read_odt_duration; - uint8_t write_odt_delay; - uint8_t read_odt_delay; - - /* NOTE - * Rank count per DIMM and DCT is encoded by pDCTstat->DimmRanks[(<dimm number> * 2) + dct] - */ - - /* Select appropriate ODT pattern for installed DIMMs - * Refer to the Fam15h BKDG Rev. 3.14, page 149 onwards - */ - if (pDCTstat->Status & (1 << SB_Registered)) { - if (MaxDimmsInstallable == 2) { - if (dimm_count == 1) { - /* 1 DIMM detected */ - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - if (rank_count_dimm1 == 1) { - odt_pattern_0 = 0x00000000; - odt_pattern_1 = 0x00000000; - odt_pattern_2 = 0x00000000; - odt_pattern_3 = 0x00020000; - } else if (rank_count_dimm1 == 2) { - odt_pattern_0 = 0x00000000; - odt_pattern_1 = 0x00000000; - odt_pattern_2 = 0x00000000; - odt_pattern_3 = 0x08020000; - } else if (rank_count_dimm1 == 4) { - odt_pattern_0 = 0x00000000; - odt_pattern_1 = 0x00000000; - odt_pattern_2 = 0x020a0000; - odt_pattern_3 = 0x080a0000; - } else { - /* Fallback */ - odt_pattern_0 = 0x00000000; - odt_pattern_1 = 0x00000000; - odt_pattern_2 = 0x00000000; - odt_pattern_3 = 0x08020000; - } - } else { - /* 2 DIMMs detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct]; - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4)) { - odt_pattern_0 = 0x00000000; - odt_pattern_1 = 0x01010202; - odt_pattern_2 = 0x00000000; - odt_pattern_3 = 0x09030603; - } else if ((rank_count_dimm0 < 4) && (rank_count_dimm1 == 4)) { - odt_pattern_0 = 0x01010000; - odt_pattern_1 = 0x01010a0a; - odt_pattern_2 = 0x01090000; - odt_pattern_3 = 0x01030e0b; - } else if ((rank_count_dimm0 == 4) && (rank_count_dimm1 < 4)) { - odt_pattern_0 = 0x00000202; - odt_pattern_1 = 0x05050202; - odt_pattern_2 = 0x00000206; - odt_pattern_3 = 0x0d070203; - } else if ((rank_count_dimm0 == 4) && (rank_count_dimm1 == 4)) { - odt_pattern_0 = 0x05050a0a; - odt_pattern_1 = 0x05050a0a; - odt_pattern_2 = 0x050d0a0e; - odt_pattern_3 = 0x05070a0b; - } else { - /* Fallback */ - odt_pattern_0 = 0x00000000; - odt_pattern_1 = 0x00000000; - odt_pattern_2 = 0x00000000; - odt_pattern_3 = 0x00000000; - } - } - } else { - /* FIXME - * 3 DIMMs per channel UNIMPLEMENTED - */ - odt_pattern_0 = 0x00000000; - odt_pattern_1 = 0x00000000; - odt_pattern_2 = 0x00000000; - odt_pattern_3 = 0x00000000; - } - } else if (pDCTstat->Status & (1 << SB_LoadReduced)) { - /* TODO - * Load reduced dimms UNIMPLEMENTED - */ - odt_pattern_0 = 0x00000000; - odt_pattern_1 = 0x00000000; - odt_pattern_2 = 0x00000000; - odt_pattern_3 = 0x00000000; - } else { - if (MaxDimmsInstallable == 2) { - if (dimm_count == 1) { - /* 1 DIMM detected */ - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct]; - if (rank_count_dimm1 == 1) { - odt_pattern_0 = 0x00000000; - odt_pattern_1 = 0x00000000; - odt_pattern_2 = 0x00000000; - odt_pattern_3 = 0x00020000; - } else if (rank_count_dimm1 == 2) { - odt_pattern_0 = 0x00000000; - odt_pattern_1 = 0x00000000; - odt_pattern_2 = 0x00000000; - odt_pattern_3 = 0x08020000; - } else { - /* Fallback */ - odt_pattern_0 = 0x00000000; - odt_pattern_1 = 0x00000000; - odt_pattern_2 = 0x00000000; - odt_pattern_3 = 0x08020000; - } - } else { - /* 2 DIMMs detected */ - odt_pattern_0 = 0x00000000; - odt_pattern_1 = 0x01010202; - odt_pattern_2 = 0x00000000; - odt_pattern_3 = 0x09030603; - } - } else { - /* FIXME - * 3 DIMMs per channel UNIMPLEMENTED - */ - odt_pattern_0 = 0x00000000; - odt_pattern_1 = 0x00000000; - odt_pattern_2 = 0x00000000; - odt_pattern_3 = 0x00000000; - } - } - - if (pDCTstat->Status & (1 << SB_LoadReduced)) { - /* TODO - * Load reduced dimms UNIMPLEMENTED - */ - write_odt_duration = 0x0; - read_odt_duration = 0x0; - write_odt_delay = 0x0; - read_odt_delay = 0x0; - } else { - uint8_t tcl; - uint8_t tcwl; - tcl = Get_NB32_DCT(dev, dct, 0x200) & 0x1f; - tcwl = Get_NB32_DCT(dev, dct, 0x20c) & 0x1f; - - write_odt_duration = 0x6; - read_odt_duration = 0x6; - write_odt_delay = 0x0; - if (tcl > tcwl) - read_odt_delay = tcl - tcwl; - else - read_odt_delay = 0x0; - } - - /* Program ODT pattern */ - Set_NB32_DCT(dev, dct, 0x230, odt_pattern_1); - Set_NB32_DCT(dev, dct, 0x234, odt_pattern_0); - Set_NB32_DCT(dev, dct, 0x238, odt_pattern_3); - Set_NB32_DCT(dev, dct, 0x23c, odt_pattern_2); - dword = Get_NB32_DCT(dev, dct, 0x240); - dword &= ~(0x7 << 12); /* WrOdtOnDuration = write_odt_duration */ - dword |= (write_odt_duration & 0x7) << 12; - dword &= ~(0x7 << 8); /* WrOdtTrnOnDly = write_odt_delay */ - dword |= (write_odt_delay & 0x7) << 8; - dword &= ~(0xf << 4); /* RdOdtOnDuration = read_odt_duration */ - dword |= (read_odt_duration & 0xf) << 4; - dword &= ~(0xf); /* RdOdtTrnOnDly = read_odt_delay */ - dword |= (read_odt_delay & 0xf); - Set_NB32_DCT(dev, dct, 0x240, dword); - - printk(BIOS_SPEW, "Programmed DCT %d ODT pattern %08x %08x %08x %08x\n", dct, odt_pattern_0, odt_pattern_1, odt_pattern_2, odt_pattern_3); - } else if (pDCTstat->LogicalCPUID & AMD_DR_Dx) { - if (pDCTstat->Speed == 3) - dword = 0x00000800; - else - dword = 0x00000000; - for (i = 0; i < 2; i++) { - Set_NB32_DCT(dev, i, 0x98, 0x0D000030); - Set_NB32_DCT(dev, i, 0x9C, dword); - Set_NB32_DCT(dev, i, 0x98, 0x4D040F30); - - /* Obtain number of DIMMs on channel */ - uint8_t dimm_count = pDCTstat->MAdimms[i]; - uint8_t rank_count_dimm0; - uint8_t rank_count_dimm1; - uint32_t odt_pattern_0; - uint32_t odt_pattern_1; - uint32_t odt_pattern_2; - uint32_t odt_pattern_3; - - /* Select appropriate ODT pattern for installed DIMMs - * Refer to the Fam10h BKDG Rev. 3.62, page 120 onwards - */ - if (pDCTstat->Status & (1 << SB_Registered)) { - if (MaxDimmsInstallable == 2) { - if (dimm_count == 1) { - /* 1 DIMM detected */ - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + i]; - if (rank_count_dimm1 == 1) { - odt_pattern_0 = 0x00000000; - odt_pattern_1 = 0x00000000; - odt_pattern_2 = 0x00000000; - odt_pattern_3 = 0x00020000; - } else if (rank_count_dimm1 == 2) { - odt_pattern_0 = 0x00000000; - odt_pattern_1 = 0x00000000; - odt_pattern_2 = 0x00000000; - odt_pattern_3 = 0x02080000; - } else if (rank_count_dimm1 == 4) { - odt_pattern_0 = 0x00000000; - odt_pattern_1 = 0x00000000; - odt_pattern_2 = 0x020a0000; - odt_pattern_3 = 0x080a0000; - } else { - /* Fallback */ - odt_pattern_0 = 0x00000000; - odt_pattern_1 = 0x00000000; - odt_pattern_2 = 0x00000000; - odt_pattern_3 = 0x00000000; - } - } else { - /* 2 DIMMs detected */ - rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + i]; - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + i]; - if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4)) { - odt_pattern_0 = 0x00000000; - odt_pattern_1 = 0x01010202; - odt_pattern_2 = 0x00000000; - odt_pattern_3 = 0x09030603; - } else if ((rank_count_dimm0 < 4) && (rank_count_dimm1 == 4)) { - odt_pattern_0 = 0x01010000; - odt_pattern_1 = 0x01010a0a; - odt_pattern_2 = 0x01090000; - odt_pattern_3 = 0x01030e0b; - } else if ((rank_count_dimm0 == 4) && (rank_count_dimm1 < 4)) { - odt_pattern_0 = 0x00000202; - odt_pattern_1 = 0x05050202; - odt_pattern_2 = 0x00000206; - odt_pattern_3 = 0x0d070203; - } else if ((rank_count_dimm0 == 4) && (rank_count_dimm1 == 4)) { - odt_pattern_0 = 0x05050a0a; - odt_pattern_1 = 0x05050a0a; - odt_pattern_2 = 0x050d0a0e; - odt_pattern_3 = 0x05070a0b; - } else { - /* Fallback */ - odt_pattern_0 = 0x00000000; - odt_pattern_1 = 0x00000000; - odt_pattern_2 = 0x00000000; - odt_pattern_3 = 0x00000000; - } - } - } else { - /* FIXME - * 3 DIMMs per channel UNIMPLEMENTED - */ - odt_pattern_0 = 0x00000000; - odt_pattern_1 = 0x00000000; - odt_pattern_2 = 0x00000000; - odt_pattern_3 = 0x00000000; - } - } else { - if (MaxDimmsInstallable == 2) { - if (dimm_count == 1) { - /* 1 DIMM detected */ - rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + i]; - if (rank_count_dimm1 == 1) { - odt_pattern_0 = 0x00000000; - odt_pattern_1 = 0x00000000; - odt_pattern_2 = 0x00000000; - odt_pattern_3 = 0x00020000; - } else if (rank_count_dimm1 == 2) { - odt_pattern_0 = 0x00000000; - odt_pattern_1 = 0x00000000; - odt_pattern_2 = 0x00000000; - odt_pattern_3 = 0x02080000; - } else { - /* Fallback */ - odt_pattern_0 = 0x00000000; - odt_pattern_1 = 0x00000000; - odt_pattern_2 = 0x00000000; - odt_pattern_3 = 0x00000000; - } - } else { - /* 2 DIMMs detected */ - odt_pattern_0 = 0x00000000; - odt_pattern_1 = 0x01010202; - odt_pattern_2 = 0x00000000; - odt_pattern_3 = 0x09030603; - } - } else { - /* FIXME - * 3 DIMMs per channel UNIMPLEMENTED - */ - odt_pattern_0 = 0x00000000; - odt_pattern_1 = 0x00000000; - odt_pattern_2 = 0x00000000; - odt_pattern_3 = 0x00000000; - } - } - - /* Program ODT pattern */ - Set_NB32_index_wait_DCT(dev, i, 0xf0, 0x180, odt_pattern_1); - Set_NB32_index_wait_DCT(dev, i, 0xf0, 0x181, odt_pattern_0); - Set_NB32_index_wait_DCT(dev, i, 0xf0, 0x182, odt_pattern_3); - Set_NB32_index_wait_DCT(dev, i, 0xf0, 0x183, odt_pattern_2); - - printk(BIOS_SPEW, "Programmed ODT pattern %08x %08x %08x %08x\n", odt_pattern_0, odt_pattern_1, odt_pattern_2, odt_pattern_3); - } - } - - printk(BIOS_DEBUG, "%s: Done\n", __func__); -} - -static void mct_EnDllShutdownSR(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u32 dev = pDCTstat->dev_dct, val; - - /* Write 0000_07D0h to register F2x[1, 0]98_x4D0FE006 */ - if (pDCTstat->LogicalCPUID & (AMD_DR_DAC2_OR_C3)) { - Set_NB32_DCT(dev, dct, 0x9C, 0x1C); - Set_NB32_DCT(dev, dct, 0x98, 0x4D0FE006); - Set_NB32_DCT(dev, dct, 0x9C, 0x13D); - Set_NB32_DCT(dev, dct, 0x98, 0x4D0FE007); - - val = Get_NB32_DCT(dev, dct, 0x90); - val &= ~(1 << 27/* DisDllShutdownSR */); - Set_NB32_DCT(dev, dct, 0x90, val); - } -} - -static u32 mct_DisDllShutdownSR(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u32 DramConfigLo, u8 dct) -{ - u32 dev = pDCTstat->dev_dct; - - /* Write 0000_07D0h to register F2x[1, 0]98_x4D0FE006 */ - if (pDCTstat->LogicalCPUID & (AMD_DR_DAC2_OR_C3)) { - Set_NB32_DCT(dev, dct, 0x9C, 0x7D0); - Set_NB32_DCT(dev, dct, 0x98, 0x4D0FE006); - Set_NB32_DCT(dev, dct, 0x9C, 0x190); - Set_NB32_DCT(dev, dct, 0x98, 0x4D0FE007); - - DramConfigLo |= /* DisDllShutdownSR */ 1 << 27; - } - - return DramConfigLo; -} - -void mct_SetClToNB_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u32 lo, hi; - u32 msr; - - /* FIXME: Maybe check the CPUID? - not for now. */ - /* pDCTstat->LogicalCPUID; */ - - msr = BU_CFG2_MSR; - _RDMSR(msr, &lo, &hi); - lo |= 1 << ClLinesToNbDis; - _WRMSR(msr, lo, hi); -} - -void mct_ClrClToNB_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - - u32 lo, hi; - u32 msr; - - /* FIXME: Maybe check the CPUID? - not for now. */ - /* pDCTstat->LogicalCPUID; */ - - msr = BU_CFG2_MSR; - _RDMSR(msr, &lo, &hi); - if (!pDCTstat->ClToNB_flag) - lo &= ~(1<<ClLinesToNbDis); - _WRMSR(msr, lo, hi); - -} - -void mct_SetWbEnhWsbDis_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u32 lo, hi; - u32 msr; - - /* FIXME: Maybe check the CPUID? - not for now. */ - /* pDCTstat->LogicalCPUID; */ - - msr = BU_CFG_MSR; - _RDMSR(msr, &lo, &hi); - hi |= (1 << WbEnhWsbDis_D); - _WRMSR(msr, lo, hi); -} - -void mct_ClrWbEnhWsbDis_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u32 lo, hi; - u32 msr; - - /* FIXME: Maybe check the CPUID? - not for now. */ - /* pDCTstat->LogicalCPUID; */ - - msr = BU_CFG_MSR; - _RDMSR(msr, &lo, &hi); - hi &= ~(1 << WbEnhWsbDis_D); - _WRMSR(msr, lo, hi); -} - -void ProgDramMRSReg_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u32 DramMRS, dword; - u8 byte; - - DramMRS = 0; - - /* Set chip select CKE control mode */ - if (mctGet_NVbits(NV_CKE_CTL)) { - if (pDCTstat->CSPresent == 3) { - u16 word; - word = pDCTstat->DIMMSPDCSE; - if (dct == 0) - word &= 0b01010100; - else - word &= 0b10101000; - if (word == 0) - DramMRS |= 1 << 23; - } - } - - if (is_fam15h()) { - DramMRS |= (0x1 << 23); /* PchgPDModeSel = 1 */ - } else { - /* - DRAM MRS Register - DrvImpCtrl: drive impedance control.01b(34 ohm driver; Ron34 = Rzq/7) - */ - DramMRS |= 1 << 2; - /* Dram nominal termination: */ - byte = pDCTstat->MAdimms[dct]; - if (!(pDCTstat->Status & (1 << SB_Registered))) { - DramMRS |= 1 << 7; /* 60 ohms */ - if (byte & 2) { - if (pDCTstat->Speed < 6) - DramMRS |= 1 << 8; /* 40 ohms */ - else - DramMRS |= 1 << 9; /* 30 ohms */ - } - } - /* Dram dynamic termination: Disable(1DIMM), 120ohm(>=2DIMM) */ - if (!(pDCTstat->Status & (1 << SB_Registered))) { - if (byte >= 2) { - if (pDCTstat->Speed == 7) - DramMRS |= 1 << 10; - else - DramMRS |= 1 << 11; - } - } else { - DramMRS |= mct_DramTermDyn_RDimm(pMCTstat, pDCTstat, byte); - } - - /* Qoff = 0, output buffers enabled */ - /* Tcwl */ - DramMRS |= (pDCTstat->Speed - 4) << 20; - /* ASR = 1, auto self refresh */ - /* SRT = 0 */ - DramMRS |= 1 << 18; - } - - /* burst length control */ - if (pDCTstat->Status & (1 << SB_128bitmode)) - DramMRS |= 1 << 1; - - dword = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x84); - if (is_fam15h()) { - dword &= ~0x00800003; - dword |= DramMRS; - } else { - dword &= ~0x00fc2f8f; - dword |= DramMRS; - } - Set_NB32_DCT(pDCTstat->dev_dct, dct, 0x84, dword); -} - -void mct_SetDramConfigHi_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u32 dct, u32 DramConfigHi) -{ - /* Bug#15114: Comp. update interrupted by Freq. change can cause - * subsequent update to be invalid during any MemClk frequency change: - * Solution: From the bug report: - * 1. A software-initiated frequency change should be wrapped into the - * following sequence : - * a) Disable Compensation (F2[1, 0]9C_x08[30]) - * b) Reset the Begin Compensation bit (D3CMP->COMP_CONFIG[0]) in - * all the compensation engines - * c) Do frequency change - * d) Enable Compensation (F2[1, 0]9C_x08[30]) - * 2. A software-initiated Disable Compensation should always be - * followed by step b) of the above steps. - * Silicon Status: Fixed In Rev B0 - * - * Errata#177: DRAM Phy Automatic Compensation Updates May Be Invalid - * Solution: BIOS should disable the phy automatic compensation prior - * to initiating a memory clock frequency change as follows: - * 1. Disable PhyAutoComp by writing 1'b1 to F2x[1, 0]9C_x08[30] - * 2. Reset the Begin Compensation bits by writing 32'h0 to - * F2x[1, 0]9C_x4D004F00 - * 3. Perform frequency change - * 4. Enable PhyAutoComp by writing 1'b0 to F2x[1, 0]9C_08[30] - * In addition, any time software disables the automatic phy - * compensation it should reset the begin compensation bit per step 2. - * Silicon Status: Fixed in DR-B0 - */ - - u32 dev = pDCTstat->dev_dct; - u32 index_reg = 0x98; - u32 index; - - uint32_t dword; - - printk(BIOS_DEBUG, "%s: Start\n", __func__); - - if (is_fam15h()) { - /* Initial setup for frequency change - * 9C_x0000_0004 must be configured before MemClkFreqVal is set - */ - - /* Program D18F2x9C_x0D0F_E006_dct[1:0][PllLockTime] = 0x190 */ - dword = Get_NB32_index_wait_DCT(pDCTstat->dev_dct, dct, index_reg, 0x0d0fe006); - dword &= ~(0x0000ffff); - dword |= 0x00000190; - Set_NB32_index_wait_DCT(pDCTstat->dev_dct, dct, index_reg, 0x0d0fe006, dword); - - dword = Get_NB32_DCT(dev, dct, 0x94); - dword &= ~(1 << MemClkFreqVal); - Set_NB32_DCT(dev, dct, 0x94, dword); - - dword = DramConfigHi; - dword &= ~(1 << MemClkFreqVal); - Set_NB32_DCT(dev, dct, 0x94, dword); - - mctGet_PS_Cfg_D(pMCTstat, pDCTstat, dct); - set_2t_configuration(pMCTstat, pDCTstat, dct); - mct_BeforePlatformSpec(pMCTstat, pDCTstat, dct); - mct_PlatformSpec(pMCTstat, pDCTstat, dct); - } else { - index = 0x08; - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, index); - if (!(dword & (1 << DisAutoComp))) - Set_NB32_index_wait_DCT(dev, dct, index_reg, index, dword | (1 << DisAutoComp)); - - mct_Wait(100); - } - - printk(BIOS_DEBUG, "mct_SetDramConfigHi_D: DramConfigHi: %08x\n", DramConfigHi); - - /* Program the DRAM Configuration High register */ - Set_NB32_DCT(dev, dct, 0x94, DramConfigHi); - - if (is_fam15h()) { - /* Wait until F2x[1, 0]94[FreqChgInProg]=0. */ - do { - printk(BIOS_DEBUG, "*"); - dword = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x94); - } while (dword & (1 << FreqChgInProg)); - printk(BIOS_DEBUG, "\n"); - - /* Program D18F2x9C_x0D0F_E006_dct[1:0][PllLockTime] = 0xf */ - dword = Get_NB32_index_wait_DCT(pDCTstat->dev_dct, dct, index_reg, 0x0d0fe006); - dword &= ~(0x0000ffff); - dword |= 0x0000000f; - Set_NB32_index_wait_DCT(pDCTstat->dev_dct, dct, index_reg, 0x0d0fe006, dword); - } - - /* Clear MC4 error status */ - pci_write_config32(pDCTstat->dev_nbmisc, 0x48, 0x0); - pci_write_config32(pDCTstat->dev_nbmisc, 0x4c, 0x0); - - printk(BIOS_DEBUG, "%s: Done\n", __func__); -} - -static void mct_BeforeDQSTrain_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - if (!is_fam15h()) { - u8 Node; - struct DCTStatStruc *pDCTstat; - - /* Errata 178 - * - * Bug#15115: Uncertainty In The Sync Chain Leads To Setup Violations - * In TX FIFO - * Solution: BIOS should program DRAM Control Register[RdPtrInit] = - * 5h, (F2x[1, 0]78[3:0] = 5h). - * Silicon Status: Fixed In Rev B0 - * - * Bug#15880: Determine validity of reset settings for DDR PHY timing. - * Solution: At least, set WrDqs fine delay to be 0 for DDR3 training. - */ - for (Node = 0; Node < 8; Node++) { - pDCTstat = pDCTstatA + Node; - - if (pDCTstat->NodePresent) { - mct_BeforeDQSTrainSamp(pDCTstat); /* only Bx */ - mct_ResetDLL_D(pMCTstat, pDCTstat, 0); - mct_ResetDLL_D(pMCTstat, pDCTstat, 1); - } - } - } -} - -/* Erratum 350 */ -static void mct_ResetDLL_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u8 Receiver; - u32 dev = pDCTstat->dev_dct; - u32 addr; - u32 lo, hi; - u8 wrap32dis = 0; - u8 valid = 0; - - /* Skip reset DLL for B3 */ - if (pDCTstat->LogicalCPUID & AMD_DR_B3) { - return; - } - - /* Skip reset DLL for Family 15h */ - if (is_fam15h()) { - return; - } - - addr = HWCR_MSR; - _RDMSR(addr, &lo, &hi); - if (lo & (1<<17)) { /* save the old value */ - wrap32dis = 1; - } - lo |= (1<<17); /* HWCR.wrap32dis */ - /* Setting wrap32dis allows 64-bit memory references in 32bit mode */ - _WRMSR(addr, lo, hi); - - pDCTstat->Channel = dct; - Receiver = mct_InitReceiver_D(pDCTstat, dct); - /* there are four receiver pairs, loosely associated with chipselects.*/ - for (; Receiver < 8; Receiver += 2) { - if (mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, dct, Receiver)) { - addr = mct_GetRcvrSysAddr_D(pMCTstat, pDCTstat, dct, Receiver, &valid); - if (valid) { - mct_Read1LTestPattern_D(pMCTstat, pDCTstat, addr); /* cache fills */ - - /* Write 0000_8000h to register F2x[1,0]9C_xD080F0C */ - Set_NB32_index_wait_DCT(dev, dct, 0x98, 0xD080F0C, 0x00008000); - mct_Wait(80); /* wait >= 300ns */ - - /* Write 0000_0000h to register F2x[1,0]9C_xD080F0C */ - Set_NB32_index_wait_DCT(dev, dct, 0x98, 0xD080F0C, 0x00000000); - mct_Wait(800); /* wait >= 2us */ - break; - } - } - } - - if (!wrap32dis) { - addr = HWCR_MSR; - _RDMSR(addr, &lo, &hi); - lo &= ~(1<<17); /* restore HWCR.wrap32dis */ - _WRMSR(addr, lo, hi); - } -} - -void mct_EnableDatIntlv_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u32 dev = pDCTstat->dev_dct; - u32 val; - - /* Enable F2x110[DctDatIntlv] */ - /* Call back not required mctHookBeforeDatIntlv_D() */ - /* FIXME Skip for Ax */ - if (!pDCTstat->GangedMode) { - val = Get_NB32(dev, 0x110); - val |= 1 << 5; /* DctDatIntlv */ - Set_NB32(dev, 0x110, val); - - /* FIXME Skip for Cx */ - dev = pDCTstat->dev_nbmisc; - val = Get_NB32(dev, 0x8C); /* NB Configuration Hi */ - val |= 1 << (36-32); /* DisDatMask */ - Set_NB32(dev, 0x8C, val); - } -} - -void SetDllSpeedUp_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - if (!is_fam15h()) { - u32 val; - u32 dev = pDCTstat->dev_dct; - - if (pDCTstat->Speed >= mhz_to_memclk_config(800)) { /* DDR1600 and above */ - /* Set bit13 PowerDown to register F2x[1, 0]98_x0D080F10 */ - Set_NB32_DCT(dev, dct, 0x98, 0x0D080F10); - val = Get_NB32_DCT(dev, dct, 0x9C); - val |= 1 < 13; - Set_NB32_DCT(dev, dct, 0x9C, val); - Set_NB32_DCT(dev, dct, 0x98, 0x4D080F10); - - /* Set bit13 PowerDown to register F2x[1, 0]98_x0D080F11 */ - Set_NB32_DCT(dev, dct, 0x98, 0x0D080F11); - val = Get_NB32_DCT(dev, dct, 0x9C); - val |= 1 < 13; - Set_NB32_DCT(dev, dct, 0x9C, val); - Set_NB32_DCT(dev, dct, 0x98, 0x4D080F11); - - /* Set bit13 PowerDown to register F2x[1, 0]98_x0D088F30 */ - Set_NB32_DCT(dev, dct, 0x98, 0x0D088F30); - val = Get_NB32_DCT(dev, dct, 0x9C); - val |= 1 < 13; - Set_NB32_DCT(dev, dct, 0x9C, val); - Set_NB32_DCT(dev, dct, 0x98, 0x4D088F30); - - /* Set bit13 PowerDown to register F2x[1, 0]98_x0D08CF30 */ - Set_NB32_DCT(dev, dct, 0x98, 0x0D08CF30); - val = Get_NB32_DCT(dev, dct, 0x9C); - val |= 1 < 13; - Set_NB32_DCT(dev, dct, 0x9C, val); - Set_NB32_DCT(dev, dct, 0x98, 0x4D08CF30); - } - } -} - -static void SyncSetting(struct DCTStatStruc *pDCTstat) -{ - /* set F2x78[ChSetupSync] when F2x[1, 0]9C_x04[AddrCmdSetup, CsOdtSetup, - * CkeSetup] setups for one DCT are all 0s and at least one of the setups, - * F2x[1, 0]9C_x04[AddrCmdSetup, CsOdtSetup, CkeSetup], of the other - * controller is 1 - */ - u32 cha, chb; - u32 dev = pDCTstat->dev_dct; - u32 val; - - cha = pDCTstat->CH_ADDR_TMG[0] & 0x0202020; - chb = pDCTstat->CH_ADDR_TMG[1] & 0x0202020; - - if ((cha != chb) && ((cha == 0) || (chb == 0))) { - val = Get_NB32(dev, 0x78); - val |= 1 << ChSetupSync; - Set_NB32(dev, 0x78, val); - } -} - -static void AfterDramInit_D(struct DCTStatStruc *pDCTstat, u8 dct) { - - u32 val; - u32 dev = pDCTstat->dev_dct; - - if (pDCTstat->LogicalCPUID & (AMD_DR_B2 | AMD_DR_B3)) { - mct_Wait(10000); /* Wait 50 us*/ - val = Get_NB32(dev, 0x110); - if (!(val & (1 << DramEnabled))) { - /* If 50 us expires while DramEnable =0 then do the following */ - val = Get_NB32_DCT(dev, dct, 0x90); - val &= ~(1 << Width128); /* Program Width128 = 0 */ - Set_NB32_DCT(dev, dct, 0x90, val); - - val = Get_NB32_index_wait_DCT(dev, dct, 0x98, 0x05); /* Perform dummy CSR read to F2x09C_x05 */ - - if (pDCTstat->GangedMode) { - val = Get_NB32_DCT(dev, dct, 0x90); - val |= 1 << Width128; /* Program Width128 = 0 */ - Set_NB32_DCT(dev, dct, 0x90, val); - } - } - } -} - -/* ========================================================== - * 6-bit Bank Addressing Table - * RR = rows-13 binary - * B = Banks-2 binary - * CCC = Columns-9 binary - * ========================================================== - * DCT CCCBRR Rows Banks Columns 64-bit CS Size - * Encoding - * 0000 000000 13 2 9 128MB - * 0001 001000 13 2 10 256MB - * 0010 001001 14 2 10 512MB - * 0011 010000 13 2 11 512MB - * 0100 001100 13 3 10 512MB - * 0101 001101 14 3 10 1GB - * 0110 010001 14 2 11 1GB - * 0111 001110 15 3 10 2GB - * 1000 010101 14 3 11 2GB - * 1001 010110 15 3 11 4GB - * 1010 001111 16 3 10 4GB - * 1011 010111 16 3 11 8GB - */ -uint8_t crcCheck(struct DCTStatStruc *pDCTstat, uint8_t dimm) -{ - u16 crc_calc = spd_ddr3_calc_crc(pDCTstat->spd_data.spd_bytes[dimm], - sizeof(pDCTstat->spd_data.spd_bytes[dimm])); - u16 checksum_spd = pDCTstat->spd_data.spd_bytes[dimm][SPD_byte_127] << 8 - | pDCTstat->spd_data.spd_bytes[dimm][SPD_byte_126]; - - return crc_calc == checksum_spd; -} - -int32_t abs(int32_t val) -{ - if (val < 0) - return -val; - return val; -} |