aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/amd/amdmct/mct_ddr3
diff options
context:
space:
mode:
Diffstat (limited to 'src/northbridge/amd/amdmct/mct_ddr3')
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/Makefile.inc31
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mct_d.c8220
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mct_d.h1165
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mct_d_gcc.c296
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mct_d_gcc.h50
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mctardk5.c100
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mctardk6.c114
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mctchi_d.c123
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mctcsi_d.c144
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c2493
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c389
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mcthdi.c33
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c305
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mctmtr_d.c256
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mctndi_d.c233
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mctprob.c45
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mctproc.c113
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mctprod.c66
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mctrci.c474
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c1210
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c2438
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mctsrc1p.c104
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mctsrc2p.c126
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mcttmrl.c398
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mctwl.c509
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mhwlc_d.c1519
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/modtrd.c95
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/modtrdim.c262
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mport_d.c42
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mutilc_d.c374
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mwlc_d.h192
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/s3utils.c1237
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/s3utils.h31
33 files changed, 0 insertions, 23187 deletions
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/Makefile.inc b/src/northbridge/amd/amdmct/mct_ddr3/Makefile.inc
deleted file mode 100644
index 65c146a662..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/Makefile.inc
+++ /dev/null
@@ -1,31 +0,0 @@
-ifeq ($(CONFIG_NORTHBRIDGE_AMD_AMDFAM10),y)
-
-# DDR3
-romstage-$(CONFIG_HAVE_ACPI_RESUME) += s3utils.c
-romstage-y += mct_d.c mctmtr_d.c mctcsi_d.c mctecc_d.c mctdqs_d.c mctsrc.c
-romstage-y += mctsdi.c mctprod.c mctproc.c mctprob.c mcthwl.c mctwl.c
-romstage-y += mport_d.c mutilc_d.c modtrdim.c mhwlc_d.c mctrci.c mctsrc1p.c
-romstage-y += mcttmrl.c mcthdi.c mctndi_d.c mctchi_d.c modtrd.c mct_d_gcc.c
-
-ifeq ($(CONFIG_CPU_SOCKET_TYPE), 0x11)
-romstage-y += mctardk5.c
-endif
-ifeq ($(CONFIG_CPU_SOCKET_TYPE), 0x13)
-romstage-y += mctardk5.c
-endif
-ifeq ($(CONFIG_CPU_SOCKET_TYPE), 0x14)
-romstage-y += mctardk5.c
-endif
-ifeq ($(CONFIG_CPU_SOCKET_TYPE), 0x15)
-romstage-y += mctardk5.c
-endif
-ifeq ($(CONFIG_CPU_SOCKET_TYPE), 0x16)
-romstage-y += mctardk5.c
-endif
-ifeq ($(CONFIG_CPU_SOCKET_TYPE), 0x12)
-romstage-y += mctardk6.c
-endif
-
-ramstage-$(CONFIG_HAVE_ACPI_RESUME) += s3utils.c
-
-endif
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;
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h
deleted file mode 100644
index 952a66f71a..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h
+++ /dev/null
@@ -1,1165 +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: Include file for all generic DDR 3 MCT files.
- */
-#ifndef MCT_D_H
-#define MCT_D_H
-
-#define DQS_TRAIN_DEBUG 0
-
-#include <stdint.h>
-#include <northbridge/amd/amdfam10/raminit.h>
-
-/*===========================================================================
- CPU - K8/FAM10
-===========================================================================*/
-#define PT_L1 0 /* CPU Package Type */
-#define PT_M2 1
-#define PT_S1 2
-#define PT_GR 3
-#define PT_AS 4
-#define PT_C3 5
-#define PT_FM2 6
-
-#define J_MIN 0 /* j loop constraint. 1 = CL 2.0 T*/
-#define J_MAX 5 /* j loop constraint. 5 = CL 7.0 T*/
-#define K_MIN 1 /* k loop constraint. 1 = 200 MHz*/
-#define K_MAX 5 /* k loop constraint. 5 = 533 MHz*/
-#define CL_DEF 2 /* Default value for failsafe operation. 2 = CL 4.0 T*/
-#define T_DEF 1 /* Default value for failsafe operation. 1 = 5ns (cycle time)*/
-
-#define BSCRate 1 /* reg bit field = rate of dram scrubber for ecc*/
- /* memory initialization (ecc and check-bits).*/
- /* 1 = 40 ns/64 bytes.*/
-#define FirstPass 1 /* First pass through RcvEn training*/
-#define SecondPass 2 /* Second pass through Rcven training*/
-
-#define RCVREN_MARGIN 6 /* number of DLL taps to delay beyond first passing position*/
-#define MAXASYNCLATCTL_2 2 /* Max Async Latency Control value*/
-#define MAXASYNCLATCTL_3 3 /* Max Async Latency Control value*/
-
-#define DQS_FAIL 1
-#define DQS_PASS 0
-#define DQS_WRITEDIR 1
-#define DQS_READDIR 0
-#define MIN_DQS_WNDW 3
-#define secPassOffset 6
-#define Pass1MemClkDly 0x20 /* Add 1/2 Memlock delay */
-#define MAX_RD_LAT 0x3FF
-#define MIN_FENCE 14
-#define MAX_FENCE 20
-#define MIN_DQS_WR_FENCE 14
-#define MAX_DQS_WR_FENCE 20
-#define FenceTrnFinDlySeed 19
-#define EarlyArbEn 19
-
-#define PA_HOST(Node) ((((0x18+Node) << 3)+0) << 12) /* Node 0 Host Bus function PCI Address bits [15:0]*/
-#define PA_MAP(Node) ((((0x18+Node) << 3)+1) << 12) /* Node 0 MAP function PCI Address bits [15:0]*/
-#define PA_DCT(Node) ((((0x18+Node) << 3)+2) << 12) /* Node 0 DCT function PCI Address bits [15:0]*/
-/* #define PA_EXT_DCT (((00 << 3)+4) << 8) */ /*Node 0 DCT extended configuration registers*/
-/* #define PA_DCTADDL (((00 << 3)+2) << 8) */ /*Node x DCT function, Additional Registers PCI Address bits [15:0]*/
-/* #define PA_EXT_DCTADDL (((00 << 3)+5) << 8) */ /*Node x DCT function, Additional Registers PCI Address bits [15:0]*/
-
-#define PA_NBMISC(Node) ((((0x18+Node) << 3)+3) << 12) /*Node 0 Misc PCI Address bits [15:0]*/
-#define PA_LINK(Node) ((((0x18+Node) << 3)+4) << 12) /*Node 0 Link Control bits [15:0]*/
-#define PA_NBCTL(Node) ((((0x18+Node) << 3)+5) << 12) /*Node 0 NB Control PCI Address bits [15:0]*/
-/* #define PA_NBDEVOP (((00 << 3)+3) << 8) */ /*Node 0 Misc PCI Address bits [15:0]*/
-
-#define DCC_EN 1 /* X:2:0x94[19]*/
-#define ILD_Lmt 3 /* X:2:0x94[18:16]*/
-
-#define EncodedTSPD 0x00191709 /* encodes which SPD byte to get T from*/
- /* versus CL X, CL X-.5, and CL X-1*/
-
-#define Bias_TrpT 5 /* bias to convert bus clocks to bit field value*/
-#define Bias_TrrdT 4
-#define Bias_TrcdT 5
-#define Bias_TrasT 15
-#define Bias_TrcT 11
-#define Bias_TrtpT 4
-#define Bias_TwrT 4
-#define Bias_TwtrT 4
-#define Bias_TfawT 14
-
-#define Min_TrpT 5 /* min programmable value in busclocks */
-#define Max_TrpT 12 /* max programmable value in busclocks */
-#define Min_TrrdT 4
-#define Max_TrrdT 7
-#define Min_TrcdT 5
-#define Max_TrcdT 12
-#define Min_TrasT 15
-#define Max_TrasT 30
-#define Min_TrcT 11
-#define Max_TrcT 42
-#define Min_TrtpT 4
-#define Max_TrtpT 7
-#define Min_TwrT 5
-#define Max_TwrT 12
-#define Min_TwtrT 4
-#define Max_TwtrT 7
-#define Min_TfawT 16
-#define Max_TfawT 32
-
-/*common register bit names*/
-#define DramHoleValid 0 /* func 1, offset F0h, bit 0*/
-#define DramMemHoistValid 1 /* func 1, offset F0h, bit 1*/
-#define CSEnable 0 /* func 2, offset 40h-5C, bit 0*/
-#define Spare 1 /* func 2, offset 40h-5C, bit 1*/
-#define TestFail 2 /* func 2, offset 40h-5C, bit 2*/
-#define DqsRcvEnTrain 18 /* func 2, offset 78h, bit 18*/
-#define EnDramInit 31 /* func 2, offset 7Ch, bit 31*/
-#define PchgPDModeSel 23 /* func 2, offset 84h, bit 23 */
-#define DisAutoRefresh 18 /* func 2, offset 8Ch, bit 18*/
-#define InitDram 0 /* func 2, offset 90h, bit 0*/
-#define BurstLength32 10 /* func 2, offset 90h, bit 10*/
-#define Width128 11 /* func 2, offset 90h, bit 11*/
-#define X4Dimm 12 /* func 2, offset 90h, bit 12*/
-#define UnBuffDimm 16 /* func 2, offset 90h, bit 16*/
-#define DimmEcEn 19 /* func 2, offset 90h, bit 19*/
-#define MemClkFreqVal ((is_fam15h())?7:3) /* func 2, offset 94h, bit 3 or 7*/
-#define RDqsEn 12 /* func 2, offset 94h, bit 12*/
-#define DisDramInterface 14 /* func 2, offset 94h, bit 14*/
-#define PowerDownEn 15 /* func 2, offset 94h, bit 15*/
-#define DctAccessWrite 30 /* func 2, offset 98h, bit 30*/
-#define DctAccessDone 31 /* func 2, offset 98h, bit 31*/
-#define MemClrStatus 0 /* func 2, offset A0h, bit 0*/
-#define PwrSavingsEn 10 /* func 2, offset A0h, bit 10*/
-#define Mod64BitMux 4 /* func 2, offset A0h, bit 4*/
-#define DisableJitter 1 /* func 2, offset A0h, bit 1*/
-#define MemClrDis 1 /* func 3, offset F8h, FNC 4, bit 1*/
-#define SyncOnUcEccEn 2 /* func 3, offset 44h, bit 2*/
-#define Dr_MemClrStatus 10 /* func 3, offset 110h, bit 10*/
-#define MemClrBusy 9 /* func 3, offset 110h, bit 9*/
-#define DctGangEn 4 /* func 3, offset 110h, bit 4*/
-#define MemClrInit 3 /* func 3, offset 110h, bit 3*/
-#define SendZQCmd 29 /* func 2, offset 7Ch, bit 29 */
-#define AssertCke 28 /* func 2, offset 7Ch, bit 28*/
-#define DeassertMemRstX 27 /* func 2, offset 7Ch, bit 27*/
-#define SendMrsCmd 26 /* func 2, offset 7Ch, bit 26*/
-#define SendAutoRefresh 25 /* func 2, offset 7Ch, bit 25*/
-#define SendPchgAll 24 /* func 2, offset 7Ch, bit 24*/
-#define DisDqsBar 6 /* func 2, offset 90h, bit 6*/
-#define DramEnabled 8 /* func 2, offset 110h, bit 8*/
-#define LegacyBiosMode 9 /* func 2, offset 94h, bit 9*/
-#define PrefDramTrainMode 28 /* func 2, offset 11Ch, bit 28*/
-#define FlushWr 30 /* func 2, offset 11Ch, bit 30*/
-#define DisAutoComp 30 /* func 2, offset 9Ch, Index 8, bit 30*/
-#define DqsRcvTrEn 13 /* func 2, offset 9Ch, Index 8, bit 13*/
-#define ForceAutoPchg 23 /* func 2, offset 90h, bit 23*/
-#define ClLinesToNbDis 15 /* Bu_CFG2, bit 15*/
-#define WbEnhWsbDis_D (48-32)
-#define PhyFenceTrEn 3 /* func 2, offset 9Ch, Index 8, bit 3 */
-#define ParEn 8 /* func 2, offset 90h, bit 8 */
-#define DcqArbBypassEn 19 /* func 2, offset 94h, bit 19 */
-#define ActiveCmdAtRst 1 /* func 2, offset A8H, bit 1 */
-#define FlushWrOnStpGnt 29 /* func 2, offset 11Ch, bit 29 */
-#define BankSwizzleMode 22 /* func 2, offset 94h, bit 22 */
-#define ChSetupSync 15 /* func 2, offset 78h, bit 15 */
-
-#define Ddr3Mode 8 /* func 2, offset 94h, bit 8 */
-#define EnterSelfRef 17 /* func 2, offset 90h, bit 17 */
-#define onDimmMirror 3 /* func 2, offset 5C:40h, bit 3 */
-#define OdtSwizzle 6 /* func 2, offset A8h, bit 6 */
-#define FreqChgInProg 21 /* func 2, offset 94h, bit 21 */
-#define ExitSelfRef 1 /* func 2, offset 90h, bit 1 */
-
-#define SubMemclkRegDly 5 /* func 2, offset A8h, bit 5 */
-#define Ddr3FourSocketCh 2 /* func 2, offset A8h, bit 2 */
-#define SendControlWord 30 /* func 2, offset 7Ch, bit 30 */
-
-#define NB_GfxNbPstateDis 62 /* MSRC001_001F Northbridge Configuration Register (NB_CFG) bit 62 GfxNbPstateDis disable northbridge p-state transitions */
-/*=============================================================================
- SW Initialization
-============================================================================*/
-#define DLL_Enable 1
-#define OCD_Default 2
-#define OCD_Exit 3
-
-/*=============================================================================
- Jedec DDR II
-=============================================================================*/
-#define SPD_ByteUse 0
-#define SPD_TYPE 2 /*SPD byte read location*/
- #define JED_DDRSDRAM 0x07 /*Jedec defined bit field*/
- #define JED_DDR2SDRAM 0x08 /*Jedec defined bit field*/
- #define JED_DDR3SDRAM 0x0B /* Jedec defined bit field*/
-
-#define SPD_DIMMTYPE 3
-#define SPD_ATTRIB 21
- #define JED_DIFCKMSK 0x20 /*Differential Clock Input*/
- #define JED_REGADCMSK 0x11 /*Registered Address/Control*/
- #define JED_PROBEMSK 0x40 /*Analysis Probe installed*/
- #define JED_RDIMM 0x1 /* RDIMM */
- #define JED_MiniRDIMM 0x5 /* Mini-RDIMM */
- #define JED_LRDIMM 0xb /* Load-reduced DIMM */
-#define SPD_Density 4 /* Bank address bits,SDRAM capacity */
-#define SPD_Addressing 5 /* Row/Column address bits */
-#define SPD_Voltage 6 /* Supported voltage bitfield */
-#define SPD_Organization 7 /* rank#,Device width */
-#define SPD_BusWidth 8 /* ECC, Bus width */
- #define JED_ECC 8 /* ECC capability */
-
-#define SPD_MTBDividend 10
-#define SPD_MTBDivisor 11
-#define SPD_tCKmin 12
-#define SPD_CASLow 14
-#define SPD_CASHigh 15
-#define SPD_tAAmin 16
-
-#define SPD_DEVATTRIB 22
-#define SPD_EDCTYPE 11
- #define JED_ADRCPAR 0x04
-
-#define SPD_tWRmin 17
-#define SPD_tRCDmin 18
-#define SPD_tRRDmin 19
-#define SPD_tRPmin 20
-#define SPD_Upper_tRAS_tRC 21
-#define SPD_tRASmin 22
-#define SPD_tRCmin 23
-#define SPD_tWTRmin 26
-#define SPD_tRTPmin 27
-#define SPD_Upper_tFAW 28
-#define SPD_tFAWmin 29
-#define SPD_Thermal 31
-
-#define SPD_RefRawCard 62
-#define SPD_AddressMirror 63
-#define SPD_RegManufactureID_L 65 /* not used */
-#define SPD_RegManufactureID_H 66 /* not used */
-#define SPD_RegManRevID 67 /* not used */
-
-#define SPD_byte_126 126
-#define SPD_byte_127 127
-
-#define SPD_ROWSZ 3
-#define SPD_COLSZ 4
-#define SPD_LBANKS 17 /*number of [logical] banks on each device*/
-#define SPD_DMBANKS 5 /*number of physical banks on dimm*/
- #define SPDPLBit 4 /* Dram package bit*/
-#define SPD_BANKSZ 31 /*capacity of physical bank*/
-#define SPD_DEVWIDTH 13
-#define SPD_CASLAT 18
-#define SPD_TRP 27
-#define SPD_TRRD 28
-#define SPD_TRCD 29
-#define SPD_TRAS 30
-#define SPD_TWR 36
-#define SPD_TWTR 37
-#define SPD_TRTP 38
-#define SPD_TRCRFC 40
-#define SPD_TRC 41
-#define SPD_TRFC 42
-
-#define SPD_MANDATEYR 93 /*Module Manufacturing Year (BCD)*/
-
-#define SPD_MANDATEWK 94 /*Module Manufacturing Week (BCD)*/
-
-#define SPD_MANID_START 117
-#define SPD_SERIAL_START 122
-#define SPD_PARTN_START 128
-#define SPD_PARTN_LENGTH 18
-#define SPD_REVNO_START 146
-
-/*-----------------------------
- Jedec DDR II related equates
------------------------------*/
-#define MYEAR06 6 /* Manufacturing Year BCD encoding of 2006 - 06d*/
-#define MWEEK24 0x24 /* Manufacturing Week BCD encoding of June - 24d*/
-
-/*=============================================================================
- Macros
-=============================================================================*/
-
-#define _2GB_RJ8 (2<<(30-8))
-#define _4GB_RJ8 (4<<(30-8))
-#define _4GB_RJ4 (4<<(30-4))
-
-#define BigPagex8_RJ8 (1<<(17+3-8)) /*128KB * 8 >> 8 */
-
-/*=============================================================================
- Global MCT Status Structure
-=============================================================================*/
-struct MCTStatStruc {
- u32 GStatus; /* Global Status bitfield*/
- u32 HoleBase; /* If not zero, BASE[39:8] (system address)
- of sub 4GB dram hole for HW remapping.*/
- u32 Sub4GCacheTop; /* If not zero, the 32-bit top of cacheable memory.*/
- u32 SysLimit; /* LIMIT[39:8] (system address)*/
- uint32_t TSCFreq;
- uint16_t nvram_checksum;
- uint8_t try_ecc;
-} __attribute__((packed, aligned(4)));
-
-/*=============================================================================
- Global MCT Configuration Status Word (GStatus)
-=============================================================================*/
-/*These should begin at bit 0 of GStatus[31:0]*/
-#define GSB_MTRRshort 0 /* Ran out of MTRRs while mapping memory*/
-#define GSB_ECCDIMMs 1 /* All banks of all Nodes are ECC capable*/
-#define GSB_DramECCDis 2 /* Dram ECC requested but not enabled.*/
-#define GSB_SoftHole 3 /* A Node Base gap was created*/
-#define GSB_HWHole 4 /* A HW dram remap was created*/
-#define GSB_NodeIntlv 5 /* Node Memory interleaving was enabled*/
-#define GSB_SpIntRemapHole 16 /* Special condition for Node Interleave and HW remapping*/
-#define GSB_EnDIMMSpareNW 17 /* Indicates that DIMM Spare can be used without a warm reset */
- /* NOTE: This is a local bit used by memory code */
-#define GSB_ConfigRestored 18 /* Training configuration was restored from NVRAM */
-
-/*===============================================================================
- Local DCT Status structure (a structure for each DCT)
-===============================================================================*/
-#include "mwlc_d.h" /* I have to */
-
-struct amd_spd_node_data {
- uint8_t spd_bytes[MAX_DIMMS_SUPPORTED][256]; /* [DIMM][byte] */
- uint8_t spd_address[MAX_DIMMS_SUPPORTED]; /* [DIMM] */
- uint64_t spd_hash[MAX_DIMMS_SUPPORTED]; /* [DIMM] */
- uint64_t nvram_spd_hash[MAX_DIMMS_SUPPORTED]; /* [DIMM] */
- uint8_t nvram_spd_match;
- uint8_t nvram_memclk[2]; /* [channel] */
-} __attribute__((packed, aligned(4)));
-
-struct DCTPersistentStatStruc {
- u8 CH_D_B_TxDqs[2][4][9]; /* [A/B] [DIMM1-4] [DQS] */
- /* CHA DIMM0 Byte 0 - 7 TxDqs */
- /* CHA DIMM0 Byte 0 - 7 TxDqs */
- /* CHA DIMM1 Byte 0 - 7 TxDqs */
- /* CHA DIMM1 Byte 0 - 7 TxDqs */
- /* CHB DIMM0 Byte 0 - 7 TxDqs */
- /* CHB DIMM0 Byte 0 - 7 TxDqs */
- /* CHB DIMM1 Byte 0 - 7 TxDqs */
- /* CHB DIMM1 Byte 0 - 7 TxDqs */
- u16 HostBiosSrvc1; /* Word sized general purpose field for use by host BIOS. Scratch space.*/
- u32 HostBiosSrvc2; /* Dword sized general purpose field for use by host BIOS. Scratch space.*/
-} __attribute__((packed, aligned(4)));
-
-struct DCTStatStruc { /* A per Node structure*/
-/* DCTStatStruct_F - start */
- u8 Node_ID; /* Node ID of current controller */
- uint8_t Internal_Node_ID; /* Internal Node ID of the current controller */
- uint8_t Dual_Node_Package; /* 1 = Dual node package (G34) */
- uint8_t stopDCT[2]; /* Set if the DCT will be stopped */
- u8 ErrCode; /* Current error condition of Node
- 0= no error
- 1= Variance Error, DCT is running but not in an optimal configuration.
- 2= Stop Error, DCT is NOT running
- 3= Fatal Error, DCT/MCT initialization has been halted.*/
- u32 ErrStatus; /* Error Status bit Field */
- u32 Status; /* Status bit Field*/
- u8 DIMMAddr[8]; /* SPD address of DIMM controlled by MA0_CS_L[0,1]*/
- /* SPD address of..MB0_CS_L[0,1]*/
- /* SPD address of..MA1_CS_L[0,1]*/
- /* SPD address of..MB1_CS_L[0,1]*/
- /* SPD address of..MA2_CS_L[0,1]*/
- /* SPD address of..MB2_CS_L[0,1]*/
- /* SPD address of..MA3_CS_L[0,1]*/
- /* SPD address of..MB3_CS_L[0,1]*/
- u16 DIMMPresent; /*For each bit n 0..7, 1 = DIMM n is present.
- DIMM# Select Signal
- 0 MA0_CS_L[0,1]
- 1 MB0_CS_L[0,1]
- 2 MA1_CS_L[0,1]
- 3 MB1_CS_L[0,1]
- 4 MA2_CS_L[0,1]
- 5 MB2_CS_L[0,1]
- 6 MA3_CS_L[0,1]
- 7 MB3_CS_L[0,1]*/
- u16 DIMMValid; /* For each bit n 0..7, 1 = DIMM n is valid and is/will be configured*/
- u16 DIMMMismatch; /* For each bit n 0..7, 1 = DIMM n is mismatched, channel B is always considered the mismatch */
- u16 DIMMSPDCSE; /* For each bit n 0..7, 1 = DIMM n SPD checksum error*/
- u16 DimmECCPresent; /* For each bit n 0..7, 1 = DIMM n is ECC capable.*/
- u16 DimmPARPresent; /* For each bit n 0..7, 1 = DIMM n is ADR/CMD Parity capable.*/
- u16 Dimmx4Present; /* For each bit n 0..7, 1 = DIMM n contains x4 data devices.*/
- u16 Dimmx8Present; /* For each bit n 0..7, 1 = DIMM n contains x8 data devices.*/
- u16 Dimmx16Present; /* For each bit n 0..7, 1 = DIMM n contains x16 data devices.*/
- u16 DIMM2Kpage; /* For each bit n 0..7, 1 = DIMM n contains 1K page devices.*/
- u8 MAload[2]; /* Number of devices loading MAA bus*/
- /* Number of devices loading MAB bus*/
- u8 MAdimms[2]; /*Number of DIMMs loading CH A*/
- /* Number of DIMMs loading CH B*/
- u8 DATAload[2]; /*Number of ranks loading CH A DATA*/
- /* Number of ranks loading CH B DATA*/
- u8 DIMMAutoSpeed; /*Max valid Mfg. Speed of DIMMs
- 1 = 200MHz
- 2 = 266MHz
- 3 = 333MHz
- 4 = 400MHz
- 5 = 533MHz*/
- u8 DIMMCASL; /* Min valid Mfg. CL bitfield
- 0 = 2.0
- 1 = 3.0
- 2 = 4.0
- 3 = 5.0
- 4 = 6.0 */
- u16 DIMMTrcd; /* Minimax Trcd*40 (ns) of DIMMs*/
- u16 DIMMTrp; /* Minimax Trp*40 (ns) of DIMMs*/
- u16 DIMMTrtp; /* Minimax Trtp*40 (ns) of DIMMs*/
- u16 DIMMTras; /* Minimax Tras*40 (ns) of DIMMs*/
- u16 DIMMTrc; /* Minimax Trc*40 (ns) of DIMMs*/
- u16 DIMMTwr; /* Minimax Twr*40 (ns) of DIMMs*/
- u16 DIMMTrrd; /* Minimax Trrd*40 (ns) of DIMMs*/
- u16 DIMMTwtr; /* Minimax Twtr*40 (ns) of DIMMs*/
- u8 Speed; /* Bus Speed (to set Controller)
- 1 = 200MHz
- 2 = 266MHz
- 3 = 333MHz
- 4 = 400MHz */
- u8 CASL; /* CAS latency DCT setting
- 0 = 2.0
- 1 = 3.0
- 2 = 4.0
- 3 = 5.0
- 4 = 6.0 */
- u8 Trcd; /* DCT Trcd (busclocks) */
- u8 Trp; /* DCT Trp (busclocks) */
- u8 Trtp; /* DCT Trtp (busclocks) */
- u8 Tras; /* DCT Tras (busclocks) */
- u8 Trc; /* DCT Trc (busclocks) */
- u8 Twr; /* DCT Twr (busclocks) */
- u8 Trrd; /* DCT Trrd (busclocks) */
- u8 Twtr; /* DCT Twtr (busclocks) */
- u8 Trfc[4]; /* DCT Logical DIMM0 Trfc
- 0 = 75ns (for 256Mb devs)
- 1 = 105ns (for 512Mb devs)
- 2 = 127.5ns (for 1Gb devs)
- 3 = 195ns (for 2Gb devs)
- 4 = 327.5ns (for 4Gb devs) */
- /* DCT Logical DIMM1 Trfc (see Trfc0 for format) */
- /* DCT Logical DIMM2 Trfc (see Trfc0 for format) */
- /* DCT Logical DIMM3 Trfc (see Trfc0 for format) */
- u16 CSPresent; /* For each bit n 0..7, 1 = Chip-select n is present */
- u16 CSTestFail; /* For each bit n 0..7, 1 = Chip-select n is present but disabled */
- u32 DCTSysBase; /* BASE[39:8] (system address) of this Node's DCTs. */
- u32 DCTHoleBase; /* If not zero, BASE[39:8] (system address) of dram hole for HW remapping. Dram hole exists on this Node's DCTs. */
- u32 DCTSysLimit; /* LIMIT[39:8] (system address) of this Node's DCTs */
- u16 PresetmaxFreq; /* Maximum OEM defined DDR frequency
- 200 = 200MHz (DDR400)
- 266 = 266MHz (DDR533)
- 333 = 333MHz (DDR667)
- 400 = 400MHz (DDR800) */
- u8 _2Tmode; /* 1T or 2T CMD mode (slow access mode)
- 1 = 1T
- 2 = 2T */
- u8 TrwtTO; /* DCT TrwtTO (busclocks)*/
- u8 Twrrd; /* DCT Twrrd (busclocks)*/
- u8 Twrwr; /* DCT Twrwr (busclocks)*/
- u8 Trdrd; /* DCT Trdrd (busclocks)*/
- u32 CH_ODC_CTL[2]; /* Output Driver Strength (see BKDG FN2:Offset 9Ch, index 00h*/
- u32 CH_ADDR_TMG[2]; /* Address Bus Timing (see BKDG FN2:Offset 9Ch, index 04h*/
- /* Output Driver Strength (see BKDG FN2:Offset 9Ch, index 20h*/
- /* Address Bus Timing (see BKDG FN2:Offset 9Ch, index 24h*/
- u16 CH_EccDQSLike[2]; /* CHA DQS ECC byte like...*/
- u8 CH_EccDQSScale[2]; /* CHA DQS ECC byte scale*/
- /* CHA DQS ECC byte like...*/
- /* CHA DQS ECC byte scale*/
- u8 MaxAsyncLat; /* Max Asynchronous Latency (ns)*/
- /* NOTE: Not used in Barcelona - u8 CH_D_RCVRDLY[2][4]; */
- /* CHA DIMM 0 - 4 Receiver Enable Delay*/
- /* CHB DIMM 0 - 4 Receiver Enable Delay */
- /* NOTE: Not used in Barcelona - u8 CH_D_B_DQS[2][2][8]; */
- /* CHA Byte 0-7 Write DQS Delay */
- /* CHA Byte 0-7 Read DQS Delay */
- /* CHB Byte 0-7 Write DQS Delay */
- /* CHB Byte 0-7 Read DQS Delay */
- u32 PtrPatternBufA; /* Ptr on stack to aligned DQS testing pattern*/
- u32 PtrPatternBufB; /* Ptr on stack to aligned DQS testing pattern*/
- u8 Channel; /* Current Channel (0= CH A, 1 = CH B)*/
- u8 ByteLane; /* Current Byte Lane (0..7)*/
- u8 Direction; /* Current DQS-DQ training write direction (0 = read, 1 = write)*/
- u8 Pattern; /* Current pattern*/
- u8 DQSDelay; /* Current DQS delay value*/
- u32 TrainErrors; /* Current Training Errors*/
-
- u32 AMC_TSC_DeltaLo; /* Time Stamp Counter measurement of AMC, Low dword*/
- u32 AMC_TSC_DeltaHi; /* Time Stamp Counter measurement of AMC, High dword*/
- /* NOTE: Not used in Barcelona - */
- u8 CH_D_DIR_MaxMin_B_Dly[2][2][2][8];
- /* CH A byte lane 0 - 7 minimum filtered window passing DQS delay value*/
- /* CH A byte lane 0 - 7 maximum filtered window passing DQS delay value*/
- /* CH B byte lane 0 - 7 minimum filtered window passing DQS delay value*/
- /* CH B byte lane 0 - 7 maximum filtered window passing DQS delay value*/
- /* CH A byte lane 0 - 7 minimum filtered window passing DQS delay value*/
- /* CH A byte lane 0 - 7 maximum filtered window passing DQS delay value*/
- /* CH B byte lane 0 - 7 minimum filtered window passing DQS delay value*/
- /* CH B byte lane 0 - 7 maximum filtered window passing DQS delay value*/
- uint64_t LogicalCPUID; /* The logical CPUID of the node*/
- u16 DimmQRPresent; /* QuadRank DIMM present?*/
- u16 DimmTrainFail; /* Bitmap showing which dimms failed training*/
- u16 CSTrainFail; /* Bitmap showing which chipselects failed training*/
- u16 DimmYr06; /* Bitmap indicating which Dimms have a manufactur's year code <= 2006*/
- u16 DimmWk2406; /* Bitmap indicating which Dimms have a manufactur's week code <= 24 of 2006 (June)*/
- u16 DimmDRPresent; /* Bitmap indicating that Dual Rank Dimms are present*/
- u16 DimmPlPresent; /* Bitmap indicating that Planar (1) or Stacked (0) Dimms are present.*/
- u16 ChannelTrainFai; /* Bitmap showing the channel information about failed Chip Selects
- 0 in any bit field indicates Channel 0
- 1 in any bit field indicates Channel 1 */
- u16 DIMMTfaw; /* Minimax Tfaw*16 (ns) of DIMMs */
- u8 Tfaw; /* DCT Tfaw (busclocks) */
- u16 CSUsrTestFail; /* Chip selects excluded by user */
-/* DCTStatStruct_F - end */
-
- u16 CH_MaxRdLat[2][2]; /* Max Read Latency (nclks) [dct][pstate] */
- /* Max Read Latency (ns) for DCT 1*/
- u8 CH_D_DIR_B_DQS[2][4][2][9]; /* [A/B] [DIMM1-4] [R/W] [DQS] */
- /* CHA DIMM0 Byte 0 - 7 and Check Write DQS Delay*/
- /* CHA DIMM0 Byte 0 - 7 and Check Read DQS Delay*/
- /* CHA DIMM1 Byte 0 - 7 and Check Write DQS Delay*/
- /* CHA DIMM1 Byte 0 - 7 and Check Read DQS Delay*/
- /* CHB DIMM0 Byte 0 - 7 and Check Write DQS Delay*/
- /* CHB DIMM0 Byte 0 - 7 and Check Read DQS Delay*/
- /* CHB DIMM1 Byte 0 - 7 and Check Write DQS Delay*/
- /* CHB DIMM1 Byte 0 - 7 and Check Read DQS Delay*/
- u16 CH_D_B_RCVRDLY[2][4][8]; /* [A/B] [DIMM0-3] [DQS] */
- /* CHA DIMM 0 Receiver Enable Delay*/
- /* CHA DIMM 1 Receiver Enable Delay*/
- /* CHA DIMM 2 Receiver Enable Delay*/
- /* CHA DIMM 3 Receiver Enable Delay*/
-
- /* CHB DIMM 0 Receiver Enable Delay*/
- /* CHB DIMM 1 Receiver Enable Delay*/
- /* CHB DIMM 2 Receiver Enable Delay*/
- /* CHB DIMM 3 Receiver Enable Delay*/
- u16 CH_D_BC_RCVRDLY[2][4];
- /* CHA DIMM 0 - 4 Check Byte Receiver Enable Delay*/
- /* CHB DIMM 0 - 4 Check Byte Receiver Enable Delay*/
- u8 DIMMValidDCT[2]; /* DIMM# in DCT0*/
- /* DIMM# in DCT1*/
- u16 CSPresent_DCT[2]; /* DCT# CS mapping */
- u16 MirrPresU_NumRegR; /* Address mapping from edge connect to DIMM present for unbuffered dimm
- Number of registers on the dimm for registered dimm */
- u8 MaxDCTs; /* Max number of DCTs in system*/
- /* NOTE: removed u8 DCT. Use ->dev_ for pci R/W; */ /*DCT pointer*/
- u8 GangedMode; /* Ganged mode enabled, 0 = disabled, 1 = enabled*/
- u8 DRPresent; /* Family 10 present flag, 0 = not Fam10, 1 = Fam10*/
- u32 NodeSysLimit; /* BASE[39:8],for DCT0+DCT1 system address*/
- u8 WrDatGrossH;
- u8 DqsRcvEnGrossL;
- /* NOTE: Not used - u8 NodeSpeed */ /* Bus Speed (to set Controller) */
- /* 1 = 200MHz */
- /* 2 = 266MHz */
- /* 3 = 333MHz */
- /* NOTE: Not used - u8 NodeCASL */ /* CAS latency DCT setting */
- /* 0 = 2.0 */
- /* 1 = 3.0 */
- /* 2 = 4.0 */
- /* 3 = 5.0 */
- /* 4 = 6.0 */
- u8 TrwtWB;
- u8 CurrRcvrCHADelay; /* for keep current RcvrEnDly of chA*/
- u16 T1000; /* get the T1000 figure (cycle time (ns)*1K)*/
- u8 DqsRcvEn_Pass; /* for TrainRcvrEn byte lane pass flag*/
- u8 DqsRcvEn_Saved; /* for TrainRcvrEn byte lane saved flag*/
- u8 SeedPass1Remainder; /* for Phy assisted DQS receiver enable training*/
-
- /* for second pass - Second pass should never run for Fam10*/
- /* NOTE: Not used for Barcelona - u8 CH_D_B_RCVRDLY_1[2][4][8]; */ /* CHA DIMM 0 Receiver Enable Delay */
- /* CHA DIMM 1 Receiver Enable Delay*/
- /* CHA DIMM 2 Receiver Enable Delay*/
- /* CHA DIMM 3 Receiver Enable Delay*/
-
- /* CHB DIMM 0 Receiver Enable Delay*/
- /* CHB DIMM 1 Receiver Enable Delay*/
- /* CHB DIMM 2 Receiver Enable Delay*/
- /* CHB DIMM 3 Receiver Enable Delay*/
-
- u8 ClToNB_flag; /* is used to restore ClLinesToNbDis bit after memory */
- u32 NodeSysBase; /* for channel interleave usage */
-
- /* Fam15h specific backup variables */
- uint8_t SwNbPstateLoDis;
- uint8_t NbPstateDisOnP0;
- uint8_t NbPstateThreshold;
- uint8_t NbPstateHi;
-
- /* New for LB Support */
- u8 NodePresent;
- u32 dev_host;
- u32 dev_map;
- u32 dev_dct;
- u32 dev_nbmisc;
- u32 dev_link;
- u32 dev_nbctl;
- u8 TargetFreq;
- u8 TargetCASL;
- uint32_t CtrlWrd3;
- uint32_t CtrlWrd4;
- uint32_t CtrlWrd5;
- u8 DqsRdWrPos_Saved;
- u8 DqsRcvEnGrossMax;
- u8 DqsRcvEnGrossMin;
- u8 WrDatGrossMax;
- u8 WrDatGrossMin;
- uint8_t tcwl_delay[2];
-
- u16 RegMan1Present; /* DIMM present bitmap of Register manufacture 1 */
- u16 RegMan2Present; /* DIMM present bitmap of Register manufacture 2 */
-
- struct _sMCTStruct *C_MCTPtr;
- struct _sDCTStruct *C_DCTPtr[2];
- /* struct _sDCTStruct *C_DCT1Ptr; */
-
- struct _sMCTStruct s_C_MCTPtr;
- struct _sDCTStruct s_C_DCTPtr[2];
- /* struct _sDCTStruct s_C_DCT1Ptr[8]; */
-
- /* DIMM supported voltage bitmap ([2:0]: 1.25V, 1.35V, 1.5V) */
- uint8_t DimmSupportedVoltages[MAX_DIMMS_SUPPORTED];
- uint32_t DimmConfiguredVoltage[MAX_DIMMS_SUPPORTED]; /* mV */
-
- uint8_t DimmRows[MAX_DIMMS_SUPPORTED];
- uint8_t DimmCols[MAX_DIMMS_SUPPORTED];
- uint8_t DimmRanks[MAX_DIMMS_SUPPORTED];
- uint8_t DimmBanks[MAX_DIMMS_SUPPORTED];
- uint8_t DimmWidth[MAX_DIMMS_SUPPORTED];
- uint64_t DimmChipSize[MAX_DIMMS_SUPPORTED];
- uint32_t DimmChipWidth[MAX_DIMMS_SUPPORTED];
- uint8_t DimmRegistered[MAX_DIMMS_SUPPORTED];
- uint8_t DimmLoadReduced[MAX_DIMMS_SUPPORTED];
-
- uint64_t DimmManufacturerID[MAX_DIMMS_SUPPORTED];
- char DimmPartNumber[MAX_DIMMS_SUPPORTED][SPD_PARTN_LENGTH+1];
- uint16_t DimmRevisionNumber[MAX_DIMMS_SUPPORTED];
- uint32_t DimmSerialNumber[MAX_DIMMS_SUPPORTED];
-
- struct amd_spd_node_data spd_data;
-
- /* NOTE: This must remain the last entry in this structure */
- struct DCTPersistentStatStruc persistentData;
-} __attribute__((packed, aligned(4)));
-
-struct amd_s3_persistent_mct_channel_data {
- /* Stage 1 (1 dword) */
- uint32_t f2x110;
-
- /* Stage 2 (88 dwords) */
- uint32_t f1x40;
- uint32_t f1x44;
- uint32_t f1x48;
- uint32_t f1x4c;
- uint32_t f1x50;
- uint32_t f1x54;
- uint32_t f1x58;
- uint32_t f1x5c;
- uint32_t f1x60;
- uint32_t f1x64;
- uint32_t f1x68;
- uint32_t f1x6c;
- uint32_t f1x70;
- uint32_t f1x74;
- uint32_t f1x78;
- uint32_t f1x7c;
- uint32_t f1xf0;
- uint32_t f1x120;
- uint32_t f1x124;
- uint32_t f2x10c;
- uint32_t f2x114;
- uint32_t f2x118;
- uint32_t f2x11c;
- uint32_t f2x1b0;
- uint32_t f3x44;
- uint64_t msr0000020[16];
- uint64_t msr00000250;
- uint64_t msr00000258;
- uint64_t msr0000026[8];
- uint64_t msr000002ff;
- uint64_t msrc0010010;
- uint64_t msrc001001a;
- uint64_t msrc001001d;
- uint64_t msrc001001f;
-
- /* Stage 3 (21 dwords) */
- uint32_t f2x40;
- uint32_t f2x44;
- uint32_t f2x48;
- uint32_t f2x4c;
- uint32_t f2x50;
- uint32_t f2x54;
- uint32_t f2x58;
- uint32_t f2x5c;
- uint32_t f2x60;
- uint32_t f2x64;
- uint32_t f2x68;
- uint32_t f2x6c;
- uint32_t f2x78;
- uint32_t f2x7c;
- uint32_t f2x80;
- uint32_t f2x84;
- uint32_t f2x88;
- uint32_t f2x8c;
- uint32_t f2x90;
- uint32_t f2xa4;
- uint32_t f2xa8;
-
- /* Stage 4 (1 dword) */
- uint32_t f2x94;
-
- /* Stage 6 (33 dwords) */
- uint32_t f2x9cx0d0f0_f_8_0_0_8_4_0[9][3]; /* [lane][setting] */
- uint32_t f2x9cx00;
- uint32_t f2x9cx0a;
- uint32_t f2x9cx0c;
-
- /* Stage 7 (1 dword) */
- uint32_t f2x9cx04;
-
- /* Stage 9 (2 dwords) */
- uint32_t f2x9cx0d0fe006;
- uint32_t f2x9cx0d0fe007;
-
- /* Stage 10 (78 dwords) */
- uint32_t f2x9cx10[12];
- uint32_t f2x9cx20[12];
- uint32_t f2x9cx3_0_0_3_1[4][3]; /* [dimm][setting] */
- uint32_t f2x9cx3_0_0_7_5[4][3]; /* [dimm][setting] */
- uint32_t f2x9cx0d;
- uint32_t f2x9cx0d0f0_f_0_13[9]; /* [lane] */
- uint32_t f2x9cx0d0f0_f_0_30[9]; /* [lane] */
- uint32_t f2x9cx0d0f2_f_0_30[4]; /* [pad select] */
- uint32_t f2x9cx0d0f8_8_4_0[2][3]; /* [offset][pad select] */
- uint32_t f2x9cx0d0f812f;
-
- /* Stage 11 (24 dwords) */
- uint32_t f2x9cx30[12];
- uint32_t f2x9cx40[12];
-
- /* Other (3 dwords) */
- uint32_t f3x58;
- uint32_t f3x5c;
- uint32_t f3x60;
-
- /* Family 15h-specific registers (91 dwords) */
- uint32_t f2x200;
- uint32_t f2x204;
- uint32_t f2x208;
- uint32_t f2x20c;
- uint32_t f2x210[4]; /* [nb pstate] */
- uint32_t f2x214;
- uint32_t f2x218;
- uint32_t f2x21c;
- uint32_t f2x22c;
- uint32_t f2x230;
- uint32_t f2x234;
- uint32_t f2x238;
- uint32_t f2x23c;
- uint32_t f2x240;
- uint32_t f2x9cx0d0fe003;
- uint32_t f2x9cx0d0fe013;
- uint32_t f2x9cx0d0f0_8_0_1f[9]; /* [lane]*/
- uint32_t f2x9cx0d0f201f;
- uint32_t f2x9cx0d0f211f;
- uint32_t f2x9cx0d0f221f;
- uint32_t f2x9cx0d0f801f;
- uint32_t f2x9cx0d0f811f;
- uint32_t f2x9cx0d0f821f;
- uint32_t f2x9cx0d0fc01f;
- uint32_t f2x9cx0d0fc11f;
- uint32_t f2x9cx0d0fc21f;
- uint32_t f2x9cx0d0f4009;
- uint32_t f2x9cx0d0f0_8_0_02[9]; /* [lane]*/
- uint32_t f2x9cx0d0f0_8_0_06[9]; /* [lane]*/
- uint32_t f2x9cx0d0f0_8_0_0a[9]; /* [lane]*/
- uint32_t f2x9cx0d0f2002;
- uint32_t f2x9cx0d0f2102;
- uint32_t f2x9cx0d0f2202;
- uint32_t f2x9cx0d0f8002;
- uint32_t f2x9cx0d0f8006;
- uint32_t f2x9cx0d0f800a;
- uint32_t f2x9cx0d0f8102;
- uint32_t f2x9cx0d0f8106;
- uint32_t f2x9cx0d0f810a;
- uint32_t f2x9cx0d0fc002;
- uint32_t f2x9cx0d0fc006;
- uint32_t f2x9cx0d0fc00a;
- uint32_t f2x9cx0d0fc00e;
- uint32_t f2x9cx0d0fc012;
- uint32_t f2x9cx0d0f2031;
- uint32_t f2x9cx0d0f2131;
- uint32_t f2x9cx0d0f2231;
- uint32_t f2x9cx0d0f8031;
- uint32_t f2x9cx0d0f8131;
- uint32_t f2x9cx0d0f8231;
- uint32_t f2x9cx0d0fc031;
- uint32_t f2x9cx0d0fc131;
- uint32_t f2x9cx0d0fc231;
- uint32_t f2x9cx0d0f0_0_f_31[9]; /* [lane] */
- uint32_t f2x9cx0d0f8021;
- uint32_t f2x9cx0d0fe00a;
-
- /* TOTAL: 343 dwords */
-} __attribute__((packed, aligned(4)));
-
-struct amd_s3_persistent_node_data {
- uint32_t node_present;
- uint64_t spd_hash[MAX_DIMMS_SUPPORTED];
- uint8_t memclk[2];
- struct amd_s3_persistent_mct_channel_data channel[2];
-} __attribute__((packed, aligned(4)));
-
-struct amd_s3_persistent_data {
- struct amd_s3_persistent_node_data node[MAX_NODES_SUPPORTED];
- uint16_t nvram_checksum;
-} __attribute__((packed, aligned(4)));
-
-/*===============================================================================
- Local Error Status Codes (DCTStatStruc.ErrCode)
-===============================================================================*/
-#define SC_RunningOK 0
-#define SC_VarianceErr 1 /* Running non-optimally*/
-#define SC_StopError 2 /* Not Running*/
-#define SC_FatalErr 3 /* Fatal Error, MCTB has exited immediately*/
-
-/*===============================================================================
- Local Error Status (DCTStatStruc.ErrStatus[31:0])
-===============================================================================*/
-#define SB_NoDimms 0
-#define SB_DIMMChkSum 1
-#define SB_DimmMismatchM 2 /* dimm module type(buffer) mismatch*/
-#define SB_DimmMismatchT 3 /* dimm CL/T mismatch*/
-#define SB_DimmMismatchO 4 /* dimm organization mismatch (128-bit)*/
-#define SB_NoTrcTrfc 5 /* SPD missing Trc or Trfc info*/
-#define SB_NoCycTime 6 /* SPD missing byte 23 or 25*/
-#define SB_BkIntDis 7 /* Bank interleave requested but not enabled*/
-#define SB_DramECCDis 8 /* Dram ECC requested but not enabled*/
-#define SB_SpareDis 9 /* Online spare requested but not enabled*/
-#define SB_MinimumMode 10 /* Running in Minimum Mode*/
-#define SB_NORCVREN 11 /* No DQS Receiver Enable pass window found*/
-#define SB_CHA2BRCVREN 12 /* DQS Rcvr En pass window CHA to CH B too large*/
-#define SB_SmallRCVR 13 /* DQS Rcvr En pass window too small (far right of dynamic range)*/
-#define SB_NODQSPOS 14 /* No DQS-DQ passing positions*/
-#define SB_SMALLDQS 15 /* DQS-DQ passing window too small*/
-#define SB_DCBKScrubDis 16 /* DCache scrub requested but not enabled */
-#define SB_RetryConfigTrain 17 /* Retry configuration and training */
-#define SB_FatalError 18 /* Fatal training error detected */
-
-/*===============================================================================
- Local Configuration Status (DCTStatStruc.Status[31:0])
-===============================================================================*/
-#define SB_Registered 0 /* All DIMMs are Registered*/
-#define SB_LoadReduced 1 /* All DIMMs are Load-Reduced*/
-#define SB_ECCDIMMs 2 /* All banks ECC capable*/
-#define SB_PARDIMMs 3 /* All banks Addr/CMD Parity capable*/
-#define SB_DiagClks 4 /* Jedec ALL slots clock enable diag mode*/
-#define SB_128bitmode 5 /* DCT in 128-bit mode operation*/
-#define SB_64MuxedMode 6 /* DCT in 64-bit mux'ed mode.*/
-#define SB_2TMode 7 /* 2T CMD timing mode is enabled.*/
-#define SB_SWNodeHole 8 /* Remapping of Node Base on this Node to create a gap.*/
-#define SB_HWHole 9 /* Memory Hole created on this Node using HW remapping.*/
-#define SB_Over400MHz 10 /* DCT freq >= 400MHz flag*/
-#define SB_DQSPos_Pass2 11 /* Using for TrainDQSPos DIMM0/1, when freq >= 400MHz*/
-#define SB_DQSRcvLimit 12 /* Using for DQSRcvEnTrain to know we have reached to upper bound.*/
-#define SB_ExtConfig 13 /* Indicator the default setting for extend PCI configuration support*/
-
-
-/*===============================================================================
- NVRAM/run-time-configurable Items
-===============================================================================*/
-/*Platform Configuration*/
-#define NV_PACK_TYPE 0 /* CPU Package Type (2-bits)
- 0 = NPT L1
- 1 = NPT M2
- 2 = NPT S1*/
-#define NV_MAX_NODES 1 /* Number of Nodes/Sockets (4-bits)*/
-#define NV_MAX_DIMMS 2 /* Number of DIMM slots for the specified Node ID (4-bits)*/
-#define NV_MAX_MEMCLK 3 /* Maximum platform demonstrated Memclock (10-bits)
- 200 = 200MHz (DDR400)
- 266 = 266MHz (DDR533)
- 333 = 333MHz (DDR667)
- 400 = 400MHz (DDR800)*/
-#define NV_MIN_MEMCLK 4 /* Minimum platform demonstrated Memclock (10-bits) */
-#define NV_ECC_CAP 5 /* Bus ECC capable (1-bits)
- 0 = Platform not capable
- 1 = Platform is capable*/
-#define NV_4RANKType 6 /* Quad Rank DIMM slot type (2-bits)
- 0 = Normal
- 1 = R4 (4-Rank Registered DIMMs in AMD server configuration)
- 2 = S4 (Unbuffered SO-DIMMs)*/
-#define NV_BYPMAX 7 /* Value to set DcqBypassMax field (See Function 2, Offset 94h, [27:24] of BKDG for field definition).
- 4 = 4 times bypass (normal for non-UMA systems)
- 7 = 7 times bypass (normal for UMA systems)*/
-#define NV_RDWRQBYP 8 /* Value to set RdWrQByp field (See Function 2, Offset A0h, [3:2] of BKDG for field definition).
- 2 = 8 times (normal for non-UMA systems)
- 3 = 16 times (normal for UMA systems)*/
-
-
-/*Dram Timing*/
-#define NV_MCTUSRTMGMODE 10 /* User Memclock Mode (2-bits)
- 0 = Auto, no user limit
- 1 = Auto, user limit provided in NV_MemCkVal
- 2 = Manual, user value provided in NV_MemCkVal*/
-#define NV_MemCkVal 11 /* Memory Clock Value (2-bits)
- 0 = 200MHz
- 1 = 266MHz
- 2 = 333MHz
- 3 = 400MHz*/
-
-/*Dram Configuration*/
-#define NV_BankIntlv 20 /* Dram Bank (chip-select) Interleaving (1-bits)
- 0 = disable
- 1 = enable*/
-#define NV_AllMemClks 21 /* Turn on All DIMM clocks (1-bits)
- 0 = normal
- 1 = enable all memclocks*/
-#define NV_SPDCHK_RESTRT 22 /* SPD Check control bitmap (1-bits)
- 0 = Exit current node init if any DIMM has SPD checksum error
- 1 = Ignore faulty SPD checksums (Note: DIMM cannot be enabled)*/
-#define NV_DQSTrainCTL 23 /* DQS Signal Timing Training Control
- 0 = skip DQS training
- 1 = perform DQS training*/
-#define NV_NodeIntlv 24 /* Node Memory Interleaving (1-bits)
- 0 = disable
- 1 = enable*/
-#define NV_BurstLen32 25 /* BurstLength32 for 64-bit mode (1-bits)
- 0 = disable (normal)
- 1 = enable (4 beat burst when width is 64-bits)*/
-
-/*Dram Power*/
-#define NV_CKE_PDEN 30 /* CKE based power down mode (1-bits)
- 0 = disable
- 1 = enable*/
-#define NV_CKE_CTL 31 /* CKE based power down control (1-bits)
- 0 = per Channel control
- 1 = per Chip select control*/
-#define NV_CLKHZAltVidC3 32 /* Memclock tri-stating during C3 and Alt VID (1-bits)
- 0 = disable
- 1 = enable*/
-
-/*Memory Map/Mgt.*/
-#define NV_BottomIO 40 /* Bottom of 32-bit IO space (8-bits)
- NV_BottomIO[7:0]=Addr[31:24]*/
-#define NV_BottomUMA 41 /* Bottom of shared graphics dram (8-bits)
- NV_BottomUMA[7:0]=Addr[31:24]*/
-#define NV_MemHole 42 /* Memory Hole Remapping (1-bits)
- 0 = disable
- 1 = enable */
-
-/*ECC*/
-#define NV_ECC 50 /* Dram ECC enable*/
-#define NV_NBECC 52 /* ECC MCE enable*/
-#define NV_ChipKill 53 /* Chip-Kill ECC Mode enable*/
-#define NV_ECCRedir 54 /* Dram ECC Redirection enable*/
-#define NV_DramBKScrub 55 /* Dram ECC Background Scrubber CTL*/
-#define NV_L2BKScrub 56 /* L2 ECC Background Scrubber CTL*/
-#define NV_L3BKScrub 57 /* L3 ECC Background Scrubber CTL*/
-#define NV_DCBKScrub 58 /* DCache ECC Background Scrubber CTL*/
-#define NV_CS_SpareCTL 59 /* Chip Select Spare Control bit 0:
- 0 = disable Spare
- 1 = enable Spare */
- /* Chip Select Spare Control bit 1-4:
- Reserved, must be zero*/
-#define NV_SyncOnUnEccEn 61 /* SyncOnUnEccEn control
- 0 = disable
- 1 = enable*/
-#define NV_Unganged 62
-
-#define NV_ChannelIntlv 63 /* Channel Interleaving (3-bits)
- xx0b = disable
- yy1b = enable with DctSelIntLvAddr set to yyb */
-
-#define NV_MAX_DIMMS_PER_CH 64 /* Maximum number of DIMMs per channel */
-
-/*===============================================================================
- CBMEM storage
-===============================================================================*/
-struct amdmct_memory_info {
- struct MCTStatStruc mct_stat;
- struct DCTStatStruc dct_stat[MAX_NODES_SUPPORTED];
- uint16_t ecc_enabled;
- uint16_t ecc_scrub_rate;
-} __attribute__((packed, aligned(4)));
-
-extern const u8 Table_DQSRcvEn_Offset[];
-extern const u32 TestPattern0_D[];
-extern const u32 TestPattern1_D[];
-extern const u32 TestPattern2_D[];
-
-u32 Get_NB32(u32 dev, u32 reg);
-void Set_NB32(u32 dev, u32 reg, u32 val);
-u32 Get_NB32_index(u32 dev, u32 index_reg, u32 index);
-void Set_NB32_index(u32 dev, u32 index_reg, u32 index, u32 data);
-u32 Get_NB32_index_wait(u32 dev, u32 index_reg, u32 index);
-void Set_NB32_index_wait(u32 dev, u32 index_reg, u32 index, u32 data);
-u32 OtherTiming_A_D(struct DCTStatStruc *pDCTstat, u32 val);
-void mct_ForceAutoPrecharge_D(struct DCTStatStruc *pDCTstat, u32 dct);
-u32 Modify_D3CMP(struct DCTStatStruc *pDCTstat, u32 dct, u32 value);
-u8 mct_checkNumberOfDqsRcvEn_1Pass(u8 pass);
-u32 SetupDqsPattern_1PassA(u8 Pass);
-u32 SetupDqsPattern_1PassB(u8 Pass);
-u8 mct_Get_Start_RcvrEnDly_1Pass(u8 Pass);
-u16 mct_Average_RcvrEnDly_Pass(struct DCTStatStruc *pDCTstat, u16 RcvrEnDly, u16 RcvrEnDlyLimit, u8 Channel, u8 Receiver, u8 Pass);
-void initialize_mca(uint8_t bsp, uint8_t suppress_errors);
-void CPUMemTyping_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA);
-void UMAMemTyping_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA);
-uint64_t mctGetLogicalCPUID(u32 Node);
-u8 ECCInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA);
-void TrainReceiverEn_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA, u8 Pass);
-void TrainMaxRdLatency_En_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA);
-void mct_TrainDQSPos_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA);
-void mctSetEccDQSRcvrEn_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA);
-void TrainMaxReadLatency_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA);
-void mct_EndDQSTraining_D(struct MCTStatStruc *pMCTstat,struct DCTStatStruc *pDCTstatA);
-void mct_SetRcvrEnDly_D(struct DCTStatStruc *pDCTstat, u16 RcvrEnDly, u8 FinalValue, u8 Channel, u8 Receiver, u32 dev, u32 index_reg, u8 Addl_Index, u8 Pass);
-void SetEccDQSRcvrEn_D(struct DCTStatStruc *pDCTstat, u8 Channel);
-void mctGet_PS_Cfg_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u32 dct);
-void InterleaveBanks_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct);
-void mct_SetDramConfigHi_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u32 dct, u32 DramConfigHi);
-void mct_DramInit_Hw_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct);
-void mct_SetClToNB_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat);
-void mct_SetWbEnhWsbDis_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat);
-void mct_ForceNBPState0_En_Fam15(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat);
-void mct_ForceNBPState0_Dis_Fam15(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat);
-void mct_TrainRcvrEn_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 Pass);
-void mct_EnableDimmEccEn_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 _DisableDramECC);
-u32 procOdtWorkaround(struct DCTStatStruc *pDCTstat, u32 dct, u32 val);
-void mct_BeforeDramInit_D(struct DCTStatStruc *pDCTstat, u32 dct);
-void DIMMSetVoltages(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA);
-void InterleaveNodes_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA);
-void InterleaveChannels_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA);
-void mct_BeforeDQSTrain_Samp_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat);
-
-void phyAssistedMemFnceTraining(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA, int16_t Node);
-u8 mct_SaveRcvEnDly_D_1Pass(struct DCTStatStruc *pDCTstat, u8 pass);
-u8 mct_InitReceiver_D(struct DCTStatStruc *pDCTstat, u8 dct);
-void mct_Wait(u32 cycles);
-u8 mct_RcvrRankEnabled_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 Channel, u8 ChipSel);
-u32 mct_GetRcvrSysAddr_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 channel, u8 receiver, u8 *valid);
-void mct_Read1LTestPattern_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u32 addr);
-void mctAutoInitMCT_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA);
-void calculate_spd_hash(uint8_t *spd_data, uint64_t *spd_hash);
-int8_t load_spd_hashes_from_nvram(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat);
-int8_t restore_mct_information_from_nvram(uint8_t training_only);
-uint16_t calculate_nvram_mct_hash(void);
-
-uint32_t fam10h_address_timing_compensation_code(struct DCTStatStruc *pDCTstat, uint8_t dct);
-uint32_t fam15h_output_driver_compensation_code(struct DCTStatStruc *pDCTstat, uint8_t dct);
-uint32_t fam15h_address_timing_compensation_code(struct DCTStatStruc *pDCTstat, uint8_t dct);
-uint8_t fam15h_slow_access_mode(struct DCTStatStruc *pDCTstat, uint8_t dct);
-void precise_memclk_delay_fam15(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, uint8_t dct, uint32_t clocks);
-void mct_EnableDatIntlv_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat);
-void SetDllSpeedUp_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dct);
-uint8_t get_available_lane_count(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat);
-void read_dqs_receiver_enable_control_registers(uint16_t *current_total_delay, uint32_t dev, uint8_t dct, uint8_t dimm, uint32_t index_reg);
-void read_dqs_write_timing_control_registers(uint16_t *current_total_delay, uint32_t dev, uint8_t dct, uint8_t dimm, uint32_t index_reg);
-void fam15EnableTrainingMode(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t enable);
-void read_dqs_read_data_timing_registers(uint16_t *delay, uint32_t dev,
- uint8_t dct, uint8_t dimm, uint32_t index_reg);
-void write_dqs_read_data_timing_registers(uint16_t *delay, uint32_t dev,
- uint8_t dct, uint8_t dimm, uint32_t index_reg);
-void dqsTrainMaxRdLatency_SW_Fam15(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat);
-void proc_IOCLFLUSH_D(u32 addr_hi);
-u8 ChipSelPresent_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat,
- u8 Channel, u8 ChipSel);
-void mct_Write1LTestPattern_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat,
- u32 TestAddr, u8 pattern);
-u8 NodePresent_D(u8 Node);
-void DCTMemClr_Init_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat);
-void DCTMemClr_Sync_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat);
-void SPD2ndTiming(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dct);
-void ProgDramMRSReg_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dct);
-u8 PlatformSpec_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dct);
-void StartupDCT_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dct);
-uint16_t mhz_to_memclk_config(uint16_t freq);
-void SetTargetFreq(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstatA, uint8_t Node);
-void mct_WriteLevelization_HW(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstatA, uint8_t Pass);
-uint8_t AgesaHwWlPhase1(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dct, u8 dimm, u8 pass);
-uint8_t AgesaHwWlPhase2(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t dimm, uint8_t pass);
-uint8_t AgesaHwWlPhase3(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dct, u8 dimm, u8 pass);
-void EnableZQcalibration(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat);
-void DisableZQcalibration(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat);
-void PrepareC_MCT(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat);
-void PrepareC_DCT(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct);
-void Restore_OnDimmMirror(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat);
-void Clear_OnDimmMirror(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat);
-void MCTMemClr_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA);
-void mct_BeforeDQSTrainSamp(struct DCTStatStruc *pDCTstat);
-void mct_ExtMCTConfig_Bx(struct DCTStatStruc *pDCTstat);
-void mct_ExtMCTConfig_Cx(struct DCTStatStruc *pDCTstat);
-void mct_ExtMCTConfig_Dx(struct DCTStatStruc *pDCTstat);
-u32 mct_SetDramConfigMisc2(struct DCTStatStruc *pDCTstat,
- uint8_t dct, uint32_t misc2, uint32_t DramControl);
-
-uint8_t dct_ddr_voltage_index(struct DCTStatStruc *pDCTstat, uint8_t dct);
-void mct_DramControlReg_Init_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, uint8_t dct);
-void precise_ndelay_fam15(struct MCTStatStruc *pMCTstat, uint32_t nanoseconds);
-void FreqChgCtrlWrd(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, uint8_t dct);
-u32 mct_MR1Odt_RDimm(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dct, u32 MrsChipSel);
-void mct_DramInit_Sw_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dct);
-void print_debug_dqs(const char *str, u32 val, u8 level);
-void print_debug_dqs_pair(const char *str, u32 val, const char *str2, u32 val2, u8 level);
-u8 mct_DisableDimmEccEn_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat);
-void ResetDCTWrPtr_D(u32 dev, uint8_t dct, u32 index_reg, u32 index);
-void Calc_SetMaxRdLatency_D_Fam15(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t calc_min);
-void write_dram_dqs_training_pattern_fam15(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, uint8_t dct,
- uint8_t Receiver, uint8_t lane, uint8_t stop_on_error);
-void read_dram_dqs_training_pattern_fam15(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, uint8_t dct,
- uint8_t Receiver, uint8_t lane, uint8_t stop_on_error);
-void write_dqs_receiver_enable_control_registers(uint16_t *current_total_delay, uint32_t dev, uint8_t dct, uint8_t dimm, uint32_t index_reg);
-
-uint32_t fenceDynTraining_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, uint8_t dct);
-int32_t abs(int32_t val);
-void SetTargetWTIO_D(u32 TestAddr);
-void ResetTargetWTIO_D(void);
-u32 mct_GetMCTSysAddr_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat,
- u8 Channel, u8 receiver, u8 *valid);
-void set_2t_configuration(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dct);
-u8 mct_BeforePlatformSpec(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dct);
-u8 mct_PlatformSpec(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dct);
-void InitPhyCompensation(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dct);
-u32 mct_MR1(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dct, u32 MrsChipSel);
-u32 mct_MR2(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dct, u32 MrsChipSel);
-uint8_t fam15_rttwr(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t dimm, uint8_t rank, uint8_t package_type);
-uint8_t fam15_rttnom(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t dimm, uint8_t rank, uint8_t package_type);
-uint8_t fam15_dimm_dic(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t dimm, uint8_t rank, uint8_t package_type);
-u32 mct_DramTermDyn_RDimm(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dimm);
-
-void restore_mct_data_from_save_variable(struct amd_s3_persistent_data* persistent_data, uint8_t training_only);
-#endif
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d_gcc.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d_gcc.c
deleted file mode 100644
index ccea732709..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d_gcc.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
- *
- * 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.
- */
-
-#include "mct_d_gcc.h"
-#include <stdint.h>
-#include <arch/cpu.h>
-
-void _WRMSR(u32 addr, u32 lo, u32 hi)
-{
- __asm__ volatile (
- "wrmsr"
- :
- :"c"(addr),"a"(lo), "d" (hi)
- );
-}
-
-void _RDMSR(u32 addr, u32 *lo, u32 *hi)
-{
- __asm__ volatile (
- "rdmsr"
- :"=a"(*lo), "=d" (*hi)
- :"c"(addr)
- );
-}
-
-void _RDTSC(u32 *lo, u32 *hi)
-{
- __asm__ volatile (
- "rdtsc"
- : "=a" (*lo), "=d"(*hi)
- );
-}
-
-void _cpu_id(u32 addr, u32 *val)
-{
- __asm__ volatile(
- "cpuid"
- : "=a" (val[0]),
- "=b" (val[1]),
- "=c" (val[2]),
- "=d" (val[3])
- : "0" (addr));
-
-}
-
-u32 bsr(u32 x)
-{
- u8 i;
- u32 ret = 0;
-
- for (i = 31; i > 0; i--) {
- if (x & (1<<i)) {
- ret = i;
- break;
- }
- }
-
- return ret;
-
-}
-
-u32 bsf(u32 x)
-{
- u8 i;
- u32 ret = 32;
-
- for (i = 0; i < 32; i++) {
- if (x & (1<<i)) {
- ret = i;
- break;
- }
- }
-
- return ret;
-}
-
-void proc_MFENCE(void)
-{
- __asm__ volatile (
- "outb %%al, $0xed\n\t" /* _EXECFENCE */
- "mfence\n\t"
- :::"memory"
- );
-}
-
-void proc_CLFLUSH(u32 addr_hi)
-{
- SetUpperFSbase(addr_hi);
-
- __asm__ volatile (
- /* clflush fs:[eax] */
- "outb %%al, $0xed\n\t" /* _EXECFENCE */
- "clflush %%fs:(%0)\n\t"
- "mfence\n\t"
- ::"a" (addr_hi<<8)
- );
-}
-
-
-void WriteLNTestPattern(u32 addr_lo, u8 *buf_a, u32 line_num)
-{
- uint32_t step = 16;
- uint32_t count = line_num * 4;
-
- __asm__ volatile (
- /*prevent speculative execution of following instructions*/
- /* FIXME: needed ? */
- "outb %%al, $0xed\n\t" /* _EXECFENCE */
- "1:\n\t"
- "movdqa (%3), %%xmm0\n\t"
- "movntdq %%xmm0, %%fs:(%0)\n\t" /* xmm0 is 128 bit */
- "addl %1, %0\n\t"
- "addl %1, %3\n\t"
- "loop 1b\n\t"
- "mfence\n\t"
-
- : "+a" (addr_lo), "+d" (step), "+c" (count), "+b" (buf_a) : :
- );
-
-}
-
-u32 read32_fs(u32 addr_lo)
-{
- u32 value;
- __asm__ volatile (
- "outb %%al, $0xed\n\t" /* _EXECFENCE */
- "movl %%fs:(%1), %0\n\t"
- :"=b"(value): "a" (addr_lo)
- );
- return value;
-}
-
-uint64_t read64_fs(uint32_t addr_lo)
-{
- uint64_t value = 0;
- uint32_t value_lo;
- uint32_t value_hi;
-
- __asm__ volatile (
- "outb %%al, $0xed\n\t" /* _EXECFENCE */
- "mfence\n\t"
- "movl %%fs:(%2), %0\n\t"
- "movl %%fs:(%3), %1\n\t"
- :"=c"(value_lo), "=d"(value_hi): "a" (addr_lo), "b" (addr_lo + 4) : "memory"
- );
- value |= value_lo;
- value |= ((uint64_t)value_hi) << 32;
- return value;
-}
-
-void FlushDQSTestPattern_L9(u32 addr_lo)
-{
- __asm__ volatile (
- "outb %%al, $0xed\n\t" /* _EXECFENCE */
- "clflush %%fs:-128(%%ecx)\n\t"
- "clflush %%fs:-64(%%ecx)\n\t"
- "clflush %%fs:(%%ecx)\n\t"
- "clflush %%fs:64(%%ecx)\n\t"
-
- "clflush %%fs:-128(%%eax)\n\t"
- "clflush %%fs:-64(%%eax)\n\t"
- "clflush %%fs:(%%eax)\n\t"
- "clflush %%fs:64(%%eax)\n\t"
-
- "clflush %%fs:-128(%%ebx)\n\t"
-
- :: "b" (addr_lo+128+8*64), "c"(addr_lo+128),
- "a"(addr_lo+128+4*64)
- );
-
-}
-
-__attribute__((noinline)) void FlushDQSTestPattern_L18(u32 addr_lo)
-{
- __asm__ volatile (
- "outb %%al, $0xed\n\t" /* _EXECFENCE */
- "clflush %%fs:-128(%%eax)\n\t"
- "clflush %%fs:-64(%%eax)\n\t"
- "clflush %%fs:(%%eax)\n\t"
- "clflush %%fs:64(%%eax)\n\t"
-
- "clflush %%fs:-128(%%edi)\n\t"
- "clflush %%fs:-64(%%edi)\n\t"
- "clflush %%fs:(%%edi)\n\t"
- "clflush %%fs:64(%%edi)\n\t"
-
- "clflush %%fs:-128(%%ebx)\n\t"
- "clflush %%fs:-64(%%ebx)\n\t"
- "clflush %%fs:(%%ebx)\n\t"
- "clflush %%fs:64(%%ebx)\n\t"
-
- "clflush %%fs:-128(%%ecx)\n\t"
- "clflush %%fs:-64(%%ecx)\n\t"
- "clflush %%fs:(%%ecx)\n\t"
- "clflush %%fs:64(%%ecx)\n\t"
-
- "clflush %%fs:-128(%%edx)\n\t"
- "clflush %%fs:-64(%%edx)\n\t"
-
- :: "b" (addr_lo+128+8*64), "c" (addr_lo+128+12*64),
- "d" (addr_lo +128+16*64), "a"(addr_lo+128),
- "D"(addr_lo+128+4*64)
- );
-}
-
-void ReadMaxRdLat1CLTestPattern_D(u32 addr)
-{
- SetUpperFSbase(addr);
-
- __asm__ volatile (
- "outb %%al, $0xed\n\t" /* _EXECFENCE */
- "movl %%fs:-128(%%esi), %%eax\n\t" /* TestAddr cache line */
- "movl %%fs:-64(%%esi), %%eax\n\t" /* +1 */
- "movl %%fs:(%%esi), %%eax\n\t" /* +2 */
- "mfence\n\t"
- :: "a"(0), "S"((addr<<8)+128)
- );
-
-}
-
-void WriteMaxRdLat1CLTestPattern_D(u32 buf, u32 addr)
-{
- uint32_t addr_phys = addr << 8;
- uint32_t step = 16;
- uint32_t count = 3 * 4;
-
- SetUpperFSbase(addr);
-
- __asm__ volatile (
- "outb %%al, $0xed\n\t" /* _EXECFENCE */
- "1:\n\t"
- "movdqa (%3), %%xmm0\n\t"
- "movntdq %%xmm0, %%fs:(%0)\n\t" /* xmm0 is 128 bit */
- "addl %1, %0\n\t"
- "addl %1, %3\n\t"
- "loop 1b\n\t"
- "mfence\n\t"
-
- : "+a" (addr_phys), "+d" (step), "+c" (count), "+b" (buf) : :
- );
-}
-
-void FlushMaxRdLatTestPattern_D(u32 addr)
-{
- /* Flush a pattern of 72 bit times (per DQ) from cache.
- * This procedure is used to ensure cache miss on the next read training.
- */
-
- SetUpperFSbase(addr);
-
- __asm__ volatile (
- "outb %%al, $0xed\n\t" /* _EXECFENCE */
- "clflush %%fs:-128(%%esi)\n\t" /* TestAddr cache line */
- "clflush %%fs:-64(%%esi)\n\t" /* +1 */
- "clflush %%fs:(%%esi)\n\t" /* +2 */
- "mfence\n\t"
-
- :: "S"((addr<<8)+128)
- );
-}
-
-u32 stream_to_int(u8 *p)
-{
- int i;
- u32 val;
- u32 valx;
-
- val = 0;
-
- for (i = 3; i >= 0; i--) {
- val <<= 8;
- valx = *(p+i);
- val |= valx;
- }
-
- return val;
-}
-
-u8 oemNodePresent_D(u8 Node, u8 *ret)
-{
- *ret = 0;
- return 0;
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d_gcc.h b/src/northbridge/amd/amdmct/mct_ddr3/mct_d_gcc.h
deleted file mode 100644
index 629e6e639b..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d_gcc.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
- * Copyright (C) 2016 Damien Zammit <damien@zamaudio.com>
- *
- * 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.
- */
-#ifndef MCT_D_GCC_H
-#define MCT_D_GCC_H
-
-#include <stdint.h>
-#include <cpu/x86/cr.h>
-
-void _WRMSR(u32 addr, u32 lo, u32 hi);
-void _RDMSR(u32 addr, u32 *lo, u32 *hi);
-void _RDTSC(u32 *lo, u32 *hi);
-void _cpu_id(u32 addr, u32 *val);
-u32 bsr(u32 x);
-u32 bsf(u32 x);
-#define _MFENCE asm volatile ("mfence")
-#define _SFENCE asm volatile ("sfence")
-
-/* prevent speculative execution of following instructions */
-#define _EXECFENCE asm volatile ("outb %al, $0xed")
-
-u32 SetUpperFSbase(u32 addr_hi);
-
-void proc_MFENCE(void);
-void proc_CLFLUSH(u32 addr_hi);
-void WriteLNTestPattern(u32 addr_lo, u8 *buf_a, u32 line_num);
-u32 read32_fs(u32 addr_lo);
-uint64_t read64_fs(uint32_t addr_lo);
-void FlushDQSTestPattern_L9(u32 addr_lo);
-__attribute__((noinline)) void FlushDQSTestPattern_L18(u32 addr_lo);
-void ReadMaxRdLat1CLTestPattern_D(u32 addr);
-void WriteMaxRdLat1CLTestPattern_D(u32 buf, u32 addr);
-void FlushMaxRdLatTestPattern_D(u32 addr);
-u32 stream_to_int(u8 *p);
-u8 oemNodePresent_D(u8 Node, u8 *ret);
-
-#endif
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctardk5.c b/src/northbridge/amd/amdmct/mct_ddr3/mctardk5.c
deleted file mode 100644
index e8116340c4..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctardk5.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
- *
- * 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.
- */
-
-/* AM3/ASB2/C32/G34 DDR3 */
-
-#include <arch/cpu.h>
-#include <stdint.h>
-#include "mct_d.h"
-#include "mct_d_gcc.h"
-
-static uint8_t is_fam15h(void)
-{
- uint8_t fam15h = 0;
- uint32_t family;
-
- family = cpuid_eax(0x80000001);
- family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);
-
- if (family >= 0x6f)
- /* Family 15h or later */
- fam15h = 1;
-
- return fam15h;
-}
-
-static void Get_ChannelPS_Cfg0_D(u8 MAAdimms, u8 Speed, u8 MAAload,
- u32 *ODC_CTL,
- u8 *CMDmode);
-
-void mctGet_PS_Cfg_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u32 dct)
-{
- if (is_fam15h()) {
- pDCTstat->CH_ADDR_TMG[dct] = fam15h_address_timing_compensation_code(pDCTstat, dct);
- pDCTstat->CH_ODC_CTL[dct] = fam15h_output_driver_compensation_code(pDCTstat, dct);
- pDCTstat->_2Tmode = fam15h_slow_access_mode(pDCTstat, dct);
- } else {
- Get_ChannelPS_Cfg0_D(pDCTstat->MAdimms[dct], pDCTstat->Speed,
- pDCTstat->MAload[dct],
- &(pDCTstat->CH_ODC_CTL[dct]),
- &pDCTstat->_2Tmode);
-
- if (pDCTstat->Status & (1 << SB_Registered)) {
- pDCTstat->_2Tmode = 1; /* Disable slow access mode */
- }
- pDCTstat->CH_ADDR_TMG[dct] = fam10h_address_timing_compensation_code(pDCTstat, dct);
-
- pDCTstat->CH_ODC_CTL[dct] |= 0x20000000; /* 60ohms */
- }
-
- pDCTstat->CH_EccDQSLike[0] = 0x0403;
- pDCTstat->CH_EccDQSScale[0] = 0x70;
- pDCTstat->CH_EccDQSLike[1] = 0x0403;
- pDCTstat->CH_EccDQSScale[1] = 0x70;
-}
-
-/*
- * In: MAAdimms - number of DIMMs on the channel
- * : Speed - Speed (see DCTStatstruc.Speed for definition)
- * : MAAload - number of address bus loads on the channel
- * Out: AddrTmgCTL - Address Timing Control Register Value
- * : ODC_CTL - Output Driver Compensation Control Register Value
- * : CMDmode - CMD mode
- */
-static void Get_ChannelPS_Cfg0_D(u8 MAAdimms, u8 Speed, u8 MAAload,
- u32 *ODC_CTL,
- u8 *CMDmode)
-{
- *ODC_CTL = 0;
- *CMDmode = 1;
-
- if (MAAdimms == 1) {
- *ODC_CTL = 0x00113222;
- *CMDmode = 1;
- } else /* if (MAAdimms == 0) */ {
- if (Speed == 4) {
- *CMDmode = 1;
- } else if (Speed == 5) {
- *CMDmode = 1;
- } else if (Speed == 6) {
- *CMDmode = 2;
- } else {
- *CMDmode = 2;
- }
- *ODC_CTL = 0x00223323;
- }
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctardk6.c b/src/northbridge/amd/amdmct/mct_ddr3/mctardk6.c
deleted file mode 100644
index d6480ab91a..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctardk6.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
- *
- * 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.
- */
-
-/* The socket type Fr2, G (1207) are not tested.
- */
-
-static void Get_ChannelPS_Cfg0_D(u8 MAAdimms, u8 Speed, u8 MAAload,
- u8 DATAAload, u32 *AddrTmgCTL, u32 *ODC_CTL,
- u8 *CMDmode);
-
-
-void mctGet_PS_Cfg_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u32 dct)
-{
- Get_ChannelPS_Cfg0_D(pDCTstat->MAdimms[dct], pDCTstat->Speed,
- pDCTstat->MAload[dct], pDCTstat->DATAload[dct],
- &(pDCTstat->CH_ADDR_TMG[dct]), &(pDCTstat->CH_ODC_CTL[dct]),
- &pDCTstat->_2Tmode);
-
- if (pDCTstat->GangedMode == 1 && dct == 0)
- Get_ChannelPS_Cfg0_D(pDCTstat->MAdimms[1], pDCTstat->Speed,
- pDCTstat->MAload[1], pDCTstat->DATAload[1],
- &(pDCTstat->CH_ADDR_TMG[1]), &(pDCTstat->CH_ODC_CTL[1]),
- &pDCTstat->_2Tmode);
-
- pDCTstat->CH_EccDQSLike[0] = 0x0302;
- pDCTstat->CH_EccDQSLike[1] = 0x0302;
-
-}
-
-/*
- * In: MAAdimms - number of DIMMs on the channel
- * : Speed - Speed (see DCTStatstruc.Speed for definition)
- * : MAAload - number of address bus loads on the channel
- * : DATAAload - number of ranks on the channel
- * Out: AddrTmgCTL - Address Timing Control Register Value
- * : ODC_CTL - Output Driver Compensation Control Register Value
- * : CMDmode - CMD mode
- */
-static void Get_ChannelPS_Cfg0_D(u8 MAAdimms, u8 Speed, u8 MAAload,
- u8 DATAAload, u32 *AddrTmgCTL, u32 *ODC_CTL,
- u8 *CMDmode)
-{
- *AddrTmgCTL = 0;
- *ODC_CTL = 0;
- *CMDmode = 1;
-
- if (mctGet_NVbits(NV_MAX_DIMMS) == 4) {
- if (Speed == 4) {
- *AddrTmgCTL = 0x00000000;
- } else if (Speed == 5) {
- *AddrTmgCTL = 0x003C3C3C;
- if (MAAdimms > 1)
- *AddrTmgCTL = 0x003A3C3A;
- } else if (Speed == 6) {
- if (MAAdimms == 1)
- *AddrTmgCTL = 0x003A3A3A;
- else
- *AddrTmgCTL = 0x00383A38;
- } else {
- if (MAAdimms == 1)
- *AddrTmgCTL = 0x00373937;
- else
- *AddrTmgCTL = 0x00353935;
- }
- } else {
- if (Speed == 4) {
- *AddrTmgCTL = 0x00000000;
- if (MAAdimms == 3)
- *AddrTmgCTL = 0x00380038;
- } else if (Speed == 5) {
- if (MAAdimms == 1)
- *AddrTmgCTL = 0x003C3C3C;
- else if (MAAdimms == 2)
- *AddrTmgCTL = 0x003A3C3A;
- else
- *AddrTmgCTL = 0x00373C37;
- } else if (Speed == 6) {
- if (MAAdimms == 1)
- *AddrTmgCTL = 0x003A3A3A;
- else if (MAAdimms == 2)
- *AddrTmgCTL = 0x00383A38;
- else
- *AddrTmgCTL = 0x00343A34;
- } else {
- if (MAAdimms == 1)
- *AddrTmgCTL = 0x00393939;
- else if (MAAdimms == 2)
- *AddrTmgCTL = 0x00363936;
- else
- *AddrTmgCTL = 0x00303930;
- }
- }
-
- if ((MAAdimms == 1) && (MAAload < 4))
- *ODC_CTL = 0x20113222;
- else
- *ODC_CTL = 0x20223222;
-
- *CMDmode = 1;
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctchi_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mctchi_d.c
deleted file mode 100644
index d458f3a48e..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctchi_d.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * 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.
- */
-
-#include <stdint.h>
-#include "mct_d.h"
-#include "mct_d_gcc.h"
-#include <console/console.h>
-
-void InterleaveChannels_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstatA)
-{
-
- u8 Node;
- u32 DramBase, DctSelBase;
- u8 DctSelIntLvAddr, DctSelHi;
- u8 HoleValid = 0;
- u32 HoleSize, HoleBase = 0;
- u32 val, tmp;
- u32 dct0_size, dct1_size;
- struct DCTStatStruc *pDCTstat;
-
- /* HoleValid - indicates whether the current Node contains hole.
- * HoleSize - indicates whether there is IO hole in the whole system
- * memory.
- */
-
- /* call back to wrapper not needed ManualChannelInterleave_D(); */
- /* call back - DctSelIntLvAddr = mctGet_NVbits(NV_ChannelIntlv);*/ /* override interleave */
- /* Manually set: typ = 5, otherwise typ = 7. */
- DctSelIntLvAddr = mctGet_NVbits(NV_ChannelIntlv); /* typ = 5: Hash*: exclusive OR of address bits[20:16, 6]. */
-
- if (DctSelIntLvAddr & 1) {
- DctSelIntLvAddr >>= 1;
- HoleSize = 0;
- if ((pMCTstat->GStatus & (1 << GSB_SoftHole)) ||
- (pMCTstat->GStatus & (1 << GSB_HWHole))) {
- if (pMCTstat->HoleBase) {
- HoleBase = pMCTstat->HoleBase >> 8;
- HoleSize = HoleBase & 0xFFFF0000;
- HoleSize |= ((~HoleBase) + 1) & 0xFFFF;
- }
- }
- Node = 0;
- while (Node < MAX_NODES_SUPPORTED) {
- pDCTstat = pDCTstatA + Node;
- val = Get_NB32(pDCTstat->dev_map, 0xF0);
- if (val & (1 << DramHoleValid))
- HoleValid = 1;
- if (!pDCTstat->GangedMode && pDCTstat->DIMMValidDCT[0] && pDCTstat->DIMMValidDCT[1]) {
- DramBase = pDCTstat->NodeSysBase >> 8;
- dct1_size = ((pDCTstat->NodeSysLimit) + 2) >> 8;
- dct0_size = Get_NB32(pDCTstat->dev_dct, 0x114);
- if (dct0_size >= 0x10000) {
- dct0_size -= HoleSize;
- }
-
- dct0_size -= DramBase;
- dct1_size -= dct0_size;
- DctSelHi = 0x05; /* DctSelHiRngEn = 1, DctSelHi = 0 */
- if (dct1_size == dct0_size) {
- dct1_size = 0;
- DctSelHi = 0x04; /* DctSelHiRngEn = 0 */
- } else if (dct1_size > dct0_size) {
- dct1_size = dct0_size;
- DctSelHi = 0x07; /* DctSelHiRngEn = 1, DctSelHi = 1 */
- }
- dct0_size = dct1_size;
- dct0_size += DramBase;
- dct0_size += dct1_size;
- if (dct0_size >= HoleBase) /* if DctSelBaseAddr > HoleBase */
- dct0_size += HoleSize;
- DctSelBase = dct0_size;
-
- if (dct1_size == 0)
- dct0_size = 0;
- dct0_size -= dct1_size; /* DctSelBaseOffset = DctSelBaseAddr - Interleaved region */
- Set_NB32(pDCTstat->dev_dct, 0x114, dct0_size);
-
- if (dct1_size == 0)
- dct1_size = DctSelBase;
- val = Get_NB32(pDCTstat->dev_dct, 0x110);
- val &= 0x7F8;
- val |= dct1_size;
- val |= DctSelHi;
- val |= (DctSelIntLvAddr << 6) & 0xFF;
- Set_NB32(pDCTstat->dev_dct, 0x110, val);
-
- if (HoleValid) {
- tmp = DramBase;
- val = DctSelBase;
- if (val < HoleBase) { /* DctSelBaseAddr < DramHoleBase */
- val -= DramBase;
- val >>= 1;
- tmp += val;
- }
- tmp += HoleSize;
- val = Get_NB32(pDCTstat->dev_map, 0xF0); /* DramHoleOffset */
- val &= 0xFFFF007F;
- val |= (tmp & ~0xFFFF007F);
- Set_NB32(pDCTstat->dev_map, 0xF0, val);
- }
- }
- printk(BIOS_DEBUG, "InterleaveChannels_D: Node %x\n", Node);
- printk(BIOS_DEBUG, "InterleaveChannels_D: Status %x\n", pDCTstat->Status);
- printk(BIOS_DEBUG, "InterleaveChannels_D: ErrStatus %x\n", pDCTstat->ErrStatus);
- printk(BIOS_DEBUG, "InterleaveChannels_D: ErrCode %x\n", pDCTstat->ErrCode);
- Node++;
- }
- }
- printk(BIOS_DEBUG, "InterleaveChannels_D: Done\n\n");
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctcsi_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mctcsi_d.c
deleted file mode 100644
index 85e7930b24..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctcsi_d.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
- *
- * 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.
- */
-
-/* Low swap bit vs bank size encoding (physical, not logical address bit)
- * ;To calculate the number by hand, add the number of Bank address bits
- * ;(2 or 3) to the number of column address bits, plus 3 (the logical
- * ;page size), and subtract 8.
- */
-
-#include <stdint.h>
-#include "mct_d.h"
-#include "mct_d_gcc.h"
-#include <console/console.h>
-
-static const u8 Tab_int_D[] = {6,7,7,8,8,8,8,8,9,9,8,9};
-
-void InterleaveBanks_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dct)
-{
- u8 ChipSel, EnChipSels;
- u32 AddrLoMask, AddrHiMask;
- u32 AddrLoMaskN, AddrHiMaskN, MemSize = 0;
- u8 DoIntlv, _CsIntCap;
- u32 BitDelta, BankEncd = 0;
-
- u32 dev;
- u32 reg;
- u32 val;
- u32 val_lo, val_hi;
-
- DoIntlv = mctGet_NVbits(NV_BankIntlv);
- _CsIntCap = 0;
- EnChipSels = 0;
-
- dev = pDCTstat->dev_dct;
-
- ChipSel = 0; /* Find out if current configuration is capable */
- while (DoIntlv && (ChipSel < MAX_CS_SUPPORTED)) {
- reg = 0x40+(ChipSel<<2); /* Dram CS Base 0 */
- val = Get_NB32_DCT(dev, dct, reg);
- if (val & (1<<CSEnable)) {
- EnChipSels++;
- reg = 0x60+((ChipSel>>1)<<2); /*Dram CS Mask 0 */
- val = Get_NB32_DCT(dev, dct, reg);
- val >>= 19;
- val &= 0x3ff;
- val++;
- if (EnChipSels == 1)
- MemSize = val;
- else
- /*If mask sizes not same then skip */
- if (val != MemSize)
- break;
- reg = 0x80; /*Dram Bank Addressing */
- val = Get_NB32_DCT(dev, dct, reg);
- val >>= (ChipSel>>1)<<2;
- val &= 0x0f;
- if (EnChipSels == 1)
- BankEncd = val;
- else
- /*If number of Rows/Columns not equal, skip */
- if (val != BankEncd)
- break;
- }
- ChipSel++;
- }
- if (ChipSel == MAX_CS_SUPPORTED) {
- if ((EnChipSels == 2) || (EnChipSels == 4) || (EnChipSels == 8))
- _CsIntCap = 1;
- }
-
- if (DoIntlv) {
- if (!_CsIntCap) {
- pDCTstat->ErrStatus |= 1<<SB_BkIntDis;
- DoIntlv = 0;
- }
- }
-
- if (DoIntlv) {
- val = Tab_int_D[BankEncd];
- if (pDCTstat->Status & (1<<SB_128bitmode))
- val++;
-
- AddrLoMask = (EnChipSels - 1) << val;
- AddrLoMaskN = ~AddrLoMask;
-
- val = bsf(MemSize) + 19;
- AddrHiMask = (EnChipSels -1) << val;
- AddrHiMaskN = ~AddrHiMask;
-
- BitDelta = bsf(AddrHiMask) - bsf(AddrLoMask);
-
- for (ChipSel = 0; ChipSel < MAX_CS_SUPPORTED; ChipSel++) {
- reg = 0x40 + (ChipSel<<2); /* Dram CS Base 0 */
- val = Get_NB32_DCT(dev, dct, reg);
- if (val & 3) {
- val_lo = val & AddrLoMask;
- val_hi = val & AddrHiMask;
- val &= AddrLoMaskN;
- val &= AddrHiMaskN;
- val_lo <<= BitDelta;
- val_hi >>= BitDelta;
- val |= val_lo;
- val |= val_hi;
- Set_NB32_DCT(dev, dct, reg, val);
-
- if (ChipSel & 1)
- continue;
-
- reg = 0x60 + ((ChipSel>>1)<<2); /* Dram CS Mask 0 */
- val = Get_NB32_DCT(dev, dct, reg);
- val_lo = val & AddrLoMask;
- val_hi = val & AddrHiMask;
- val &= AddrLoMaskN;
- val &= AddrHiMaskN;
- val_lo <<= BitDelta;
- val_hi >>= BitDelta;
- val |= val_lo;
- val |= val_hi;
- Set_NB32_DCT(dev, dct, reg, val);
- }
- }
- } /* DoIntlv */
-
- /* dump_pci_device(PCI_DEV(0, 0x18+pDCTstat->Node_ID, 2)); */
-
- printk(BIOS_DEBUG, "InterleaveBanks_D: Status %x\n", pDCTstat->Status);
- printk(BIOS_DEBUG, "InterleaveBanks_D: ErrStatus %x\n", pDCTstat->ErrStatus);
- printk(BIOS_DEBUG, "InterleaveBanks_D: ErrCode %x\n", pDCTstat->ErrCode);
- printk(BIOS_DEBUG, "InterleaveBanks_D: Done\n\n");
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c
deleted file mode 100644
index d34b2dc2ba..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c
+++ /dev/null
@@ -1,2493 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- * Copyright (C) 2015 - 2016 Raptor Engineering, LLC
- *
- * 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.
- */
-
-#include <stdint.h>
-#include <console/console.h>
-#include <cpu/x86/cr.h>
-#include <string.h>
-#include <arch/cpu.h>
-#include <cpu/amd/msr.h>
-#include <cpu/amd/mtrr.h>
-#include "mct_d.h"
-#include "mct_d_gcc.h"
-
-static void CalcEccDQSPos_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u16 like,
- u8 scale, u8 ChipSel);
-static void GetDQSDatStrucVal_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 ChipSel);
-static void WriteDQSTestPattern_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat,
- u32 TestAddr_lo);
-static void WriteL18TestPattern_D(struct DCTStatStruc *pDCTstat,
- u32 TestAddr_lo);
-static void WriteL9TestPattern_D(struct DCTStatStruc *pDCTstat,
- u32 TestAddr_lo);
-static u16 CompareDQSTestPattern_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat,
- u32 addr_lo);
-static void FlushDQSTestPattern_D(struct DCTStatStruc *pDCTstat,
- u32 addr_lo);
-static void mct_SetDQSDelayCSR_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat,
- u8 ChipSel);
-static void SetupDqsPattern_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat,
- u32 *buffer);
-
-static void StoreDQSDatStrucVal_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 ChipSel);
-
-static uint8_t is_fam15h(void)
-{
- uint8_t fam15h = 0;
- uint32_t family;
-
- family = cpuid_eax(0x80000001);
- family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);
-
- if (family >= 0x6f)
- /* Family 15h or later */
- fam15h = 1;
-
- return fam15h;
-}
-
-#define DQS_TRAIN_DEBUG 0
-// #define PRINT_PASS_FAIL_BITMAPS 1
-
-void print_debug_dqs(const char *str, u32 val, u8 level)
-{
-#if DQS_TRAIN_DEBUG > 0
- if (DQS_TRAIN_DEBUG >= level) {
- printk(BIOS_DEBUG, "%s%x\n", str, val);
- }
-#endif
-}
-
-void print_debug_dqs_pair(const char *str, u32 val, const char *str2, u32 val2, u8 level)
-{
-#if DQS_TRAIN_DEBUG > 0
- if (DQS_TRAIN_DEBUG >= level) {
- printk(BIOS_DEBUG, "%s%08x%s%08x\n", str, val, str2, val2);
- }
-#endif
-}
-
-/*Warning: These must be located so they do not cross a logical 16-bit segment boundary!*/
-static const u32 TestPatternJD1a_D[] = {
- 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF, /* QW0-1, ALL-EVEN */
- 0x00000000,0x00000000,0x00000000,0x00000000, /* QW2-3, ALL-EVEN */
- 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF, /* QW4-5, ALL-EVEN */
- 0x00000000,0x00000000,0x00000000,0x00000000, /* QW6-7, ALL-EVEN */
- 0xFeFeFeFe,0xFeFeFeFe,0x01010101,0x01010101, /* QW0-1, DQ0-ODD */
- 0xFeFeFeFe,0xFeFeFeFe,0x01010101,0x01010101, /* QW2-3, DQ0-ODD */
- 0x01010101,0x01010101,0xFeFeFeFe,0xFeFeFeFe, /* QW4-5, DQ0-ODD */
- 0xFeFeFeFe,0xFeFeFeFe,0x01010101,0x01010101, /* QW6-7, DQ0-ODD */
- 0x02020202,0x02020202,0x02020202,0x02020202, /* QW0-1, DQ1-ODD */
- 0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd, /* QW2-3, DQ1-ODD */
- 0xFdFdFdFd,0xFdFdFdFd,0x02020202,0x02020202, /* QW4-5, DQ1-ODD */
- 0x02020202,0x02020202,0x02020202,0x02020202, /* QW6-7, DQ1-ODD */
- 0x04040404,0x04040404,0xfBfBfBfB,0xfBfBfBfB, /* QW0-1, DQ2-ODD */
- 0x04040404,0x04040404,0x04040404,0x04040404, /* QW2-3, DQ2-ODD */
- 0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, /* QW4-5, DQ2-ODD */
- 0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, /* QW6-7, DQ2-ODD */
- 0x08080808,0x08080808,0xF7F7F7F7,0xF7F7F7F7, /* QW0-1, DQ3-ODD */
- 0x08080808,0x08080808,0x08080808,0x08080808, /* QW2-3, DQ3-ODD */
- 0xF7F7F7F7,0xF7F7F7F7,0x08080808,0x08080808, /* QW4-5, DQ3-ODD */
- 0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7, /* QW6-7, DQ3-ODD */
- 0x10101010,0x10101010,0x10101010,0x10101010, /* QW0-1, DQ4-ODD */
- 0xeFeFeFeF,0xeFeFeFeF,0x10101010,0x10101010, /* QW2-3, DQ4-ODD */
- 0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF, /* QW4-5, DQ4-ODD */
- 0xeFeFeFeF,0xeFeFeFeF,0x10101010,0x10101010, /* QW6-7, DQ4-ODD */
- 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, /* QW0-1, DQ5-ODD */
- 0xdFdFdFdF,0xdFdFdFdF,0x20202020,0x20202020, /* QW2-3, DQ5-ODD */
- 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, /* QW4-5, DQ5-ODD */
- 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, /* QW6-7, DQ5-ODD */
- 0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf, /* QW0-1, DQ6-ODD */
- 0x40404040,0x40404040,0xBfBfBfBf,0xBfBfBfBf, /* QW2-3, DQ6-ODD */
- 0x40404040,0x40404040,0xBfBfBfBf,0xBfBfBfBf, /* QW4-5, DQ6-ODD */
- 0x40404040,0x40404040,0xBfBfBfBf,0xBfBfBfBf, /* QW6-7, DQ6-ODD */
- 0x80808080,0x80808080,0x7F7F7F7F,0x7F7F7F7F, /* QW0-1, DQ7-ODD */
- 0x80808080,0x80808080,0x7F7F7F7F,0x7F7F7F7F, /* QW2-3, DQ7-ODD */
- 0x80808080,0x80808080,0x7F7F7F7F,0x7F7F7F7F, /* QW4-5, DQ7-ODD */
- 0x80808080,0x80808080,0x80808080,0x80808080 /* QW6-7, DQ7-ODD */
-};
-static const u32 TestPatternJD1b_D[] = {
- 0x00000000,0x00000000,0x00000000,0x00000000, /* QW0,CHA-B, ALL-EVEN */
- 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, /* QW1,CHA-B, ALL-EVEN */
- 0x00000000,0x00000000,0x00000000,0x00000000, /* QW2,CHA-B, ALL-EVEN */
- 0x00000000,0x00000000,0x00000000,0x00000000, /* QW3,CHA-B, ALL-EVEN */
- 0x00000000,0x00000000,0x00000000,0x00000000, /* QW4,CHA-B, ALL-EVEN */
- 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, /* QW5,CHA-B, ALL-EVEN */
- 0x00000000,0x00000000,0x00000000,0x00000000, /* QW6,CHA-B, ALL-EVEN */
- 0x00000000,0x00000000,0x00000000,0x00000000, /* QW7,CHA-B, ALL-EVEN */
- 0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe, /* QW0,CHA-B, DQ0-ODD */
- 0x01010101,0x01010101,0x01010101,0x01010101, /* QW1,CHA-B, DQ0-ODD */
- 0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe, /* QW2,CHA-B, DQ0-ODD */
- 0x01010101,0x01010101,0x01010101,0x01010101, /* QW3,CHA-B, DQ0-ODD */
- 0x01010101,0x01010101,0x01010101,0x01010101, /* QW4,CHA-B, DQ0-ODD */
- 0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe, /* QW5,CHA-B, DQ0-ODD */
- 0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe, /* QW6,CHA-B, DQ0-ODD */
- 0x01010101,0x01010101,0x01010101,0x01010101, /* QW7,CHA-B, DQ0-ODD */
- 0x02020202,0x02020202,0x02020202,0x02020202, /* QW0,CHA-B, DQ1-ODD */
- 0x02020202,0x02020202,0x02020202,0x02020202, /* QW1,CHA-B, DQ1-ODD */
- 0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd, /* QW2,CHA-B, DQ1-ODD */
- 0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd, /* QW3,CHA-B, DQ1-ODD */
- 0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd, /* QW4,CHA-B, DQ1-ODD */
- 0x02020202,0x02020202,0x02020202,0x02020202, /* QW5,CHA-B, DQ1-ODD */
- 0x02020202,0x02020202,0x02020202,0x02020202, /* QW6,CHA-B, DQ1-ODD */
- 0x02020202,0x02020202,0x02020202,0x02020202, /* QW7,CHA-B, DQ1-ODD */
- 0x04040404,0x04040404,0x04040404,0x04040404, /* QW0,CHA-B, DQ2-ODD */
- 0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, /* QW1,CHA-B, DQ2-ODD */
- 0x04040404,0x04040404,0x04040404,0x04040404, /* QW2,CHA-B, DQ2-ODD */
- 0x04040404,0x04040404,0x04040404,0x04040404, /* QW3,CHA-B, DQ2-ODD */
- 0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, /* QW4,CHA-B, DQ2-ODD */
- 0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, /* QW5,CHA-B, DQ2-ODD */
- 0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, /* QW6,CHA-B, DQ2-ODD */
- 0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, /* QW7,CHA-B, DQ2-ODD */
- 0x08080808,0x08080808,0x08080808,0x08080808, /* QW0,CHA-B, DQ3-ODD */
- 0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7, /* QW1,CHA-B, DQ3-ODD */
- 0x08080808,0x08080808,0x08080808,0x08080808, /* QW2,CHA-B, DQ3-ODD */
- 0x08080808,0x08080808,0x08080808,0x08080808, /* QW3,CHA-B, DQ3-ODD */
- 0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7, /* QW4,CHA-B, DQ3-ODD */
- 0x08080808,0x08080808,0x08080808,0x08080808, /* QW5,CHA-B, DQ3-ODD */
- 0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7, /* QW6,CHA-B, DQ3-ODD */
- 0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7, /* QW7,CHA-B, DQ3-ODD */
- 0x10101010,0x10101010,0x10101010,0x10101010, /* QW0,CHA-B, DQ4-ODD */
- 0x10101010,0x10101010,0x10101010,0x10101010, /* QW1,CHA-B, DQ4-ODD */
- 0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF, /* QW2,CHA-B, DQ4-ODD */
- 0x10101010,0x10101010,0x10101010,0x10101010, /* QW3,CHA-B, DQ4-ODD */
- 0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF, /* QW4,CHA-B, DQ4-ODD */
- 0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF, /* QW5,CHA-B, DQ4-ODD */
- 0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF, /* QW6,CHA-B, DQ4-ODD */
- 0x10101010,0x10101010,0x10101010,0x10101010, /* QW7,CHA-B, DQ4-ODD */
- 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, /* QW0,CHA-B, DQ5-ODD */
- 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, /* QW1,CHA-B, DQ5-ODD */
- 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, /* QW2,CHA-B, DQ5-ODD */
- 0x20202020,0x20202020,0x20202020,0x20202020, /* QW3,CHA-B, DQ5-ODD */
- 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, /* QW4,CHA-B, DQ5-ODD */
- 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, /* QW5,CHA-B, DQ5-ODD */
- 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, /* QW6,CHA-B, DQ5-ODD */
- 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, /* QW7,CHA-B, DQ5-ODD */
- 0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf, /* QW0,CHA-B, DQ6-ODD */
- 0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf, /* QW1,CHA-B, DQ6-ODD */
- 0x40404040,0x40404040,0x40404040,0x40404040, /* QW2,CHA-B, DQ6-ODD */
- 0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf, /* QW3,CHA-B, DQ6-ODD */
- 0x40404040,0x40404040,0x40404040,0x40404040, /* QW4,CHA-B, DQ6-ODD */
- 0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf, /* QW5,CHA-B, DQ6-ODD */
- 0x40404040,0x40404040,0x40404040,0x40404040, /* QW6,CHA-B, DQ6-ODD */
- 0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf, /* QW7,CHA-B, DQ6-ODD */
- 0x80808080,0x80808080,0x80808080,0x80808080, /* QW0,CHA-B, DQ7-ODD */
- 0x7F7F7F7F,0x7F7F7F7F,0x7F7F7F7F,0x7F7F7F7F, /* QW1,CHA-B, DQ7-ODD */
- 0x80808080,0x80808080,0x80808080,0x80808080, /* QW2,CHA-B, DQ7-ODD */
- 0x7F7F7F7F,0x7F7F7F7F,0x7F7F7F7F,0x7F7F7F7F, /* QW3,CHA-B, DQ7-ODD */
- 0x80808080,0x80808080,0x80808080,0x80808080, /* QW4,CHA-B, DQ7-ODD */
- 0x7F7F7F7F,0x7F7F7F7F,0x7F7F7F7F,0x7F7F7F7F, /* QW5,CHA-B, DQ7-ODD */
- 0x80808080,0x80808080,0x80808080,0x80808080, /* QW6,CHA-B, DQ7-ODD */
- 0x80808080,0x80808080,0x80808080,0x80808080 /* QW7,CHA-B, DQ7-ODD */
-};
-
-void TrainReceiverEn_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstatA, u8 Pass)
-{
- u8 Node;
- struct DCTStatStruc *pDCTstat;
- u32 val;
-
- for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
- pDCTstat = pDCTstatA + Node;
-
- if (pDCTstat->DCTSysLimit) {
- if (!is_fam15h()) {
- val = Get_NB32_DCT(pDCTstat->dev_dct, 0, 0x78);
- val |= 1 <<DqsRcvEnTrain;
- Set_NB32_DCT(pDCTstat->dev_dct, 0, 0x78, val);
- val = Get_NB32_DCT(pDCTstat->dev_dct, 1, 0x78);
- val |= 1 <<DqsRcvEnTrain;
- Set_NB32_DCT(pDCTstat->dev_dct, 1, 0x78, val);
- }
- mct_TrainRcvrEn_D(pMCTstat, pDCTstat, Pass);
- }
- }
-}
-
-void TrainMaxRdLatency_En_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstatA)
-{
- uint8_t node;
- struct DCTStatStruc *pDCTstat;
-
- for (node = 0; node < MAX_NODES_SUPPORTED; node++) {
- pDCTstat = pDCTstatA + node;
-
- if (pDCTstat->DCTSysLimit) {
- if (is_fam15h()) {
- dqsTrainMaxRdLatency_SW_Fam15(pMCTstat, pDCTstat);
- } else {
- /* FIXME
- * Implement Family 10h MaxRdLatency training
- */
- }
- }
- }
-}
-
-static void SetEccDQSRdWrPos_D_Fam10(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 ChipSel)
-{
- u8 channel;
- u8 direction;
-
- for (channel = 0; channel < 2; channel++) {
- for (direction = 0; direction < 2; direction++) {
- pDCTstat->Channel = channel; /* Channel A or B */
- pDCTstat->Direction = direction; /* Read or write */
- CalcEccDQSPos_D(pMCTstat, pDCTstat, pDCTstat->CH_EccDQSLike[channel], pDCTstat->CH_EccDQSScale[channel], ChipSel);
- print_debug_dqs_pair("\t\tSetEccDQSRdWrPos: channel ", channel, direction == DQS_READDIR? " R dqs_delay":" W dqs_delay", pDCTstat->DQSDelay, 2);
- pDCTstat->ByteLane = 8;
- StoreDQSDatStrucVal_D(pMCTstat, pDCTstat, ChipSel);
- mct_SetDQSDelayCSR_D(pMCTstat, pDCTstat, ChipSel);
- }
- }
-}
-
-static void CalcEccDQSPos_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat,
- u16 like, u8 scale, u8 ChipSel)
-{
- uint8_t DQSDelay0, DQSDelay1;
- int16_t delay_differential;
- uint16_t DQSDelay;
-
- if (pDCTstat->Status & (1 << SB_Registered)) {
- pDCTstat->ByteLane = 0x2;
- GetDQSDatStrucVal_D(pMCTstat, pDCTstat, ChipSel);
- DQSDelay0 = pDCTstat->DQSDelay;
-
- pDCTstat->ByteLane = 0x3;
- GetDQSDatStrucVal_D(pMCTstat, pDCTstat, ChipSel);
- DQSDelay1 = pDCTstat->DQSDelay;
-
- if (pDCTstat->Direction == DQS_READDIR) {
- DQSDelay = DQSDelay1;
- } else {
- delay_differential = (int16_t)DQSDelay1 - (int16_t)DQSDelay0;
- delay_differential += (int16_t)DQSDelay1;
-
- DQSDelay = delay_differential;
- }
- } else {
- pDCTstat->ByteLane = like & 0xff;
- GetDQSDatStrucVal_D(pMCTstat, pDCTstat, ChipSel);
- DQSDelay0 = pDCTstat->DQSDelay;
-
- pDCTstat->ByteLane = (like >> 8) & 0xff;
- GetDQSDatStrucVal_D(pMCTstat, pDCTstat, ChipSel);
- DQSDelay1 = pDCTstat->DQSDelay;
-
- if (DQSDelay0 > DQSDelay1) {
- DQSDelay = DQSDelay0 - DQSDelay1;
- } else {
- DQSDelay = DQSDelay1 - DQSDelay0;
- }
-
- DQSDelay = DQSDelay * (~scale);
-
- DQSDelay += 0x80; /* round it */
-
- DQSDelay >>= 8; /* 256 */
-
- if (DQSDelay0 > DQSDelay1) {
- DQSDelay = DQSDelay1 - DQSDelay;
- } else {
- DQSDelay += DQSDelay1;
- }
- }
-
- pDCTstat->DQSDelay = (u8)DQSDelay;
-}
-
-static void read_dqs_write_data_timing_registers(uint16_t *delay, uint32_t dev, uint8_t dct, uint8_t dimm, uint32_t index_reg)
-{
- uint32_t dword;
- uint32_t mask;
-
- if (is_fam15h())
- mask = 0xff;
- else
- mask = 0x7f;
-
- /* Lanes 0 - 3 */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x1 | (dimm << 8));
- delay[3] = (dword >> 24) & mask;
- delay[2] = (dword >> 16) & mask;
- delay[1] = (dword >> 8) & mask;
- delay[0] = dword & mask;
-
- /* Lanes 4 - 7 */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x2 | (dimm << 8));
- delay[7] = (dword >> 24) & mask;
- delay[6] = (dword >> 16) & mask;
- delay[5] = (dword >> 8) & mask;
- delay[4] = dword & mask;
-
- /* Lane 8 (ECC) */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x3 | (dimm << 8));
- delay[8] = dword & mask;
-}
-
-static void write_dqs_write_data_timing_registers(uint16_t *delay, uint32_t dev, uint8_t dct, uint8_t dimm, uint32_t index_reg)
-{
- uint32_t dword;
- uint32_t mask;
-
- if (is_fam15h())
- mask = 0xff;
- else
- mask = 0x7f;
-
- /* Lanes 0 - 3 */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x1 | (dimm << 8));
- dword &= ~(mask << 24);
- dword &= ~(mask << 16);
- dword &= ~(mask << 8);
- dword &= ~mask;
- dword |= (delay[3] & mask) << 24;
- dword |= (delay[2] & mask) << 16;
- dword |= (delay[1] & mask) << 8;
- dword |= delay[0] & mask;
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x1 | (dimm << 8), dword);
-
- /* Lanes 4 - 7 */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x2 | (dimm << 8));
- dword &= ~(mask << 24);
- dword &= ~(mask << 16);
- dword &= ~(mask << 8);
- dword &= ~mask;
- dword |= (delay[7] & mask) << 24;
- dword |= (delay[6] & mask) << 16;
- dword |= (delay[5] & mask) << 8;
- dword |= delay[4] & mask;
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x2 | (dimm << 8), dword);
-
- /* Lane 8 (ECC) */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x3 | (dimm << 8));
- dword &= ~mask;
- dword |= delay[8] & mask;
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x3 | (dimm << 8), dword);
-}
-
-/* DQS Position Training
- * Algorithm detailed in the Fam10h BKDG Rev. 3.62 section 2.8.9.9.3
- */
-static void TrainDQSRdWrPos_D_Fam10(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat)
-{
- u32 Errors;
- u8 Channel;
- u8 Receiver;
- u8 _DisableDramECC = 0;
- u32 PatternBuffer[304]; /* 288 + 16 */
- u8 _Wrap32Dis = 0, _SSE2 = 0;
-
- u32 dev;
- u32 addr;
- u8 valid;
- CRx_TYPE cr4;
- u32 lo, hi;
- u32 index_reg;
- uint32_t TestAddr;
-
- uint8_t dual_rank;
- uint8_t iter;
- uint8_t lane;
- uint16_t bytelane_test_results;
- uint16_t current_write_dqs_delay[MAX_BYTE_LANES];
- uint16_t current_read_dqs_delay[MAX_BYTE_LANES];
- uint16_t write_dqs_delay_stepping_done[MAX_BYTE_LANES];
- uint8_t dqs_read_results_array[2][MAX_BYTE_LANES][64]; /* [rank][lane][step] */
- uint8_t dqs_write_results_array[2][MAX_BYTE_LANES][128]; /* [rank][lane][step] */
-
- uint8_t last_pos = 0;
- uint8_t cur_count = 0;
- uint8_t best_pos = 0;
- uint8_t best_count = 0;
-
- print_debug_dqs("\nTrainDQSRdWrPos: Node_ID ", pDCTstat->Node_ID, 0);
- cr4 = read_cr4();
- if (cr4 & (1<<9)) {
- _SSE2 = 1;
- }
- cr4 |= (1<<9); /* OSFXSR enable SSE2 */
- write_cr4(cr4);
-
- addr = HWCR_MSR;
- _RDMSR(addr, &lo, &hi);
- if (lo & (1<<17)) {
- _Wrap32Dis = 1;
- }
- lo |= (1<<17); /* HWCR.wrap32dis */
- _WRMSR(addr, lo, hi); /* allow 64-bit memory references in real mode */
-
- /* Disable ECC correction of reads on the dram bus. */
- _DisableDramECC = mct_DisableDimmEccEn_D(pMCTstat, pDCTstat);
-
- SetupDqsPattern_D(pMCTstat, pDCTstat, PatternBuffer);
-
- /* mct_BeforeTrainDQSRdWrPos_D */
-
- dev = pDCTstat->dev_dct;
- pDCTstat->Direction = DQS_READDIR;
-
- /* 2.8.9.9.3 (2)
- * Loop over each channel, lane, and rank
- */
-
- /* NOTE
- * The BKDG originally stated to iterate over lane, then rank, however this process is quite slow
- * compared to an equivalent loop over rank, then lane as the latter allows multiple lanes to be
- * tested simultaneously, thus improving performance by around 8x.
- */
-
- Errors = 0;
- for (Channel = 0; Channel < 2; Channel++) {
- print_debug_dqs("\tTrainDQSRdWrPos: 1 Channel ", Channel, 1);
- pDCTstat->Channel = Channel;
-
- if (pDCTstat->DIMMValidDCT[Channel] == 0) /* mct_BeforeTrainDQSRdWrPos_D */
- continue;
-
- index_reg = 0x98;
-
- dual_rank = 0;
- Receiver = mct_InitReceiver_D(pDCTstat, Channel);
- /* There are four receiver pairs, loosely associated with chipselects.
- * This is essentially looping over each rank of each DIMM.
- */
- for (; Receiver < 8; Receiver++) {
- if ((Receiver & 0x1) == 0) {
- /* Even rank of DIMM */
- if (mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, Channel, Receiver+1))
- dual_rank = 1;
- else
- dual_rank = 0;
- }
-
- if (!mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, Channel, Receiver)) {
- continue;
- }
-
- /* Select the base test address for the current rank */
- TestAddr = mct_GetMCTSysAddr_D(pMCTstat, pDCTstat, Channel, Receiver, &valid);
- if (!valid) { /* Address not supported on current CS */
- continue;
- }
-
- print_debug_dqs("\t\t\t\tTrainDQSRdWrPos: 14 TestAddr ", TestAddr, 4);
- SetUpperFSbase(TestAddr); /* fs:eax = far ptr to target */
-
- print_debug_dqs("\t\t\t\tTrainDQSRdWrPos: 12 Receiver ", Receiver, 2);
-
- /* 2.8.9.9.3 (DRAM Write Data Timing Loop)
- * Iterate over all possible DQS delay values (0x0 - 0x7f)
- */
- uint8_t test_write_dqs_delay = 0;
- uint8_t test_read_dqs_delay = 0;
- uint8_t passing_dqs_delay_found[MAX_BYTE_LANES];
-
- /* Initialize variables */
- for (lane = 0; lane < MAX_BYTE_LANES; lane++) {
- current_write_dqs_delay[lane] = 0;
- passing_dqs_delay_found[lane] = 0;
- write_dqs_delay_stepping_done[lane] = 0;
- }
-
- for (test_write_dqs_delay = 0; test_write_dqs_delay < 128; test_write_dqs_delay++) {
- print_debug_dqs("\t\t\t\tTrainDQSRdWrPos: 16 test_write_dqs_delay ", test_write_dqs_delay, 6);
-
- /* Break out of loop if passing window already found, */
- if (write_dqs_delay_stepping_done[0] && write_dqs_delay_stepping_done[1]
- && write_dqs_delay_stepping_done[2] && write_dqs_delay_stepping_done[3]
- && write_dqs_delay_stepping_done[4] && write_dqs_delay_stepping_done[5]
- && write_dqs_delay_stepping_done[6] && write_dqs_delay_stepping_done[7])
- break;
-
- /* Commit the current Write Data Timing settings to the hardware registers */
- write_dqs_write_data_timing_registers(current_write_dqs_delay, dev, Channel, (Receiver >> 1), index_reg);
-
- /* Write the DRAM training pattern to the base test address */
- WriteDQSTestPattern_D(pMCTstat, pDCTstat, TestAddr << 8);
-
- /* 2.8.9.9.3 (DRAM Read DQS Timing Control Loop)
- * Iterate over all possible DQS delay values (0x0 - 0x3f)
- */
- for (test_read_dqs_delay = 0; test_read_dqs_delay < 64; test_read_dqs_delay++) {
- print_debug_dqs("\t\t\t\t\tTrainDQSRdWrPos: 161 test_read_dqs_delay ", test_read_dqs_delay, 6);
-
- /* Initialize Read DQS Timing Control settings for this iteration */
- for (lane = 0; lane < MAX_BYTE_LANES; lane++)
- if (!write_dqs_delay_stepping_done[lane])
- current_read_dqs_delay[lane] = test_read_dqs_delay;
-
- /* Commit the current Read DQS Timing Control settings to the hardware registers */
- write_dqs_read_data_timing_registers(current_read_dqs_delay, dev, Channel, (Receiver >> 1), index_reg);
-
- /* Initialize test result variable */
- bytelane_test_results = 0xff;
-
- /* Read the DRAM training pattern from the base test address three times
- * NOTE
- * While the BKDG states to read three times this is probably excessive!
- * Decrease training time by only reading the test pattern once per iteration
- */
- for (iter = 0; iter < 1; iter++) {
- /* Flush caches */
- SetTargetWTIO_D(TestAddr);
- FlushDQSTestPattern_D(pDCTstat, TestAddr << 8);
- ResetTargetWTIO_D();
-
- /* Read and compare pattern */
- bytelane_test_results &= (CompareDQSTestPattern_D(pMCTstat, pDCTstat, TestAddr << 8) & 0xff); /* [Lane 7 :: Lane 0] 0 = fail, 1 = pass */
-
- /* If all lanes have already failed testing bypass remaining re-read attempt(s) */
- if (bytelane_test_results == 0x0)
- break;
- }
-
- /* Store any lanes that passed testing for later use */
- for (lane = 0; lane < 8; lane++)
- if (!write_dqs_delay_stepping_done[lane])
- dqs_read_results_array[Receiver & 0x1][lane][test_read_dqs_delay] = (!!(bytelane_test_results & (1 << lane)));
-
- print_debug_dqs("\t\t\t\t\tTrainDQSRdWrPos: 162 bytelane_test_results ", bytelane_test_results, 6);
- }
-
- for (lane = 0; lane < MAX_BYTE_LANES; lane++) {
- if (write_dqs_delay_stepping_done[lane])
- continue;
-
- /* Determine location and length of longest consecutive string of passing values
- * Output is stored in best_pos and best_count
- */
- last_pos = 0;
- cur_count = 0;
- best_pos = 0;
- best_count = 0;
- for (iter = 0; iter < 64; iter++) {
- if ((dqs_read_results_array[Receiver & 0x1][lane][iter]) && (iter < 63)) {
- /* Pass */
- cur_count++;
- } else {
- /* Failure or end of loop */
- if (cur_count > best_count) {
- best_count = cur_count;
- best_pos = last_pos;
- }
- cur_count = 0;
- last_pos = iter;
- }
- }
-
- if (best_count > 2) {
- /* Exit the DRAM Write Data Timing Loop after programming the Read DQS Timing Control
- * register with the center of the passing window
- */
- current_read_dqs_delay[lane] = (best_pos + (best_count / 2));
- passing_dqs_delay_found[lane] = 1;
-
- /* Commit the current Read DQS Timing Control settings to the hardware registers */
- write_dqs_read_data_timing_registers(current_read_dqs_delay, dev, Channel, (Receiver >> 1), index_reg);
-
- /* Exit the DRAM Write Data Timing Loop */
- write_dqs_delay_stepping_done[lane] = 1;
-
- print_debug_dqs("\t\t\t\tTrainDQSRdWrPos: 142 largest passing region ", best_count, 4);
- print_debug_dqs("\t\t\t\tTrainDQSRdWrPos: 143 largest passing region start ", best_pos, 4);
- }
-
- /* Increment the DQS Write Delay value if needed for the next DRAM Write Data Timing Loop iteration */
- if (!write_dqs_delay_stepping_done[lane])
- current_write_dqs_delay[lane]++;
- }
- }
-
- /* Flag failure(s) if present */
- for (lane = 0; lane < 8; lane++) {
- if (!passing_dqs_delay_found[lane]) {
- print_debug_dqs("\t\t\t\tTrainDQSRdWrPos: 121 Unable to find passing region for lane ", lane, 2);
-
- /* Flag absence of passing window */
- Errors |= 1 << SB_NODQSPOS;
- }
- }
-
- /* Iterate over all possible Write Data Timing values (0x0 - 0x7f)
- * Note that the Read DQS Timing Control was calibrated / centered in the prior nested loop
- */
- for (test_write_dqs_delay = 0; test_write_dqs_delay < 128; test_write_dqs_delay++) {
- /* Initialize Write Data Timing settings for this iteration */
- for (lane = 0; lane < MAX_BYTE_LANES; lane++)
- current_write_dqs_delay[lane] = test_write_dqs_delay;
-
- /* Commit the current Write Data Timing settings to the hardware registers */
- write_dqs_write_data_timing_registers(current_write_dqs_delay, dev, Channel, (Receiver >> 1), index_reg);
-
- /* Write the DRAM training pattern to the base test address */
- WriteDQSTestPattern_D(pMCTstat, pDCTstat, TestAddr << 8);
-
- /* Flush caches */
- SetTargetWTIO_D(TestAddr);
- FlushDQSTestPattern_D(pDCTstat, TestAddr << 8);
- ResetTargetWTIO_D();
-
- /* Read and compare pattern from the base test address */
- bytelane_test_results = (CompareDQSTestPattern_D(pMCTstat, pDCTstat, TestAddr << 8) & 0xff); /* [Lane 7 :: Lane 0] 0 = fail, 1 = pass */
-
- /* Store any lanes that passed testing for later use */
- for (lane = 0; lane < 8; lane++)
- dqs_write_results_array[Receiver & 0x1][lane][test_write_dqs_delay] = (!!(bytelane_test_results & (1 << lane)));
- }
-
- for (lane = 0; lane < 8; lane++) {
- if ((!dual_rank) || (dual_rank && (Receiver & 0x1))) {
-
-#ifdef PRINT_PASS_FAIL_BITMAPS
- for (iter = 0; iter < 64; iter++) {
- if (dqs_read_results_array[0][lane][iter])
- printk(BIOS_DEBUG, "+");
- else
- printk(BIOS_DEBUG, ".");
- }
- printk(BIOS_DEBUG, "\n");
- for (iter = 0; iter < 64; iter++) {
- if (dqs_read_results_array[1][lane][iter])
- printk(BIOS_DEBUG, "+");
- else
- printk(BIOS_DEBUG, ".");
- }
- printk(BIOS_DEBUG, "\n\n");
- for (iter = 0; iter < 128; iter++) {
- if (dqs_write_results_array[0][lane][iter])
- printk(BIOS_DEBUG, "+");
- else
- printk(BIOS_DEBUG, ".");
- }
- printk(BIOS_DEBUG, "\n");
- for (iter = 0; iter < 128; iter++) {
- if (dqs_write_results_array[1][lane][iter])
- printk(BIOS_DEBUG, "+");
- else
- printk(BIOS_DEBUG, ".");
- }
- printk(BIOS_DEBUG, "\n\n");
-#endif
-
- /* Base rank of single-rank DIMM, or odd rank of dual-rank DIMM */
- if (dual_rank) {
- /* Intersect the passing windows of both ranks */
- for (iter = 0; iter < 64; iter++)
- if (!dqs_read_results_array[1][lane][iter])
- dqs_read_results_array[0][lane][iter] = 0;
- for (iter = 0; iter < 128; iter++)
- if (!dqs_write_results_array[1][lane][iter])
- dqs_write_results_array[0][lane][iter] = 0;
- }
-
- /* Determine location and length of longest consecutive string of passing values for read DQS timing
- * Output is stored in best_pos and best_count
- */
- last_pos = 0;
- cur_count = 0;
- best_pos = 0;
- best_count = 0;
- for (iter = 0; iter < 64; iter++) {
- if ((dqs_read_results_array[0][lane][iter]) && (iter < 63)) {
- /* Pass */
- cur_count++;
- } else {
- /* Failure or end of loop */
- if (cur_count > best_count) {
- best_count = cur_count;
- best_pos = last_pos;
- }
- cur_count = 0;
- last_pos = iter;
- }
- }
- print_debug_dqs("\t\t\t\tTrainDQSRdWrPos: 144 largest read passing region ", best_count, 4);
- if (best_count > 0) {
- if (best_count < MIN_DQS_WNDW) {
- /* Flag excessively small passing window */
- Errors |= 1 << SB_SMALLDQS;
- }
-
- /* Find the center of the passing window */
- current_read_dqs_delay[lane] = (best_pos + (best_count / 2));
-
- /* Commit the current Read DQS Timing Control settings to the hardware registers */
- write_dqs_read_data_timing_registers(current_read_dqs_delay, dev, Channel, (Receiver >> 1), index_reg);
-
- /* Save the final Read DQS Timing Control settings for later use */
- pDCTstat->CH_D_DIR_B_DQS[Channel][Receiver >> 1][DQS_READDIR][lane] = current_read_dqs_delay[lane];
- } else {
- print_debug_dqs("\t\t\t\tTrainDQSRdWrPos: 122 Unable to find read passing region for lane ", lane, 2);
-
- /* Flag absence of passing window */
- Errors |= 1 << SB_NODQSPOS;
- }
-
- /* Determine location and length of longest consecutive string of passing values for write DQS timing
- * Output is stored in best_pos and best_count
- */
- last_pos = 0;
- cur_count = 0;
- best_pos = 0;
- best_count = 0;
- for (iter = 0; iter < 128; iter++) {
- if ((dqs_write_results_array[0][lane][iter]) && (iter < 127)) {
- /* Pass */
- cur_count++;
- } else {
- /* Failure or end of loop */
- if (cur_count > best_count) {
- best_count = cur_count;
- best_pos = last_pos;
- }
- cur_count = 0;
- last_pos = iter;
- }
- }
- print_debug_dqs("\t\t\t\tTrainDQSRdWrPos: 145 largest write passing region ", best_count, 4);
- if (best_count > 0) {
- if (best_count < MIN_DQS_WNDW) {
- /* Flag excessively small passing window */
- Errors |= 1 << SB_SMALLDQS;
- }
-
- /* Find the center of the passing window */
- current_write_dqs_delay[lane] = (best_pos + (best_count / 2));
-
- /* Commit the current Write Data Timing settings to the hardware registers */
- write_dqs_write_data_timing_registers(current_write_dqs_delay, dev, Channel, (Receiver >> 1), index_reg);
-
- /* Save the final Write Data Timing settings for later use */
- pDCTstat->CH_D_DIR_B_DQS[Channel][Receiver >> 1][DQS_WRITEDIR][lane] = current_write_dqs_delay[lane];
- } else {
- print_debug_dqs("\t\t\t\tTrainDQSRdWrPos: 123 Unable to find write passing region for lane ", lane, 2);
-
- /* Flag absence of passing window */
- Errors |= 1 << SB_NODQSPOS;
- }
- }
- }
-
- }
- }
-
- pDCTstat->TrainErrors |= Errors;
- pDCTstat->ErrStatus |= Errors;
-
-#if DQS_TRAIN_DEBUG > 0
- {
- u8 val;
- u8 i;
- u8 ChannelDTD, ReceiverDTD, Dir;
- u8 *p;
-
- for (Dir = 0; Dir < 2; Dir++) {
- if (Dir == 1) {
- printk(BIOS_DEBUG, "TrainDQSRdWrPos: CH_D_DIR_B_DQS WR:\n");
- } else {
- printk(BIOS_DEBUG, "TrainDQSRdWrPos: CH_D_DIR_B_DQS RD:\n");
- }
- for (ChannelDTD = 0; ChannelDTD < 2; ChannelDTD++) {
- printk(BIOS_DEBUG, "Channel: %02x\n", ChannelDTD);
- for (ReceiverDTD = 0; ReceiverDTD < MAX_CS_SUPPORTED; ReceiverDTD += 2) {
- printk(BIOS_DEBUG, "\t\tReceiver: %02x:", ReceiverDTD);
- p = pDCTstat->CH_D_DIR_B_DQS[ChannelDTD][ReceiverDTD >> 1][Dir];
- for (i = 0; i < 8; i++) {
- val = p[i];
- printk(BIOS_DEBUG, " %02x", val);
- }
- printk(BIOS_DEBUG, "\n");
- }
- }
- }
-
- }
-#endif
- if (_DisableDramECC) {
- mct_EnableDimmEccEn_D(pMCTstat, pDCTstat, _DisableDramECC);
- }
- if (!_Wrap32Dis) {
- addr = HWCR_MSR;
- _RDMSR(addr, &lo, &hi);
- lo &= ~(1<<17); /* restore HWCR.wrap32dis */
- _WRMSR(addr, lo, hi);
- }
- if (!_SSE2) {
- cr4 = read_cr4();
- cr4 &= ~(1<<9); /* restore cr4.OSFXSR */
- write_cr4(cr4);
- }
-
- printk(BIOS_DEBUG, "TrainDQSRdWrPos: Status %x\n", pDCTstat->Status);
- printk(BIOS_DEBUG, "TrainDQSRdWrPos: TrainErrors %x\n", pDCTstat->TrainErrors);
- printk(BIOS_DEBUG, "TrainDQSRdWrPos: ErrStatus %x\n", pDCTstat->ErrStatus);
- printk(BIOS_DEBUG, "TrainDQSRdWrPos: ErrCode %x\n", pDCTstat->ErrCode);
- printk(BIOS_DEBUG, "TrainDQSRdWrPos: Done\n\n");
-}
-
-/* Calcuate and set MaxRdLatency
- * Algorithm detailed in the Fam15h BKDG Rev. 3.14 section 2.10.5.8.5
- */
-void Calc_SetMaxRdLatency_D_Fam15(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t calc_min)
-{
- uint8_t dimm;
- uint8_t lane;
- uint32_t dword;
- uint32_t dword2;
- uint32_t max_delay;
- uint8_t mem_clk = 0;
- uint8_t nb_pstate;
- uint32_t nb_clk;
- uint32_t p = 0;
- uint32_t n = 0;
- uint32_t t = 0;
- uint16_t current_phy_phase_delay[MAX_BYTE_LANES];
- uint16_t current_read_dqs_delay[MAX_BYTE_LANES];
-
- uint32_t index_reg = 0x98;
- uint32_t dev = pDCTstat->dev_dct;
- 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};
-
-#if DQS_TRAIN_DEBUG > 0
- printk(BIOS_DEBUG, "%s: Start\n", __func__);
-#endif
-
- uint8_t lane_count;
- lane_count = get_available_lane_count(pMCTstat, pDCTstat);
-
- mem_clk = Get_NB32_DCT(dev, dct, 0x94) & 0x1f;
- if (fam15h_freq_tab[mem_clk] == 0) {
- pDCTstat->CH_MaxRdLat[dct][0] = 0x55;
- pDCTstat->CH_MaxRdLat[dct][1] = 0x55;
- return;
- }
-
- /* P is specified in PhyCLKs (1/2 MEMCLKs) */
- for (nb_pstate = 0; nb_pstate < 2; nb_pstate++) {
- /* 2.10.5.8.5 (2) */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x00000004);
- if ((!(dword & (0x1 << 21))) && (!(dword & (0x1 << 13))) && (!(dword & (0x1 << 5))))
- p += 1;
- else
- p += 2;
-
- /* 2.10.5.8.5 (3) */
- dword = Get_NB32_DCT_NBPstate(dev, dct, nb_pstate, 0x210) & 0xf; /* Retrieve RdPtrInit */
- p += (9 - dword);
-
- /* 2.10.5.8.5 (4) */
- if (!calc_min)
- p += 5;
-
- /* 2.10.5.8.5 (5) */
- dword = Get_NB32_DCT(dev, dct, 0xa8);
- dword2 = Get_NB32_DCT(dev, dct, 0x90);
- if ((!(dword & (0x1 << 5))) && (!(dword2 & (0x1 << 16))))
- p += 2;
-
- /* 2.10.5.8.5 (6) */
- dword = Get_NB32_DCT(dev, dct, 0x200) & 0x1f; /* Retrieve Tcl */
- p += (2 * (dword - 1));
-
- /* 2.10.5.8.5 (7) */
- max_delay = 0;
- for (dimm = 0; dimm < 4; dimm++) {
- if (!mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, dct, dimm * 2))
- continue;
-
- read_dqs_receiver_enable_control_registers(current_phy_phase_delay, dev, dct, dimm, index_reg);
- read_dqs_read_data_timing_registers(current_read_dqs_delay, dev, dct, dimm, index_reg);
- for (lane = 0; lane < lane_count; lane++)
- if ((current_phy_phase_delay[lane] + current_read_dqs_delay[lane]) > max_delay)
- max_delay = (current_phy_phase_delay[lane] + current_read_dqs_delay[lane]);
- }
- p += (max_delay >> 5);
-
- /* 2.10.5.8.5 (8) */
- if (!calc_min)
- p += 5;
-
- /* 2.10.5.8.5 (9) */
- t += 800;
-
- /* 2.10.5.8.5 (10) */
- dword = Get_NB32(pDCTstat->dev_nbctl, (0x160 + (nb_pstate * 4))); /* Retrieve NbDid, NbFid */
- nb_clk = (200 * (((dword >> 1) & 0x1f) + 0x4)) / (((dword >> 7) & 0x1)?2:1);
- n = (((((uint64_t)p * 1000000000000ULL)/(((uint64_t)fam15h_freq_tab[mem_clk] * 1000000ULL) * 2)) + ((uint64_t)t)) * ((uint64_t)nb_clk * 1000)) / 1000000000ULL;
-
- /* 2.10.5.8.5 (11) */
- if (!calc_min)
- n -= 1;
-
- /* 2.10.5.8.5 (12) */
- if (!calc_min) {
- dword = Get_NB32_DCT_NBPstate(dev, dct, nb_pstate, 0x210);
- dword &= ~(0x3ff << 22);
- dword |= (((n - 1) & 0x3ff) << 22);
- Set_NB32_DCT_NBPstate(dev, dct, nb_pstate, 0x210, dword);
- }
-
- /* Save result for later use */
- pDCTstat->CH_MaxRdLat[dct][nb_pstate] = n - 1;
-
-#if DQS_TRAIN_DEBUG > 0
- printk(BIOS_DEBUG, "%s: CH_MaxRdLat[%d][%d]: %03x\n", __func__, dct, nb_pstate, pDCTstat->CH_MaxRdLat[dct][nb_pstate]);
-#endif
- }
-
-#if DQS_TRAIN_DEBUG > 0
- printk(BIOS_DEBUG, "%s: Done\n", __func__);
-#endif
-}
-
-static void start_dram_dqs_training_pattern_fam15(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t Receiver)
-{
- uint32_t dword;
- uint32_t dev = pDCTstat->dev_dct;
-
- /* 2.10.5.7.1.1
- * It appears that the DCT only supports 8-beat burst length mode,
- * so do nothing here...
- */
-
- /* Wait for CmdSendInProg == 0 */
- do {
- dword = Get_NB32_DCT(dev, dct, 0x250);
- } while (dword & (0x1 << 12));
-
- /* Set CmdTestEnable = 1 */
- dword = Get_NB32_DCT(dev, dct, 0x250);
- dword |= (0x1 << 2);
- Set_NB32_DCT(dev, dct, 0x250, dword);
-
- /* 2.10.5.8.6.1.1 Send Activate Command (Target A) */
- dword = Get_NB32_DCT(dev, dct, 0x28c);
- dword &= ~(0xff << 22); /* CmdChipSelect = Receiver */
- dword |= ((0x1 << Receiver) << 22);
- dword &= ~(0x7 << 19); /* CmdBank = 0 */
- dword &= ~(0x3ffff); /* CmdAddress = 0 */
- dword |= (0x1 << 31); /* SendActCmd = 1 */
- Set_NB32_DCT(dev, dct, 0x28c, dword);
-
- /* Wait for SendActCmd == 0 */
- do {
- dword = Get_NB32_DCT(dev, dct, 0x28c);
- } while (dword & (0x1 << 31));
-
- /* Wait 75 MEMCLKs. */
- precise_memclk_delay_fam15(pMCTstat, pDCTstat, dct, 75);
-
- /* 2.10.5.8.6.1.1 Send Activate Command (Target B) */
- dword = Get_NB32_DCT(dev, dct, 0x28c);
- dword &= ~(0xff << 22); /* CmdChipSelect = Receiver */
- dword |= ((0x1 << Receiver) << 22);
- dword &= ~(0x7 << 19); /* CmdBank = 1 */
- dword |= (0x1 << 19);
- dword &= ~(0x3ffff); /* CmdAddress = 0 */
- dword |= (0x1 << 31); /* SendActCmd = 1 */
- Set_NB32_DCT(dev, dct, 0x28c, dword);
-
- /* Wait for SendActCmd == 0 */
- do {
- dword = Get_NB32_DCT(dev, dct, 0x28c);
- } while (dword & (0x1 << 31));
-
- /* Wait 75 MEMCLKs. */
- precise_memclk_delay_fam15(pMCTstat, pDCTstat, dct, 75);
-}
-
-static void stop_dram_dqs_training_pattern_fam15(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t Receiver)
-{
- uint32_t dword;
- uint32_t dev = pDCTstat->dev_dct;
-
- /* 2.10.5.8.6.1.1 Send Precharge Command */
- /* Wait 25 MEMCLKs. */
- precise_memclk_delay_fam15(pMCTstat, pDCTstat, dct, 25);
-
- dword = Get_NB32_DCT(dev, dct, 0x28c);
- dword &= ~(0xff << 22); /* CmdChipSelect = Receiver */
- dword |= ((0x1 << Receiver) << 22);
- dword &= ~(0x7 << 19); /* CmdBank = 0 */
- dword &= ~(0x3ffff); /* CmdAddress = 0x400 */
- dword |= 0x400;
- dword |= (0x1 << 30); /* SendPchgCmd = 1 */
- Set_NB32_DCT(dev, dct, 0x28c, dword);
-
- /* Wait for SendPchgCmd == 0 */
- do {
- dword = Get_NB32_DCT(dev, dct, 0x28c);
- } while (dword & (0x1 << 30));
-
- /* Wait 25 MEMCLKs. */
- precise_memclk_delay_fam15(pMCTstat, pDCTstat, dct, 25);
-
- /* Set CmdTestEnable = 0 */
- dword = Get_NB32_DCT(dev, dct, 0x250);
- dword &= ~(0x1 << 2);
- Set_NB32_DCT(dev, dct, 0x250, dword);
-}
-
-void read_dram_dqs_training_pattern_fam15(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, uint8_t dct,
- uint8_t Receiver, uint8_t lane, uint8_t stop_on_error)
-{
- uint32_t dword;
- uint32_t dev = pDCTstat->dev_dct;
-
- start_dram_dqs_training_pattern_fam15(pMCTstat, pDCTstat, dct, Receiver);
-
- /* 2.10.5.8.6.1.2 */
- /* Configure DQMask */
- if (lane < 4) {
- Set_NB32_DCT(dev, dct, 0x274, ~(0xff << (lane * 8)));
- Set_NB32_DCT(dev, dct, 0x278, ~0x0);
- dword = Get_NB32_DCT(dev, dct, 0x27c);
- dword |= 0xff; /* EccMask = 0xff */
- Set_NB32_DCT(dev, dct, 0x27c, dword);
- } else if (lane < 8) {
- Set_NB32_DCT(dev, dct, 0x274, ~0x0);
- Set_NB32_DCT(dev, dct, 0x278, ~(0xff << ((lane - 4) * 8)));
- dword = Get_NB32_DCT(dev, dct, 0x27c);
- dword |= 0xff; /* EccMask = 0xff */
- Set_NB32_DCT(dev, dct, 0x27c, dword);
- } else if (lane == 8) {
- Set_NB32_DCT(dev, dct, 0x274, ~0x0);
- Set_NB32_DCT(dev, dct, 0x278, ~0x0);
- dword = Get_NB32_DCT(dev, dct, 0x27c);
- dword &= ~(0xff); /* EccMask = 0x0 */
- Set_NB32_DCT(dev, dct, 0x27c, dword);
- } else if (lane == 0xff) {
- Set_NB32_DCT(dev, dct, 0x274, ~0xffffffff);
- Set_NB32_DCT(dev, dct, 0x278, ~0xffffffff);
- dword = Get_NB32_DCT(dev, dct, 0x27c);
- if (get_available_lane_count(pMCTstat, pDCTstat) < 9)
- dword |= 0xff; /* EccMask = 0xff */
- else
- dword &= ~(0xff); /* EccMask = 0x0 */
- Set_NB32_DCT(dev, dct, 0x27c, dword);
- } else {
- Set_NB32_DCT(dev, dct, 0x274, ~0x0);
- Set_NB32_DCT(dev, dct, 0x278, ~0x0);
- dword = Get_NB32_DCT(dev, dct, 0x27c);
- dword |= 0xff; /* EccMask = 0xff */
- Set_NB32_DCT(dev, dct, 0x27c, dword);
- }
-
- dword = Get_NB32_DCT(dev, dct, 0x270);
- dword &= ~(0x7ffff); /* DataPrbsSeed = 55555 */
-// dword |= (0x55555);
- dword |= (0x44443); /* Use AGESA seed */
- Set_NB32_DCT(dev, dct, 0x270, dword);
-
- /* 2.10.5.8.4 */
- dword = Get_NB32_DCT(dev, dct, 0x260);
- dword &= ~(0x1fffff); /* CmdCount = 256 */
- dword |= 256;
- Set_NB32_DCT(dev, dct, 0x260, dword);
-
- /* Configure Target A */
- dword = Get_NB32_DCT(dev, dct, 0x254);
- dword &= ~(0x7 << 24); /* TgtChipSelect = Receiver */
- dword |= (Receiver & 0x7) << 24;
- dword &= ~(0x7 << 21); /* TgtBank = 0 */
- dword &= ~(0x3ff); /* TgtAddress = 0 */
- Set_NB32_DCT(dev, dct, 0x254, dword);
-
- /* Configure Target B */
- dword = Get_NB32_DCT(dev, dct, 0x258);
- dword &= ~(0x7 << 24); /* TgtChipSelect = Receiver */
- dword |= (Receiver & 0x7) << 24;
- dword &= ~(0x7 << 21); /* TgtBank = 1 */
- dword |= (0x1 << 21);
- dword &= ~(0x3ff); /* TgtAddress = 0 */
- Set_NB32_DCT(dev, dct, 0x258, dword);
-
- dword = Get_NB32_DCT(dev, dct, 0x250);
- dword |= (0x1 << 3); /* ResetAllErr = 1 */
- dword &= ~(0x1 << 4); /* StopOnErr = stop_on_error */
- dword |= (stop_on_error & 0x1) << 4;
- dword &= ~(0x3 << 8); /* CmdTgt = 1 (Alternate between Target A and Target B) */
- dword |= (0x1 << 8);
- dword &= ~(0x7 << 5); /* CmdType = 0 (Read) */
- dword |= (0x1 << 11); /* SendCmd = 1 */
- Set_NB32_DCT(dev, dct, 0x250, dword);
-
- /* 2.10.5.8.6.1.2 Wait for TestStatus == 1 and CmdSendInProg == 0 */
- do {
- dword = Get_NB32_DCT(dev, dct, 0x250);
- } while ((dword & (0x1 << 12)) || (!(dword & (0x1 << 10))));
-
- dword = Get_NB32_DCT(dev, dct, 0x250);
- dword &= ~(0x1 << 11); /* SendCmd = 0 */
- Set_NB32_DCT(dev, dct, 0x250, dword);
-
- stop_dram_dqs_training_pattern_fam15(pMCTstat, pDCTstat, dct, Receiver);
-}
-
-void write_dram_dqs_training_pattern_fam15(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, uint8_t dct,
- uint8_t Receiver, uint8_t lane, uint8_t stop_on_error)
-{
- uint32_t dword;
- uint32_t dev = pDCTstat->dev_dct;
-
- start_dram_dqs_training_pattern_fam15(pMCTstat, pDCTstat, dct, Receiver);
-
- /* 2.10.5.8.6.1.2 */
- /* Configure DQMask */
- if (lane < 4) {
- Set_NB32_DCT(dev, dct, 0x274, ~(0xff << (lane * 8)));
- Set_NB32_DCT(dev, dct, 0x278, ~0x0);
- dword = Get_NB32_DCT(dev, dct, 0x27c);
- dword |= 0xff; /* EccMask = 0xff */
- Set_NB32_DCT(dev, dct, 0x27c, dword);
- } else if (lane < 8) {
- Set_NB32_DCT(dev, dct, 0x274, ~0x0);
- Set_NB32_DCT(dev, dct, 0x278, ~(0xff << ((lane - 4) * 8)));
- dword = Get_NB32_DCT(dev, dct, 0x27c);
- dword |= 0xff; /* EccMask = 0xff */
- Set_NB32_DCT(dev, dct, 0x27c, dword);
- } else if (lane == 8) {
- Set_NB32_DCT(dev, dct, 0x274, ~0x0);
- Set_NB32_DCT(dev, dct, 0x278, ~0x0);
- dword = Get_NB32_DCT(dev, dct, 0x27c);
- dword &= ~(0xff); /* EccMask = 0x0 */
- Set_NB32_DCT(dev, dct, 0x27c, dword);
- } else if (lane == 0xff) {
- Set_NB32_DCT(dev, dct, 0x274, ~0xffffffff);
- Set_NB32_DCT(dev, dct, 0x278, ~0xffffffff);
- dword = Get_NB32_DCT(dev, dct, 0x27c);
- if (get_available_lane_count(pMCTstat, pDCTstat) < 9)
- dword |= 0xff; /* EccMask = 0xff */
- else
- dword &= ~(0xff); /* EccMask = 0x0 */
- Set_NB32_DCT(dev, dct, 0x27c, dword);
- } else {
- Set_NB32_DCT(dev, dct, 0x274, ~0x0);
- Set_NB32_DCT(dev, dct, 0x278, ~0x0);
- dword = Get_NB32_DCT(dev, dct, 0x27c);
- dword |= 0xff; /* EccMask = 0xff */
- Set_NB32_DCT(dev, dct, 0x27c, dword);
- }
-
- dword = Get_NB32_DCT(dev, dct, 0x270);
- dword &= ~(0x7ffff); /* DataPrbsSeed = 55555 */
-// dword |= (0x55555);
- dword |= (0x44443); /* Use AGESA seed */
- Set_NB32_DCT(dev, dct, 0x270, dword);
-
- /* 2.10.5.8.4 */
- dword = Get_NB32_DCT(dev, dct, 0x260);
- dword &= ~(0x1fffff); /* CmdCount = 256 */
- dword |= 256;
- Set_NB32_DCT(dev, dct, 0x260, dword);
-
- /* Configure Target A */
- dword = Get_NB32_DCT(dev, dct, 0x254);
- dword &= ~(0x7 << 24); /* TgtChipSelect = Receiver */
- dword |= (Receiver & 0x7) << 24;
- dword &= ~(0x7 << 21); /* TgtBank = 0 */
- dword &= ~(0x3ff); /* TgtAddress = 0 */
- Set_NB32_DCT(dev, dct, 0x254, dword);
-
- /* Configure Target B */
- dword = Get_NB32_DCT(dev, dct, 0x258);
- dword &= ~(0x7 << 24); /* TgtChipSelect = Receiver */
- dword |= (Receiver & 0x7) << 24;
- dword &= ~(0x7 << 21); /* TgtBank = 1 */
- dword |= (0x1 << 21);
- dword &= ~(0x3ff); /* TgtAddress = 0 */
- Set_NB32_DCT(dev, dct, 0x258, dword);
-
- dword = Get_NB32_DCT(dev, dct, 0x250);
- dword |= (0x1 << 3); /* ResetAllErr = 1 */
- dword &= ~(0x1 << 4); /* StopOnErr = stop_on_error */
- dword |= (stop_on_error & 0x1) << 4;
- dword &= ~(0x3 << 8); /* CmdTgt = 1 (Alternate between Target A and Target B) */
- dword |= (0x1 << 8);
- dword &= ~(0x7 << 5); /* CmdType = 1 (Write) */
- dword |= (0x1 << 5);
- dword |= (0x1 << 11); /* SendCmd = 1 */
- Set_NB32_DCT(dev, dct, 0x250, dword);
-
- /* 2.10.5.8.6.1.2 Wait for TestStatus == 1 and CmdSendInProg == 0 */
- do {
- dword = Get_NB32_DCT(dev, dct, 0x250);
- } while ((dword & (0x1 << 12)) || (!(dword & (0x1 << 10))));
-
- dword = Get_NB32_DCT(dev, dct, 0x250);
- dword &= ~(0x1 << 11); /* SendCmd = 0 */
- Set_NB32_DCT(dev, dct, 0x250, dword);
-
- stop_dram_dqs_training_pattern_fam15(pMCTstat, pDCTstat, dct, Receiver);
-}
-
-#define LANE_DIFF 1
-
-/* DQS Position Training
- * Algorithm detailed in the Fam15h BKDG Rev. 3.14 section 2.10.5.8.4
- */
-static uint8_t TrainDQSRdWrPos_D_Fam15(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat,
- uint8_t dct, uint8_t receiver_start,
- uint8_t receiver_end, uint8_t lane_start)
-{
- uint8_t dimm;
- uint8_t lane;
- uint32_t dword;
- uint32_t Errors;
- uint8_t Receiver;
- uint8_t dual_rank;
- uint8_t write_iter;
- uint8_t read_iter;
- uint8_t check_antiphase;
- uint8_t passing_read_dqs_delay_found;
- uint8_t passing_write_dqs_delay_found;
- uint16_t initial_write_dqs_delay[MAX_BYTE_LANES];
- uint16_t initial_read_dqs_delay[MAX_BYTE_LANES];
- uint16_t initial_write_data_timing[MAX_BYTE_LANES];
- uint16_t current_write_data_delay[MAX_BYTE_LANES];
- uint16_t current_read_dqs_delay[MAX_BYTE_LANES];
- uint16_t current_write_dqs_delay[MAX_BYTE_LANES];
- uint8_t passing_dqs_delay_found[MAX_BYTE_LANES];
- /* [rank][lane][write step][read step + 16] */
- uint8_t dqs_results_array[2][LANE_DIFF][32][48];
-
- uint8_t last_pos = 0;
- uint8_t cur_count = 0;
- uint8_t best_pos = 0;
- uint8_t best_count = 0;
-
- uint32_t index_reg = 0x98;
- uint32_t dev = pDCTstat->dev_dct;
-
- uint8_t lane_end = lane_start + LANE_DIFF;
-
- uint8_t lane_count;
- lane_count = get_available_lane_count(pMCTstat, pDCTstat);
-
- /* Calculate and program MaxRdLatency */
- Calc_SetMaxRdLatency_D_Fam15(pMCTstat, pDCTstat, dct, 0);
-
- Errors = 0;
- dual_rank = 0;
-
- /* There are four receiver pairs, loosely associated with chipselects.
- * This is essentially looping over each rank within each DIMM.
- */
- for (Receiver = receiver_start; Receiver < receiver_end; Receiver++) {
- dimm = (Receiver >> 1);
- if ((Receiver & 0x1) == 0) {
- /* Even rank of DIMM */
- if (mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, dct, Receiver+1))
- dual_rank = 1;
- else
- dual_rank = 0;
- }
-
- if (!mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, dct, Receiver)) {
- continue;
- }
-
-#if DQS_TRAIN_DEBUG > 0
- printk(BIOS_DEBUG, "TrainDQSRdWrPos: Training DQS read/write position for receiver %d (DIMM %d)\n", Receiver, dimm);
-#endif
-
- /* Initialize variables */
- for (lane = lane_start; lane < lane_end; lane++) {
- passing_dqs_delay_found[lane] = 0;
- }
- if ((Receiver & 0x1) == 0) {
- /* Even rank of DIMM */
- memset(dqs_results_array, 0, sizeof(dqs_results_array));
-
- /* Read initial read / write DQS delays */
- read_dqs_write_timing_control_registers(initial_write_dqs_delay, dev, dct, dimm, index_reg);
- read_dqs_read_data_timing_registers(initial_read_dqs_delay, dev, dct, dimm, index_reg);
-
- /* Read current settings of other (previously trained) lanes */
- read_dqs_write_data_timing_registers(initial_write_data_timing, dev, dct, dimm, index_reg);
- }
-
- /* Initialize iterators */
- memcpy(current_write_data_delay, initial_write_data_timing, sizeof(current_write_data_delay));
-
- for (lane = lane_start; lane < lane_end; lane++) {
- passing_read_dqs_delay_found = 0;
- passing_write_dqs_delay_found = 0;
-
- /* 2.10.5.8.4 (2)
- * For each Write Data Delay value from Write DQS Delay to Write DQS Delay + 1 UI
- */
- for (current_write_data_delay[lane] = initial_write_dqs_delay[lane]; current_write_data_delay[lane] < (initial_write_dqs_delay[lane] + 0x20); current_write_data_delay[lane]++) {
- print_debug_dqs("\t\t\t\tTrainDQSRdWrPos: 16 current_write_data_delay[lane] ", current_write_data_delay[lane], 6);
-
- /* 2.10.5.8.4 (2 A)
- * Commit the current Write Data Timing settings to the hardware registers
- */
- write_dqs_write_data_timing_registers(current_write_data_delay, dev, dct, dimm, index_reg);
-
- /* 2.10.5.8.4 (2 B)
- * Write the DRAM training pattern to the test address
- */
- write_dram_dqs_training_pattern_fam15(pMCTstat, pDCTstat, dct, Receiver, lane, 0);
-
- /* Read current settings of other (previously trained) lanes */
- read_dqs_read_data_timing_registers(current_read_dqs_delay, dev, dct, dimm, index_reg);
-
- /* 2.10.5.8.4 (2 C)
- * For each Read DQS Delay value from 0 to 1 UI
- */
- for (current_read_dqs_delay[lane] = 0; current_read_dqs_delay[lane] < 0x20; current_read_dqs_delay[lane]++) {
- print_debug_dqs("\t\t\t\t\tTrainDQSRdWrPos: 161 current_read_dqs_delay[lane] ", current_read_dqs_delay[lane], 6);
-
- if (current_read_dqs_delay[lane] >= (32 - 16)) {
- check_antiphase = 1;
- } else {
- check_antiphase = 0;
- }
-
- /* 2.10.5.8.4 (2 A i)
- * Commit the current Read DQS Timing Control settings to the hardware registers
- */
- write_dqs_read_data_timing_registers(current_read_dqs_delay, dev, dct, dimm, index_reg);
-
- /* 2.10.5.8.4 (2 A ii)
- * Read the DRAM training pattern from the test address
- */
- read_dram_dqs_training_pattern_fam15(pMCTstat, pDCTstat, dct, Receiver, lane, ((check_antiphase == 0)?1:0));
-
- if (check_antiphase == 0) {
- /* Check for early abort before analyzing per-nibble status */
- dword = Get_NB32_DCT(dev, dct, 0x264);
- if ((dword & 0x1ffffff) != 0) {
- print_debug_dqs("\t\t\t\t\tTrainDQSRdWrPos: 162 early abort: F2x264 ", dword, 6);
- dqs_results_array[Receiver & 0x1][lane - lane_start][current_write_data_delay[lane] - initial_write_dqs_delay[lane]][current_read_dqs_delay[lane] + 16] = 0; /* Fail */
- continue;
- }
- }
-
- /* 2.10.5.8.4 (2 A iii)
- * Record pass / fail status
- */
- dword = Get_NB32_DCT(dev, dct, 0x268) & 0x3ffff;
- print_debug_dqs("\t\t\t\t\tTrainDQSRdWrPos: 163 read results: F2x268 ", dword, 6);
- if (dword & (0x3 << (lane * 2)))
- dqs_results_array[Receiver & 0x1][lane - lane_start][current_write_data_delay[lane] - initial_write_dqs_delay[lane]][current_read_dqs_delay[lane] + 16] = 0; /* Fail */
- else
- dqs_results_array[Receiver & 0x1][lane - lane_start][current_write_data_delay[lane] - initial_write_dqs_delay[lane]][current_read_dqs_delay[lane] + 16] = 1; /* Pass */
- if (check_antiphase == 1) {
- /* Check antiphase results */
- dword = Get_NB32_DCT(dev, dct, 0x26c) & 0x3ffff;
- if (dword & (0x3 << (lane * 2)))
- dqs_results_array[Receiver & 0x1][lane - lane_start][current_write_data_delay[lane] - initial_write_dqs_delay[lane]][16 - (32 - current_read_dqs_delay[lane])] = 0; /* Fail */
- else
- dqs_results_array[Receiver & 0x1][lane - lane_start][current_write_data_delay[lane] - initial_write_dqs_delay[lane]][16 - (32 - current_read_dqs_delay[lane])] = 1; /* Pass */
- }
- }
- }
-
- if (dual_rank && (Receiver & 0x1)) {
- /* Overlay the previous rank test results with the current rank */
- for (write_iter = 0; write_iter < 32; write_iter++) {
- for (read_iter = 0; read_iter < 48; read_iter++) {
- if ((dqs_results_array[0][lane - lane_start][write_iter][read_iter])
- && (dqs_results_array[1][lane - lane_start][write_iter][read_iter]))
- dqs_results_array[1][lane - lane_start][write_iter][read_iter] = 1;
- else
- dqs_results_array[1][lane - lane_start][write_iter][read_iter] = 0;
- }
- }
- }
-
- /* Determine location and length of longest consecutive string of read passing values
- * Output is stored in best_pos and best_count
- */
- last_pos = 0;
- cur_count = 0;
- best_pos = 0;
- best_count = 0;
- for (write_iter = 0; write_iter < 32; write_iter++) {
- for (read_iter = 0; read_iter < 48; read_iter++) {
- if ((dqs_results_array[Receiver & 0x1][lane - lane_start][write_iter][read_iter]) && (read_iter < 47)) {
- /* Pass */
- cur_count++;
- } else {
- /* Failure or end of loop */
- if (cur_count > best_count) {
- best_count = cur_count;
- best_pos = last_pos;
- }
- cur_count = 0;
- last_pos = read_iter + 1;
- }
- }
- last_pos = 0;
- }
-
- if (best_count > 2) {
- uint16_t region_center = (best_pos + (best_count / 2));
-
- if (region_center < 16) {
- printk(BIOS_WARNING, "TrainDQSRdWrPos: negative DQS recovery delay detected!"
- " Attempting to continue but your system may be unstable...\n");
- region_center = 0;
- } else {
- region_center -= 16;
- }
-
- /* Restore current settings of other (previously trained) lanes to the active array */
- memcpy(current_read_dqs_delay, initial_read_dqs_delay, sizeof(current_read_dqs_delay));
-
- /* Program the Read DQS Timing Control register with the center of the passing window */
- current_read_dqs_delay[lane] = region_center;
- passing_dqs_delay_found[lane] = 1;
-
- /* Commit the current Read DQS Timing Control settings to the hardware registers */
- write_dqs_read_data_timing_registers(current_read_dqs_delay, dev, dct, dimm, index_reg);
-
- /* Save the final Read DQS Timing Control settings for later use */
- pDCTstat->CH_D_DIR_B_DQS[dct][Receiver >> 1][DQS_READDIR][lane] = current_read_dqs_delay[lane];
-
- print_debug_dqs("\t\t\t\tTrainDQSRdWrPos: 142 largest read passing region ", best_count, 4);
- print_debug_dqs("\t\t\t\tTrainDQSRdWrPos: 143 largest read passing region start ", best_pos, 4);
- print_debug_dqs("\t\t\t\tTrainDQSRdWrPos: 144 largest read passing region center (raw hardware value) ", region_center, 4);
- } else {
- /* Restore current settings of other (previously trained) lanes to the active array */
- memcpy(current_read_dqs_delay, initial_read_dqs_delay, sizeof(current_read_dqs_delay));
-
- /* Reprogram the Read DQS Timing Control register with the original settings */
- write_dqs_read_data_timing_registers(initial_read_dqs_delay, dev, dct, dimm, index_reg);
- }
-
- /* Determine location and length of longest consecutive string of write passing values
- * Output is stored in best_pos and best_count
- */
- last_pos = 0;
- cur_count = 0;
- best_pos = 0;
- best_count = 0;
- for (read_iter = 0; read_iter < 48; read_iter++) {
- for (write_iter = 0; write_iter < 32; write_iter++) {
- if ((dqs_results_array[Receiver & 0x1][lane - lane_start][write_iter][read_iter]) && (write_iter < 31)) {
- /* Pass */
- cur_count++;
- } else {
- /* Failure or end of loop */
- if (cur_count > best_count) {
- best_count = cur_count;
- best_pos = last_pos;
- }
- cur_count = 0;
- last_pos = write_iter + 1;
- }
- }
- last_pos = 0;
- }
-
- if (best_count > 2) {
- /* Restore current settings of other (previously trained) lanes to the active array */
- memcpy(current_write_dqs_delay, initial_write_data_timing, sizeof(current_write_data_delay));
-
- /* Program the Write DQS Timing Control register with the optimal region within the passing window */
- if (pDCTstat->Status & (1 << SB_LoadReduced))
- current_write_dqs_delay[lane] = ((best_pos + initial_write_dqs_delay[lane]) + (best_count / 3));
- else
- current_write_dqs_delay[lane] = ((best_pos + initial_write_dqs_delay[lane]) + (best_count / 2));
- passing_write_dqs_delay_found = 1;
-
- /* Commit the current Write DQS Timing Control settings to the hardware registers */
- write_dqs_write_data_timing_registers(current_write_dqs_delay, dev, dct, dimm, index_reg);
-
- /* Save the final Write Data Timing settings for later use */
- pDCTstat->CH_D_DIR_B_DQS[dct][Receiver >> 1][DQS_WRITEDIR][lane] = current_write_dqs_delay[lane];
-
- print_debug_dqs("\t\t\t\tTrainDQSRdWrPos: 145 largest write passing region ", best_count, 4);
- print_debug_dqs("\t\t\t\tTrainDQSRdWrPos: 146 largest write passing region start ", best_pos, 4);
- } else {
- /* Restore current settings of other (previously trained) lanes to the active array */
- memcpy(current_write_dqs_delay, initial_write_data_timing, sizeof(current_write_data_delay));
-
- /* Reprogram the Write DQS Timing Control register with the original settings */
- write_dqs_write_data_timing_registers(current_write_dqs_delay, dev, dct, dimm, index_reg);
- }
-
- if (passing_read_dqs_delay_found && passing_write_dqs_delay_found)
- passing_dqs_delay_found[lane] = 1;
- }
-
-#ifdef PRINT_PASS_FAIL_BITMAPS
- for (lane = lane_start; lane < lane_end; lane++) {
- for (write_iter = 0; write_iter < 32; write_iter++) {
- for (read_iter = 0; read_iter < 48; read_iter++) {
- if (dqs_results_array[Receiver & 0x1][lane - lane_start][write_iter][read_iter]) {
- printk(BIOS_DEBUG, "+");
- } else {
- if (read_iter < 16)
- printk(BIOS_DEBUG, ":");
- else
- printk(BIOS_DEBUG, ".");
- }
- }
- printk(BIOS_DEBUG, "\n");
- }
- printk(BIOS_DEBUG, "\n\n");
- }
-#endif
-
- /* Flag failure(s) if present */
- for (lane = lane_start; lane < lane_end; lane++) {
- if (!passing_dqs_delay_found[lane]) {
- print_debug_dqs("\t\t\t\tTrainDQSRdWrPos: 121 Unable to find passing region for lane ", lane, 2);
-
- /* Flag absence of passing window */
- Errors |= 1 << SB_NODQSPOS;
- }
- }
-
- pDCTstat->TrainErrors |= Errors;
- pDCTstat->ErrStatus |= Errors;
-
-#if DQS_TRAIN_DEBUG > 0
- {
- u8 val;
- u8 i;
- u8 ChannelDTD, ReceiverDTD, Dir;
- u8 *p;
-
- for (Dir = 0; Dir < 2; Dir++) {
- if (Dir == 1) {
- printk(BIOS_DEBUG, "TrainDQSRdWrPos: CH_D_DIR_B_DQS WR:\n");
- } else {
- printk(BIOS_DEBUG, "TrainDQSRdWrPos: CH_D_DIR_B_DQS RD:\n");
- }
- for (ChannelDTD = 0; ChannelDTD < 2; ChannelDTD++) {
- printk(BIOS_DEBUG, "Channel: %02x\n", ChannelDTD);
- for (ReceiverDTD = 0; ReceiverDTD < MAX_CS_SUPPORTED; ReceiverDTD += 2) {
- printk(BIOS_DEBUG, "\t\tReceiver: %02x:", ReceiverDTD);
- p = pDCTstat->CH_D_DIR_B_DQS[ChannelDTD][ReceiverDTD >> 1][Dir];
- for (i = 0; i < 8; i++) {
- val = p[i];
- printk(BIOS_DEBUG, " %02x", val);
- }
- printk(BIOS_DEBUG, "\n");
- }
- }
- }
-
- }
-#endif
- }
-
- /* Return 1 on success, 0 on failure */
- return !Errors;
-}
-
-/* DQS Receiver Enable Cycle Training
- * Algorithm detailed in the Fam15h BKDG Rev. 3.14 section 2.10.5.8.3
- */
-static void TrainDQSReceiverEnCyc_D_Fam15(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat)
-{
- u32 Errors;
- u8 Receiver;
- u8 _DisableDramECC = 0;
- u8 _Wrap32Dis = 0, _SSE2 = 0;
-
- u32 addr;
- CRx_TYPE cr4;
- u32 lo, hi;
-
- uint8_t dct;
- uint8_t prev;
- uint8_t dimm;
- uint8_t lane;
- uint32_t dword;
- uint32_t rx_en_offset;
- uint8_t internal_lane;
- uint8_t dct_training_success;
- uint8_t lane_success_count;
- uint16_t initial_phy_phase_delay[MAX_BYTE_LANES];
- uint16_t current_phy_phase_delay[MAX_BYTE_LANES];
- uint16_t current_read_dqs_delay[MAX_BYTE_LANES];
- uint8_t lane_training_success[MAX_BYTE_LANES];
- uint8_t dqs_results_array[1024];
-
- uint16_t ren_step = 0x40;
- uint32_t index_reg = 0x98;
- uint32_t dev = pDCTstat->dev_dct;
-
- uint8_t lane_count;
- lane_count = get_available_lane_count(pMCTstat, pDCTstat);
-
- print_debug_dqs("\nTrainDQSReceiverEnCyc: Node_ID ", pDCTstat->Node_ID, 0);
- cr4 = read_cr4();
- if (cr4 & (1<<9)) {
- _SSE2 = 1;
- }
- cr4 |= (1<<9); /* OSFXSR enable SSE2 */
- write_cr4(cr4);
-
- addr = HWCR_MSR;
- _RDMSR(addr, &lo, &hi);
- if (lo & (1<<17)) {
- _Wrap32Dis = 1;
- }
- lo |= (1<<17); /* HWCR.wrap32dis */
- _WRMSR(addr, lo, hi); /* allow 64-bit memory references in real mode */
-
- /* Disable ECC correction of reads on the dram bus. */
- _DisableDramECC = mct_DisableDimmEccEn_D(pMCTstat, pDCTstat);
-
- Errors = 0;
-
- for (dct = 0; dct < 2; dct++) {
- /* Program D18F2x9C_x0D0F_E003_dct[1:0][DisAutoComp, DisablePredriverCal] */
- /* NOTE: DisablePredriverCal only takes effect when set on DCT 0 */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fe003);
- dword &= ~(0x3 << 13);
- dword |= (0x1 << 13);
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fe003, dword);
- }
-
- for (dct = 0; dct < 2; dct++) {
- /* 2.10.5.6 */
- fam15EnableTrainingMode(pMCTstat, pDCTstat, dct, 1);
-
- /* 2.10.5.8.3 */
- Receiver = mct_InitReceiver_D(pDCTstat, dct);
-
- /* Indicate success unless training the DCT explicitly fails */
- dct_training_success = 1;
-
- /* There are four receiver pairs, loosely associated with chipselects.
- * This is essentially looping over each DIMM.
- */
- for (; Receiver < 8; Receiver += 2) {
- dimm = (Receiver >> 1);
-
- if (!mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, dct, Receiver)) {
- continue;
- }
-
- /* Initialize variables */
- memset(lane_training_success, 0, sizeof(lane_training_success));
- memset(current_phy_phase_delay, 0, sizeof(current_phy_phase_delay));
-
- /* 2.10.5.8.3 (2) */
- read_dqs_receiver_enable_control_registers(initial_phy_phase_delay, dev, dct, dimm, index_reg);
-
- /* Reset the read data timing registers to 1UI before calculating MaxRdLatency */
- for (internal_lane = 0; internal_lane < MAX_BYTE_LANES; internal_lane++)
- current_read_dqs_delay[internal_lane] = 0x20;
- write_dqs_read_data_timing_registers(current_read_dqs_delay, dev, dct, dimm, index_reg);
-
- for (lane = 0; lane < lane_count; lane++) {
- /* Initialize variables */
- memset(dqs_results_array, 0, sizeof(dqs_results_array));
- lane_success_count = 0;
-
- /* 2.10.5.8.3 (1) */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0030 | (lane << 8));
- dword |= (0x1 << 8); /* BlockRxDqsLock = 1 */
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0030 | (lane << 8), dword);
-
- /* 2.10.5.8.3 (3) */
- rx_en_offset = (initial_phy_phase_delay[lane] + 0x10) % 0x40;
-
- /* 2.10.5.8.3 (4) */
-#if DQS_TRAIN_DEBUG > 0
- printk(BIOS_DEBUG, "TrainDQSReceiverEnCyc_D_Fam15 Receiver %d lane %d initial phy delay %04x: iterating from %04x to %04x\n", Receiver, lane, initial_phy_phase_delay[lane], rx_en_offset, 0x3ff);
-#endif
- for (current_phy_phase_delay[lane] = rx_en_offset; current_phy_phase_delay[lane] < 0x3ff; current_phy_phase_delay[lane] += ren_step) {
-#if DQS_TRAIN_DEBUG > 0
- printk(BIOS_DEBUG, "%s: Receiver %d lane %d current phy delay: %04x\n", __func__, Receiver, lane, current_phy_phase_delay[lane]);
-#endif
-
- /* 2.10.5.8.3 (4 A) */
- write_dqs_receiver_enable_control_registers(current_phy_phase_delay, dev, dct, dimm, index_reg);
-
- /* Calculate and program MaxRdLatency */
- Calc_SetMaxRdLatency_D_Fam15(pMCTstat, pDCTstat, dct, 0);
-
- /* 2.10.5.8.3 (4 B) */
- dqs_results_array[current_phy_phase_delay[lane]] =
- TrainDQSRdWrPos_D_Fam15(pMCTstat, pDCTstat, dct,
- Receiver, Receiver + 2,
- lane);
-
- if (dqs_results_array[current_phy_phase_delay[lane]])
- lane_success_count++;
-
- /* Don't bother testing larger values if the end of the passing window was already found */
- if (!dqs_results_array[current_phy_phase_delay[lane]] && (lane_success_count > 1))
- break;
- }
-
- uint16_t phase_delay;
- for (phase_delay = 0; phase_delay < 0x3ff; phase_delay++)
- if (dqs_results_array[phase_delay])
- lane_training_success[lane] = 1;
-
- if (!lane_training_success[lane]) {
- if (pDCTstat->tcwl_delay[dct] >= 1) {
- Errors |= 1 << SB_FatalError;
- printk(BIOS_ERR, "%s: lane %d failed to train! "
- "Training for receiver %d on DCT %d aborted\n",
- __func__, lane, Receiver, dct);
- }
-
- /* Restore BlockRxDqsLock setting to normal operation in preparation for retraining */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0030 | (lane << 8));
- dword &= ~(0x1 << 8); /* BlockRxDqsLock = 0 */
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0030 | (lane << 8), dword);
-
- break;
- }
-
-#ifdef PRINT_PASS_FAIL_BITMAPS
- for (phase_delay = 0; phase_delay < 0x3ff; phase_delay++) {
- if (dqs_results_array[phase_delay])
- printk(BIOS_DEBUG, "+");
- else
- printk(BIOS_DEBUG, ".");
- }
- printk(BIOS_DEBUG, "\n");
-#endif
-
- /* 2.10.5.8.3 (5) */
- prev = dqs_results_array[rx_en_offset];
- for (current_phy_phase_delay[lane] = rx_en_offset + ren_step; current_phy_phase_delay[lane] < 0x3ff; current_phy_phase_delay[lane] += ren_step) {
- if ((dqs_results_array[current_phy_phase_delay[lane]] == 0) && (prev == 1)) {
- /* Restore last known good delay */
- current_phy_phase_delay[lane] -= ren_step;
-
- /* 2.10.5.8.3 (5 A B) */
- if (current_phy_phase_delay[lane] < 0x10)
- current_phy_phase_delay[lane] = 0x0;
- else
- current_phy_phase_delay[lane] -= 0x10;
-
- /* Update hardware registers with final values */
- write_dqs_receiver_enable_control_registers(current_phy_phase_delay, dev, dct, dimm, index_reg);
- TrainDQSRdWrPos_D_Fam15(pMCTstat, pDCTstat, dct,
- Receiver, Receiver + 2,
- lane);
- break;
- }
- prev = dqs_results_array[current_phy_phase_delay[lane]];
- }
-
- /* 2.10.5.8.3 (6) */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0030 | (lane << 8));
- dword &= ~(0x1 << 8); /* BlockRxDqsLock = 0 */
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0030 | (lane << 8), dword);
- }
-
- for (lane = 0; lane < lane_count; lane++) {
- if (!lane_training_success[lane]) {
- dct_training_success = 0;
- Errors |= 1 << SB_NODQSPOS;
- }
- }
-
-#if DQS_TRAIN_DEBUG > 0
- printk(BIOS_DEBUG, "TrainDQSReceiverEnCyc_D_Fam15 DQS receiver enable timing: ");
- for (lane = 0; lane < lane_count; lane++) {
- printk(BIOS_DEBUG, " %03x", current_phy_phase_delay[lane]);
- }
- printk(BIOS_DEBUG, "\n");
-#endif
- }
-
- if (!dct_training_success) {
- if (pDCTstat->tcwl_delay[dct] < 1) {
- /* Increase TCWL */
- pDCTstat->tcwl_delay[dct]++;
- /* Request retraining */
- Errors |= 1 << SB_RetryConfigTrain;
- }
- }
- }
-
- pDCTstat->TrainErrors |= Errors;
- pDCTstat->ErrStatus |= Errors;
-
-#if DQS_TRAIN_DEBUG > 0
- {
- u8 val;
- u8 i;
- u8 ChannelDTD, ReceiverDTD, Dir;
- u8 *p;
-
- for (Dir = 0; Dir < 2; Dir++) {
- if (Dir == 1) {
- printk(BIOS_DEBUG, "TrainDQSRdWrPos: CH_D_DIR_B_DQS WR:\n");
- } else {
- printk(BIOS_DEBUG, "TrainDQSRdWrPos: CH_D_DIR_B_DQS RD:\n");
- }
- for (ChannelDTD = 0; ChannelDTD < 2; ChannelDTD++) {
- printk(BIOS_DEBUG, "Channel: %02x\n", ChannelDTD);
- for (ReceiverDTD = 0; ReceiverDTD < MAX_CS_SUPPORTED; ReceiverDTD += 2) {
- printk(BIOS_DEBUG, "\t\tReceiver: %02x:", ReceiverDTD);
- p = pDCTstat->CH_D_DIR_B_DQS[ChannelDTD][ReceiverDTD >> 1][Dir];
- for (i = 0; i < 8; i++) {
- val = p[i];
- printk(BIOS_DEBUG, " %02x", val);
- }
- printk(BIOS_DEBUG, "\n");
- }
- }
- }
-
- }
-#endif
- if (_DisableDramECC) {
- mct_EnableDimmEccEn_D(pMCTstat, pDCTstat, _DisableDramECC);
- }
- if (!_Wrap32Dis) {
- addr = HWCR_MSR;
- _RDMSR(addr, &lo, &hi);
- lo &= ~(1<<17); /* restore HWCR.wrap32dis */
- _WRMSR(addr, lo, hi);
- }
- if (!_SSE2) {
- cr4 = read_cr4();
- cr4 &= ~(1<<9); /* restore cr4.OSFXSR */
- write_cr4(cr4);
- }
-
- printk(BIOS_DEBUG, "TrainDQSReceiverEnCyc: Status %x\n", pDCTstat->Status);
- printk(BIOS_DEBUG, "TrainDQSReceiverEnCyc: TrainErrors %x\n", pDCTstat->TrainErrors);
- printk(BIOS_DEBUG, "TrainDQSReceiverEnCyc: ErrStatus %x\n", pDCTstat->ErrStatus);
- printk(BIOS_DEBUG, "TrainDQSReceiverEnCyc: ErrCode %x\n", pDCTstat->ErrCode);
- printk(BIOS_DEBUG, "TrainDQSReceiverEnCyc: Done\n\n");
-}
-
-static void SetupDqsPattern_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u32 *buffer)
-{
- /* 1. Set the Pattern type (0 or 1) in DCTStatstruc.Pattern
- * 2. Copy the pattern from ROM to Cache, aligning on 16 byte boundary
- * 3. Set the ptr to Cacheable copy in DCTStatstruc.PtrPatternBufA
- */
-
- u32 *buf;
- u16 i;
-
- buf = (u32 *)(((u32)buffer + 0x10) & (0xfffffff0));
- if (pDCTstat->Status & (1<<SB_128bitmode)) {
- pDCTstat->Pattern = 1; /* 18 cache lines, alternating qwords */
- for (i = 0; i < 16*18; i++)
- buf[i] = TestPatternJD1b_D[i];
- } else {
- pDCTstat->Pattern = 0; /* 9 cache lines, sequential qwords */
- for (i = 0; i < 16*9; i++)
- buf[i] = TestPatternJD1a_D[i];
- }
- pDCTstat->PtrPatternBufA = (u32)buf;
-}
-
-static void StoreDQSDatStrucVal_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 ChipSel)
-{
- /* Store the DQSDelay value, found during a training sweep, into the DCT
- * status structure for this node
- */
-
- /* 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
- */
-
- /* FindDQSDatDimmVal_D is not required since we use an array */
- u8 dn = 0;
-
- dn = ChipSel>>1; /* if odd or even logical DIMM */
-
- pDCTstat->CH_D_DIR_B_DQS[pDCTstat->Channel][dn][pDCTstat->Direction][pDCTstat->ByteLane] =
- pDCTstat->DQSDelay;
-}
-
-static void GetDQSDatStrucVal_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 ChipSel)
-{
- u8 dn = 0;
-
- /* 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
- */
-
- /* FindDQSDatDimmVal_D is not required since we use an array */
- dn = ChipSel >> 1; /*if odd or even logical DIMM */
-
- pDCTstat->DQSDelay =
- pDCTstat->CH_D_DIR_B_DQS[pDCTstat->Channel][dn][pDCTstat->Direction][pDCTstat->ByteLane];
-}
-
-/* FindDQSDatDimmVal_D is not required since we use an array */
-
-void proc_IOCLFLUSH_D(u32 addr_hi)
-{
- SetTargetWTIO_D(addr_hi);
- proc_CLFLUSH(addr_hi);
- ResetTargetWTIO_D();
-}
-
-u8 ChipSelPresent_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat,
- u8 Channel, u8 ChipSel)
-{
- u32 val;
- u32 reg;
- u32 dev = pDCTstat->dev_dct;
- uint8_t dct = 0;
- u8 ret = 0;
-
- if (!pDCTstat->GangedMode)
- dct = Channel;
- else
- dct = 0;
-
- if (ChipSel < MAX_CS_SUPPORTED) {
- reg = 0x40 + (ChipSel << 2);
- val = Get_NB32_DCT(dev, dct, reg);
- if (val & (1 << 0))
- ret = 1;
- }
-
- return ret;
-}
-
-/* proc_CLFLUSH_D located in mct_gcc.h */
-
-static void WriteDQSTestPattern_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat,
- u32 TestAddr_lo)
-{
- /* Write a pattern of 72 bit times (per DQ), to test dram functionality.
- * The pattern is a stress pattern which exercises both ISI and
- * crosstalk. The number of cache lines to fill is dependent on DCT
- * width mode and burstlength.
- * Mode BL Lines Pattern no.
- * ----+---+-------------------
- * 64 4 9 0
- * 64 8 9 0
- * 64M 4 9 0
- * 64M 8 9 0
- * 128 4 18 1
- * 128 8 N/A -
- */
- if (pDCTstat->Pattern == 0)
- WriteL9TestPattern_D(pDCTstat, TestAddr_lo);
- else
- WriteL18TestPattern_D(pDCTstat, TestAddr_lo);
-}
-
-static void WriteL18TestPattern_D(struct DCTStatStruc *pDCTstat,
- u32 TestAddr_lo)
-{
- u8 *buf;
-
- buf = (u8 *)pDCTstat->PtrPatternBufA;
- WriteLNTestPattern(TestAddr_lo, buf, 18);
-
-}
-
-static void WriteL9TestPattern_D(struct DCTStatStruc *pDCTstat,
- u32 TestAddr_lo)
-{
- u8 *buf;
-
- buf = (u8 *)pDCTstat->PtrPatternBufA;
- WriteLNTestPattern(TestAddr_lo, buf, 9);
-}
-
-static u16 CompareDQSTestPattern_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u32 addr_lo)
-{
- /* Compare a pattern of 72 bit times (per DQ), to test dram functionality.
- * The pattern is a stress pattern which exercises both ISI and
- * crosstalk. The number of cache lines to fill is dependent on DCT
- * width mode and burstlength.
- * Mode BL Lines Pattern no.
- * ----+---+-------------------
- * 64 4 9 0
- * 64 8 9 0
- * 64M 4 9 0
- * 64M 8 9 0
- * 128 4 18 1
- * 128 8 N/A -
- */
-
- u32 *test_buf;
- u16 MEn1Results, bitmap;
- u8 bytelane;
- u8 i;
- u32 value;
- u8 j;
- u32 value_test;
- u32 value_r = 0, value_r_test = 0;
- u8 pattern, channel, BeatCnt;
- struct DCTStatStruc *ptrAddr;
-
- ptrAddr = pDCTstat;
- pattern = pDCTstat->Pattern;
- channel = pDCTstat->Channel;
- test_buf = (u32 *)pDCTstat->PtrPatternBufA;
-
- if (pattern && channel) {
- addr_lo += 8; /* second channel */
- test_buf += 2;
- }
-
- bytelane = 0; /* bytelane counter */
- bitmap = 0xFFFF; /* bytelane test bitmap, 1 = pass */
- MEn1Results = 0xFFFF;
- BeatCnt = 0;
- for (i = 0; i < (9 * 64 / 4); i++) { /* sizeof testpattern. /4 due to next loop */
- value = read32_fs(addr_lo);
- value_test = *test_buf;
-
- print_debug_dqs_pair("\t\t\t\t\t\ttest_buf = ", (u32)test_buf, " value = ", value_test, 7);
- print_debug_dqs_pair("\t\t\t\t\t\ttaddr_lo = ", addr_lo, " value = ", value, 7);
-
- if (pDCTstat->Direction == DQS_READDIR) {
- if (BeatCnt != 0) {
- value_r = *test_buf;
- if (pattern) /* if multi-channel */
- value_r_test = read32_fs(addr_lo - 16);
- else
- value_r_test = read32_fs(addr_lo - 8);
- }
- print_debug_dqs_pair("\t\t\t\t\t\t\ttest_buf = ", (u32)test_buf, " value_r_test = ", value_r, 7);
- print_debug_dqs_pair("\t\t\t\t\t\t\ttaddr_lo = ", addr_lo, " value_r = ", value_r_test, 7);
- }
-
- for (j = 0; j < (4 * 8); j += 8) { /* go through a 32bit data, on 1 byte step. */
- if (((value >> j) & 0xff) != ((value_test >> j) & 0xff)) {
- bitmap &= ~(1 << bytelane);
- }
-
- if (pDCTstat->Direction == DQS_READDIR) {
- if (BeatCnt != 0) {
- if (((value_r >> j) & 0xff) != ((value_r_test >> j) & 0xff)) {
- MEn1Results &= ~(1 << bytelane);
- }
- }
- }
- bytelane++;
- bytelane &= 0x7;
- }
-
- print_debug_dqs("\t\t\t\t\t\tbitmap = ", bitmap, 7);
- print_debug_dqs("\t\t\t\t\t\tMEn1Results = ", MEn1Results, 7);
-
- if (!bitmap)
- break;
-
- if (bytelane == 0) {
- BeatCnt += 4;
- if (!(pDCTstat->Status & (1 << SB_128bitmode))) {
- if (BeatCnt == 8) BeatCnt = 0; /* 8 beat burst */
- } else {
- if (BeatCnt == 4) BeatCnt = 0; /* 4 beat burst */
- }
- if (pattern == 1) { /* dual channel */
- addr_lo += 8; /* skip over other channel's data */
- test_buf += 2;
- }
- }
- addr_lo += 4;
- test_buf += 1;
- }
-
- if (pDCTstat->Direction == DQS_READDIR) {
- bitmap &= 0xFF;
- bitmap |= MEn1Results << 8;
- }
-
- print_debug_dqs("\t\t\t\t\t\tbitmap = ", bitmap, 6);
-
- return bitmap;
-}
-
-static void FlushDQSTestPattern_D(struct DCTStatStruc *pDCTstat,
- u32 addr_lo)
-{
- /* Flush functions in mct_gcc.h */
- if (pDCTstat->Pattern == 0) {
- FlushDQSTestPattern_L9(addr_lo);
- } else {
- FlushDQSTestPattern_L18(addr_lo);
- }
-}
-
-void SetTargetWTIO_D(u32 TestAddr)
-{
- u32 lo, hi;
- hi = TestAddr >> 24;
- lo = TestAddr << 8;
- _WRMSR(MTRR_IORR0_BASE, lo, hi); /* IORR0 Base */
- hi = 0xFF;
- lo = 0xFC000800; /* 64MB Mask */
- _WRMSR(MTRR_IORR0_MASK, lo, hi); /* IORR0 Mask */
-}
-
-void ResetTargetWTIO_D(void)
-{
- u32 lo, hi;
-
- hi = 0;
- lo = 0;
- _WRMSR(MTRR_IORR0_MASK, lo, hi); /* IORR0 Mask */
-}
-
-u32 SetUpperFSbase(u32 addr_hi)
-{
- /* Set the upper 32-bits of the Base address, 4GB aligned) for the
- * FS selector.
- */
- u32 lo, hi;
- u32 addr;
- lo = 0;
- hi = addr_hi>>24;
- addr = FS_Base;
- _WRMSR(addr, lo, hi);
- return addr_hi << 8;
-}
-
-void ResetDCTWrPtr_D(u32 dev, uint8_t dct, u32 index_reg, u32 index)
-{
- u32 val;
-
- val = Get_NB32_index_wait_DCT(dev, dct, index_reg, index);
- Set_NB32_index_wait_DCT(dev, dct, index_reg, index, val);
-}
-
-void mct_TrainDQSPos_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstatA)
-{
- u8 Node;
- u8 ChipSel;
- struct DCTStatStruc *pDCTstat;
-
- for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
- pDCTstat = pDCTstatA + Node;
- if (pDCTstat->DCTSysLimit) {
- if (is_fam15h()) {
- TrainDQSReceiverEnCyc_D_Fam15(pMCTstat, pDCTstat);
- } else {
- TrainDQSRdWrPos_D_Fam10(pMCTstat, pDCTstat);
- for (ChipSel = 0; ChipSel < MAX_CS_SUPPORTED; ChipSel += 2) {
- SetEccDQSRdWrPos_D_Fam10(pMCTstat, pDCTstat, ChipSel);
- }
- }
- }
- }
-}
-
-/* mct_BeforeTrainDQSRdWrPos_D
- * Function is inline.
- */
-u8 mct_DisableDimmEccEn_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat)
-{
- u8 _DisableDramECC = 0;
- u32 val;
- u32 reg;
- u32 dev;
-
- /*Disable ECC correction of reads on the dram bus. */
-
- dev = pDCTstat->dev_dct;
- reg = 0x90;
- val = Get_NB32_DCT(dev, 0, reg);
- if (val & (1<<DimmEcEn)) {
- _DisableDramECC |= 0x01;
- val &= ~(1<<DimmEcEn);
- Set_NB32_DCT(dev, 0, reg, val);
- }
- if (!pDCTstat->GangedMode) {
- val = Get_NB32_DCT(dev, 1, reg);
- if (val & (1<<DimmEcEn)) {
- _DisableDramECC |= 0x02;
- val &= ~(1<<DimmEcEn);
- Set_NB32_DCT(dev, 1, reg, val);
- }
- }
- return _DisableDramECC;
-}
-
-void mct_EnableDimmEccEn_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 _DisableDramECC)
-{
- u32 val;
- u32 dev;
-
- /* Enable ECC correction if it was previously disabled */
- dev = pDCTstat->dev_dct;
-
- if ((_DisableDramECC & 0x01) == 0x01) {
- val = Get_NB32_DCT(dev, 0, 0x90);
- val |= (1<<DimmEcEn);
- Set_NB32_DCT(dev, 0, 0x90, val);
- }
- if ((_DisableDramECC & 0x02) == 0x02) {
- val = Get_NB32_DCT(dev, 1, 0x90);
- val |= (1<<DimmEcEn);
- Set_NB32_DCT(dev, 1, 0x90, val);
- }
-}
-
-/*
- * Set DQS delay value to related register
- */
-static void mct_SetDQSDelayCSR_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 ChipSel)
-{
- u8 ByteLane;
- u32 val;
- u32 index_reg = 0x98;
- u8 shift;
- u32 dqs_delay = (u32)pDCTstat->DQSDelay;
- u32 dev = pDCTstat->dev_dct;
- u32 index;
-
- ByteLane = pDCTstat->ByteLane;
-
- if (!(pDCTstat->DqsRdWrPos_Saved & (1 << ByteLane))) {
- /* Channel is offset */
- if (ByteLane < 4) {
- index = 1;
- } else if (ByteLane <8) {
- index = 2;
- } else {
- index = 3;
- }
-
- if (pDCTstat->Direction == DQS_READDIR) {
- index += 4;
- }
-
- /* get the proper register index */
- shift = ByteLane % 4;
- shift <<= 3; /* get bit position of bytelane, 8 bit */
-
- index += (ChipSel>>1) << 8;
-
- val = Get_NB32_index_wait_DCT(dev, pDCTstat->Channel, index_reg, index);
- if (ByteLane < 8) {
- if (pDCTstat->Direction == DQS_WRITEDIR) {
- dqs_delay += pDCTstat->persistentData.CH_D_B_TxDqs[pDCTstat->Channel][ChipSel>>1][ByteLane];
- } else {
- dqs_delay <<= 1;
- }
- }
- val &= ~(0x7f << shift);
- val |= (dqs_delay << shift);
- Set_NB32_index_wait_DCT(dev, pDCTstat->Channel, index_reg, index, val);
- }
-}
-
-u8 mct_RcvrRankEnabled_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat,
- u8 Channel, u8 ChipSel)
-{
- u8 ret;
-
- ret = ChipSelPresent_D(pMCTstat, pDCTstat, Channel, ChipSel);
- return ret;
-}
-
-u32 mct_GetRcvrSysAddr_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat,
- u8 channel, u8 receiver, u8 *valid)
-{
- return mct_GetMCTSysAddr_D(pMCTstat, pDCTstat, channel, receiver, valid);
-}
-
-u32 mct_GetMCTSysAddr_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat,
- u8 Channel, u8 receiver, u8 *valid)
-{
- u32 val;
- uint8_t dct = 0;
- u32 reg;
- u32 dword;
- u32 dev = pDCTstat->dev_dct;
-
- *valid = 0;
-
-
- if (!pDCTstat->GangedMode) {
- dct = Channel;
- }
-
- /* get the local base addr of the chipselect */
- reg = 0x40 + (receiver << 2);
- val = Get_NB32_DCT(dev, dct, reg);
-
- val &= ~0xe007c01f;
-
- /* unganged mode DCT0+DCT1, sys addr of DCT1 = node
- * base+DctSelBaseAddr+local ca base*/
- if ((Channel) && (pDCTstat->GangedMode == 0) && (pDCTstat->DIMMValidDCT[0] > 0)) {
- reg = 0x110;
- dword = Get_NB32(dev, reg);
- dword &= 0xfffff800;
- dword <<= 8; /* scale [47:27] of F2x110[31:11] to [39:8]*/
- val += dword;
-
- /* if DCTSelBaseAddr < Hole, and eax > HoleBase, then add Hole size to test address */
- if ((val >= pDCTstat->DCTHoleBase) && (pDCTstat->DCTHoleBase > dword)) {
- dword = (~(pDCTstat->DCTHoleBase >> (24 - 8)) + 1) & 0xFF;
- dword <<= (24 - 8);
- val += dword;
- }
- } else {
- /* sys addr = node base+local cs base */
- val += pDCTstat->DCTSysBase;
-
- /* New stuff */
- if (pDCTstat->DCTHoleBase && (val >= pDCTstat->DCTHoleBase)) {
- val -= pDCTstat->DCTSysBase;
- dword = Get_NB32(pDCTstat->dev_map, 0xF0); /* get Hole Offset */
- val += (dword & 0x0000ff00) << (24-8-8);
- }
- }
-
- /* New stuff */
- val += ((1 << 21) >> 8); /* Add 2MB offset to avoid compat area */
- if (val >= MCT_TRNG_KEEPOUT_START) {
- while (val < MCT_TRNG_KEEPOUT_END)
- val += (1 << (15-8)); /* add 32K */
- }
-
- /* Add a node seed */
- val += (((1 * pDCTstat->Node_ID) << 20) >> 8); /* Add 1MB per node to avoid aliases */
-
- /* HW remap disabled? */
- if (!(pDCTstat->Status & (1 << SB_HWHole))) {
- if (!(pDCTstat->Status & (1 << SB_SWNodeHole))) {
- /* SW memhole disabled */
- u32 lo, hi;
- _RDMSR(TOP_MEM, &lo, &hi);
- lo >>= 8;
- if ((val >= lo) && (val < _4GB_RJ8)) {
- val = 0;
- *valid = 0;
- goto exitGetAddr;
- } else {
- *valid = 1;
- goto exitGetAddrWNoError;
- }
- } else {
- *valid = 1;
- goto exitGetAddrWNoError;
- }
- } else {
- *valid = 1;
- goto exitGetAddrWNoError;
- }
-
-exitGetAddrWNoError:
-
- /* Skip if Address is in UMA region */
- dword = pMCTstat->Sub4GCacheTop;
- dword >>= 8;
- if (dword != 0) {
- if ((val >= dword) && (val < _4GB_RJ8)) {
- val = 0;
- *valid = 0;
- } else {
- *valid = 1;
- }
- }
- print_debug_dqs("mct_GetMCTSysAddr_D: receiver ", receiver, 2);
- print_debug_dqs("mct_GetMCTSysAddr_D: Channel ", Channel, 2);
- print_debug_dqs("mct_GetMCTSysAddr_D: base_addr ", val, 2);
- print_debug_dqs("mct_GetMCTSysAddr_D: valid ", *valid, 2);
- print_debug_dqs("mct_GetMCTSysAddr_D: status ", pDCTstat->Status, 2);
- print_debug_dqs("mct_GetMCTSysAddr_D: SysBase ", pDCTstat->DCTSysBase, 2);
- print_debug_dqs("mct_GetMCTSysAddr_D: HoleBase ", pDCTstat->DCTHoleBase, 2);
- print_debug_dqs("mct_GetMCTSysAddr_D: Cachetop ", pMCTstat->Sub4GCacheTop, 2);
-
-exitGetAddr:
- return val;
-}
-
-void mct_Write1LTestPattern_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat,
- u32 TestAddr, u8 pattern)
-{
-
- u8 *buf;
-
- /* Issue the stream of writes. When F2x11C[MctWrLimit] is reached
- * (or when F2x11C[FlushWr] is set again), all the writes are written
- * to DRAM.
- */
-
- SetUpperFSbase(TestAddr);
-
- if (pattern)
- buf = (u8 *)pDCTstat->PtrPatternBufB;
- else
- buf = (u8 *)pDCTstat->PtrPatternBufA;
-
- WriteLNTestPattern(TestAddr << 8, buf, 1);
-}
-
-void mct_Read1LTestPattern_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u32 addr)
-{
- u32 value;
-
- /* BIOS issues the remaining (Ntrain - 2) reads after checking that
- * F2x11C[PrefDramTrainMode] is cleared. These reads must be to
- * consecutive cache lines (i.e., 64 bytes apart) and must not cross
- * a naturally aligned 4KB boundary. These reads hit the prefetches and
- * read the data from the prefetch buffer.
- */
-
- /* get data from DIMM */
- SetUpperFSbase(addr);
-
- /* 1st move causes read fill (to exclusive or shared)*/
- value = read32_fs(addr << 8);
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c
deleted file mode 100644
index 4c33b9e4b6..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- * Copyright (C) 2015 - 2016 Raptor Engineering, LLC
- *
- * 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.
- */
-
-#include <arch/cpu.h>
-#include <stdint.h>
-#include <console/console.h>
-#include <device/pci_ops.h>
-
-#include "mct_d.h"
-#include "mct_d_gcc.h"
-
-static void setSyncOnUnEccEn_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstatA);
-static u8 isDramECCEn_D(struct DCTStatStruc *pDCTstat);
-
-static uint8_t is_fam15h(void)
-{
- uint8_t fam15h = 0;
- uint32_t family;
-
- family = cpuid_eax(0x80000001);
- family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);
-
- if (family >= 0x6f)
- /* Family 15h or later */
- fam15h = 1;
-
- return fam15h;
-}
-
-/* Initialize ECC modes of Integrated Dram+Memory Controllers of a network of
- * Hammer processors. Use Dram background scrubber to fast initialize ECC bits
- * of all dram.
- *
- * Notes:
- *
- * Order that items are set:
- * 1. eccen bit in NB
- * 2. Scrub Base
- * 3. Temp Node Base
- * 4. Temp Node Limit
- * 5. Redir bit in NB
- * 6. Scrub CTL
- *
- * Conditions for setting background scrubber.
- * 1. node is present
- * 2. node has dram functioning (WE = RE = 1)
- * 3. all eccdimms (or bit 17 of offset 90,fn 2)
- * 4. no chip-select gap exists
- *
- * The dram background scrubber is used under very controlled circumstances to
- * initialize all the ECC bits on the DIMMs of the entire dram address map
- * (including hidden or lost dram and dram above 4GB). We will turn the scrub
- * rate up to maximum, which should clear 4GB of dram in about 2.7 seconds.
- * We will activate the scrubbers of all nodes with ecc dram and let them run in
- * parallel, thereby reducing even further the time required to condition dram.
- * Finally, we will go through each node and either disable background scrubber,
- * or set the scrub rate to the user setup specified rate.
- *
- * To allow the NB to scrub, we need to wait a time period long enough to
- * guarantee that the NB scrubs the entire dram on its node. Do do this, we
- * simply sample the scrub ADDR once, for an initial value, then we sample and poll until the polled value of scrub ADDR
- * has wrapped around at least once: Scrub ADDRi+1 < Scrub ADDRi. Since we let all
- * Nodes run in parallel, we need to guarantee that all nodes have wrapped. To do
- * this efficiently, we need only to sample one of the nodes, the node with the
- * largest ammount of dram populated is the one which will take the longest amount
- * of time (the scrub rate is set to max, the same rate, on all nodes). So,
- * during setup of scrub Base, we determine how much memory and which node has
- * the largest memory installed.
- *
- * Scrubbing should not ordinarily be enabled on a Node with a chip-select gap
- * (aka SW memhole, cs hoisting, etc..).To init ECC memory on this node, the
- * scrubber is used in two steps. First, the Dram Limit for the node is adjusted
- * down to the bottom of the gap, and that ECC dram is initialized. Second, the
- * original Limit is restored, the Scrub base is set to 4GB, and scrubber is
- * allowed to run until the Scrub Addr wraps around to zero.
- */
-u8 ECCInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA)
-{
- u8 Node;
- u8 AllECC;
- u16 OB_NBECC;
- u32 curBase;
- u16 OB_ECCRedir;
- u32 LDramECC;
- u32 OF_ScrubCTL;
- u16 OB_ChipKill;
- u8 MemClrECC;
-
- u32 dev;
- u32 reg;
- u32 val;
- u16 nvbits;
-
- uint32_t dword;
- uint8_t sync_flood_on_dram_err[MAX_NODES_SUPPORTED];
- uint8_t sync_flood_on_any_uc_err[MAX_NODES_SUPPORTED];
-
- mctHookBeforeECC();
-
- /* Construct these booleans, based on setup options, for easy handling
- later in this procedure */
- OB_NBECC = mctGet_NVbits(NV_NBECC); /* MCA ECC (MCE) enable bit */
-
- OB_ECCRedir = mctGet_NVbits(NV_ECCRedir); /* ECC Redirection */
-
- OB_ChipKill = mctGet_NVbits(NV_ChipKill); /* ECC Chip-kill mode */
- OF_ScrubCTL = 0; /* Scrub CTL for Dcache, L2, and dram */
-
- if (!is_fam15h()) {
- nvbits = mctGet_NVbits(NV_DCBKScrub);
- /* mct_AdjustScrub_D(pDCTstatA, &nvbits); */ /* Need not adjust */
- OF_ScrubCTL |= (u32) nvbits << 16;
-
- nvbits = mctGet_NVbits(NV_L2BKScrub);
- OF_ScrubCTL |= (u32) nvbits << 8;
- }
-
- nvbits = mctGet_NVbits(NV_L3BKScrub);
- OF_ScrubCTL |= (nvbits & 0x1f) << 24; /* L3Scrub = NV_L3BKScrub */
-
- nvbits = mctGet_NVbits(NV_DramBKScrub);
- OF_ScrubCTL |= nvbits; /* DramScrub = NV_DramBKScrub */
-
- /* Prevent lockups on DRAM errors during ECC init */
- for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
- struct DCTStatStruc *pDCTstat;
- pDCTstat = pDCTstatA + Node;
-
- if (NodePresent_D(Node)) {
- dword = Get_NB32(pDCTstat->dev_nbmisc, 0x44);
- sync_flood_on_dram_err[Node] = (dword >> 30) & 0x1;
- sync_flood_on_any_uc_err[Node] = (dword >> 21) & 0x1;
- dword &= ~(0x1 << 30);
- dword &= ~(0x1 << 21);
- Set_NB32(pDCTstat->dev_nbmisc, 0x44, dword);
-
- uint32_t mc4_status_high = pci_read_config32(pDCTstat->dev_nbmisc, 0x4c);
- uint32_t mc4_status_low = pci_read_config32(pDCTstat->dev_nbmisc, 0x48);
- if ((mc4_status_high & (0x1 << 31)) && (mc4_status_high != 0xffffffff)) {
- printk(BIOS_WARNING, "WARNING: MC4 Machine Check Exception detected!\n"
- "Signature: %08x%08x\n", mc4_status_high, mc4_status_low);
- }
-
- /* Clear MC4 error status */
- pci_write_config32(pDCTstat->dev_nbmisc, 0x48, 0x0);
- pci_write_config32(pDCTstat->dev_nbmisc, 0x4c, 0x0);
- }
- }
-
- AllECC = 1;
- MemClrECC = 0;
- for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
- struct DCTStatStruc *pDCTstat;
- pDCTstat = pDCTstatA + Node;
- LDramECC = 0;
- if (NodePresent_D(Node)) { /*If Node is present */
- dev = pDCTstat->dev_map;
- reg = 0x40+(Node << 3); /* Dram Base Node 0 + index */
- val = Get_NB32(dev, reg);
-
- /* WE/RE is checked */
- if ((val & 3) == 3) { /* Node has dram populated */
- /* Negate 'all nodes/dimms ECC' flag if non ecc
- memory populated */
- if (pDCTstat->Status & (1 << SB_ECCDIMMs)) {
- LDramECC = isDramECCEn_D(pDCTstat);
- if (pDCTstat->ErrCode != SC_RunningOK) {
- pDCTstat->Status &= ~(1 << SB_ECCDIMMs);
- if (!OB_NBECC) {
- pDCTstat->ErrStatus |= (1 << SB_DramECCDis);
- }
- AllECC = 0;
- LDramECC = 0;
- }
- } else {
- AllECC = 0;
- }
- if (LDramECC) { /* if ECC is enabled on this dram */
- if (OB_NBECC) {
- mct_EnableDatIntlv_D(pMCTstat, pDCTstat);
- val = Get_NB32(pDCTstat->dev_dct, 0x110);
- val |= 1 << 5; /* DctDatIntLv = 1 */
- Set_NB32(pDCTstat->dev_dct, 0x110, val);
- dev = pDCTstat->dev_nbmisc;
- reg = 0x44; /* MCA NB Configuration */
- val = Get_NB32(dev, reg);
- val |= 1 << 22; /* EccEn */
- Set_NB32(dev, reg, val);
- DCTMemClr_Init_D(pMCTstat, pDCTstat);
- MemClrECC = 1;
- printk(BIOS_DEBUG, " ECC enabled on node: %02x\n", Node);
- }
- } /* this node has ECC enabled dram */
-
- if (MemClrECC) {
- DCTMemClr_Sync_D(pMCTstat, pDCTstat);
- }
- } else {
- LDramECC = 0;
- } /* Node has Dram */
- } /* if Node present */
- }
-
- if (AllECC)
- pMCTstat->GStatus |= 1 << GSB_ECCDIMMs;
- else
- pMCTstat->GStatus &= ~(1 << GSB_ECCDIMMs);
-
- /* Program the Dram BKScrub CTL to the proper (user selected) value.*/
- /* Reset MC4_STS. */
- for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
- struct DCTStatStruc *pDCTstat;
- pDCTstat = pDCTstatA + Node;
- LDramECC = 0;
- if (NodePresent_D(Node)) { /* If Node is present */
- reg = 0x40+(Node << 3); /* Dram Base Node 0 + index */
- val = Get_NB32(pDCTstat->dev_map, reg);
- curBase = val & 0xffff0000;
- /*WE/RE is checked because memory config may have been */
- if ((val & 3) == 3) { /* Node has dram populated */
- if (isDramECCEn_D(pDCTstat)) { /* if ECC is enabled on this dram */
- dev = pDCTstat->dev_nbmisc;
- val = curBase << 8;
- if (OB_ECCRedir) {
- val |= (1 << 0); /* Enable redirection */
- }
- Set_NB32(dev, 0x5c, val); /* Dram Scrub Addr Low */
- val = curBase >> 24;
- Set_NB32(dev, 0x60, val); /* Dram Scrub Addr High */
-
- /* Set scrub rate controls */
- if (is_fam15h()) {
- /* Erratum 505 */
- fam15h_switch_dct(pDCTstat->dev_map, 0);
- }
- Set_NB32(dev, 0x58, OF_ScrubCTL); /* Scrub Control */
- if (is_fam15h()) {
- fam15h_switch_dct(pDCTstat->dev_map, 1); /* Erratum 505 */
- Set_NB32(dev, 0x58, OF_ScrubCTL); /* Scrub Control */
- fam15h_switch_dct(pDCTstat->dev_map, 0); /* Erratum 505 */
- }
-
- if (!is_fam15h()) {
- /* Divisor should not be set deeper than
- * divide by 16 when Dcache scrubber or
- * L2 scrubber is enabled.
- */
- if ((OF_ScrubCTL & (0x1F << 16)) || (OF_ScrubCTL & (0x1F << 8))) {
- val = Get_NB32(dev, 0x84);
- if ((val & 0xE0000000) > 0x80000000) { /* Get F3x84h[31:29]ClkDivisor for C1 */
- val &= 0x1FFFFFFF; /* If ClkDivisor is deeper than divide-by-16 */
- val |= 0x80000000; /* set it to divide-by-16 */
- Set_NB32(dev, 0x84, val);
- }
- }
- }
-
- if (pDCTstat->LogicalCPUID & (AMD_DR_GT_D0 | AMD_FAM15_ALL)) {
- /* Set up message triggered C1E */
- val = pci_read_config32(pDCTstat->dev_nbmisc, 0xd4);
- val &= ~(0x1 << 15); /* StutterScrubEn = DRAM scrub enabled */
- val |= (mctGet_NVbits(NV_DramBKScrub)?1:0) << 15;
- pci_write_config32(pDCTstat->dev_nbmisc, 0xd4, val);
- }
- } /* this node has ECC enabled dram */
- } /*Node has Dram */
- } /*if Node present */
- }
-
- /* Restore previous MCA error handling settings */
- for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
- struct DCTStatStruc *pDCTstat;
- pDCTstat = pDCTstatA + Node;
-
- if (NodePresent_D(Node)) {
- dev = pDCTstat->dev_map;
- reg = 0x40 + (Node << 3); /* Dram Base Node 0 + index */
- val = Get_NB32(dev, reg);
-
- /* WE/RE is checked */
- if ((val & 0x3) == 0x3) { /* Node has dram populated */
- uint32_t mc4_status_high = pci_read_config32(pDCTstat->dev_nbmisc, 0x4c);
- uint32_t mc4_status_low = pci_read_config32(pDCTstat->dev_nbmisc, 0x48);
- if ((mc4_status_high & (0x1 << 31)) && (mc4_status_high != 0xffffffff)) {
- printk(BIOS_WARNING, "WARNING: MC4 Machine Check Exception detected!\n"
- "Signature: %08x%08x\n", mc4_status_high, mc4_status_low);
- }
-
- /* Clear MC4 error status */
- pci_write_config32(pDCTstat->dev_nbmisc, 0x48, 0x0);
- pci_write_config32(pDCTstat->dev_nbmisc, 0x4c, 0x0);
-
- /* Restore previous MCA error handling settings */
- dword = Get_NB32(pDCTstat->dev_nbmisc, 0x44);
- dword |= (sync_flood_on_dram_err[Node] & 0x1) << 30;
- dword |= (sync_flood_on_any_uc_err[Node] & 0x1) << 21;
- Set_NB32(pDCTstat->dev_nbmisc, 0x44, dword);
- }
- }
- }
-
- if (mctGet_NVbits(NV_SyncOnUnEccEn))
- setSyncOnUnEccEn_D(pMCTstat, pDCTstatA);
-
- mctHookAfterECC();
- for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
- struct DCTStatStruc *pDCTstat;
- pDCTstat = pDCTstatA + Node;
- if (NodePresent_D(Node)) {
- printk(BIOS_DEBUG, "ECCInit: Node %02x\n", Node);
- printk(BIOS_DEBUG, "ECCInit: Status %x\n", pDCTstat->Status);
- printk(BIOS_DEBUG, "ECCInit: ErrStatus %x\n", pDCTstat->ErrStatus);
- printk(BIOS_DEBUG, "ECCInit: ErrCode %x\n", pDCTstat->ErrCode);
- printk(BIOS_DEBUG, "ECCInit: Done\n");
- }
- }
- return MemClrECC;
-}
-
-static void setSyncOnUnEccEn_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstatA)
-{
- u32 Node;
- u32 reg;
- u32 dev;
- u32 val;
-
- for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
- struct DCTStatStruc *pDCTstat;
- pDCTstat = pDCTstatA + Node;
- if (NodePresent_D(Node)) { /* If Node is present*/
- reg = 0x40+(Node << 3); /* Dram Base Node 0 + index*/
- val = Get_NB32(pDCTstat->dev_map, reg);
- /*WE/RE is checked because memory config may have been*/
- if ((val & 3) == 3) { /* Node has dram populated*/
- if (isDramECCEn_D(pDCTstat)) {
- /*if ECC is enabled on this dram*/
- dev = pDCTstat->dev_nbmisc;
- reg = 0x44; /* MCA NB Configuration*/
- val = Get_NB32(dev, reg);
- val |= (1 << SyncOnUcEccEn);
- Set_NB32(dev, reg, val);
- }
- } /* Node has Dram*/
- } /* if Node present*/
- }
-}
-
-static u8 isDramECCEn_D(struct DCTStatStruc *pDCTstat)
-{
- u32 reg;
- u32 val;
- u8 i;
- u32 dev = pDCTstat->dev_dct;
- u8 ch_end;
- u8 isDimmECCEn = 0;
-
- if (pDCTstat->GangedMode) {
- ch_end = 1;
- } else {
- ch_end = 2;
- }
- for (i = 0; i < ch_end; i++) {
- if (pDCTstat->DIMMValidDCT[i] > 0) {
- reg = 0x90; /* Dram Config Low */
- val = Get_NB32_DCT(dev, i, reg);
- if (val & (1 << DimmEcEn)) {
- /* set local flag 'dram ecc capable' */
- isDimmECCEn = 1;
- break;
- }
- }
- }
- return isDimmECCEn;
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mcthdi.c b/src/northbridge/amd/amdmct/mct_ddr3/mcthdi.c
deleted file mode 100644
index c821ec0628..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mcthdi.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
- *
- * 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.
- */
-
-#include <stdint.h>
-#include "mct_d.h"
-#include "mct_d_gcc.h"
-
-void mct_DramInit_Hw_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dct)
-{
- u32 val;
- u32 reg;
- u32 dev = pDCTstat->dev_dct;
-
- /*flag for selecting HW/SW DRAM Init HW DRAM Init */
- reg = 0x90; /*DRAM Configuration Low */
- val = Get_NB32_DCT(dev, dct, reg);
- val |= (1<<InitDram);
- Set_NB32_DCT(dev, dct, reg, val);
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c b/src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c
deleted file mode 100644
index 1ee10608b9..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
- *
- * 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.
- */
-
-#include <arch/cpu.h>
-#include <stdint.h>
-#include <console/console.h>
-#include <string.h>
-#include "mct_d.h"
-#include "mct_d_gcc.h"
-
-static uint8_t is_fam15h(void)
-{
- uint8_t fam15h = 0;
- uint32_t family;
-
- family = cpuid_eax(0x80000001);
- family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);
-
- if (family >= 0x6f)
- /* Family 15h or later */
- fam15h = 1;
-
- return fam15h;
-}
-
-static void SetEccWrDQS_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat)
-{
- u8 ByteLane, DimmNum, OddByte, Addl_Index, Channel;
- u8 EccRef1, EccRef2, EccDQSScale;
- u32 val;
- u16 word;
-
- for (Channel = 0; Channel < 2; Channel ++) {
- for (DimmNum = 0; DimmNum < C_MAX_DIMMS; DimmNum ++) { /* we use DimmNum instead of DimmNumx3 */
- for (ByteLane = 0; ByteLane < 9; ByteLane ++) {
- /* Get RxEn initial value from WrDqs */
- if (ByteLane & 1)
- OddByte = 1;
- else
- OddByte = 0;
- if (ByteLane < 2)
- Addl_Index = 0x30;
- else if (ByteLane < 4)
- Addl_Index = 0x31;
- else if (ByteLane < 6)
- Addl_Index = 0x40;
- else if (ByteLane < 8)
- Addl_Index = 0x41;
- else
- Addl_Index = 0x32;
- Addl_Index += DimmNum * 3;
-
- val = Get_NB32_index_wait_DCT(pDCTstat->dev_dct, Channel, 0x98, Addl_Index);
- if (OddByte)
- val >>= 16;
- /* Save WrDqs to stack for later usage */
- pDCTstat->persistentData.CH_D_B_TxDqs[Channel][DimmNum][ByteLane] = val & 0xFF;
- EccDQSScale = pDCTstat->CH_EccDQSScale[Channel];
- word = pDCTstat->CH_EccDQSLike[Channel];
- if ((word & 0xFF) == ByteLane) EccRef1 = val & 0xFF;
- if (((word >> 8) & 0xFF) == ByteLane) EccRef2 = val & 0xFF;
- }
- }
- }
-}
-
-static void EnableAutoRefresh_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat)
-{
- u32 val;
-
- val = Get_NB32_DCT(pDCTstat->dev_dct, 0, 0x8C);
- val &= ~(1 << DisAutoRefresh);
- Set_NB32_DCT(pDCTstat->dev_dct, 0, 0x8C, val);
-
- val = Get_NB32_DCT(pDCTstat->dev_dct, 1, 0x8C);
- val &= ~(1 << DisAutoRefresh);
- Set_NB32_DCT(pDCTstat->dev_dct, 1, 0x8C, val);
-}
-
-static void DisableAutoRefresh_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat)
-{
- u32 val;
-
- val = Get_NB32_DCT(pDCTstat->dev_dct, 0, 0x8C);
- val |= 1 << DisAutoRefresh;
- Set_NB32_DCT(pDCTstat->dev_dct, 0, 0x8C, val);
-
- val = Get_NB32_DCT(pDCTstat->dev_dct, 1, 0x8C);
- val |= 1 << DisAutoRefresh;
- Set_NB32_DCT(pDCTstat->dev_dct, 1, 0x8C, val);
-}
-
-
-static uint8_t PhyWLPass1(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dct)
-{
- u8 dimm;
- u16 DIMMValid;
- uint8_t status = 0;
- void *DCTPtr;
-
- dct &= 1;
-
- DCTPtr = (void *)(pDCTstat->C_DCTPtr[dct]);
- pDCTstat->DIMMValid = pDCTstat->DIMMValidDCT[dct];
- pDCTstat->CSPresent = pDCTstat->CSPresent_DCT[dct];
-
- if (pDCTstat->GangedMode & 1)
- pDCTstat->CSPresent = pDCTstat->CSPresent_DCT[0];
-
- if (pDCTstat->DIMMValid) {
- DIMMValid = pDCTstat->DIMMValid;
- PrepareC_DCT(pMCTstat, pDCTstat, dct);
- for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm ++) {
- if (DIMMValid & (1 << (dimm << 1))) {
- status |= AgesaHwWlPhase1(pMCTstat, pDCTstat, dct, dimm, FirstPass);
- status |= AgesaHwWlPhase2(pMCTstat, pDCTstat, dct, dimm, FirstPass);
- status |= AgesaHwWlPhase3(pMCTstat, pDCTstat, dct, dimm, FirstPass);
- }
- }
- }
-
- return status;
-}
-
-static uint8_t PhyWLPass2(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t final)
-{
- u8 dimm;
- u16 DIMMValid;
- uint8_t status = 0;
- void *DCTPtr;
-
- dct &= 1;
-
- DCTPtr = (void *)&(pDCTstat->C_DCTPtr[dct]); /* todo: */
- pDCTstat->DIMMValid = pDCTstat->DIMMValidDCT[dct];
- pDCTstat->CSPresent = pDCTstat->CSPresent_DCT[dct];
-
- if (pDCTstat->GangedMode & 1)
- pDCTstat->CSPresent = pDCTstat->CSPresent_DCT[0];
-
- if (pDCTstat->DIMMValid) {
- DIMMValid = pDCTstat->DIMMValid;
- PrepareC_DCT(pMCTstat, pDCTstat, dct);
- pDCTstat->Speed = pDCTstat->DIMMAutoSpeed = pDCTstat->TargetFreq;
- pDCTstat->CASL = pDCTstat->DIMMCASL = pDCTstat->TargetCASL;
- SPD2ndTiming(pMCTstat, pDCTstat, dct);
- if (!is_fam15h()) {
- ProgDramMRSReg_D(pMCTstat, pDCTstat, dct);
- PlatformSpec_D(pMCTstat, pDCTstat, dct);
- fenceDynTraining_D(pMCTstat, pDCTstat, dct);
- }
- Restore_OnDimmMirror(pMCTstat, pDCTstat);
- StartupDCT_D(pMCTstat, pDCTstat, dct);
- Clear_OnDimmMirror(pMCTstat, pDCTstat);
- SetDllSpeedUp_D(pMCTstat, pDCTstat, dct);
- DisableAutoRefresh_D(pMCTstat, pDCTstat);
- for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm ++) {
- if (DIMMValid & (1 << (dimm << 1))) {
- status |= AgesaHwWlPhase1(pMCTstat, pDCTstat, dct, dimm, SecondPass);
- status |= AgesaHwWlPhase2(pMCTstat, pDCTstat, dct, dimm, SecondPass);
- status |= AgesaHwWlPhase3(pMCTstat, pDCTstat, dct, dimm, SecondPass);
- }
- }
- }
-
- return status;
-}
-
-static uint16_t fam15h_next_highest_memclk_freq(uint16_t memclk_freq)
-{
- uint16_t fam15h_next_highest_freq_tab[] = {0, 0, 0, 0, 0x6, 0, 0xa, 0, 0, 0, 0xe, 0, 0, 0, 0x12, 0, 0, 0, 0x16, 0, 0, 0, 0x16};
- return fam15h_next_highest_freq_tab[memclk_freq];
-}
-
-/* Write Levelization Training
- * Algorithm detailed in the Fam10h BKDG Rev. 3.62 section 2.8.9.9.1
- */
-static void WriteLevelization_HW(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstatA, uint8_t Node, uint8_t Pass)
-{
- uint8_t status;
- uint8_t timeout;
- uint16_t final_target_freq;
-
- struct DCTStatStruc *pDCTstat;
- pDCTstat = pDCTstatA + Node;
-
- pDCTstat->C_MCTPtr = &(pDCTstat->s_C_MCTPtr);
- pDCTstat->C_DCTPtr[0] = &(pDCTstat->s_C_DCTPtr[0]);
- pDCTstat->C_DCTPtr[1] = &(pDCTstat->s_C_DCTPtr[1]);
-
- /* Disable auto refresh by configuring F2x[1, 0]8C[DisAutoRefresh] = 1 */
- DisableAutoRefresh_D(pMCTstat, pDCTstat);
-
- /* Disable ZQ calibration short command by F2x[1,0]94[ZqcsInterval]=00b */
- DisableZQcalibration(pMCTstat, pDCTstat);
- PrepareC_MCT(pMCTstat, pDCTstat);
-
- if (pDCTstat->GangedMode & (1 << 0)) {
- pDCTstat->DIMMValidDCT[1] = pDCTstat->DIMMValidDCT[0];
- }
-
- if (Pass == FirstPass) {
- timeout = 0;
- do {
- status = 0;
- timeout++;
- status |= PhyWLPass1(pMCTstat, pDCTstat, 0);
- status |= PhyWLPass1(pMCTstat, pDCTstat, 1);
- if (status)
- printk(BIOS_INFO,
- "%s: Retrying write levelling due to invalid value(s) detected in first phase\n",
- __func__);
- } while (status && (timeout < 8));
- if (status)
- printk(BIOS_INFO,
- "%s: Uncorrectable invalid value(s) detected in first phase of write levelling\n",
- __func__);
- }
-
- if (Pass == SecondPass) {
- if (pDCTstat->TargetFreq > mhz_to_memclk_config(mctGet_NVbits(NV_MIN_MEMCLK))) {
- /* 8.Prepare the memory subsystem for the target MEMCLK frequency.
- * NOTE: BIOS must program both DCTs to the same frequency.
- * NOTE: Fam15h steps the frequency, Fam10h slams the frequency.
- */
- uint8_t global_phy_training_status = 0;
- final_target_freq = pDCTstat->TargetFreq;
-
- while (pDCTstat->Speed != final_target_freq) {
- if (is_fam15h())
- pDCTstat->TargetFreq = fam15h_next_highest_memclk_freq(pDCTstat->Speed);
- else
- pDCTstat->TargetFreq = final_target_freq;
- SetTargetFreq(pMCTstat, pDCTstatA, Node);
- timeout = 0;
- do {
- status = 0;
- timeout++;
- status |= PhyWLPass2(pMCTstat, pDCTstat, 0, (pDCTstat->TargetFreq == final_target_freq));
- status |= PhyWLPass2(pMCTstat, pDCTstat, 1, (pDCTstat->TargetFreq == final_target_freq));
- if (status)
- printk(BIOS_INFO,
- "%s: Retrying write levelling due to invalid value(s) detected in last phase\n",
- __func__);
- } while (status && (timeout < 8));
- global_phy_training_status |= status;
- }
-
- pDCTstat->TargetFreq = final_target_freq;
-
- if (global_phy_training_status)
- printk(BIOS_WARNING,
- "%s: Uncorrectable invalid value(s) detected in second phase of write levelling; "
- "continuing but system may be unstable!\n",
- __func__);
-
- uint8_t dct;
- for (dct = 0; dct < 2; dct++) {
- sDCTStruct *pDCTData = pDCTstat->C_DCTPtr[dct];
- memcpy(pDCTData->WLGrossDelayFinalPass, pDCTData->WLGrossDelayPrevPass, sizeof(pDCTData->WLGrossDelayPrevPass));
- memcpy(pDCTData->WLFineDelayFinalPass, pDCTData->WLFineDelayPrevPass, sizeof(pDCTData->WLFineDelayPrevPass));
- pDCTData->WLCriticalGrossDelayFinalPass = pDCTData->WLCriticalGrossDelayPrevPass;
- }
- }
- }
-
- SetEccWrDQS_D(pMCTstat, pDCTstat);
- EnableAutoRefresh_D(pMCTstat, pDCTstat);
- EnableZQcalibration(pMCTstat, pDCTstat);
-}
-
-void mct_WriteLevelization_HW(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstatA, uint8_t Pass)
-{
- u8 Node;
-
- for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
- struct DCTStatStruc *pDCTstat;
- pDCTstat = pDCTstatA + Node;
-
- if (pDCTstat->NodePresent) {
- mctSMBhub_Init(Node);
- Clear_OnDimmMirror(pMCTstat, pDCTstat);
- WriteLevelization_HW(pMCTstat, pDCTstatA, Node, Pass);
- Restore_OnDimmMirror(pMCTstat, pDCTstat);
- }
- }
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctmtr_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mctmtr_d.c
deleted file mode 100644
index 73370e715b..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctmtr_d.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
- *
- * 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.
- */
-
-#include <stdint.h>
-#include <console/console.h>
-#include <cpu/amd/mtrr.h>
-#include <cpu/x86/mtrr.h>
-
-#include "mct_d.h"
-#include "mct_d_gcc.h"
-
-static void SetMTRRrangeWB_D(u32 Base, u32 *pLimit, u32 *pMtrrAddr);
-static void SetMTRRrange_D(u32 Base, u32 *pLimit, u32 *pMtrrAddr, u16 MtrrType);
-
-void CPUMemTyping_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstatA)
-{
- /* BSP only. Set the fixed MTRRs for common legacy ranges.
- * Set TOP_MEM and TOM2.
- * Set some variable MTRRs with WB Uncacheable type.
- */
-
- u32 Bottom32bIO, Bottom40bIO, Cache32bTOP;
- u32 val;
- u32 addr;
- u32 lo, hi;
-
- /* Set temporary top of memory from Node structure data.
- * Adjust temp top of memory down to accommodate 32-bit IO space.
- * Bottom40bIO = top of memory, right justified 8 bits
- * (defines dram versus IO space type)
- * Bottom32bIO = sub 4GB top of memory, right justified 8 bits
- * (defines dram versus IO space type)
- * Cache32bTOP = sub 4GB top of WB cacheable memory,
- * right justified 8 bits
- */
-
- val = mctGet_NVbits(NV_BottomIO);
- if (val == 0)
- val++;
-
- Bottom32bIO = val << (24-8);
-
- val = pMCTstat->SysLimit + 1;
- if (val <= _4GB_RJ8) {
- Bottom40bIO = 0;
- if (Bottom32bIO >= val)
- Bottom32bIO = val;
- } else {
- Bottom40bIO = val;
- }
-
- Cache32bTOP = Bottom32bIO;
-
- /*======================================================================
- Set default values for CPU registers
- ======================================================================*/
-
- /* NOTE : For coreboot, we don't need to set mtrr enables here because
- they are still enable from cache_as_ram.inc */
-
- addr = MTRR_FIX_64K_00000;
- lo = 0x1E1E1E1E;
- hi = lo;
- _WRMSR(addr, lo, hi); /* 0 - 512K = WB Mem */
- addr = MTRR_FIX_16K_80000;
- _WRMSR(addr, lo, hi); /* 512K - 640K = WB Mem */
-
- /*======================================================================
- Set variable MTRR values
- ======================================================================*/
- /* NOTE: for coreboot change from 0x200 to 0x204: coreboot is using
- 0x200, 0x201 for [1M, CONFIG_TOP_MEM)
- 0x202, 0x203 for ROM Caching
- */
- addr = MTRR_PHYS_BASE(2); /* MTRR phys base 2*/
- /* use TOP_MEM as limit*/
- /* Limit = TOP_MEM|TOM2*/
- /* Base = 0*/
- printk(BIOS_DEBUG, "\t CPUMemTyping: Cache32bTOP:%x\n", Cache32bTOP);
- SetMTRRrangeWB_D(0, &Cache32bTOP, &addr);
- /* Base */
- /* Limit */
- /* MtrrAddr */
- if (addr == -1) /* ran out of MTRRs?*/
- pMCTstat->GStatus |= 1<<GSB_MTRRshort;
-
- pMCTstat->Sub4GCacheTop = Cache32bTOP<<8;
-
- /*======================================================================
- Set TOP_MEM and TOM2 CPU registers
- ======================================================================*/
- addr = TOP_MEM;
- lo = Bottom32bIO<<8;
- hi = Bottom32bIO>>24;
- _WRMSR(addr, lo, hi);
- printk(BIOS_DEBUG, "\t CPUMemTyping: Bottom32bIO:%x\n", Bottom32bIO);
- printk(BIOS_DEBUG, "\t CPUMemTyping: Bottom40bIO:%x\n", Bottom40bIO);
- if (Bottom40bIO) {
- hi = Bottom40bIO >> 24;
- lo = Bottom40bIO << 8;
- addr += 3; /* TOM2 */
- _WRMSR(addr, lo, hi);
- }
- addr = SYSCFG_MSR; /* SYS_CFG */
- _RDMSR(addr, &lo, &hi);
- if (Bottom40bIO) {
- lo |= SYSCFG_MSR_TOM2En; /* MtrrTom2En = 1 */
- lo |= SYSCFG_MSR_TOM2WB; /* Tom2ForceMemTypeWB */
- } else {
- lo &= ~SYSCFG_MSR_TOM2En; /* MtrrTom2En = 0 */
- lo &= ~SYSCFG_MSR_TOM2WB; /* Tom2ForceMemTypeWB */
- }
- _WRMSR(addr, lo, hi);
-}
-
-static void SetMTRRrangeWB_D(u32 Base, u32 *pLimit, u32 *pMtrrAddr)
-{
- /*set WB type*/
- SetMTRRrange_D(Base, pLimit, pMtrrAddr, 6);
-}
-
-static void SetMTRRrange_D(u32 Base, u32 *pLimit, u32 *pMtrrAddr, u16 MtrrType)
-{
- /* Program MTRRs to describe given range as given cache type.
- * Use MTRR pairs starting with the given MTRRphys Base address,
- * and use as many as is required up to (excluding) MSR 020C, which
- * is reserved for OS.
- *
- * "Limit" in the context of this procedure is not the numerically
- * correct limit, but rather the Last address+1, for purposes of coding
- * efficiency and readability. Size of a region is then Limit-Base.
- *
- * 1. Size of each range must be a power of two
- * 2. Each range must be naturally aligned (Base is same as size)
- *
- * There are two code paths: the ascending path and descending path
- * (analogous to bsf and bsr), where the next limit is a function of the
- * next set bit in a forward or backward sequence of bits (as a function
- * of the Limit). We start with the ascending path, to ensure that
- * regions are naturally aligned, then we switch to the descending path
- * to maximize MTRR usage efficiency. Base = 0 is a special case where we
- * start with the descending path. Correct Mask for region is
- * 2comp(Size-1)-1, which is 2comp(Limit-Base-1)-1
- */
-
- u32 curBase, curLimit, curSize;
- u32 val, valx;
- u32 addr;
-
- val = curBase = Base;
- curLimit = *pLimit;
- addr = *pMtrrAddr;
- while ((addr >= 0x200) && (addr < 0x20C) && (val < *pLimit)) {
- /* start with "ascending" code path */
- /* alignment (largest block size)*/
- valx = 1 << bsf(curBase);
- curSize = valx;
-
- /* largest legal limit, given current non-zero range Base*/
- valx += curBase;
- if ((curBase == 0) || (*pLimit < valx)) {
- /* flop direction to "descending" code path*/
- valx = 1<<bsr(*pLimit - curBase);
- curSize = valx;
- valx += curBase;
- }
- curLimit = valx; /*eax = curBase, edx = curLimit*/
- valx = val>>24;
- val <<= 8;
-
- /* now program the MTRR */
- val |= MtrrType; /* set cache type (UC or WB)*/
- _WRMSR(addr, val, valx); /* prog. MTRR with current region Base*/
- val = ((~(curSize - 1))+1) - 1; /* Size-1*/ /*Mask = 2comp(Size-1)-1*/
- valx = (val >> 24) | (0xff00); /* GH have 48 bits addr */
- val <<= 8;
- val |= (1 << 11); /* set MTRR valid*/
- addr++;
- _WRMSR(addr, val, valx); /* prog. MTRR with current region Mask*/
- val = curLimit;
- curBase = val; /* next Base = current Limit (loop exit)*/
- addr++; /* next MTRR pair addr */
- }
- if (val < *pLimit) {
- *pLimit = val;
- addr = -1;
- }
- *pMtrrAddr = addr;
-}
-
-void UMAMemTyping_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA)
-{
- /* UMA memory size may need splitting the MTRR configuration into two
- * Before training use NB_BottomIO or the physical memory size to set the MTRRs.
- * After training, add UMAMemTyping function to reconfigure the MTRRs based on
- * NV_BottomUMA (for UMA systems only).
- * This two-step process allows all memory to be cached for training
- */
-
- u32 Bottom32bIO, Cache32bTOP;
- u32 val;
- u32 addr;
- u32 lo, hi;
-
- /*======================================================================
- * Adjust temp top of memory down to accommodate UMA memory start
- *======================================================================*/
- /* Bottom32bIO = sub 4GB top of memory, right justified 8 bits
- * (defines dram versus IO space type)
- * Cache32bTOP = sub 4GB top of WB cacheable memory, right justified 8 bits */
-
- Bottom32bIO = pMCTstat->Sub4GCacheTop >> 8;
-
- val = mctGet_NVbits(NV_BottomUMA);
- if (val == 0)
- val++;
-
- val <<= (24-8);
- if (val < Bottom32bIO) {
- Cache32bTOP = val;
- pMCTstat->Sub4GCacheTop = val;
-
- /*======================================================================
- * Clear variable MTRR values
- *======================================================================*/
- addr = MTRR_PHYS_BASE(0);
- lo = 0;
- hi = lo;
- while (addr < MTRR_PHYS_BASE(6)) {
- _WRMSR(addr, lo, hi); /* prog. MTRR with current region Mask */
- addr++; /* next MTRR pair addr */
- }
-
- /*======================================================================
- * Set variable MTRR values
- *======================================================================*/
- printk(BIOS_DEBUG, "\t UMAMemTyping_D: Cache32bTOP:%x\n", Cache32bTOP);
- SetMTRRrangeWB_D(0, &Cache32bTOP, &addr);
- if (addr == -1) /* ran out of MTRRs?*/
- pMCTstat->GStatus |= 1<<GSB_MTRRshort;
- }
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctndi_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mctndi_d.c
deleted file mode 100644
index 29949e02d4..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctndi_d.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
- *
- * 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.
- */
-
-#include <stdint.h>
-#include <console/console.h>
-
-#include "mct_d.h"
-#include "mct_d_gcc.h"
-
-void InterleaveNodes_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstatA)
-{
- /* Applies Node memory interleaving if enabled and if all criteria are met. */
- u8 Node;
- u32 Base;
- u32 MemSize, MemSize0 = 0;
- u32 Dct0MemSize = 0, DctSelBase, DctSelBaseOffset = 0;
- u8 Nodes;
- u8 NodesWmem;
- u8 DoIntlv;
- u8 _NdIntCap;
- u8 _SWHole;
- u32 HWHoleSz;
- u32 DramHoleAddrReg;
- u32 HoleBase;
- u32 dev0;
- u32 reg0;
- u32 val;
- u8 i;
- struct DCTStatStruc *pDCTstat;
-
- DoIntlv = mctGet_NVbits(NV_NodeIntlv);
-
- _NdIntCap = 0;
- HWHoleSz = 0; /*For HW remapping, NOT Node hoisting. */
-
- pDCTstat = pDCTstatA + 0;
- dev0 = pDCTstat->dev_host;
- Nodes = ((Get_NB32(dev0, 0x60) >> 4) & 0x7) + 1;
-
- dev0 = pDCTstat->dev_map;
- reg0 = 0x40;
-
- NodesWmem = 0;
- Node = 0;
-
- while (DoIntlv && (Node < Nodes)) {
- pDCTstat = pDCTstatA + Node;
- if (pMCTstat->GStatus & (1 << GSB_SpIntRemapHole)) {
- pMCTstat->GStatus |= 1 << GSB_HWHole;
- _SWHole = 0;
- } else if (pDCTstat->Status & (1 << SB_SWNodeHole)) {
- _SWHole = 1;
- } else {
- _SWHole = 0;
- }
-
- if (!_SWHole) {
- Base = Get_NB32(dev0, reg0);
- if (Base & 1) {
- NodesWmem++;
- Base &= 0xFFFF0000; /* Base[39:8] */
-
- if (pDCTstat->Status & (1 << SB_HWHole)) {
-
- /* to get true amount of dram,
- * subtract out memory hole if HW dram remapping */
- DramHoleAddrReg = Get_NB32(pDCTstat->dev_map, 0xF0);
- HWHoleSz = DramHoleAddrReg >> 16;
- HWHoleSz = (((~HWHoleSz) + 1) & 0xFF);
- HWHoleSz <<= 24-8;
- }
- /* check to see if the amount of memory on each channel
- * are the same on all nodes */
-
- DctSelBase = Get_NB32(pDCTstat->dev_dct, 0x114);
- if (DctSelBase) {
- DctSelBase <<= 8;
- if (pDCTstat->Status & (1 << SB_HWHole)) {
- if (DctSelBase >= 0x1000000) {
- DctSelBase -= HWHoleSz;
- }
- }
- DctSelBaseOffset -= Base;
- if (Node == 0) {
- Dct0MemSize = DctSelBase;
- } else if (DctSelBase != Dct0MemSize) {
- break;
- }
- }
-
- MemSize = Get_NB32(dev0, reg0 + 4);
- MemSize &= 0xFFFF0000;
- MemSize += 0x00010000;
- MemSize -= Base;
- if (pDCTstat->Status & (1 << SB_HWHole)) {
- MemSize -= HWHoleSz;
- }
- if (Node == 0) {
- MemSize0 = MemSize;
- } else if (MemSize0 != MemSize) {
- break;
- }
- } else {
- break;
- }
- } else {
- break;
- }
- Node++;
- reg0 += 8;
- }
-
- if (Node == Nodes) {
- /* if all nodes have memory and no Node had SW memhole */
- if (Nodes == 2 || Nodes == 4 || Nodes == 8)
- _NdIntCap = 1;
- }
-
- if (!_NdIntCap)
- DoIntlv = 0;
-
- if (pMCTstat->GStatus & 1 << (GSB_SpIntRemapHole)) {
- HWHoleSz = pMCTstat->HoleBase;
- if (HWHoleSz == 0) {
- HWHoleSz = mctGet_NVbits(NV_BottomIO) & 0xFF;
- HWHoleSz <<= 24-8;
- }
- HWHoleSz = ((~HWHoleSz) + 1) & 0x00FF0000;
- }
-
- if (DoIntlv) {
- MCTMemClr_D(pMCTstat, pDCTstatA);
- /* Program Interleaving enabled on Node 0 map only.*/
- MemSize0 <<= bsf(Nodes); /* MemSize = MemSize*2 (or 4, or 8) */
- Dct0MemSize <<= bsf(Nodes);
- MemSize0 += HWHoleSz;
- Base = ((Nodes - 1) << 8) | 3;
- reg0 = 0x40;
- Node = 0;
- while (Node < Nodes) {
- Set_NB32(dev0, reg0, Base);
- MemSize = MemSize0;
- MemSize--;
- MemSize &= 0xFFFF0000;
- MemSize |= Node << 8; /* set IntlvSel[2:0] field */
- MemSize |= Node; /* set DstNode[2:0] field */
- Set_NB32(dev0, reg0 + 4, MemSize0);
- reg0 += 8;
- Node++;
- }
-
- /* set base/limit to F1x120/124 per Node */
- Node = 0;
- while (Node < Nodes) {
- pDCTstat = pDCTstatA + Node;
- pDCTstat->NodeSysBase = 0;
- MemSize = MemSize0;
- MemSize -= HWHoleSz;
- MemSize--;
- pDCTstat->NodeSysLimit = MemSize;
- Set_NB32(pDCTstat->dev_map, 0x120, Node << 21);
- MemSize = MemSize0;
- MemSize--;
- MemSize >>= 19;
- val = Base;
- val &= 0x700;
- val <<= 13;
- val |= MemSize;
- Set_NB32(pDCTstat->dev_map, 0x124, val);
-
- if (pMCTstat->GStatus & (1 << GSB_HWHole)) {
- HoleBase = pMCTstat->HoleBase;
- if (Dct0MemSize >= HoleBase) {
- val = HWHoleSz;
- if (Node == 0) {
- val += Dct0MemSize;
- }
- } else {
- val = HWHoleSz + Dct0MemSize;
- }
-
- val >>= 8; /* DramHoleOffset */
- HoleBase <<= 8; /* DramHoleBase */
- val |= HoleBase;
- val |= 1 << DramMemHoistValid;
- val |= 1 << DramHoleValid;
- Set_NB32(pDCTstat->dev_map, 0xF0, val);
- }
-
- Set_NB32(pDCTstat->dev_dct, 0x114, Dct0MemSize >> 8); /* DctSelBaseOffset */
- val = Get_NB32(pDCTstat->dev_dct, 0x110);
- val &= 0x7FF;
- val |= Dct0MemSize >> 8;
- Set_NB32(pDCTstat->dev_dct, 0x110, val); /* DctSelBaseAddr */
- printk(BIOS_DEBUG, "InterleaveNodes: DRAM Controller Select Low Register = %x\n", val);
- Node++;
- }
-
- /* Copy Node 0 into other Nodes' CSRs */
- Node = 1;
- while (Node < Nodes) {
- pDCTstat = pDCTstatA + Node;
-
- for (i = 0x40; i <= 0x80; i++) {
- val = Get_NB32(dev0, i);
- Set_NB32(pDCTstat->dev_map, i, val);
- }
-
- val = Get_NB32(dev0, 0xF0);
- Set_NB32(pDCTstat->dev_map, 0xF0, val);
- Node++;
- }
- pMCTstat->GStatus = (1 << GSB_NodeIntlv);
- }
- printk(BIOS_DEBUG, "InterleaveNodes_D: Status %x\n", pDCTstat->Status);
- printk(BIOS_DEBUG, "InterleaveNodes_D: ErrStatus %x\n", pDCTstat->ErrStatus);
- printk(BIOS_DEBUG, "InterleaveNodes_D: ErrCode %x\n", pDCTstat->ErrCode);
- printk(BIOS_DEBUG, "InterleaveNodes_D: Done\n\n");
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctprob.c b/src/northbridge/amd/amdmct/mct_ddr3/mctprob.c
deleted file mode 100644
index 3cb75675df..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctprob.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * 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.
- */
-
-#include <stdint.h>
-
-#include "mct_d.h"
-#include "mct_d_gcc.h"
-
-void mct_BeforeDQSTrainSamp(struct DCTStatStruc *pDCTstat)
-{
- u32 val;
-
- if (pDCTstat->LogicalCPUID & AMD_DR_Bx) {
- Set_NB32(pDCTstat->dev_dct, 0x98, 0x0D004007);
- val = Get_NB32(pDCTstat->dev_dct, 0x9C);
- val |= 0x3FF;
- Set_NB32(pDCTstat->dev_dct, 0x9C, val);
- Set_NB32(pDCTstat->dev_dct, 0x98, 0x4D0F4F07);
-
- Set_NB32(pDCTstat->dev_dct, 0x198, 0x0D004007);
- val = Get_NB32(pDCTstat->dev_dct, 0x19C);
- val |= 0x3FF;
- Set_NB32(pDCTstat->dev_dct, 0x19C, val);
- Set_NB32(pDCTstat->dev_dct, 0x198, 0x4D0F4F07);
- }
-}
-
-void mct_ExtMCTConfig_Bx(struct DCTStatStruc *pDCTstat)
-{
- if (pDCTstat->LogicalCPUID & (AMD_DR_Bx)) {
- Set_NB32(pDCTstat->dev_dct, 0x11C, 0x0FE40FC0 | 1 << 29/* FlushWrOnStpGnt */);
- }
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctproc.c b/src/northbridge/amd/amdmct/mct_ddr3/mctproc.c
deleted file mode 100644
index ddaaaab8d5..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctproc.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
- *
- * 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.
- */
-
-#include <stdint.h>
-
-#include "mct_d.h"
-#include "mct_d_gcc.h"
-
-/* mct_SetDramConfigMisc2_Cx & mct_SetDramConfigMisc2_Dx */
-u32 mct_SetDramConfigMisc2(struct DCTStatStruc *pDCTstat,
- uint8_t dct, uint32_t misc2, uint32_t DramControl)
-{
- u32 val;
-
- uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH);
-
- if (pDCTstat->LogicalCPUID & AMD_FAM15_ALL) {
- uint8_t cs_mux_45;
- uint8_t cs_mux_67;
- uint32_t f2x80;
-
- misc2 &= ~(0x1 << 28); /* FastSelfRefEntryDis = 0x0 */
- if (MaxDimmsInstallable == 3) {
- /* FIXME 3 DIMMS per channel unimplemented */
- cs_mux_45 = 0;
- } else {
- uint32_t f2x60 = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x60);
- f2x80 = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x80);
- if ((((f2x80 & 0xf) == 0x7) || ((f2x80 & 0xf) == 0x9))
- && ((f2x60 & 0x3) == 0x3))
- cs_mux_45 = 1;
- else if ((((f2x80 & 0xf) == 0xa) || ((f2x80 & 0xf) == 0xb))
- && ((f2x60 & 0x3) > 0x1))
- cs_mux_45 = 1;
- else
- cs_mux_45 = 0;
- }
-
- if (MaxDimmsInstallable == 1) {
- cs_mux_67 = 0;
- } else if (MaxDimmsInstallable == 2) {
- uint32_t f2x64 = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x64);
- f2x80 = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x80);
- if (((((f2x80 >> 4) & 0xf) == 0x7) || (((f2x80 >> 4) & 0xf) == 0x9))
- && ((f2x64 & 0x3) == 0x3))
- cs_mux_67 = 1;
- else if (((((f2x80 >> 4) & 0xf) == 0xa) || (((f2x80 >> 4) & 0xf) == 0xb))
- && ((f2x64 & 0x3) > 0x1))
- cs_mux_67 = 1;
- else
- cs_mux_67 = 0;
- } else {
- /* FIXME 3 DIMMS per channel unimplemented */
- cs_mux_67 = 0;
- }
-
- misc2 &= ~(0x1 << 27); /* CsMux67 = cs_mux_67 */
- misc2 |= ((cs_mux_67 & 0x1) << 27);
- misc2 &= ~(0x1 << 26); /* CsMux45 = cs_mux_45 */
- misc2 |= ((cs_mux_45 & 0x1) << 26);
- } else if (pDCTstat->LogicalCPUID & (AMD_DR_Dx | AMD_DR_Cx)) {
- if (pDCTstat->Status & (1 << SB_Registered)) {
- misc2 |= 1 << SubMemclkRegDly;
- if (mctGet_NVbits(NV_MAX_DIMMS) == 8)
- misc2 |= 1 << Ddr3FourSocketCh;
- else
- misc2 &= ~(1 << Ddr3FourSocketCh);
- }
-
- if (pDCTstat->LogicalCPUID & AMD_DR_Cx)
- misc2 |= 1 << OdtSwizzle;
-
- val = DramControl;
- val &= 7;
- val = ((~val) & 0xff) + 1;
- val += 6;
- val &= 0x7;
- misc2 &= 0xfff8ffff;
- misc2 |= val << 16; /* DataTxFifoWrDly */
- if (pDCTstat->LogicalCPUID & AMD_DR_Dx)
- misc2 |= 1 << 7; /* ProgOdtEn */
- }
- return misc2;
-}
-
-void mct_ExtMCTConfig_Cx(struct DCTStatStruc *pDCTstat)
-{
- u32 val;
-
- if (pDCTstat->LogicalCPUID & (AMD_DR_Cx)) {
- /* Revision C */
- Set_NB32(pDCTstat->dev_dct, 0x11c, 0x0ce00fc0 | 1 << 29/* FlushWrOnStpGnt */);
-
- val = Get_NB32(pDCTstat->dev_dct, 0x1b0);
- val &= ~0x73f;
- val |= 0x101; /* BKDG recommended settings */
-
- Set_NB32(pDCTstat->dev_dct, 0x1b0, val);
- }
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctprod.c b/src/northbridge/amd/amdmct/mct_ddr3/mctprod.c
deleted file mode 100644
index b203942058..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctprod.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
- * 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.
- */
-
-#include <stdint.h>
-
-#include "mct_d.h"
-#include "mct_d_gcc.h"
-
-void mct_ExtMCTConfig_Dx(struct DCTStatStruc *pDCTstat)
-{
- uint32_t dword;
-
- if (pDCTstat->LogicalCPUID & AMD_DR_Dx) {
- dword = 0x0ce00f00 | 0x1 << 29; /* FlushWrOnStpGnt */
- if (!(pDCTstat->GangedMode))
- dword |= 0x18 << 2; /* MctWrLimit = 0x18 for unganged mode */
- else
- dword |= 0x10 << 2; /* MctWrLimit = 0x10 for ganged mode */
- Set_NB32(pDCTstat->dev_dct, 0x11c, dword);
-
- dword = Get_NB32(pDCTstat->dev_dct, 0x1b0);
- dword &= ~0x3; /* AdapPrefMissRatio = 0x1 */
- dword |= 0x1;
- dword &= ~(0x3 << 2); /* AdapPrefPositiveStep = 0x0 */
- dword &= ~(0x3 << 4); /* AdapPrefNegativeStep = 0x0 */
- dword &= ~(0x7 << 8); /* CohPrefPrbLmt = 0x1 */
- dword |= (0x1 << 8);
- dword |= (0x7 << 22); /* PrefFourConf = 0x7 */
- dword |= (0x7 << 25); /* PrefFiveConf = 0x7 */
-
- if (!(pDCTstat->GangedMode))
- dword |= (0x1 << 12); /* EnSplitDctLimits = 0x1 */
- else
- dword &= ~(0x1 << 12); /* EnSplitDctLimits = 0x0 */
-
- dword &= ~(0xf << 28); /* DcqBwThrotWm = ... */
- switch (pDCTstat->Speed) {
- case 4:
- dword |= (0x5 << 28); /* ...5 for DDR800 */
- break;
- case 5:
- dword |= (0x6 << 28); /* ...6 for DDR1066 */
- break;
- case 6:
- dword |= (0x8 << 28); /* ...8 for DDR800 */
- break;
- default:
- dword |= (0x9 << 28); /* ...9 for DDR1600 */
- break;
- }
- Set_NB32(pDCTstat->dev_dct, 0x1b0, dword);
- }
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c b/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c
deleted file mode 100644
index 93cfb4bf1b..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- * Copyright (C) 2015 - 2016 Raptor Engineering, LLC
- *
- * 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.
- */
-
-#include <arch/cpu.h>
-#include <stdint.h>
-#include <console/console.h>
-
-#include "mct_d.h"
-#include "mct_d_gcc.h"
-
-static uint8_t is_fam15h(void)
-{
- uint8_t fam15h = 0;
- uint32_t family;
-
- family = cpuid_eax(0x80000001);
- family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);
-
- if (family >= 0x6f)
- /* Family 15h or later */
- fam15h = 1;
-
- return fam15h;
-}
-
-static uint8_t fam15h_rdimm_rc2_ibt_code(struct DCTStatStruc *pDCTstat, uint8_t dct)
-{
- uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH);
-
- uint8_t package_type;
- uint8_t control_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];
-
- /* FIXME
- * Assume there is only one register on the RDIMM for now
- */
- uint8_t num_registers = 1;
-
- if (package_type == PT_GR) {
- /* Socket G34 */
- /* Fam15h BKDG Rev. 3.14 section 2.10.5.7.1.2.1 Table 85 */
- if (MaxDimmsInstallable == 1) {
- if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) {
- /* DDR3-667 - DDR3-800 */
- control_code = 0x1;
- } else if ((MemClkFreq == 0xa) || (MemClkFreq == 0xe)) {
- /* DDR3-1066 - DDR3-1333 */
- if (num_registers == 1) {
- control_code = 0x0;
- } else {
- control_code = 0x1;
- }
- } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) {
- /* DDR3-1600 - DDR3-1866 */
- control_code = 0x0;
- }
- } else if (MaxDimmsInstallable == 2) {
- if (dimm_count == 1) {
- /* 1 DIMM detected */
- if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) {
- /* DDR3-667 - DDR3-800 */
- control_code = 0x1;
- } else if ((MemClkFreq >= 0xa) && (MemClkFreq <= 0x12)) {
- /* DDR3-1066 - DDR3-1600 */
- if (num_registers == 1) {
- control_code = 0x0;
- } else {
- control_code = 0x1;
- }
- }
- } else if (dimm_count == 2) {
- /* 2 DIMMs detected */
- if (num_registers == 1) {
- control_code = 0x1;
- } else {
- control_code = 0x8;
- }
- }
- } else if (MaxDimmsInstallable == 3) {
- /* TODO
- * 3 DIMM/channel support unimplemented
- */
- }
- } else if (package_type == PT_C3) {
- /* Socket C32 */
- /* Fam15h BKDG Rev. 3.14 section 2.10.5.7.1.2.1 Table 86 */
- if (MaxDimmsInstallable == 1) {
- if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) {
- /* DDR3-667 - DDR3-800 */
- control_code = 0x1;
- } else if ((MemClkFreq == 0xa) || (MemClkFreq == 0xe)) {
- /* DDR3-1066 - DDR3-1333 */
- if (num_registers == 1) {
- control_code = 0x0;
- } else {
- control_code = 0x1;
- }
- } else if ((MemClkFreq == 0x12) || (MemClkFreq == 0x16)) {
- /* DDR3-1600 - DDR3-1866 */
- control_code = 0x0;
- }
- } else if (MaxDimmsInstallable == 2) {
- if (dimm_count == 1) {
- /* 1 DIMM detected */
- if ((MemClkFreq == 0x4) || (MemClkFreq == 0x6)) {
- /* DDR3-667 - DDR3-800 */
- control_code = 0x1;
- } else if ((MemClkFreq >= 0xa) && (MemClkFreq <= 0x12)) {
- /* DDR3-1066 - DDR3-1600 */
- if (num_registers == 1) {
- control_code = 0x0;
- } else {
- control_code = 0x1;
- }
- }
- } else if (dimm_count == 2) {
- /* 2 DIMMs detected */
- if (num_registers == 1) {
- control_code = 0x1;
- } else {
- control_code = 0x8;
- }
- }
- } else if (MaxDimmsInstallable == 3) {
- /* TODO
- * 3 DIMM/channel support unimplemented
- */
- }
- } else {
- /* TODO
- * Other socket support unimplemented
- */
- }
-
- printk(BIOS_SPEW, "%s: DCT %d IBT code: %01x\n", __func__, dct, control_code);
- return control_code;
-}
-
-static uint16_t memclk_to_freq(uint16_t memclk) {
- uint16_t fam10h_freq_tab[] = {0, 0, 0, 400, 533, 667, 800};
- 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 mem_freq = 0;
-
- if (is_fam15h()) {
- if (memclk < 0x17) {
- mem_freq = fam15h_freq_tab[memclk];
- }
- } else {
- if ((memclk > 0x0) && (memclk < 0x8)) {
- mem_freq = fam10h_freq_tab[memclk - 1];
- }
- }
-
- return mem_freq;
-}
-
-static uint8_t rc_word_chip_select_lower_bit(void) {
- if (is_fam15h()) {
- return 21;
- } else {
- return 20;
- }
-}
-
-static uint32_t rc_word_address_to_ctl_bits(uint32_t address) {
- if (is_fam15h()) {
- return (((address >> 3) & 0x1) << 2) << 18 | (address & 0x7);
- } else {
- return (((address >> 3) & 0x1) << 2) << 16 | (address & 0x7);
- }
-}
-
-static uint32_t rc_word_value_to_ctl_bits(uint32_t value) {
- if (is_fam15h()) {
- return ((value >> 2) & 0x3) << 18 | ((value & 0x3) << 3);
- } else {
- return ((value >> 2) & 0x3) << 16 | ((value & 0x3) << 3);
- }
-}
-
-static u32 mct_ControlRC(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, uint8_t dct, u32 MrsChipSel, u32 CtrlWordNum)
-{
- u8 Dimms, DimmNum;
- u32 val;
- uint8_t ddr_voltage_index;
- uint16_t mem_freq;
- uint8_t package_type = mctGet_NVbits(NV_PACK_TYPE);
- uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH);
-
- DimmNum = (MrsChipSel >> rc_word_chip_select_lower_bit()) & 0x7;
-
- if (dct == 1)
- DimmNum++;
-
- mem_freq = memclk_to_freq(pDCTstat->DIMMAutoSpeed);
- Dimms = pDCTstat->MAdimms[dct];
-
- ddr_voltage_index = dct_ddr_voltage_index(pDCTstat, dct);
-
- val = 0;
- if (CtrlWordNum == 0)
- val = 0x2;
- else if (CtrlWordNum == 1) {
- if (!((pDCTstat->DimmDRPresent | pDCTstat->DimmQRPresent) & (1 << DimmNum)))
- val = 0xc; /* if single rank, set DBA1 and DBA0 */
- } else if (CtrlWordNum == 2) {
- if (is_fam15h()) {
- val = (fam15h_rdimm_rc2_ibt_code(pDCTstat, dct) & 0x1) << 2;
- } else {
- if (package_type == PT_GR) {
- /* Socket G34 */
- if (MaxDimmsInstallable == 2) {
- if (Dimms > 1)
- val = 0x4;
- }
- }
- else if (package_type == PT_C3) {
- /* Socket C32 */
- if (MaxDimmsInstallable == 2) {
- if (Dimms > 1)
- val = 0x4;
- }
- }
- }
- } else if (CtrlWordNum == 3) {
- val = (pDCTstat->CtrlWrd3 >> (DimmNum << 2)) & 0xff;
- } else if (CtrlWordNum == 4) {
- val = (pDCTstat->CtrlWrd4 >> (DimmNum << 2)) & 0xff;
- } else if (CtrlWordNum == 5) {
- val = (pDCTstat->CtrlWrd5 >> (DimmNum << 2)) & 0xff;
- } else if (CtrlWordNum == 6) {
- val = ((pDCTstat->spd_data.spd_bytes[DimmNum][72] & 0xf) >> (DimmNum << 2)) & 0xff;
- } else if (CtrlWordNum == 7) {
- val = (((pDCTstat->spd_data.spd_bytes[DimmNum][72] >> 4) & 0xf) >> (DimmNum << 2)) & 0xff;
- } else if (CtrlWordNum == 8) {
- if (is_fam15h()) {
- val = (fam15h_rdimm_rc2_ibt_code(pDCTstat, dct) & 0xe) >> 1;
- } else {
- if (package_type == PT_GR) {
- /* Socket G34 */
- if (MaxDimmsInstallable == 2) {
- val = 0x0;
- }
- }
- else if (package_type == PT_C3) {
- /* Socket C32 */
- if (MaxDimmsInstallable == 2) {
- val = 0x0;
- }
- }
- }
- } else if (CtrlWordNum == 9) {
- val = 0xd; /* DBA1, DBA0, DA3 = 0 */
- } else if (CtrlWordNum == 10) {
- val = 0x0; /* Lowest operating frequency */
- } else if (CtrlWordNum == 11) {
- if (ddr_voltage_index & 0x4)
- val = 0x2; /* 1.25V */
- else if (ddr_voltage_index & 0x2)
- val = 0x1; /* 1.35V */
- else
- val = 0x0; /* 1.5V */
- } else if (CtrlWordNum == 12) {
- val = ((pDCTstat->spd_data.spd_bytes[DimmNum][75] & 0xf) >> (DimmNum << 2)) & 0xff;
- } else if (CtrlWordNum == 13) {
- val = (((pDCTstat->spd_data.spd_bytes[DimmNum][75] >> 4) & 0xf) >> (DimmNum << 2)) & 0xff;
- } else if (CtrlWordNum == 14) {
- val = ((pDCTstat->spd_data.spd_bytes[DimmNum][76] & 0xf) >> (DimmNum << 2)) & 0xff;
- } else if (CtrlWordNum == 15) {
- val = (((pDCTstat->spd_data.spd_bytes[DimmNum][76] >> 4) & 0xf) >> (DimmNum << 2)) & 0xff;
- }
- val &= 0xf;
-
- printk(BIOS_SPEW, "%s: Preparing to send DCT %d DIMM %d RC%d: %02x\n", __func__, dct, DimmNum >> 1, CtrlWordNum, val);
-
- val = MrsChipSel | rc_word_value_to_ctl_bits(val);
- val |= rc_word_address_to_ctl_bits(CtrlWordNum);
-
- return val;
-}
-
-static void mct_SendCtrlWrd(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, uint8_t dct, uint32_t val)
-{
- u32 dev = pDCTstat->dev_dct;
-
- val |= Get_NB32_DCT(dev, dct, 0x7c) & ~0xffffff;
- val |= 1 << SendControlWord;
- Set_NB32_DCT(dev, dct, 0x7c, val);
-
- do {
- val = Get_NB32_DCT(dev, dct, 0x7c);
- } while (val & (1 << SendControlWord));
-}
-
-void mct_DramControlReg_Init_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, uint8_t dct)
-{
- u8 MrsChipSel;
- u32 dev = pDCTstat->dev_dct;
- u32 val, cw;
-
- printk(BIOS_SPEW, "%s: Start\n", __func__);
-
- if (!is_fam15h()) {
- mct_Wait(1600);
- mct_Wait(1200);
- }
-
- pDCTstat->CSPresent = pDCTstat->CSPresent_DCT[dct];
- if (pDCTstat->GangedMode & 1)
- pDCTstat->CSPresent = pDCTstat->CSPresent_DCT[0];
-
- for (MrsChipSel = 0; MrsChipSel < 8; MrsChipSel += 2) {
- if (pDCTstat->CSPresent & (1 << MrsChipSel)) {
- val = Get_NB32_DCT(dev, dct, 0xa8);
- val &= ~(0xff << 8);
-
- switch (MrsChipSel) {
- case 0:
- case 1:
- val |= 3 << 8;
- break;
- case 2:
- case 3:
- val |= (3 << 2) << 8;
- break;
- case 4:
- case 5:
- val |= (3 << 4) << 8;
- break;
- case 6:
- case 7:
- val |= (3 << 6) << 8;
- break;
- }
- Set_NB32_DCT(dev, dct, 0xa8, val);
- printk(BIOS_SPEW, "%s: F2xA8: %08x\n", __func__, val);
-
- if (is_fam15h()) {
- for (cw = 0; cw <=15; cw ++) {
- val = mct_ControlRC(pMCTstat, pDCTstat, dct, MrsChipSel << rc_word_chip_select_lower_bit(), cw);
- mct_SendCtrlWrd(pMCTstat, pDCTstat, dct, val);
- if ((cw == 2) || (cw == 8) || (cw == 10))
- precise_ndelay_fam15(pMCTstat, 6000);
- }
- } else {
- for (cw = 0; cw <=15; cw ++) {
- mct_Wait(1600);
- val = mct_ControlRC(pMCTstat, pDCTstat, dct, MrsChipSel << rc_word_chip_select_lower_bit(), cw);
- mct_SendCtrlWrd(pMCTstat, pDCTstat, dct, val);
- }
- }
- }
- }
-
- mct_Wait(1200);
-
- printk(BIOS_SPEW, "%s: Done\n", __func__);
-}
-
-void FreqChgCtrlWrd(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, uint8_t dct)
-{
- u32 SaveSpeed = pDCTstat->DIMMAutoSpeed;
- u32 MrsChipSel;
- u32 dev = pDCTstat->dev_dct;
- u32 val;
- uint16_t mem_freq;
-
- pDCTstat->CSPresent = pDCTstat->CSPresent_DCT[dct];
- if (pDCTstat->GangedMode & 1)
- pDCTstat->CSPresent = pDCTstat->CSPresent_DCT[0];
-
- pDCTstat->DIMMAutoSpeed = pDCTstat->TargetFreq;
- mem_freq = memclk_to_freq(pDCTstat->TargetFreq);
- for (MrsChipSel = 0; MrsChipSel < 8; MrsChipSel += 2) {
- if (pDCTstat->CSPresent & (1 << MrsChipSel)) {
- /* 2. Program F2x[1, 0]A8[CtrlWordCS]=bit mask for target chip selects. */
- val = Get_NB32_DCT(dev, dct, 0xa8);
- val &= ~(0xff << 8);
-
- switch (MrsChipSel) {
- case 0:
- case 1:
- val |= 3 << 8;
- break;
- case 2:
- case 3:
- val |= (3 << 2) << 8;
- break;
- case 4:
- case 5:
- val |= (3 << 4) << 8;
- break;
- case 6:
- case 7:
- val |= (3 << 6) << 8;
- break;
- }
- Set_NB32_DCT(dev, dct, 0xa8, val);
-
- /* Resend control word 10 */
- uint8_t freq_ctl_val = 0;
- mct_Wait(1600);
- switch (mem_freq) {
- case 333:
- case 400:
- freq_ctl_val = 0x0;
- break;
- case 533:
- freq_ctl_val = 0x1;
- break;
- case 667:
- freq_ctl_val = 0x2;
- break;
- case 800:
- freq_ctl_val = 0x3;
- break;
- case 933:
- freq_ctl_val = 0x4;
- break;
- }
-
- printk(BIOS_SPEW, "Preparing to send DCT %d DIMM %d RC%d: %02x (F2xA8: %08x)\n", dct, MrsChipSel >> 1, 10, freq_ctl_val, val);
-
- mct_SendCtrlWrd(pMCTstat, pDCTstat, dct, (MrsChipSel << rc_word_chip_select_lower_bit()) | rc_word_address_to_ctl_bits(10) | rc_word_value_to_ctl_bits(freq_ctl_val));
-
- if (is_fam15h())
- precise_ndelay_fam15(pMCTstat, 6000);
- else
- mct_Wait(1600);
-
- /* Resend control word 2 */
- val = mct_ControlRC(pMCTstat, pDCTstat, dct, MrsChipSel << rc_word_chip_select_lower_bit(), 2);
- mct_SendCtrlWrd(pMCTstat, pDCTstat, dct, val);
-
- if (is_fam15h())
- precise_ndelay_fam15(pMCTstat, 6000);
- else
- mct_Wait(1600);
-
- /* Resend control word 8 */
- val = mct_ControlRC(pMCTstat, pDCTstat, dct, MrsChipSel << rc_word_chip_select_lower_bit(), 8);
- mct_SendCtrlWrd(pMCTstat, pDCTstat, dct, val);
-
- if (is_fam15h())
- precise_ndelay_fam15(pMCTstat, 6000);
- else
- mct_Wait(1600);
- }
- }
- pDCTstat->DIMMAutoSpeed = SaveSpeed;
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c b/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c
deleted file mode 100644
index f215695580..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c
+++ /dev/null
@@ -1,1210 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
- *
- * 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.
- */
-
-#include <arch/cpu.h>
-#include <stdint.h>
-#include <console/console.h>
-
-#include "mct_d.h"
-#include "mct_d_gcc.h"
-
-static uint8_t is_fam15h(void)
-{
- uint8_t fam15h = 0;
- uint32_t family;
-
- family = cpuid_eax(0x80000001);
- family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);
-
- if (family >= 0x6f)
- /* Family 15h or later */
- fam15h = 1;
-
- return fam15h;
-}
-
-uint8_t fam15_dimm_dic(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t dimm, uint8_t rank, uint8_t package_type)
-{
- uint8_t dic;
-
- /* Calculate DIC based on recommendations in MR1_dct[1:0] */
- if (pDCTstat->Status & (1 << SB_LoadReduced)) {
- /* TODO
- * LRDIMM unimplemented
- */
- dic = 0x0;
- } else {
- dic = 0x1;
- }
-
- return dic;
-}
-
-uint8_t fam15_rttwr(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t dimm, uint8_t rank, uint8_t package_type)
-{
- uint8_t term = 0;
- uint8_t number_of_dimms = pDCTstat->MAdimms[dct];
- uint8_t frequency_index;
- uint8_t rank_count = pDCTstat->DimmRanks[(dimm * 2) + dct];
-
- uint8_t rank_count_dimm0;
- uint8_t rank_count_dimm1;
- uint8_t rank_count_dimm2;
-
- if (is_fam15h())
- frequency_index = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x94) & 0x1f;
- else
- frequency_index = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x94) & 0x7;
-
- uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH);
-
- if (is_fam15h()) {
- if (pDCTstat->Status & (1 << SB_LoadReduced)) {
- /* TODO
- * LRDIMM unimplemented
- */
- } else if (pDCTstat->Status & (1 << SB_Registered)) {
- /* RDIMM */
- if (package_type == PT_GR) {
- /* Socket G34: Fam15h BKDG v3.14 Table 57 */
- if (MaxDimmsInstallable == 1) {
- if ((frequency_index == 0x4) || (frequency_index == 0x6)
- || (frequency_index == 0xa) || (frequency_index == 0xe)) {
- /* DDR3-667 - DDR3-1333 */
- if (rank_count < 3)
- term = 0x0;
- else
- term = 0x2;
- } else {
- /* DDR3-1600 */
- term = 0x0;
- }
- } else if (MaxDimmsInstallable == 2) {
- rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
- rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
-
- if ((frequency_index == 0x4) || (frequency_index == 0x6)) {
- /* DDR3-667 - DDR3-800 */
- if ((number_of_dimms == 1) && ((rank_count_dimm0 < 4)
- && (rank_count_dimm1 < 4)))
- term = 0x0;
- else
- term = 0x2;
- } else if (frequency_index == 0xa) {
- /* DDR3-1066 */
- if (number_of_dimms == 1) {
- if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4))
- term = 0x0;
- else
- term = 0x2;
- } else {
- term = 0x1;
- }
- } else if (frequency_index == 0xe) {
- /* DDR3-1333 */
- term = 0x2;
- } else {
- /* DDR3-1600 */
- if (number_of_dimms == 1)
- term = 0x0;
- else
- term = 0x1;
- }
- } else if (MaxDimmsInstallable == 3) {
- rank_count_dimm2 = pDCTstat->DimmRanks[(2 * 2) + dct];
-
- if ((frequency_index == 0xa) || (frequency_index == 0xe)) {
- /* DDR3-1066 - DDR3-1333 */
- if (rank_count_dimm2 < 4)
- term = 0x1;
- else
- term = 0x2;
- } else if (frequency_index == 0x12) {
- /* DDR3-1600 */
- term = 0x1;
- } else {
- term = 0x2;
- }
- }
- } else if (package_type == PT_C3) {
- /* Socket C32: Fam15h BKDG v3.14 Table 60 */
- if (MaxDimmsInstallable == 1) {
- if ((frequency_index == 0x4) || (frequency_index == 0x6)
- || (frequency_index == 0xa) || (frequency_index == 0xe)) {
- /* DDR3-667 - DDR3-1333 */
- if (rank_count < 3)
- term = 0x0;
- else
- term = 0x2;
- } else {
- /* DDR3-1600 */
- term = 0x0;
- }
- } else if (MaxDimmsInstallable == 2) {
- rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
- rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
-
- if ((frequency_index == 0x4) || (frequency_index == 0x6)) {
- /* DDR3-667 - DDR3-800 */
- if ((number_of_dimms == 1) && ((rank_count_dimm0 < 4)
- && (rank_count_dimm1 < 4)))
- term = 0x0;
- else
- term = 0x2;
- } else if (frequency_index == 0xa) {
- /* DDR3-1066 */
- if (number_of_dimms == 1) {
- if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4))
- term = 0x0;
- else
- term = 0x2;
- } else {
- term = 0x1;
- }
- } else if (frequency_index == 0xe) {
- /* DDR3-1333 */
- term = 0x2;
- } else {
- /* DDR3-1600 */
- if (number_of_dimms == 1)
- term = 0x0;
- else
- term = 0x1;
- }
- } else if (MaxDimmsInstallable == 3) {
- rank_count_dimm2 = pDCTstat->DimmRanks[(2 * 2) + dct];
-
- if ((frequency_index == 0xa) || (frequency_index == 0xe)) {
- /* DDR3-1066 - DDR3-1333 */
- if (rank_count_dimm2 < 4)
- term = 0x1;
- else
- term = 0x2;
- } else if (frequency_index == 0x12) {
- /* DDR3-1600 */
- term = 0x1;
- } else {
- term = 0x2;
- }
- }
- } else {
- /* TODO
- * Other sockets unimplemented
- */
- }
- } else {
- /* UDIMM */
- if (package_type == PT_GR) {
- /* Socket G34: Fam15h BKDG v3.14 Table 56 */
- if (MaxDimmsInstallable == 1) {
- term = 0x0;
- } else if (MaxDimmsInstallable == 2) {
- if ((number_of_dimms == 2) && (frequency_index == 0x12)) {
- term = 0x1;
- } else if (number_of_dimms == 1) {
- term = 0x0;
- } else {
- term = 0x2;
- }
- } else if (MaxDimmsInstallable == 3) {
- if (number_of_dimms == 1) {
- if (frequency_index <= 0xa) {
- term = 0x2;
- } else {
- if (rank_count < 3) {
- term = 0x1;
- } else {
- term = 0x2;
- }
- }
- } else if (number_of_dimms == 2) {
- term = 0x2;
- }
- }
- } else if (package_type == PT_C3) {
- /* Socket C32: Fam15h BKDG v3.14 Table 59 */
- if (MaxDimmsInstallable == 1) {
- term = 0x0;
- } else if (MaxDimmsInstallable == 2) {
- if ((number_of_dimms == 2) && (frequency_index == 0x12)) {
- term = 0x1;
- } else if (number_of_dimms == 1) {
- term = 0x0;
- } else {
- term = 0x2;
- }
- } else if (MaxDimmsInstallable == 3) {
- if (number_of_dimms == 1) {
- if (frequency_index <= 0xa) {
- term = 0x2;
- } else {
- if (rank_count < 3) {
- term = 0x1;
- } else {
- term = 0x2;
- }
- }
- } else if (number_of_dimms == 2) {
- term = 0x2;
- }
- }
- } else if (package_type == PT_FM2) {
- /* Socket FM2: Fam15h Model10 BKDG 3.12 Table 32 */
- if (MaxDimmsInstallable == 1) {
- term = 0x0;
- } else if (MaxDimmsInstallable == 2) {
- if ((number_of_dimms == 2) && (frequency_index >= 0x12)) {
- term = 0x1;
- } else if (number_of_dimms == 1) {
- term = 0x0;
- } else {
- term = 0x2;
- }
- }
- } else {
- /* TODO
- * Other sockets unimplemented
- */
- }
- }
- }
-
- printk(BIOS_INFO, "DIMM %d RttWr: %01x\n", dimm, term);
-
- return term;
-}
-
-uint8_t fam15_rttnom(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t dimm, uint8_t rank, uint8_t package_type)
-{
- uint8_t term = 0;
- uint8_t number_of_dimms = pDCTstat->MAdimms[dct];
- uint8_t frequency_index;
-
- uint8_t rank_count_dimm0;
- uint8_t rank_count_dimm1;
-
- if (is_fam15h())
- frequency_index = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x94) & 0x1f;
- else
- frequency_index = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0x94) & 0x7;
-
- uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH);
-
- if (is_fam15h()) {
- if (pDCTstat->Status & (1 << SB_LoadReduced)) {
- /* TODO
- * LRDIMM unimplemented
- */
- } else if (pDCTstat->Status & (1 << SB_Registered)) {
- /* RDIMM */
- if (package_type == PT_GR) {
- /* Socket G34: Fam15h BKDG v3.14 Table 57 */
- if (MaxDimmsInstallable == 1) {
- rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
-
- if ((frequency_index == 0x4) || (frequency_index == 0x6)) {
- /* DDR3-667 - DDR3-800 */
- if (rank_count_dimm0 < 4) {
- term = 0x2;
- } else {
- if (!rank)
- term = 0x2;
- else
- term = 0x0;
- }
- } else if (frequency_index == 0xa) {
- /* DDR3-1066 */
- term = 0x1;
- } else if (frequency_index == 0xe) {
- /* DDR3-1333 */
- if (rank_count_dimm0 < 4) {
- term = 0x1;
- } else {
- if (!rank)
- term = 0x3;
- else
- term = 0x0;
- }
- } else {
- term = 0x3;
- }
- } else if (MaxDimmsInstallable == 2) {
- rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
- rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
-
- if ((frequency_index == 0x4) || (frequency_index == 0x6)) {
- /* DDR3-667 - DDR3-800 */
- if (number_of_dimms == 1) {
- if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4))
- term = 0x2;
- else if (rank)
- term = 0x0;
- else
- term = 0x2;
- } else {
- if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4)) {
- term = 0x3;
- } else {
- if (rank_count_dimm0 == 4) {
- if (rank_count_dimm1 == 1)
- term = 0x5;
- else
- term = 0x1;
- } else if (rank_count_dimm1 == 4) {
- if (rank_count_dimm0 == 1)
- term = 0x5;
- else
- term = 0x1;
- }
- if (rank)
- term = 0x0;
- }
- }
- } else if (frequency_index == 0xa) {
- /* DDR3-1066 */
- if (number_of_dimms == 1) {
- if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4))
- term = 0x1;
- else if (rank)
- term = 0x0;
- else
- term = 0x1;
- } else {
- if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4)) {
- term = 0x3;
- } else {
- if (rank_count_dimm0 == 4) {
- if (rank_count_dimm1 == 1)
- term = 0x5;
- else
- term = 0x1;
- } else if (rank_count_dimm1 == 4) {
- if (rank_count_dimm0 == 1)
- term = 0x5;
- else
- term = 0x1;
- }
- if (rank)
- term = 0x0;
- }
- }
- } else if (frequency_index == 0xe) {
- /* DDR3-1333 */
- if (number_of_dimms == 1) {
- if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4))
- term = 0x1;
- else if (rank)
- term = 0x0;
- else
- term = 0x3;
- } else {
- term = 0x5;
- }
- } else {
- /* DDR3-1600 */
- if (number_of_dimms == 1)
- term = 0x3;
- else
- term = 0x4;
- }
- } else if (MaxDimmsInstallable == 3) {
- /* TODO
- * 3 DIMM/channel support unimplemented
- */
- }
- } else if (package_type == PT_C3) {
- /* Socket C32: Fam15h BKDG v3.14 Table 60 */
- if (MaxDimmsInstallable == 1) {
- rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
-
- if ((frequency_index == 0x4) || (frequency_index == 0x6)) {
- /* DDR3-667 - DDR3-800 */
- if (rank_count_dimm0 < 4) {
- term = 0x2;
- } else {
- if (!rank)
- term = 0x2;
- else
- term = 0x0;
- }
- } else if (frequency_index == 0xa) {
- /* DDR3-1066 */
- term = 0x1;
- } else if (frequency_index == 0xe) {
- /* DDR3-1333 */
- if (rank_count_dimm0 < 4) {
- term = 0x1;
- } else {
- if (!rank)
- term = 0x3;
- else
- term = 0x0;
- }
- } else {
- term = 0x3;
- }
- } else if (MaxDimmsInstallable == 2) {
- rank_count_dimm0 = pDCTstat->DimmRanks[(0 * 2) + dct];
- rank_count_dimm1 = pDCTstat->DimmRanks[(1 * 2) + dct];
-
- if ((frequency_index == 0x4) || (frequency_index == 0x6)) {
- /* DDR3-667 - DDR3-800 */
- if (number_of_dimms == 1) {
- if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4))
- term = 0x2;
- else if (rank)
- term = 0x0;
- else
- term = 0x2;
- } else {
- if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4)) {
- term = 0x3;
- } else {
- if (rank_count_dimm0 == 4) {
- if (rank_count_dimm1 == 1)
- term = 0x5;
- else
- term = 0x1;
- } else if (rank_count_dimm1 == 4) {
- if (rank_count_dimm0 == 1)
- term = 0x5;
- else
- term = 0x1;
- }
- if (rank)
- term = 0x0;
- }
- }
- } else if (frequency_index == 0xa) {
- /* DDR3-1066 */
- if (number_of_dimms == 1) {
- if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4))
- term = 0x1;
- else if (rank)
- term = 0x0;
- else
- term = 0x1;
- } else {
- if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4)) {
- term = 0x3;
- } else {
- if (rank_count_dimm0 == 4) {
- if (rank_count_dimm1 == 1)
- term = 0x5;
- else
- term = 0x1;
- } else if (rank_count_dimm1 == 4) {
- if (rank_count_dimm0 == 1)
- term = 0x5;
- else
- term = 0x1;
- }
- if (rank)
- term = 0x0;
- }
- }
- } else if (frequency_index == 0xe) {
- /* DDR3-1333 */
- if (number_of_dimms == 1) {
- if ((rank_count_dimm0 < 4) && (rank_count_dimm1 < 4))
- term = 0x1;
- else if (rank)
- term = 0x0;
- else
- term = 0x3;
- } else {
- term = 0x5;
- }
- } else {
- /* DDR3-1600 */
- if (number_of_dimms == 1)
- term = 0x3;
- else
- term = 0x4;
- }
- } else if (MaxDimmsInstallable == 3) {
- /* TODO
- * 3 DIMM/channel support unimplemented
- */
- }
- } else {
- /* TODO
- * Other sockets unimplemented
- */
- }
- } else {
- /* UDIMM */
- if (package_type == PT_GR) {
- /* Socket G34: Fam15h BKDG v3.14 Table 56 */
- if (MaxDimmsInstallable == 1) {
- if ((frequency_index == 0x4) || (frequency_index == 0x6))
- term = 0x2;
- else if ((frequency_index == 0xa) || (frequency_index == 0xe))
- term = 0x1;
- else
- term = 0x3;
- }
- if (MaxDimmsInstallable == 2) {
- if (number_of_dimms == 1) {
- if (frequency_index <= 0x6) {
- term = 0x2;
- } else if (frequency_index <= 0xe) {
- term = 0x1;
- } else {
- term = 0x3;
- }
- } else {
- if (frequency_index <= 0xa) {
- term = 0x3;
- } else if (frequency_index <= 0xe) {
- term = 0x5;
- } else {
- term = 0x4;
- }
- }
- } else if (MaxDimmsInstallable == 3) {
- if (number_of_dimms == 1) {
- term = 0x0;
- } else if (number_of_dimms == 2) {
- if (frequency_index <= 0xa) {
- if (rank == 1) {
- term = 0x0;
- } else {
- term = 0x3;
- }
- } else if (frequency_index <= 0xe) {
- if (rank == 1) {
- term = 0x0;
- } else {
- term = 0x5;
- }
- }
- }
- }
- } else if (package_type == PT_C3) {
- /* Socket C32: Fam15h BKDG v3.14 Table 62 */
- if (MaxDimmsInstallable == 1) {
- if ((frequency_index == 0x4) || (frequency_index == 0x6))
- term = 0x2;
- else if ((frequency_index == 0xa) || (frequency_index == 0xe))
- term = 0x1;
- else
- term = 0x3;
- }
- if (MaxDimmsInstallable == 2) {
- if (number_of_dimms == 1) {
- if (frequency_index <= 0x6) {
- term = 0x2;
- } else if (frequency_index <= 0xe) {
- term = 0x1;
- } else {
- term = 0x3;
- }
- } else {
- if (frequency_index <= 0xa) {
- term = 0x3;
- } else if (frequency_index <= 0xe) {
- term = 0x5;
- } else {
- term = 0x4;
- }
- }
- } else if (MaxDimmsInstallable == 3) {
- if (number_of_dimms == 1) {
- term = 0x0;
- } else if (number_of_dimms == 2) {
- if (frequency_index <= 0xa) {
- if (rank == 1) {
- term = 0x0;
- } else {
- term = 0x3;
- }
- } else if (frequency_index <= 0xe) {
- if (rank == 1) {
- term = 0x0;
- } else {
- term = 0x5;
- }
- }
- }
- }
- } else if (package_type == PT_FM2) {
- /* Socket FM2: Fam15h Model10 BKDG 3.12 Table 32 */
- if (MaxDimmsInstallable == 1) {
- if ((frequency_index == 0x4)
- || (frequency_index == 0x6)
- || (frequency_index == 0xa))
- term = 0x4;
- else if (frequency_index == 0xe)
- term = 0x3;
- else if (frequency_index >= 0x12)
- term = 0x2;
- }
- if (MaxDimmsInstallable == 2) {
- if (number_of_dimms == 1) {
- if (frequency_index <= 0xa) {
- term = 0x4;
- } else if (frequency_index <= 0xe) {
- term = 0x3;
- } else {
- term = 0x2;
- }
- } else {
- if (frequency_index <= 0xa) {
- term = 0x2;
- } else if (frequency_index <= 0xe) {
- term = 0x1;
- } else {
- term = 0x0;
- }
- }
- }
- } else {
- /* TODO
- * Other sockets unimplemented
- */
- }
- }
- }
-
- printk(BIOS_INFO, "DIMM %d RttNom: %01x\n", dimm, term);
- return term;
-}
-
-static void mct_DCTAccessDone(struct DCTStatStruc *pDCTstat, u8 dct)
-{
- u32 dev = pDCTstat->dev_dct;
- u32 val;
-
- printk(BIOS_DEBUG, "%s: Start\n", __func__);
-
- do {
- val = Get_NB32_DCT(dev, dct, 0x98);
- } while (!(val & (1 << DctAccessDone)));
-
- printk(BIOS_DEBUG, "%s: Done\n", __func__);
-}
-
-static u32 swapAddrBits(struct DCTStatStruc *pDCTstat, u32 MR_register_setting, u8 MrsChipSel, u8 dct)
-{
- u16 word;
- u32 ret;
-
- if (!(pDCTstat->Status & (1 << SB_Registered))) {
- word = pDCTstat->MirrPresU_NumRegR;
- if (dct == 0) {
- word &= 0x55;
- word <<= 1;
- } else
- word &= 0xAA;
-
- if (word & (1 << MrsChipSel)) {
- /* A3<->A4,A5<->A6,A7<->A8,BA0<->BA1 */
- ret = 0;
- if (MR_register_setting & (1 << 3)) ret |= 1 << 4;
- if (MR_register_setting & (1 << 4)) ret |= 1 << 3;
- if (MR_register_setting & (1 << 5)) ret |= 1 << 6;
- if (MR_register_setting & (1 << 6)) ret |= 1 << 5;
- if (MR_register_setting & (1 << 7)) ret |= 1 << 8;
- if (MR_register_setting & (1 << 8)) ret |= 1 << 7;
- if (is_fam15h()) {
- if (MR_register_setting & (1 << 18)) ret |= 1 << 19;
- if (MR_register_setting & (1 << 19)) ret |= 1 << 18;
- MR_register_setting &= ~0x000c01f8;
- } else {
- if (MR_register_setting & (1 << 16)) ret |= 1 << 17;
- if (MR_register_setting & (1 << 17)) ret |= 1 << 16;
- MR_register_setting &= ~0x000301f8;
- }
- MR_register_setting |= ret;
- }
- }
- return MR_register_setting;
-}
-
-static void mct_SendMrsCmd(struct DCTStatStruc *pDCTstat, u8 dct, u32 EMRS)
-{
- u32 dev = pDCTstat->dev_dct;
- u32 val;
-
- printk(BIOS_DEBUG, "%s: Start\n", __func__);
-
- val = Get_NB32_DCT(dev, dct, 0x7c);
- val &= ~0x00ffffff;
- val |= EMRS;
- val |= 1 << SendMrsCmd;
- Set_NB32_DCT(dev, dct, 0x7c, val);
-
- do {
- val = Get_NB32_DCT(dev, dct, 0x7c);
- } while (val & (1 << SendMrsCmd));
-
- printk(BIOS_DEBUG, "%s: Done\n", __func__);
-}
-
-u32 mct_MR2(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dct, u32 MrsChipSel)
-{
- u32 dev = pDCTstat->dev_dct;
- u32 dword, ret;
-
- /* The formula for chip select number is: CS = dimm*2+rank */
- uint8_t dimm = MrsChipSel / 2;
- uint8_t rank = MrsChipSel % 2;
-
- if (is_fam15h()) {
- uint8_t package_type = mctGet_NVbits(NV_PACK_TYPE);
-
- /* FIXME: These parameters should be configurable
- * For now, err on the side of caution and enable automatic 2x refresh
- * when the DDR temperature rises above the internal limits
- */
- uint8_t force_2x_self_refresh = 0; /* ASR */
- uint8_t auto_2x_self_refresh = 1; /* SRT */
-
- ret = 0x80000;
- ret |= (MrsChipSel << 21);
-
- /* Set self refresh parameters */
- ret |= (force_2x_self_refresh << 6);
- ret |= (auto_2x_self_refresh << 7);
-
- /* Obtain Tcwl, adjust, and set CWL with the adjusted value */
- dword = Get_NB32_DCT(dev, dct, 0x20c) & 0x1f;
- dword -= pDCTstat->tcwl_delay[dct];
- ret |= ((dword - 5) << 3);
-
- /* Obtain and set RttWr */
- ret |= (fam15_rttwr(pDCTstat, dct, dimm, rank, package_type) << 9);
- } else {
- ret = 0x20000;
- ret |= (MrsChipSel << 20);
-
- /* program MrsAddress[5:3]=CAS write latency (CWL):
- * based on F2x[1,0]84[Tcwl] */
- dword = Get_NB32_DCT(dev, dct, 0x84);
- dword = mct_AdjustSPDTimings(pMCTstat, pDCTstat, dword);
-
- ret |= ((dword >> 20) & 7) << 3;
-
- /* program MrsAddress[6]=auto self refresh method (ASR):
- * based on F2x[1,0]84[ASR]
- * program MrsAddress[7]=self refresh temperature range (SRT):
- * based on F2x[1,0]84[ASR and SRT]
- */
- ret |= ((dword >> 18) & 3) << 6;
-
- /* program MrsAddress[10:9]=dynamic termination during writes (RTT_WR)
- * based on F2x[1,0]84[DramTermDyn]
- */
- ret |= ((dword >> 10) & 3) << 9;
- }
-
- printk(BIOS_SPEW, "Going to send DCT %d DIMM %d rank %d MR2 control word %08x\n", dct, dimm, rank, ret);
-
- return ret;
-}
-
-static u32 mct_MR3(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dct, u32 MrsChipSel)
-{
- u32 dev = pDCTstat->dev_dct;
- u32 dword, ret;
-
- /* The formula for chip select number is: CS = dimm*2+rank */
- uint8_t dimm = MrsChipSel / 2;
- uint8_t rank = MrsChipSel % 2;
-
- if (is_fam15h()) {
- ret = 0xc0000;
- ret |= (MrsChipSel << 21);
-
- /* Program MPR and MPRLoc to 0 */
- // ret |= 0x0; /* MPR */
- // ret |= (0x0 << 2); /* MPRLoc */
- } else {
- ret = 0x30000;
- ret |= (MrsChipSel << 20);
-
- /* program MrsAddress[1:0]=multi purpose register address location
- * (MPR Location):based on F2x[1,0]84[MprLoc]
- * program MrsAddress[2]=multi purpose register
- * (MPR):based on F2x[1,0]84[MprEn]
- */
- dword = Get_NB32_DCT(dev, dct, 0x84);
- ret |= (dword >> 24) & 7;
- }
-
- printk(BIOS_SPEW, "Going to send DCT %d DIMM %d rank %d MR3 control word %08x\n", dct, dimm, rank, ret);
-
- return ret;
-}
-
-u32 mct_MR1(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dct, u32 MrsChipSel)
-{
- u32 dev = pDCTstat->dev_dct;
- u32 dword, ret;
-
- /* The formula for chip select number is: CS = dimm*2+rank */
- uint8_t dimm = MrsChipSel / 2;
- uint8_t rank = MrsChipSel % 2;
-
- if (is_fam15h()) {
- uint8_t package_type = mctGet_NVbits(NV_PACK_TYPE);
-
- /* Set defaults */
- uint8_t qoff = 0; /* Enable output buffers */
- uint8_t wrlvl = 0; /* Disable write levelling */
- uint8_t tqds = 0;
- uint8_t rttnom = 0;
- uint8_t dic = 0;
- uint8_t additive_latency = 0;
- uint8_t dll_enable = 0;
-
- ret = 0x40000;
- ret |= (MrsChipSel << 21);
-
- /* Determine if TQDS should be set */
- if ((pDCTstat->Dimmx8Present & (1 << dimm))
- && (((dimm & 0x1)?(pDCTstat->Dimmx4Present&0x55):(pDCTstat->Dimmx4Present&0xaa)) != 0x0)
- && (pDCTstat->Status & (1 << SB_LoadReduced)))
- tqds = 1;
-
- /* Obtain RttNom */
- rttnom = fam15_rttnom(pDCTstat, dct, dimm, rank, package_type);
-
- /* Obtain DIC */
- dic = fam15_dimm_dic(pDCTstat, dct, dimm, rank, package_type);
-
- /* Load data into MRS word */
- ret |= (qoff & 0x1) << 12;
- ret |= (tqds & 0x1) << 11;
- ret |= ((rttnom & 0x4) >> 2) << 9;
- ret |= ((rttnom & 0x2) >> 1) << 6;
- ret |= ((rttnom & 0x1) >> 0) << 2;
- ret |= (wrlvl & 0x1) << 7;
- ret |= ((dic & 0x2) >> 1) << 5;
- ret |= ((dic & 0x1) >> 0) << 1;
- ret |= (additive_latency & 0x3) << 3;
- ret |= (dll_enable & 0x1);
- } else {
- ret = 0x10000;
- ret |= (MrsChipSel << 20);
-
- /* program MrsAddress[5,1]=output driver impedance control (DIC):
- * based on F2x[1,0]84[DrvImpCtrl]
- */
- dword = Get_NB32_DCT(dev, dct, 0x84);
- if (dword & (1 << 3))
- ret |= 1 << 5;
- if (dword & (1 << 2))
- ret |= 1 << 1;
-
- /* program MrsAddress[9,6,2]=nominal termination resistance of ODT (RTT):
- * based on F2x[1,0]84[DramTerm]
- */
- if (!(pDCTstat->Status & (1 << SB_Registered))) {
- if (dword & (1 << 9))
- ret |= 1 << 9;
- if (dword & (1 << 8))
- ret |= 1 << 6;
- if (dword & (1 << 7))
- ret |= 1 << 2;
- } else {
- ret |= mct_MR1Odt_RDimm(pMCTstat, pDCTstat, dct, MrsChipSel);
- }
-
- /* program MrsAddress[11]=TDQS: based on F2x[1,0]94[RDqsEn] */
- if (Get_NB32_DCT(dev, dct, 0x94) & (1 << RDqsEn)) {
- u8 bit;
- /* Set TDQS = 1b for x8 DIMM, TDQS = 0b for x4 DIMM, when mixed x8 & x4 */
- bit = (ret >> 21) << 1;
- if ((dct & 1) != 0)
- bit ++;
- if (pDCTstat->Dimmx8Present & (1 << bit))
- ret |= 1 << 11;
- }
-
- /* program MrsAddress[12]=QOFF: based on F2x[1,0]84[Qoff] */
- if (dword & (1 << 13))
- ret |= 1 << 12;
- }
-
- printk(BIOS_SPEW, "Going to send DCT %d DIMM %d rank %d MR1 control word %08x\n", dct, dimm, rank, ret);
-
- return ret;
-}
-
-static u32 mct_MR0(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dct, u32 MrsChipSel)
-{
- u32 dev = pDCTstat->dev_dct;
- u32 dword, ret, dword2;
-
- /* The formula for chip select number is: CS = dimm*2+rank */
- uint8_t dimm = MrsChipSel / 2;
- uint8_t rank = MrsChipSel % 2;
-
- if (is_fam15h()) {
- ret = 0x00000;
- ret |= (MrsChipSel << 21);
-
- /* Set defaults */
- uint8_t ppd = 0;
- uint8_t wr_ap = 0;
- uint8_t dll_reset = 1;
- uint8_t test_mode = 0;
- uint8_t cas_latency = 0;
- uint8_t read_burst_type = 1;
- uint8_t burst_length = 0;
-
- /* Obtain PchgPDModeSel */
- dword = Get_NB32_DCT(dev, dct, 0x84);
- ppd = (dword >> 23) & 0x1;
-
- /* Obtain Twr */
- dword = Get_NB32_DCT(dev, dct, 0x22c) & 0x1f;
-
- /* Calculate wr_ap (Fam15h BKDG v3.14 Table 82) */
- if (dword == 0x10)
- wr_ap = 0x0;
- else if (dword == 0x5)
- wr_ap = 0x1;
- else if (dword == 0x6)
- wr_ap = 0x2;
- else if (dword == 0x7)
- wr_ap = 0x3;
- else if (dword == 0x8)
- wr_ap = 0x4;
- else if (dword == 0xa)
- wr_ap = 0x5;
- else if (dword == 0xc)
- wr_ap = 0x6;
- else if (dword == 0xe)
- wr_ap = 0x7;
-
- /* Obtain Tcl */
- dword = Get_NB32_DCT(dev, dct, 0x200) & 0x1f;
-
- /* Calculate cas_latency (Fam15h BKDG v3.14 Table 83) */
- if (dword == 0x5)
- cas_latency = 0x2;
- else if (dword == 0x6)
- cas_latency = 0x4;
- else if (dword == 0x7)
- cas_latency = 0x6;
- else if (dword == 0x8)
- cas_latency = 0x8;
- else if (dword == 0x9)
- cas_latency = 0xa;
- else if (dword == 0xa)
- cas_latency = 0xc;
- else if (dword == 0xb)
- cas_latency = 0xe;
- else if (dword == 0xc)
- cas_latency = 0x1;
- else if (dword == 0xd)
- cas_latency = 0x3;
- else if (dword == 0xe)
- cas_latency = 0x5;
- else if (dword == 0xf)
- cas_latency = 0x7;
- else if (dword == 0x10)
- cas_latency = 0x9;
-
- /* Obtain BurstCtrl */
- burst_length = Get_NB32_DCT(dev, dct, 0x84) & 0x3;
-
- /* Load data into MRS word */
- ret |= (ppd & 0x1) << 12;
- ret |= (wr_ap & 0x7) << 9;
- ret |= (dll_reset & 0x1) << 8;
- ret |= (test_mode & 0x1) << 7;
- ret |= ((cas_latency & 0xe) >> 1) << 4;
- ret |= ((cas_latency & 0x1) >> 0) << 2;
- ret |= (read_burst_type & 0x1) << 3;
- ret |= (burst_length & 0x3);
- } else {
- ret = 0x00000;
- ret |= (MrsChipSel << 20);
-
- /* program MrsAddress[1:0]=burst length and control method
- (BL):based on F2x[1,0]84[BurstCtrl] */
- dword = Get_NB32_DCT(dev, dct, 0x84);
- ret |= dword & 3;
-
- /* program MrsAddress[3]=1 (BT):interleaved */
- ret |= 1 << 3;
-
- /* program MrsAddress[6:4,2]=read CAS latency
- (CL):based on F2x[1,0]88[Tcl] */
- dword2 = Get_NB32_DCT(dev, dct, 0x88);
- ret |= (dword2 & 0x7) << 4; /* F2x88[2:0] to MrsAddress[6:4] */
- ret |= ((dword2 & 0x8) >> 3) << 2; /* F2x88[3] to MrsAddress[2] */
-
- /* program MrsAddress[12]=0 (PPD):slow exit */
- if (dword & (1 << 23))
- ret |= 1 << 12;
-
- /* program MrsAddress[11:9]=write recovery for auto-precharge
- (WR):based on F2x[1,0]84[Twr] */
- ret |= ((dword >> 4) & 7) << 9;
-
- /* program MrsAddress[8]=1 (DLL):DLL reset
- just issue DLL reset at first time */
- ret |= 1 << 8;
- }
-
- printk(BIOS_SPEW, "Going to send DCT %d DIMM %d rank %d MR0 control word %08x\n", dct, dimm, rank, ret);
-
- return ret;
-}
-
-static void mct_SendZQCmd(struct DCTStatStruc *pDCTstat, u8 dct)
-{
- u32 dev = pDCTstat->dev_dct;
- u32 dword;
-
- printk(BIOS_DEBUG, "%s: Start\n", __func__);
-
- /*1.Program MrsAddress[10]=1
- 2.Set SendZQCmd = 1
- */
- dword = Get_NB32_DCT(dev, dct, 0x7C);
- dword &= ~0xFFFFFF;
- dword |= 1 << 10;
- dword |= 1 << SendZQCmd;
- Set_NB32_DCT(dev, dct, 0x7C, dword);
-
- /* Wait for SendZQCmd = 0 */
- do {
- dword = Get_NB32_DCT(dev, dct, 0x7C);
- } while (dword & (1 << SendZQCmd));
-
- /* 4.Wait 512 MEMCLKs */
- mct_Wait(300);
-
- printk(BIOS_DEBUG, "%s: Done\n", __func__);
-}
-
-void mct_DramInit_Sw_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dct)
-{
- u8 MrsChipSel;
- u32 dword;
- u32 dev = pDCTstat->dev_dct;
-
- printk(BIOS_DEBUG, "%s: Start\n", __func__);
-
- if (pDCTstat->DIMMAutoSpeed == mhz_to_memclk_config(mctGet_NVbits(NV_MIN_MEMCLK))) {
- /* 3.Program F2x[1,0]7C[EnDramInit]=1 */
- dword = Get_NB32_DCT(dev, dct, 0x7c);
- dword |= 1 << EnDramInit;
- Set_NB32_DCT(dev, dct, 0x7c, dword);
- mct_DCTAccessDone(pDCTstat, dct);
-
- /* 4.wait 200us */
- mct_Wait(40000);
-
- /* 5.Program F2x[1, 0]7C[DeassertMemRstX] = 1. */
- dword = Get_NB32_DCT(dev, dct, 0x7c);
- dword |= 1 << DeassertMemRstX;
- Set_NB32_DCT(dev, dct, 0x7c, dword);
-
- /* 6.wait 500us */
- mct_Wait(200000);
-
- /* 7.Program F2x[1,0]7C[AssertCke]=1 */
- dword = Get_NB32_DCT(dev, dct, 0x7c);
- dword |= 1 << AssertCke;
- Set_NB32_DCT(dev, dct, 0x7c, dword);
-
- /* 8.wait 360ns */
- mct_Wait(80);
-
- /* Set up address parity */
- if ((pDCTstat->Status & (1 << SB_Registered))
- || (pDCTstat->Status & (1 << SB_LoadReduced))) {
- if (is_fam15h()) {
- dword = Get_NB32_DCT(dev, dct, 0x90);
- dword |= 1 << ParEn;
- Set_NB32_DCT(dev, dct, 0x90, dword);
- }
- }
-
- /* The following steps are performed with registered DIMMs only and
- * must be done for each chip select pair */
- if (pDCTstat->Status & (1 << SB_Registered))
- mct_DramControlReg_Init_D(pMCTstat, pDCTstat, dct);
-
- /* The following steps are performed with load reduced DIMMs only and
- * must be done for each DIMM */
- // if (pDCTstat->Status & (1 << SB_LoadReduced))
- /* TODO
- * Implement LRDIMM configuration
- */
- }
-
- pDCTstat->CSPresent = pDCTstat->CSPresent_DCT[dct];
- if (pDCTstat->GangedMode & 1)
- pDCTstat->CSPresent = pDCTstat->CSPresent_DCT[0];
-
- /* The following steps are performed once for unbuffered DIMMs and once for each
- * chip select on registered DIMMs: */
- for (MrsChipSel = 0; MrsChipSel < 8; MrsChipSel++) {
- if (pDCTstat->CSPresent & (1 << MrsChipSel)) {
- u32 EMRS;
- /* 13.Send EMRS(2) */
- EMRS = mct_MR2(pMCTstat, pDCTstat, dct, MrsChipSel);
- EMRS = swapAddrBits(pDCTstat, EMRS, MrsChipSel, dct);
- mct_SendMrsCmd(pDCTstat, dct, EMRS);
- /* 14.Send EMRS(3). Ordinarily at this time, MrsAddress[2:0]=000b */
- EMRS= mct_MR3(pMCTstat, pDCTstat, dct, MrsChipSel);
- EMRS = swapAddrBits(pDCTstat, EMRS, MrsChipSel, dct);
- mct_SendMrsCmd(pDCTstat, dct, EMRS);
- /* 15.Send EMRS(1) */
- EMRS= mct_MR1(pMCTstat, pDCTstat, dct, MrsChipSel);
- EMRS = swapAddrBits(pDCTstat, EMRS, MrsChipSel, dct);
- mct_SendMrsCmd(pDCTstat, dct, EMRS);
- /* 16.Send MRS with MrsAddress[8]=1(reset the DLL) */
- EMRS= mct_MR0(pMCTstat, pDCTstat, dct, MrsChipSel);
- EMRS = swapAddrBits(pDCTstat, EMRS, MrsChipSel, dct);
- mct_SendMrsCmd(pDCTstat, dct, EMRS);
-
- if (pDCTstat->DIMMAutoSpeed == mhz_to_memclk_config(mctGet_NVbits(NV_MIN_MEMCLK)))
- if (!(pDCTstat->Status & (1 << SB_Registered)))
- break; /* For UDIMM, only send MR commands once per channel */
- }
- if (pDCTstat->LogicalCPUID & (AMD_DR_Bx/* | AMD_RB_C0 */)) /* TODO: We dont support RB_C0 now. need to be added and tested. */
- if (!(pDCTstat->Status & (1 << SB_Registered)))
- MrsChipSel ++;
- }
-
- if (pDCTstat->DIMMAutoSpeed == mhz_to_memclk_config(mctGet_NVbits(NV_MIN_MEMCLK))) {
- /* 17.Send two ZQCL commands */
- mct_SendZQCmd(pDCTstat, dct);
- mct_SendZQCmd(pDCTstat, dct);
-
- /* 18.Program F2x[1,0]7C[EnDramInit]=0 */
- dword = Get_NB32_DCT(dev, dct, 0x7C);
- dword &= ~(1 << EnDramInit);
- Set_NB32_DCT(dev, dct, 0x7C, dword);
- mct_DCTAccessDone(pDCTstat, dct);
- }
-
- printk(BIOS_DEBUG, "%s: Done\n", __func__);
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c b/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c
deleted file mode 100644
index dbb989fe3d..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c
+++ /dev/null
@@ -1,2438 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- * Copyright (C) 2015 - 2016 Raptor Engineering, LLC
- *
- * 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; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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: Receiver En and DQS Timing Training feature for DDR 3 MCT
-******************************************************************************/
-
-#include <arch/cpu.h>
-#include <stdint.h>
-#include <console/console.h>
-#include <cpu/x86/cr.h>
-#include <string.h>
-#include <cpu/x86/msr.h>
-#include <cpu/amd/msr.h>
-#include "mct_d.h"
-#include "mct_d_gcc.h"
-
-static void dqsTrainRcvrEn_SW_Fam10(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 Pass);
-static void dqsTrainRcvrEn_SW_Fam15(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 Pass);
-static void mct_InitDQSPos4RcvrEn_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat);
-static void InitDQSPos4RcvrEn_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 Channel);
-static void CalcEccDQSRcvrEn_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 Channel);
-static void mct_SetMaxLatency_D(struct DCTStatStruc *pDCTstat, u8 Channel, u16 DQSRcvEnDly);
-static void mct_DisableDQSRcvEn_D(struct DCTStatStruc *pDCTstat);
-
-static uint8_t is_fam15h(void)
-{
- uint8_t fam15h = 0;
- uint32_t family;
-
- family = cpuid_eax(0x80000001);
- family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);
-
- if (family >= 0x6f)
- /* Family 15h or later */
- fam15h = 1;
-
- return fam15h;
-}
-
-/* Warning: These must be located so they do not cross a logical 16-bit
- segment boundary! */
-const u32 TestPattern0_D[] = {
- 0x55555555, 0x55555555, 0x55555555, 0x55555555,
- 0x55555555, 0x55555555, 0x55555555, 0x55555555,
- 0x55555555, 0x55555555, 0x55555555, 0x55555555,
- 0x55555555, 0x55555555, 0x55555555, 0x55555555,
-};
-const u32 TestPattern1_D[] = {
- 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
- 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
- 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
- 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
-};
-const u32 TestPattern2_D[] = {
- 0x12345678, 0x87654321, 0x23456789, 0x98765432,
- 0x59385824, 0x30496724, 0x24490795, 0x99938733,
- 0x40385642, 0x38465245, 0x29432163, 0x05067894,
- 0x12349045, 0x98723467, 0x12387634, 0x34587623,
-};
-
-static void SetupRcvrPattern(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u32 *buffer, u8 pass)
-{
- /*
- * 1. Copy the alpha and Beta patterns from ROM to Cache,
- * aligning on 16 byte boundary
- * 2. Set the ptr to DCTStatstruc.PtrPatternBufA for Alpha
- * 3. Set the ptr to DCTStatstruc.PtrPatternBufB for Beta
- */
- u32 *buf_a;
- u32 *buf_b;
- u32 *p_A;
- u32 *p_B;
- u8 i;
-
- buf_a = (u32 *)(((u32)buffer + 0x10) & (0xfffffff0));
- buf_b = buf_a + 32; /* ?? */
- p_A = (u32 *)SetupDqsPattern_1PassB(pass);
- p_B = (u32 *)SetupDqsPattern_1PassA(pass);
-
- for (i = 0; i < 16; i++) {
- buf_a[i] = p_A[i];
- buf_b[i] = p_B[i];
- }
-
- pDCTstat->PtrPatternBufA = (u32)buf_a;
- pDCTstat->PtrPatternBufB = (u32)buf_b;
-}
-
-void mct_TrainRcvrEn_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 Pass)
-{
- if (mct_checkNumberOfDqsRcvEn_1Pass(Pass)) {
- if (is_fam15h())
- dqsTrainRcvrEn_SW_Fam15(pMCTstat, pDCTstat, Pass);
- else
- dqsTrainRcvrEn_SW_Fam10(pMCTstat, pDCTstat, Pass);
- }
-}
-
-static uint16_t fam15_receiver_enable_training_seed(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t dimm, uint8_t rank, uint8_t package_type)
-{
- uint32_t dword;
- uint16_t seed = 0;
-
- uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH);
-
- uint8_t channel = dct;
- if (package_type == PT_GR) {
- /* Get the internal node number */
- dword = Get_NB32(pDCTstat->dev_nbmisc, 0xe8);
- dword = (dword >> 30) & 0x3;
- if (dword == 1) {
- channel += 2;
- }
- }
-
- if (pDCTstat->Status & (1 << SB_Registered)) {
- if (package_type == PT_GR) {
- /* Socket G34: Fam15h BKDG v3.14 Table 99 */
- if (MaxDimmsInstallable == 1) {
- if (channel == 0)
- seed = 0x43;
- else if (channel == 1)
- seed = 0x3f;
- else if (channel == 2)
- seed = 0x3a;
- else if (channel == 3)
- seed = 0x35;
- } else if (MaxDimmsInstallable == 2) {
- if (channel == 0)
- seed = 0x54;
- else if (channel == 1)
- seed = 0x4d;
- else if (channel == 2)
- seed = 0x45;
- else if (channel == 3)
- seed = 0x40;
- } else if (MaxDimmsInstallable == 3) {
- if (channel == 0)
- seed = 0x6b;
- else if (channel == 1)
- seed = 0x5e;
- else if (channel == 2)
- seed = 0x4b;
- else if (channel == 3)
- seed = 0x3d;
- }
- } else if (package_type == PT_C3) {
- /* Socket C32: Fam15h BKDG v3.14 Table 100 */
- if ((MaxDimmsInstallable == 1) || (MaxDimmsInstallable == 2)) {
- if (channel == 0)
- seed = 0x3f;
- else if (channel == 1)
- seed = 0x3e;
- } else if (MaxDimmsInstallable == 3) {
- if (channel == 0)
- seed = 0x47;
- else if (channel == 1)
- seed = 0x38;
- }
- }
- } else if (pDCTstat->Status & (1 << SB_LoadReduced)) {
- if (package_type == PT_GR) {
- /* Socket G34: Fam15h BKDG v3.14 Table 99 */
- if (MaxDimmsInstallable == 1) {
- if (channel == 0)
- seed = 0x123;
- else if (channel == 1)
- seed = 0x122;
- else if (channel == 2)
- seed = 0x112;
- else if (channel == 3)
- seed = 0x102;
- }
- } else if (package_type == PT_C3) {
- /* Socket C32: Fam15h BKDG v3.14 Table 100 */
- if (channel == 0)
- seed = 0x132;
- else if (channel == 1)
- seed = 0x122;
- }
- } else {
- if (package_type == PT_GR) {
- /* Socket G34: Fam15h BKDG v3.14 Table 99 */
- if (MaxDimmsInstallable == 1) {
- if (channel == 0)
- seed = 0x3e;
- else if (channel == 1)
- seed = 0x38;
- else if (channel == 2)
- seed = 0x37;
- else if (channel == 3)
- seed = 0x31;
- } else if (MaxDimmsInstallable == 2) {
- if (channel == 0)
- seed = 0x51;
- else if (channel == 1)
- seed = 0x4a;
- else if (channel == 2)
- seed = 0x46;
- else if (channel == 3)
- seed = 0x3f;
- } else if (MaxDimmsInstallable == 3) {
- if (channel == 0)
- seed = 0x5e;
- else if (channel == 1)
- seed = 0x52;
- else if (channel == 2)
- seed = 0x48;
- else if (channel == 3)
- seed = 0x3c;
- }
- } else if (package_type == PT_C3) {
- /* Socket C32: Fam15h BKDG v3.14 Table 100 */
- if ((MaxDimmsInstallable == 1) || (MaxDimmsInstallable == 2)) {
- if (channel == 0)
- seed = 0x39;
- else if (channel == 1)
- seed = 0x32;
- } else if (MaxDimmsInstallable == 3) {
- if (channel == 0)
- seed = 0x45;
- else if (channel == 1)
- seed = 0x37;
- }
- } else if (package_type == PT_M2) {
- /* Socket AM3: Fam15h BKDG v3.14 Table 101 */
- seed = 0x3a;
- } else if (package_type == PT_FM2) {
- /* Socket FM2: Fam15h Model10 BKDG 3.12 Table 43 */
- seed = 0x32;
- }
- }
-
- printk(BIOS_DEBUG, "%s: using seed: %04x\n", __func__, seed);
-
- return seed;
-}
-
-void read_dqs_write_timing_control_registers(uint16_t *current_total_delay, uint32_t dev, uint8_t dct, uint8_t dimm, uint32_t index_reg)
-{
- uint8_t lane;
- uint32_t dword;
-
- for (lane = 0; lane < MAX_BYTE_LANES; lane++) {
- uint32_t wdt_reg;
- if ((lane == 0) || (lane == 1))
- wdt_reg = 0x30;
- if ((lane == 2) || (lane == 3))
- wdt_reg = 0x31;
- if ((lane == 4) || (lane == 5))
- wdt_reg = 0x40;
- if ((lane == 6) || (lane == 7))
- wdt_reg = 0x41;
- if (lane == 8)
- wdt_reg = 0x32;
- wdt_reg += dimm * 3;
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, wdt_reg);
- if ((lane == 7) || (lane == 5) || (lane == 3) || (lane == 1))
- current_total_delay[lane] = (dword & 0x00ff0000) >> 16;
- if ((lane == 8) || (lane == 6) || (lane == 4) || (lane == 2) || (lane == 0))
- current_total_delay[lane] = dword & 0x000000ff;
- }
-}
-
-#ifdef UNUSED_CODE
-static void write_dqs_write_timing_control_registers(uint16_t *current_total_delay, uint32_t dev, uint8_t dct, uint8_t dimm, uint32_t index_reg)
-{
- uint8_t lane;
- uint32_t dword;
-
- for (lane = 0; lane < MAX_BYTE_LANES; lane++) {
- uint32_t ret_reg;
- if ((lane == 0) || (lane == 1))
- ret_reg = 0x30;
- if ((lane == 2) || (lane == 3))
- ret_reg = 0x31;
- if ((lane == 4) || (lane == 5))
- ret_reg = 0x40;
- if ((lane == 6) || (lane == 7))
- ret_reg = 0x41;
- if (lane == 8)
- ret_reg = 0x32;
- ret_reg += dimm * 3;
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, ret_reg);
- if ((lane == 7) || (lane == 5) || (lane == 3) || (lane == 1)) {
- dword &= ~(0xff << 16);
- dword |= (current_total_delay[lane] & 0xff) << 16;
- }
- if ((lane == 8) || (lane == 6) || (lane == 4) || (lane == 2) || (lane == 0)) {
- dword &= ~0xff;
- dword |= current_total_delay[lane] & 0xff;
- }
- Set_NB32_index_wait_DCT(dev, dct, index_reg, ret_reg, dword);
- }
-}
-#endif
-
-static void write_write_data_timing_control_registers(uint16_t *current_total_delay, uint32_t dev, uint8_t dct, uint8_t dimm, uint32_t index_reg)
-{
- uint8_t lane;
- uint32_t dword;
-
- for (lane = 0; lane < MAX_BYTE_LANES; lane++) {
- uint32_t wdt_reg;
-
- /* Calculate Write Data Timing register location */
- if ((lane == 0) || (lane == 1) || (lane == 2) || (lane == 3))
- wdt_reg = 0x1;
- if ((lane == 4) || (lane == 5) || (lane == 6) || (lane == 7))
- wdt_reg = 0x2;
- if (lane == 8)
- wdt_reg = 0x3;
- wdt_reg |= (dimm << 8);
-
- /* Set Write Data Timing register values */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, wdt_reg);
- if ((lane == 7) || (lane == 3)) {
- dword &= ~(0x7f << 24);
- dword |= (current_total_delay[lane] & 0x7f) << 24;
- }
- if ((lane == 6) || (lane == 2)) {
- dword &= ~(0x7f << 16);
- dword |= (current_total_delay[lane] & 0x7f) << 16;
- }
- if ((lane == 5) || (lane == 1)) {
- dword &= ~(0x7f << 8);
- dword |= (current_total_delay[lane] & 0x7f) << 8;
- }
- if ((lane == 8) || (lane == 4) || (lane == 0)) {
- dword &= ~0x7f;
- dword |= current_total_delay[lane] & 0x7f;
- }
- Set_NB32_index_wait_DCT(dev, dct, index_reg, wdt_reg, dword);
- }
-}
-
-void read_dqs_receiver_enable_control_registers(uint16_t *current_total_delay, uint32_t dev, uint8_t dct, uint8_t dimm, uint32_t index_reg)
-{
- uint8_t lane;
- uint32_t mask;
- uint32_t dword;
-
- if (is_fam15h())
- mask = 0x3ff;
- else
- mask = 0x1ff;
-
- for (lane = 0; lane < MAX_BYTE_LANES; lane++) {
- uint32_t ret_reg;
- if ((lane == 0) || (lane == 1))
- ret_reg = 0x10;
- if ((lane == 2) || (lane == 3))
- ret_reg = 0x11;
- if ((lane == 4) || (lane == 5))
- ret_reg = 0x20;
- if ((lane == 6) || (lane == 7))
- ret_reg = 0x21;
- if (lane == 8)
- ret_reg = 0x12;
- ret_reg += dimm * 3;
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, ret_reg);
- if ((lane == 7) || (lane == 5) || (lane == 3) || (lane == 1)) {
- current_total_delay[lane] = (dword & (mask << 16)) >> 16;
- }
- if ((lane == 8) || (lane == 6) || (lane == 4) || (lane == 2) || (lane == 0)) {
- current_total_delay[lane] = dword & mask;
- }
- }
-}
-
-void write_dqs_receiver_enable_control_registers(uint16_t *current_total_delay, uint32_t dev, uint8_t dct, uint8_t dimm, uint32_t index_reg)
-{
- uint8_t lane;
- uint32_t mask;
- uint32_t dword;
-
- if (is_fam15h())
- mask = 0x3ff;
- else
- mask = 0x1ff;
-
- for (lane = 0; lane < MAX_BYTE_LANES; lane++) {
- uint32_t ret_reg;
- if ((lane == 0) || (lane == 1))
- ret_reg = 0x10;
- if ((lane == 2) || (lane == 3))
- ret_reg = 0x11;
- if ((lane == 4) || (lane == 5))
- ret_reg = 0x20;
- if ((lane == 6) || (lane == 7))
- ret_reg = 0x21;
- if (lane == 8)
- ret_reg = 0x12;
- ret_reg += dimm * 3;
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, ret_reg);
- if ((lane == 7) || (lane == 5) || (lane == 3) || (lane == 1)) {
- dword &= ~(mask << 16);
- dword |= (current_total_delay[lane] & mask) << 16;
- }
- if ((lane == 8) || (lane == 6) || (lane == 4) || (lane == 2) || (lane == 0)) {
- dword &= ~mask;
- dword |= current_total_delay[lane] & mask;
- }
- Set_NB32_index_wait_DCT(dev, dct, index_reg, ret_reg, dword);
- }
-}
-
-static void read_dram_phase_recovery_control_registers(uint16_t *current_total_delay, uint32_t dev, uint8_t dct, uint8_t dimm, uint32_t index_reg)
-{
- uint8_t lane;
- uint32_t dword;
-
- for (lane = 0; lane < MAX_BYTE_LANES; lane++) {
- uint32_t prc_reg;
-
- /* Calculate DRAM Phase Recovery Control register location */
- if ((lane == 0) || (lane == 1) || (lane == 2) || (lane == 3))
- prc_reg = 0x50;
- if ((lane == 4) || (lane == 5) || (lane == 6) || (lane == 7))
- prc_reg = 0x51;
- if (lane == 8)
- prc_reg = 0x52;
-
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, prc_reg);
- if ((lane == 7) || (lane == 3)) {
- current_total_delay[lane] = (dword >> 24) & 0x7f;
- }
- if ((lane == 6) || (lane == 2)) {
- current_total_delay[lane] = (dword >> 16) & 0x7f;
- }
- if ((lane == 5) || (lane == 1)) {
- current_total_delay[lane] = (dword >> 8) & 0x7f;
- }
- if ((lane == 8) || (lane == 4) || (lane == 0)) {
- current_total_delay[lane] = dword & 0x7f;
- }
- }
-}
-
-static void write_dram_phase_recovery_control_registers(uint16_t *current_total_delay, uint32_t dev, uint8_t dct, uint8_t dimm, uint32_t index_reg)
-{
- uint8_t lane;
- uint32_t dword;
-
- for (lane = 0; lane < MAX_BYTE_LANES; lane++) {
- uint32_t prc_reg;
-
- /* Calculate DRAM Phase Recovery Control register location */
- if ((lane == 0) || (lane == 1) || (lane == 2) || (lane == 3))
- prc_reg = 0x50;
- if ((lane == 4) || (lane == 5) || (lane == 6) || (lane == 7))
- prc_reg = 0x51;
- if (lane == 8)
- prc_reg = 0x52;
-
- /* Set DRAM Phase Recovery Control register values */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, prc_reg);
- if ((lane == 7) || (lane == 3)) {
- dword &= ~(0x7f << 24);
- dword |= (current_total_delay[lane] & 0x7f) << 24;
- }
- if ((lane == 6) || (lane == 2)) {
- dword &= ~(0x7f << 16);
- dword |= (current_total_delay[lane] & 0x7f) << 16;
- }
- if ((lane == 5) || (lane == 1)) {
- dword &= ~(0x7f << 8);
- dword |= (current_total_delay[lane] & 0x7f) << 8;
- }
- if ((lane == 8) || (lane == 4) || (lane == 0)) {
- dword &= ~0x7f;
- dword |= current_total_delay[lane] & 0x7f;
- }
- Set_NB32_index_wait_DCT(dev, dct, index_reg, prc_reg, dword);
- }
-}
-
-void read_dqs_read_data_timing_registers(uint16_t *delay, uint32_t dev, uint8_t dct, uint8_t dimm, uint32_t index_reg)
-{
- uint8_t shift;
- uint32_t dword;
- uint32_t mask;
-
- if (is_fam15h()) {
- mask = 0x3e;
- shift = 1;
- }
- else {
- mask = 0x3f;
- shift = 0;
- }
-
- /* Lanes 0 - 3 */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x5 | (dimm << 8));
- delay[3] = ((dword >> 24) & mask) >> shift;
- delay[2] = ((dword >> 16) & mask) >> shift;
- delay[1] = ((dword >> 8) & mask) >> shift;
- delay[0] = (dword & mask) >> shift;
-
- /* Lanes 4 - 7 */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x6 | (dimm << 8));
- delay[7] = ((dword >> 24) & mask) >> shift;
- delay[6] = ((dword >> 16) & mask) >> shift;
- delay[5] = ((dword >> 8) & mask) >> shift;
- delay[4] = (dword & mask) >> shift;
-
- /* Lane 8 (ECC) */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x7 | (dimm << 8));
- delay[8] = (dword & mask) >> shift;
-}
-
-void write_dqs_read_data_timing_registers(uint16_t *delay, uint32_t dev, uint8_t dct, uint8_t dimm, uint32_t index_reg)
-{
- uint8_t shift;
- uint32_t dword;
- uint32_t mask;
-
- if (is_fam15h()) {
- mask = 0x3e;
- shift = 1;
- }
- else {
- mask = 0x3f;
- shift = 0;
- }
-
- /* Lanes 0 - 3 */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x5 | (dimm << 8));
- dword &= ~(mask << 24);
- dword &= ~(mask << 16);
- dword &= ~(mask << 8);
- dword &= ~mask;
- dword |= ((delay[3] << shift) & mask) << 24;
- dword |= ((delay[2] << shift) & mask) << 16;
- dword |= ((delay[1] << shift) & mask) << 8;
- dword |= (delay[0] << shift) & mask;
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x5 | (dimm << 8), dword);
-
- /* Lanes 4 - 7 */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x6 | (dimm << 8));
- dword &= ~(mask << 24);
- dword &= ~(mask << 16);
- dword &= ~(mask << 8);
- dword &= ~mask;
- dword |= ((delay[7] << shift) & mask) << 24;
- dword |= ((delay[6] << shift) & mask) << 16;
- dword |= ((delay[5] << shift) & mask) << 8;
- dword |= (delay[4] << shift) & mask;
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x6 | (dimm << 8), dword);
-
- /* Lane 8 (ECC) */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x7 | (dimm << 8));
- dword &= ~mask;
- dword |= (delay[8] << shift) & mask;
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x7 | (dimm << 8), dword);
-}
-
-static uint32_t convert_testaddr_and_channel_to_address(struct DCTStatStruc *pDCTstat, uint32_t testaddr, uint8_t channel)
-{
- SetUpperFSbase(testaddr);
- testaddr <<= 8;
-
- if ((pDCTstat->Status & (1<<SB_128bitmode)) && channel) {
- testaddr += 8; /* second channel */
- }
-
- return testaddr;
-}
-
-/* DQS Receiver Enable Training (Family 10h)
- * Algorithm detailed in:
- * The Fam10h BKDG Rev. 3.62 section 2.8.9.9.2
- */
-static void dqsTrainRcvrEn_SW_Fam10(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 Pass)
-{
- u8 Channel;
- u8 _2Ranks;
- u8 Addl_Index = 0;
- u8 Receiver;
- u8 _DisableDramECC = 0, _Wrap32Dis = 0, _SSE2 = 0;
- u16 CTLRMaxDelay;
- u16 MaxDelay_CH[2];
- u32 TestAddr0, TestAddr1, TestAddr0B, TestAddr1B;
- u32 PatternBuffer[64+4]; /* FIXME: need increase 8? */
- u32 Errors;
-
- u32 val;
- u32 reg;
- u32 dev;
- u32 index_reg;
- u32 ch_start, ch_end, ch;
- msr_t msr;
- CRx_TYPE cr4;
-
- uint32_t dword;
- uint8_t dimm;
- uint8_t rank;
- uint8_t lane;
- uint16_t current_total_delay[MAX_BYTE_LANES];
- uint16_t candidate_total_delay[8];
- uint8_t data_test_pass_sr[2][8]; /* [rank][lane] */
- uint8_t data_test_pass[8]; /* [lane] */
- uint8_t data_test_pass_prev[8]; /* [lane] */
- uint8_t window_det_toggle[8];
- uint8_t trained[8];
- uint64_t result_qword1;
- uint64_t result_qword2;
-
- u8 valid;
-
- print_debug_dqs("\nTrainRcvEn: Node", pDCTstat->Node_ID, 0);
- print_debug_dqs("TrainRcvEn: Pass", Pass, 0);
-
- dev = pDCTstat->dev_dct;
- ch_start = 0;
- if (!pDCTstat->GangedMode) {
- ch_end = 2;
- } else {
- ch_end = 1;
- }
-
- for (ch = ch_start; ch < ch_end; ch++) {
- reg = 0x78;
- val = Get_NB32_DCT(dev, ch, reg);
- val &= ~(0x3ff << 22);
- val |= (0x0c8 << 22); /* MaxRdLatency = 0xc8 */
- Set_NB32_DCT(dev, ch, reg, val);
- }
-
- if (Pass == FirstPass) {
- mct_InitDQSPos4RcvrEn_D(pMCTstat, pDCTstat);
- } else {
- pDCTstat->DimmTrainFail = 0;
- pDCTstat->CSTrainFail = ~pDCTstat->CSPresent;
- }
-
- cr4 = read_cr4();
- if (cr4 & (1 << 9)) { /* save the old value */
- _SSE2 = 1;
- }
- cr4 |= (1 << 9); /* OSFXSR enable SSE2 */
- write_cr4(cr4);
-
- msr = rdmsr(HWCR_MSR);
- /* FIXME: Why use SSEDIS */
- if (msr.lo & (1 << 17)) { /* save the old value */
- _Wrap32Dis = 1;
- }
- msr.lo |= (1 << 17); /* HWCR.wrap32dis */
- msr.lo &= ~(1 << 15); /* SSEDIS */
- wrmsr(HWCR_MSR, msr); /* Setting wrap32dis allows 64-bit memory
- references in real mode */
-
- _DisableDramECC = mct_DisableDimmEccEn_D(pMCTstat, pDCTstat);
-
- SetupRcvrPattern(pMCTstat, pDCTstat, PatternBuffer, Pass);
-
- Errors = 0;
- dev = pDCTstat->dev_dct;
-
- for (Channel = 0; Channel < 2; Channel++) {
- print_debug_dqs("\tTrainRcvEn51: Node ", pDCTstat->Node_ID, 1);
- print_debug_dqs("\tTrainRcvEn51: Channel ", Channel, 1);
- pDCTstat->Channel = Channel;
-
- CTLRMaxDelay = 0;
- MaxDelay_CH[Channel] = 0;
- index_reg = 0x98;
-
- Receiver = mct_InitReceiver_D(pDCTstat, Channel);
- /* There are four receiver pairs, loosely associated with chipselects.
- * This is essentially looping over each DIMM.
- */
- for (; Receiver < 8; Receiver += 2) {
- Addl_Index = (Receiver >> 1) * 3 + 0x10;
- dimm = (Receiver >> 1);
-
- print_debug_dqs("\t\tTrainRcvEnd52: index ", Addl_Index, 2);
-
- if (!mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, Channel, Receiver)) {
- continue;
- }
-
- /* Clear data structures */
- for (lane = 0; lane < 8; lane++) {
- data_test_pass_prev[lane] = 0;
- trained[lane] = 0;
- }
-
- /* 2.8.9.9.2 (1, 6)
- * Retrieve gross and fine timing fields from write DQS registers
- */
- read_dqs_write_timing_control_registers(current_total_delay, dev, Channel, dimm, index_reg);
-
- /* 2.8.9.9.2 (1)
- * Program the Write Data Timing and Write ECC Timing register to
- * the values stored in the DQS Write Timing Control register
- * for each lane
- */
- write_write_data_timing_control_registers(current_total_delay, dev, Channel, dimm, index_reg);
-
- /* 2.8.9.9.2 (2)
- * Program the Read DQS Timing Control and the Read DQS ECC Timing Control registers
- * to 1/2 MEMCLK for all lanes
- */
- for (lane = 0; lane < MAX_BYTE_LANES; lane++) {
- uint32_t rdt_reg;
- if ((lane == 0) || (lane == 1) || (lane == 2) || (lane == 3))
- rdt_reg = 0x5;
- if ((lane == 4) || (lane == 5) || (lane == 6) || (lane == 7))
- rdt_reg = 0x6;
- if (lane == 8)
- rdt_reg = 0x7;
- rdt_reg |= (dimm << 8);
- if (lane == 8)
- dword = 0x0000003f;
- else
- dword = 0x3f3f3f3f;
- Set_NB32_index_wait_DCT(dev, Channel, index_reg, rdt_reg, dword);
- }
-
- /* 2.8.9.9.2 (3)
- * Select two test addresses for each rank present
- */
- TestAddr0 = mct_GetRcvrSysAddr_D(pMCTstat, pDCTstat, Channel, Receiver, &valid);
- if (!valid) { /* Address not supported on current CS */
- continue;
- }
-
- TestAddr0B = TestAddr0 + (BigPagex8_RJ8 << 3);
-
- if (mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, Channel, Receiver+1)) {
- TestAddr1 = mct_GetRcvrSysAddr_D(pMCTstat, pDCTstat, Channel, Receiver+1, &valid);
- if (!valid) { /* Address not supported on current CS */
- continue;
- }
- TestAddr1B = TestAddr1 + (BigPagex8_RJ8 << 3);
- _2Ranks = 1;
- } else {
- _2Ranks = TestAddr1 = TestAddr1B = 0;
- }
-
- print_debug_dqs("\t\tTrainRcvEn53: TestAddr0 ", TestAddr0, 2);
- print_debug_dqs("\t\tTrainRcvEn53: TestAddr0B ", TestAddr0B, 2);
- print_debug_dqs("\t\tTrainRcvEn53: TestAddr1 ", TestAddr1, 2);
- print_debug_dqs("\t\tTrainRcvEn53: TestAddr1B ", TestAddr1B, 2);
-
- /* 2.8.9.9.2 (4, 5)
- * Write 1 cache line of the appropriate test pattern to each test address
- */
- mct_Write1LTestPattern_D(pMCTstat, pDCTstat, TestAddr0, 0); /* rank 0 of DIMM, testpattern 0 */
- mct_Write1LTestPattern_D(pMCTstat, pDCTstat, TestAddr0B, 1); /* rank 0 of DIMM, testpattern 1 */
- if (_2Ranks) {
- mct_Write1LTestPattern_D(pMCTstat, pDCTstat, TestAddr1, 0); /*rank 1 of DIMM, testpattern 0 */
- mct_Write1LTestPattern_D(pMCTstat, pDCTstat, TestAddr1B, 1); /*rank 1 of DIMM, testpattern 1 */
- }
-
-#if DQS_TRAIN_DEBUG > 0
- for (lane = 0; lane < 8; lane++) {
- print_debug_dqs("\t\tTrainRcvEn54: lane: ", lane, 2);
- print_debug_dqs("\t\tTrainRcvEn54: current_total_delay ", current_total_delay[lane], 2);
- }
-#endif
-
- /* 2.8.9.9.2 (6)
- * Write gross and fine timing fields to read DQS registers
- */
- write_dqs_receiver_enable_control_registers(current_total_delay, dev, Channel, dimm, index_reg);
-
- /* 2.8.9.9.2 (7)
- * Loop over all delay values up to 1 MEMCLK (0x40 delay steps) from the initial delay values
- *
- * FIXME
- * It is not clear if training should be discontinued if any test failures occur in the first
- * 1 MEMCLK window, or if it should be discontinued if no successes occur in the first 1 MEMCLK
- * window. Therefore, loop over up to 2 MEMCLK (0x80 delay steps) to be on the safe side.
- */
- uint16_t current_delay_step;
-
- for (current_delay_step = 0; current_delay_step < 0x80; current_delay_step++) {
- print_debug_dqs("\t\t\tTrainRcvEn541: current_delay_step ", current_delay_step, 3);
-
- /* 2.8.9.9.2 (7 D)
- * Terminate if all lanes are trained
- */
- uint8_t all_lanes_trained = 1;
- for (lane = 0; lane < 8; lane++)
- if (!trained[lane])
- all_lanes_trained = 0;
-
- if (all_lanes_trained)
- break;
-
- /* 2.8.9.9.2 (7 A)
- * Loop over all ranks
- */
- for (rank = 0; rank < (_2Ranks + 1); rank++) {
- /* 2.8.9.9.2 (7 A a-d)
- * Read the first test address of the current rank
- * Store the first data beat for analysis
- * Reset read pointer in the DRAM controller FIFO
- * Read the second test address of the current rank
- * Store the first data beat for analysis
- * Reset read pointer in the DRAM controller FIFO
- */
- if (rank & 1) {
- /* 2.8.9.9.2 (7 D)
- * Invert read instructions to alternate data read order on the bus
- */
- proc_IOCLFLUSH_D((rank == 0)?TestAddr0B:TestAddr1B);
- result_qword2 = read64_fs(convert_testaddr_and_channel_to_address(pDCTstat, (rank == 0)?TestAddr0B:TestAddr1B, Channel));
- write_dqs_receiver_enable_control_registers(current_total_delay, dev, Channel, dimm, index_reg);
- proc_IOCLFLUSH_D((rank == 0)?TestAddr0:TestAddr1);
- result_qword1 = read64_fs(convert_testaddr_and_channel_to_address(pDCTstat, (rank == 0)?TestAddr0:TestAddr1, Channel));
- write_dqs_receiver_enable_control_registers(current_total_delay, dev, Channel, dimm, index_reg);
- } else {
- proc_IOCLFLUSH_D((rank == 0)?TestAddr0:TestAddr1);
- result_qword1 = read64_fs(convert_testaddr_and_channel_to_address(pDCTstat, (rank == 0)?TestAddr0:TestAddr1, Channel));
- write_dqs_receiver_enable_control_registers(current_total_delay, dev, Channel, dimm, index_reg);
- proc_IOCLFLUSH_D((rank == 0)?TestAddr0B:TestAddr1B);
- result_qword2 = read64_fs(convert_testaddr_and_channel_to_address(pDCTstat, (rank == 0)?TestAddr0B:TestAddr1B, Channel));
- write_dqs_receiver_enable_control_registers(current_total_delay, dev, Channel, dimm, index_reg);
- }
- /* 2.8.9.9.2 (7 A e)
- * Compare both read patterns and flag passing ranks/lanes
- */
- uint8_t result_lane_byte1;
- uint8_t result_lane_byte2;
- for (lane = 0; lane < 8; lane++) {
- if (trained[lane] == 1) {
-#if DQS_TRAIN_DEBUG > 0
- print_debug_dqs("\t\t\t\t\t\t\t\t lane already trained: ", lane, 4);
-#endif
- continue;
- }
-
- result_lane_byte1 = (result_qword1 >> (lane * 8)) & 0xff;
- result_lane_byte2 = (result_qword2 >> (lane * 8)) & 0xff;
- if ((result_lane_byte1 == 0x55) && (result_lane_byte2 == 0xaa))
- data_test_pass_sr[rank][lane] = 1;
- else
- data_test_pass_sr[rank][lane] = 0;
-#if DQS_TRAIN_DEBUG > 0
- print_debug_dqs_pair("\t\t\t\t\t\t\t\t ", 0x55, " | ", result_lane_byte1, 4);
- print_debug_dqs_pair("\t\t\t\t\t\t\t\t ", 0xaa, " | ", result_lane_byte2, 4);
-#endif
- }
- }
-
- /* 2.8.9.9.2 (7 B)
- * If DIMM is dual rank, only use delays that pass testing for both ranks
- */
- for (lane = 0; lane < 8; lane++) {
- if (_2Ranks) {
- if ((data_test_pass_sr[0][lane]) && (data_test_pass_sr[1][lane]))
- data_test_pass[lane] = 1;
- else
- data_test_pass[lane] = 0;
- } else {
- data_test_pass[lane] = data_test_pass_sr[0][lane];
- }
- }
-
- /* 2.8.9.9.2 (7 E)
- * For each lane, update the DQS receiver delay setting in support of next iteration
- */
- for (lane = 0; lane < 8; lane++) {
- if (trained[lane] == 1)
- continue;
-
- /* 2.8.9.9.2 (7 C a)
- * Save the total delay of the first success after a failure for later use
- */
- if ((data_test_pass[lane] == 1) && (data_test_pass_prev[lane] == 0)) {
- candidate_total_delay[lane] = current_total_delay[lane];
- window_det_toggle[lane] = 0;
- }
-
- /* 2.8.9.9.2 (7 C b)
- * If the current delay failed testing add 1/8 UI to the current delay
- */
- if (data_test_pass[lane] == 0)
- current_total_delay[lane] += 0x4;
-
- /* 2.8.9.9.2 (7 C c)
- * If the current delay passed testing alternately add either 1/32 UI or 1/4 UI to the current delay
- * If 1.25 UI of delay have been added with no failures the lane is considered trained
- */
- if (data_test_pass[lane] == 1) {
- /* See if lane is trained */
- if ((current_total_delay[lane] - candidate_total_delay[lane]) >= 0x28) {
- trained[lane] = 1;
-
- /* Calculate and set final lane delay value
- * The final delay is the candidate delay + 7/8 UI
- */
- current_total_delay[lane] = candidate_total_delay[lane] + 0x1c;
- } else {
- if (window_det_toggle[lane] == 0) {
- current_total_delay[lane] += 0x1;
- window_det_toggle[lane] = 1;
- } else {
- current_total_delay[lane] += 0x8;
- window_det_toggle[lane] = 0;
- }
- }
- }
- }
-
- /* Update delays in hardware */
- write_dqs_receiver_enable_control_registers(current_total_delay, dev, Channel, dimm, index_reg);
-
- /* Save previous results for comparison in the next iteration */
- for (lane = 0; lane < 8; lane++)
- data_test_pass_prev[lane] = data_test_pass[lane];
- }
-
-#if DQS_TRAIN_DEBUG > 0
- for (lane = 0; lane < 8; lane++)
- print_debug_dqs_pair("\t\tTrainRcvEn55: Lane ", lane, " current_total_delay ", current_total_delay[lane], 2);
-#endif
-
- /* Find highest delay value and save for later use */
- for (lane = 0; lane < 8; lane++)
- if (current_total_delay[lane] > CTLRMaxDelay)
- CTLRMaxDelay = current_total_delay[lane];
-
- /* See if any lanes failed training, and set error flags appropriately
- * For all trained lanes, save delay values for later use
- */
- for (lane = 0; lane < 8; lane++) {
- if (trained[lane]) {
- pDCTstat->CH_D_B_RCVRDLY[Channel][Receiver >> 1][lane] = current_total_delay[lane];
- } else {
- printk(BIOS_WARNING, "TrainRcvrEn: WARNING: Lane %d of receiver %d on channel %d failed training!\n", lane, Receiver, Channel);
-
- /* Set error flags */
- pDCTstat->ErrStatus |= 1 << SB_NORCVREN;
- Errors |= 1 << SB_NORCVREN;
- pDCTstat->ErrCode = SC_FatalErr;
- pDCTstat->CSTrainFail |= 1 << Receiver;
- pDCTstat->DimmTrainFail |= 1 << (Receiver + Channel);
- }
- }
-
- /* 2.8.9.9.2 (8)
- * Flush the receiver FIFO
- * Write one full cache line of non-0x55/0xaa data to one of the test addresses, then read it back to flush the FIFO
- */
- /* FIXME
- * This does not seem to be needed, and has a tendency to lock up the
- * boot process while attempting to write the test pattern.
- */
- }
- MaxDelay_CH[Channel] = CTLRMaxDelay;
- }
-
- CTLRMaxDelay = MaxDelay_CH[0];
- if (MaxDelay_CH[1] > CTLRMaxDelay)
- CTLRMaxDelay = MaxDelay_CH[1];
-
- for (Channel = 0; Channel < 2; Channel++) {
- mct_SetMaxLatency_D(pDCTstat, Channel, CTLRMaxDelay); /* program Ch A/B MaxAsyncLat to correspond with max delay */
- }
-
- for (Channel = 0; Channel < 2; Channel++) {
- ResetDCTWrPtr_D(dev, Channel, index_reg, Addl_Index);
- }
-
- if (_DisableDramECC) {
- mct_EnableDimmEccEn_D(pMCTstat, pDCTstat, _DisableDramECC);
- }
-
- if (Pass == FirstPass) {
- /*Disable DQSRcvrEn training mode */
- mct_DisableDQSRcvEn_D(pDCTstat);
- }
-
- if (!_Wrap32Dis) {
- msr = rdmsr(HWCR_MSR);
- msr.lo &= ~(1<<17); /* restore HWCR.wrap32dis */
- wrmsr(HWCR_MSR, msr);
- }
- if (!_SSE2) {
- cr4 = read_cr4();
- cr4 &= ~(1<<9); /* restore cr4.OSFXSR */
- write_cr4(cr4);
- }
-
-#if DQS_TRAIN_DEBUG > 0
- {
- u8 ChannelDTD;
- printk(BIOS_DEBUG, "TrainRcvrEn: CH_MaxRdLat:\n");
- for (ChannelDTD = 0; ChannelDTD < 2; ChannelDTD++) {
- printk(BIOS_DEBUG, "Channel:%x: %x\n",
- ChannelDTD, pDCTstat->CH_MaxRdLat[ChannelDTD][0]);
- }
- }
-#endif
-
-#if DQS_TRAIN_DEBUG > 0
- {
- u16 valDTD;
- u8 ChannelDTD, ReceiverDTD;
- u8 i;
- u16 *p;
-
- printk(BIOS_DEBUG, "TrainRcvrEn: CH_D_B_RCVRDLY:\n");
- for (ChannelDTD = 0; ChannelDTD < 2; ChannelDTD++) {
- printk(BIOS_DEBUG, "Channel:%x\n", ChannelDTD);
- for (ReceiverDTD = 0; ReceiverDTD < 8; ReceiverDTD+=2) {
- printk(BIOS_DEBUG, "\t\tReceiver:%x:", ReceiverDTD);
- p = pDCTstat->CH_D_B_RCVRDLY[ChannelDTD][ReceiverDTD>>1];
- for (i = 0; i < 8; i++) {
- valDTD = p[i];
- printk(BIOS_DEBUG, " %03x", valDTD);
- }
- printk(BIOS_DEBUG, "\n");
- }
- }
- }
-#endif
-
- printk(BIOS_DEBUG, "TrainRcvrEn: Status %x\n", pDCTstat->Status);
- printk(BIOS_DEBUG, "TrainRcvrEn: ErrStatus %x\n", pDCTstat->ErrStatus);
- printk(BIOS_DEBUG, "TrainRcvrEn: ErrCode %x\n", pDCTstat->ErrCode);
- printk(BIOS_DEBUG, "TrainRcvrEn: Done\n\n");
-}
-
-/* DQS Receiver Enable Training Pattern Generation (Family 15h)
- * Algorithm detailed in:
- * The Fam15h BKDG Rev. 3.14 section 2.10.5.8.2 (4)
- */
-static void generate_dram_receiver_enable_training_pattern_fam15(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t Receiver)
-{
- uint32_t dword;
- uint32_t dev = pDCTstat->dev_dct;
-
- /* 2.10.5.7.1.1
- * It appears that the DCT only supports 8-beat burst length mode,
- * so do nothing here...
- */
-
- /* Wait for CmdSendInProg == 0 */
- do {
- dword = Get_NB32_DCT(dev, dct, 0x250);
- } while (dword & (0x1 << 12));
-
- /* Set CmdTestEnable = 1 */
- dword = Get_NB32_DCT(dev, dct, 0x250);
- dword |= (0x1 << 2);
- Set_NB32_DCT(dev, dct, 0x250, dword);
-
- /* 2.10.5.8.6.1.1 Send Activate Command */
- dword = Get_NB32_DCT(dev, dct, 0x28c);
- dword &= ~(0xff << 22); /* CmdChipSelect = Receiver */
- dword |= ((0x1 << Receiver) << 22);
- dword &= ~(0x7 << 19); /* CmdBank = 0 */
- dword &= ~(0x3ffff); /* CmdAddress = 0 */
- dword |= (0x1 << 31); /* SendActCmd = 1 */
- Set_NB32_DCT(dev, dct, 0x28c, dword);
-
- /* Wait for SendActCmd == 0 */
- do {
- dword = Get_NB32_DCT(dev, dct, 0x28c);
- } while (dword & (0x1 << 31));
-
- /* Wait 75 MEMCLKs. */
- precise_memclk_delay_fam15(pMCTstat, pDCTstat, dct, 75);
-
- /* 2.10.5.8.6.1.2 */
- Set_NB32_DCT(dev, dct, 0x274, 0x0); /* DQMask = 0 */
- Set_NB32_DCT(dev, dct, 0x278, 0x0);
-
- dword = Get_NB32_DCT(dev, dct, 0x27c);
- dword &= ~(0xff); /* EccMask = 0 */
- if (pDCTstat->DimmECCPresent == 0)
- dword |= 0xff; /* EccMask = 0xff */
- Set_NB32_DCT(dev, dct, 0x27c, dword);
-
- /* 2.10.5.8.6.1.2 */
- dword = Get_NB32_DCT(dev, dct, 0x270);
- dword &= ~(0x7ffff); /* DataPrbsSeed = 55555 */
- dword |= (0x44443); /* Use AGESA seed */
- Set_NB32_DCT(dev, dct, 0x270, dword);
-
- /* 2.10.5.8.2 (4) */
- dword = Get_NB32_DCT(dev, dct, 0x260);
- dword &= ~(0x1fffff); /* CmdCount = 192 */
- dword |= 192;
- Set_NB32_DCT(dev, dct, 0x260, dword);
-
- /* Configure Target A */
- dword = Get_NB32_DCT(dev, dct, 0x254);
- dword &= ~(0x7 << 24); /* TgtChipSelect = Receiver */
- dword |= (Receiver & 0x7) << 24;
- dword &= ~(0x7 << 21); /* TgtBank = 0 */
- dword &= ~(0x3ff); /* TgtAddress = 0 */
- Set_NB32_DCT(dev, dct, 0x254, dword);
-
- dword = Get_NB32_DCT(dev, dct, 0x250);
- dword |= (0x1 << 3); /* ResetAllErr = 1 */
- dword &= ~(0x1 << 4); /* StopOnErr = 0 */
- dword &= ~(0x3 << 8); /* CmdTgt = 0 (Target A) */
- dword &= ~(0x7 << 5); /* CmdType = 0 (Read) */
- dword |= (0x1 << 11); /* SendCmd = 1 */
- Set_NB32_DCT(dev, dct, 0x250, dword);
-
- /* 2.10.5.8.6.1.2 Wait for TestStatus == 1 and CmdSendInProg == 0 */
- do {
- dword = Get_NB32_DCT(dev, dct, 0x250);
- } while ((dword & (0x1 << 12)) || (!(dword & (0x1 << 10))));
-
- dword = Get_NB32_DCT(dev, dct, 0x250);
- dword &= ~(0x1 << 11); /* SendCmd = 0 */
- Set_NB32_DCT(dev, dct, 0x250, dword);
-
- /* 2.10.5.8.6.1.1 Send Precharge Command */
- /* Wait 25 MEMCLKs. */
- precise_memclk_delay_fam15(pMCTstat, pDCTstat, dct, 25);
-
- dword = Get_NB32_DCT(dev, dct, 0x28c);
- dword &= ~(0xff << 22); /* CmdChipSelect = Receiver */
- dword |= ((0x1 << Receiver) << 22);
- dword &= ~(0x7 << 19); /* CmdBank = 0 */
- dword &= ~(0x3ffff); /* CmdAddress = 0x400 */
- dword |= 0x400;
- dword |= (0x1 << 30); /* SendPchgCmd = 1 */
- Set_NB32_DCT(dev, dct, 0x28c, dword);
-
- /* Wait for SendPchgCmd == 0 */
- do {
- dword = Get_NB32_DCT(dev, dct, 0x28c);
- } while (dword & (0x1 << 30));
-
- /* Wait 25 MEMCLKs. */
- precise_memclk_delay_fam15(pMCTstat, pDCTstat, dct, 25);
-
- /* Set CmdTestEnable = 0 */
- dword = Get_NB32_DCT(dev, dct, 0x250);
- dword &= ~(0x1 << 2);
- Set_NB32_DCT(dev, dct, 0x250, dword);
-}
-
-/* DQS Receiver Enable Training (Family 15h)
- * Algorithm detailed in:
- * The Fam15h BKDG Rev. 3.14 section 2.10.5.8.2
- * This algorithm runs once at the lowest supported MEMCLK,
- * then once again at the highest supported MEMCLK.
- */
-static void dqsTrainRcvrEn_SW_Fam15(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 Pass)
-{
- u8 Channel;
- u8 _2Ranks;
- u8 Addl_Index = 0;
- u8 Receiver;
- u8 _DisableDramECC = 0, _Wrap32Dis = 0, _SSE2 = 0;
- u32 Errors;
-
- u32 val;
- u32 dev;
- u32 index_reg;
- u32 ch_start, ch_end, ch;
- u32 msr;
- CRx_TYPE cr4;
- u32 lo, hi;
-
- uint32_t dword;
- uint8_t dimm;
- uint8_t rank;
- uint8_t lane;
- uint8_t nibble;
- uint8_t mem_clk;
- uint16_t min_mem_clk;
- uint16_t initial_seed;
- uint8_t train_both_nibbles;
- uint16_t current_total_delay[MAX_BYTE_LANES];
- uint16_t nibble0_current_total_delay[MAX_BYTE_LANES];
- uint16_t dqs_ret_pass1_total_delay[MAX_BYTE_LANES];
- uint16_t rank0_current_total_delay[MAX_BYTE_LANES];
- uint16_t phase_recovery_delays[MAX_BYTE_LANES];
- uint16_t seed[MAX_BYTE_LANES];
- uint16_t seed_gross[MAX_BYTE_LANES];
- uint16_t seed_fine[MAX_BYTE_LANES];
- uint16_t seed_pre_gross[MAX_BYTE_LANES];
-
- uint8_t package_type = mctGet_NVbits(NV_PACK_TYPE);
- 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};
-
- uint8_t lane_count;
- lane_count = get_available_lane_count(pMCTstat, pDCTstat);
-
- print_debug_dqs("\nTrainRcvEn: Node", pDCTstat->Node_ID, 0);
- print_debug_dqs("TrainRcvEn: Pass", Pass, 0);
-
- min_mem_clk = mctGet_NVbits(NV_MIN_MEMCLK);
-
- train_both_nibbles = 0;
- if (pDCTstat->Dimmx4Present)
- if (is_fam15h())
- train_both_nibbles = 1;
-
- dev = pDCTstat->dev_dct;
- index_reg = 0x98;
- ch_start = 0;
- ch_end = 2;
-
- for (ch = ch_start; ch < ch_end; ch++) {
- uint8_t max_rd_latency = 0x55;
- uint8_t p_state;
-
- /* 2.10.5.6 */
- fam15EnableTrainingMode(pMCTstat, pDCTstat, ch, 1);
-
- /* 2.10.5.2 */
- for (p_state = 0; p_state < 3; p_state++) {
- val = Get_NB32_DCT_NBPstate(dev, ch, p_state, 0x210);
- val &= ~(0x3ff << 22); /* MaxRdLatency = max_rd_latency */
- val |= (max_rd_latency & 0x3ff) << 22;
- Set_NB32_DCT_NBPstate(dev, ch, p_state, 0x210, val);
- }
- }
-
- if (Pass != FirstPass) {
- pDCTstat->DimmTrainFail = 0;
- pDCTstat->CSTrainFail = ~pDCTstat->CSPresent;
- }
-
- cr4 = read_cr4();
- if (cr4 & (1 << 9)) { /* save the old value */
- _SSE2 = 1;
- }
- cr4 |= (1 << 9); /* OSFXSR enable SSE2 */
- write_cr4(cr4);
-
- msr = HWCR_MSR;
- _RDMSR(msr, &lo, &hi);
- /* FIXME: Why use SSEDIS */
- if (lo & (1 << 17)) { /* save the old value */
- _Wrap32Dis = 1;
- }
- lo |= (1 << 17); /* HWCR.wrap32dis */
- lo &= ~(1 << 15); /* SSEDIS */
- _WRMSR(msr, lo, hi); /* Setting wrap32dis allows 64-bit memory references in real mode */
-
- _DisableDramECC = mct_DisableDimmEccEn_D(pMCTstat, pDCTstat);
-
- Errors = 0;
- dev = pDCTstat->dev_dct;
-
- for (Channel = 0; Channel < 2; Channel++) {
- print_debug_dqs("\tTrainRcvEn51: Node ", pDCTstat->Node_ID, 1);
- print_debug_dqs("\tTrainRcvEn51: Channel ", Channel, 1);
- pDCTstat->Channel = Channel;
-
- mem_clk = Get_NB32_DCT(dev, Channel, 0x94) & 0x1f;
-
- Receiver = mct_InitReceiver_D(pDCTstat, Channel);
- /* There are four receiver pairs, loosely associated with chipselects.
- * This is essentially looping over each DIMM.
- */
- for (; Receiver < 8; Receiver += 2) {
- Addl_Index = (Receiver >> 1) * 3 + 0x10;
- dimm = (Receiver >> 1);
-
- print_debug_dqs("\t\tTrainRcvEnd52: index ", Addl_Index, 2);
-
- if (!mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, Channel, Receiver)) {
- continue;
- }
-
- /* Retrieve the total delay values from pass 1 of DQS receiver enable training */
- if (Pass != FirstPass) {
- read_dqs_receiver_enable_control_registers(dqs_ret_pass1_total_delay, dev, Channel, dimm, index_reg);
- }
-
- /* 2.10.5.8.2
- * Loop over all ranks
- */
- if (mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, Channel, Receiver+1))
- _2Ranks = 1;
- else
- _2Ranks = 0;
- for (rank = 0; rank < (_2Ranks + 1); rank++) {
- for (nibble = 0; nibble < (train_both_nibbles + 1); nibble++) {
- /* 2.10.5.8.2 (1)
- * Specify the target DIMM and nibble to be trained
- */
- dword = Get_NB32_index_wait_DCT(dev, Channel, index_reg, 0x00000008);
- dword &= ~(0x3 << 4); /* TrDimmSel = dimm */
- dword |= ((dimm & 0x3) << 4);
- dword &= ~(0x1 << 2); /* TrNibbleSel = nibble */
- dword |= ((nibble & 0x1) << 2);
- Set_NB32_index_wait_DCT(dev, Channel, index_reg, 0x00000008, dword);
-
- /* 2.10.5.8.2 (2)
- * Retrieve gross and fine timing fields from write DQS registers
- */
- read_dqs_write_timing_control_registers(current_total_delay, dev, Channel, dimm, index_reg);
-
- /* 2.10.5.8.2.1
- * Generate the DQS Receiver Enable Training Seed Values
- */
- if (Pass == FirstPass) {
- initial_seed = fam15_receiver_enable_training_seed(pDCTstat, Channel, dimm, rank, package_type);
-
- /* Adjust seed for the minimum platform supported frequency */
- initial_seed = (uint16_t) (((((uint64_t) initial_seed) *
- fam15h_freq_tab[mem_clk] * 100) / (min_mem_clk * 100)));
-
- for (lane = 0; lane < lane_count; lane++) {
- uint16_t wl_pass1_delay;
- wl_pass1_delay = current_total_delay[lane];
-
- seed[lane] = initial_seed + wl_pass1_delay;
- }
- } else {
- uint8_t addr_prelaunch = 0; /* TODO: Fetch the correct value from RC2[0] */
- uint16_t register_delay;
- int16_t seed_prescaling;
-
- memcpy(current_total_delay, dqs_ret_pass1_total_delay, sizeof(current_total_delay));
- if ((pDCTstat->Status & (1 << SB_Registered))) {
- if (addr_prelaunch)
- register_delay = 0x30;
- else
- register_delay = 0x20;
- } else if ((pDCTstat->Status & (1 << SB_LoadReduced))) {
- /* TODO
- * Load reduced DIMM support unimplemented
- */
- register_delay = 0x0;
- } else {
- register_delay = 0x0;
- }
-
- for (lane = 0; lane < lane_count; lane++) {
- seed_prescaling = current_total_delay[lane] - register_delay - 0x20;
- seed[lane] = (uint16_t) (register_delay + ((((uint64_t) seed_prescaling) * fam15h_freq_tab[mem_clk] * 100) / (min_mem_clk * 100)));
- }
- }
-
- for (lane = 0; lane < lane_count; lane++) {
- seed_gross[lane] = (seed[lane] >> 5) & 0x1f;
- seed_fine[lane] = seed[lane] & 0x1f;
-
- /*if (seed_gross[lane] == 0)
- seed_pre_gross[lane] = 0;
- else */if (seed_gross[lane] & 0x1)
- seed_pre_gross[lane] = 1;
- else
- seed_pre_gross[lane] = 2;
-
- /* Calculate phase recovery delays */
- phase_recovery_delays[lane] = ((seed_pre_gross[lane] & 0x1f) << 5) | (seed_fine[lane] & 0x1f);
-
- /* Set the gross delay.
- * NOTE: While the BKDG states to only program DqsRcvEnGrossDelay, this appears
- * to have been a misprint as DqsRcvEnFineDelay should be set to zero as well.
- */
- current_total_delay[lane] = ((seed_gross[lane] & 0x1f) << 5);
- }
-
- /* 2.10.5.8.2 (2) / 2.10.5.8.2.1 (5 6)
- * Program PhRecFineDly and PhRecGrossDly
- */
- write_dram_phase_recovery_control_registers(phase_recovery_delays, dev, Channel, dimm, index_reg);
-
- /* 2.10.5.8.2 (2) / 2.10.5.8.2.1 (7)
- * Program the DQS Receiver Enable delay values for each lane
- */
- write_dqs_receiver_enable_control_registers(current_total_delay, dev, Channel, dimm, index_reg);
-
- /* 2.10.5.8.2 (3)
- * Program DqsRcvTrEn = 1
- */
- dword = Get_NB32_index_wait_DCT(dev, Channel, index_reg, 0x00000008);
- dword |= (0x1 << 13);
- Set_NB32_index_wait_DCT(dev, Channel, index_reg, 0x00000008, dword);
-
- /* 2.10.5.8.2 (4)
- * Issue 192 read requests to the target rank
- */
- generate_dram_receiver_enable_training_pattern_fam15(pMCTstat, pDCTstat, Channel, Receiver + (rank & 0x1));
-
- /* 2.10.5.8.2 (5)
- * Program DqsRcvTrEn = 0
- */
- dword = Get_NB32_index_wait_DCT(dev, Channel, index_reg, 0x00000008);
- dword &= ~(0x1 << 13);
- Set_NB32_index_wait_DCT(dev, Channel, index_reg, 0x00000008, dword);
-
- /* 2.10.5.8.2 (6)
- * Read PhRecGrossDly, PhRecFineDly
- */
- read_dram_phase_recovery_control_registers(phase_recovery_delays, dev, Channel, dimm, index_reg);
-
- /* 2.10.5.8.2 (7)
- * Calculate and program the DQS Receiver Enable delay values
- */
- for (lane = 0; lane < lane_count; lane++) {
- current_total_delay[lane] = (phase_recovery_delays[lane] & 0x1f);
- current_total_delay[lane] |= ((seed_gross[lane] + ((phase_recovery_delays[lane] >> 5) & 0x1f) - seed_pre_gross[lane] + 1) << 5);
- if (nibble == 1) {
- /* 2.10.5.8.2 (1)
- * Average the trained values of both nibbles on x4 DIMMs
- */
- current_total_delay[lane] = (nibble0_current_total_delay[lane] + current_total_delay[lane]) / 2;
- }
- }
-
-#if DQS_TRAIN_DEBUG > 1
- for (lane = 0; lane < 8; lane++)
- printk(BIOS_DEBUG, "\t\tTrainRcvEn55: Channel: %d dimm: %d nibble: %d lane %d current_total_delay: %04x CH_D_B_RCVRDLY: %04x\n",
- Channel, dimm, nibble, lane, current_total_delay[lane], pDCTstat->CH_D_B_RCVRDLY[Channel][dimm][lane]);
-#endif
- write_dqs_receiver_enable_control_registers(current_total_delay, dev, Channel, dimm, index_reg);
-
- if (nibble == 0) {
- /* Back up the Nibble 0 delays for later use */
- memcpy(nibble0_current_total_delay, current_total_delay, sizeof(current_total_delay));
- }
-
- /* Exit nibble training if current DIMM is not x4 */
- if ((pDCTstat->Dimmx4Present & (1 << (dimm + Channel))) == 0)
- break;
- }
-
- if (_2Ranks) {
- if (rank == 0) {
- /* Back up the Rank 0 delays for later use */
- memcpy(rank0_current_total_delay, current_total_delay, sizeof(current_total_delay));
- }
- if (rank == 1) {
- /* 2.10.5.8.2 (8)
- * Compute the average delay across both ranks and program the result into
- * the DQS Receiver Enable delay registers
- */
- for (lane = 0; lane < lane_count; lane++) {
- current_total_delay[lane] = (rank0_current_total_delay[lane] + current_total_delay[lane]) / 2;
- if (lane == 8)
- pDCTstat->CH_D_BC_RCVRDLY[Channel][dimm] = current_total_delay[lane];
- else
- pDCTstat->CH_D_B_RCVRDLY[Channel][dimm][lane] = current_total_delay[lane];
- }
- write_dqs_receiver_enable_control_registers(current_total_delay, dev, Channel, dimm, index_reg);
- }
- } else {
- /* Save the current delay for later use by other routines */
- for (lane = 0; lane < lane_count; lane++) {
- if (lane == 8)
- pDCTstat->CH_D_BC_RCVRDLY[Channel][dimm] = current_total_delay[lane];
- else
- pDCTstat->CH_D_B_RCVRDLY[Channel][dimm][lane] = current_total_delay[lane];
- }
- }
- }
-
-#if DQS_TRAIN_DEBUG > 0
- for (lane = 0; lane < 8; lane++)
- print_debug_dqs_pair("\t\tTrainRcvEn56: Lane ", lane, " current_total_delay ", current_total_delay[lane], 2);
-#endif
- }
- }
-
- /* Calculate and program MaxRdLatency for both channels */
- Calc_SetMaxRdLatency_D_Fam15(pMCTstat, pDCTstat, 0, 0);
- Calc_SetMaxRdLatency_D_Fam15(pMCTstat, pDCTstat, 1, 0);
-
- if (_DisableDramECC) {
- mct_EnableDimmEccEn_D(pMCTstat, pDCTstat, _DisableDramECC);
- }
-
- if (Pass == FirstPass) {
- /*Disable DQSRcvrEn training mode */
- mct_DisableDQSRcvEn_D(pDCTstat);
- }
-
- if (!_Wrap32Dis) {
- msr = HWCR_MSR;
- _RDMSR(msr, &lo, &hi);
- lo &= ~(1<<17); /* restore HWCR.wrap32dis */
- _WRMSR(msr, lo, hi);
- }
- if (!_SSE2) {
- cr4 = read_cr4();
- cr4 &= ~(1<<9); /* restore cr4.OSFXSR */
- write_cr4(cr4);
- }
-
-#if DQS_TRAIN_DEBUG > 0
- {
- u8 ChannelDTD;
- printk(BIOS_DEBUG, "TrainRcvrEn: CH_MaxRdLat:\n");
- for (ChannelDTD = 0; ChannelDTD < 2; ChannelDTD++) {
- printk(BIOS_DEBUG, "Channel:%x: %x\n",
- ChannelDTD, pDCTstat->CH_MaxRdLat[ChannelDTD][0]);
- }
- }
-#endif
-
-#if DQS_TRAIN_DEBUG > 0
- {
- u16 valDTD;
- u8 ChannelDTD, ReceiverDTD;
- u8 i;
- u16 *p;
-
- printk(BIOS_DEBUG, "TrainRcvrEn: CH_D_B_RCVRDLY:\n");
- for (ChannelDTD = 0; ChannelDTD < 2; ChannelDTD++) {
- printk(BIOS_DEBUG, "Channel:%x\n", ChannelDTD);
- for (ReceiverDTD = 0; ReceiverDTD < 8; ReceiverDTD+=2) {
- printk(BIOS_DEBUG, "\t\tReceiver:%x:", ReceiverDTD);
- p = pDCTstat->CH_D_B_RCVRDLY[ChannelDTD][ReceiverDTD>>1];
- for (i = 0; i < 8; i++) {
- valDTD = p[i];
- printk(BIOS_DEBUG, " %03x", valDTD);
- }
- printk(BIOS_DEBUG, "\n");
- }
- }
- }
-#endif
-
- printk(BIOS_DEBUG, "TrainRcvrEn: Status %x\n", pDCTstat->Status);
- printk(BIOS_DEBUG, "TrainRcvrEn: ErrStatus %x\n", pDCTstat->ErrStatus);
- printk(BIOS_DEBUG, "TrainRcvrEn: ErrCode %x\n", pDCTstat->ErrCode);
- printk(BIOS_DEBUG, "TrainRcvrEn: Done\n\n");
-}
-
-static void write_max_read_latency_to_registers(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, uint8_t dct, uint16_t *latency)
-{
- uint32_t dword;
- uint8_t nb_pstate;
-
- for (nb_pstate = 0; nb_pstate < 2; nb_pstate++) {
- dword = Get_NB32_DCT_NBPstate(pDCTstat->dev_dct, dct, nb_pstate, 0x210);
- dword &= ~(0x3ff << 22);
- dword |= ((latency[nb_pstate] & 0x3ff) << 22);
- Set_NB32_DCT_NBPstate(pDCTstat->dev_dct, dct, nb_pstate, 0x210, dword);
- }
-}
-
-/* DQS MaxRdLatency Training (Family 15h)
- * Algorithm detailed in:
- * The Fam15h BKDG Rev. 3.14 section 2.10.5.8.5.1
- * This algorithm runs at the highest supported MEMCLK.
- */
-void dqsTrainMaxRdLatency_SW_Fam15(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat)
-{
- u8 Channel;
- u8 Receiver;
- u8 _DisableDramECC = 0, _Wrap32Dis = 0, _SSE2 = 0;
- u32 Errors;
-
- u32 dev;
- u32 index_reg;
- u32 ch_start, ch_end;
- u32 msr;
- CRx_TYPE cr4;
- u32 lo, hi;
-
- uint32_t dword;
- uint8_t dimm;
- uint8_t lane;
- uint8_t mem_clk;
- uint32_t nb_clk;
- uint8_t nb_pstate;
- uint16_t current_total_delay[MAX_BYTE_LANES];
- uint16_t current_rdqs_total_delay[MAX_BYTE_LANES];
- uint8_t current_worst_case_total_delay_dimm;
- uint16_t current_worst_case_total_delay_value;
-
- uint8_t lane_count;
- lane_count = get_available_lane_count(pMCTstat, pDCTstat);
-
- 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};
-
- print_debug_dqs("\nTrainMaxRdLatency: Node", pDCTstat->Node_ID, 0);
-
- dev = pDCTstat->dev_dct;
- index_reg = 0x98;
- ch_start = 0;
- ch_end = 2;
-
- cr4 = read_cr4();
- if (cr4 & (1 << 9)) { /* save the old value */
- _SSE2 = 1;
- }
- cr4 |= (1 << 9); /* OSFXSR enable SSE2 */
- write_cr4(cr4);
-
- msr = HWCR_MSR;
- _RDMSR(msr, &lo, &hi);
- /* FIXME: Why use SSEDIS */
- if (lo & (1 << 17)) { /* save the old value */
- _Wrap32Dis = 1;
- }
- lo |= (1 << 17); /* HWCR.wrap32dis */
- lo &= ~(1 << 15); /* SSEDIS */
- _WRMSR(msr, lo, hi); /* Setting wrap32dis allows 64-bit memory references in real mode */
-
- _DisableDramECC = mct_DisableDimmEccEn_D(pMCTstat, pDCTstat);
-
- Errors = 0;
- dev = pDCTstat->dev_dct;
-
- for (Channel = 0; Channel < 2; Channel++) {
- print_debug_dqs("\tTrainMaxRdLatency51: Node ", pDCTstat->Node_ID, 1);
- print_debug_dqs("\tTrainMaxRdLatency51: Channel ", Channel, 1);
- pDCTstat->Channel = Channel;
-
- if (pDCTstat->DIMMValidDCT[Channel] == 0)
- continue;
-
- mem_clk = Get_NB32_DCT(dev, Channel, 0x94) & 0x1f;
-
- Receiver = mct_InitReceiver_D(pDCTstat, Channel);
-
- /* Find DIMM with worst case receiver enable delays */
- current_worst_case_total_delay_dimm = 0;
- current_worst_case_total_delay_value = 0;
-
- /* There are four receiver pairs, loosely associated with chipselects.
- * This is essentially looping over each DIMM.
- */
- for (; Receiver < 8; Receiver += 2) {
- dimm = (Receiver >> 1);
-
- print_debug_dqs("\t\tTrainMaxRdLatency52: Receiver ", Receiver, 2);
-
- if (!mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, Channel, Receiver)) {
- continue;
- }
-
- /* Retrieve the total delay values from pass 1 of DQS receiver enable training */
- read_dqs_receiver_enable_control_registers(current_total_delay, dev, Channel, dimm, index_reg);
- read_dqs_read_data_timing_registers(current_rdqs_total_delay, dev, Channel, dimm, index_reg);
-
- for (lane = 0; lane < lane_count; lane++) {
- current_total_delay[lane] += current_rdqs_total_delay[lane];
- if (current_total_delay[lane] > current_worst_case_total_delay_value) {
- current_worst_case_total_delay_dimm = dimm;
- current_worst_case_total_delay_value = current_total_delay[lane];
- }
- }
-
-#if DQS_TRAIN_DEBUG > 0
- for (lane = 0; lane < lane_count; lane++)
- print_debug_dqs_pair("\t\tTrainMaxRdLatency56: Lane ", lane, " current_total_delay ", current_total_delay[lane], 2);
-#endif
- }
-
- /* 2.10.5.8.5.1.1 */
- Calc_SetMaxRdLatency_D_Fam15(pMCTstat, pDCTstat, Channel, 1);
-
- /* 2.10.5.8.5.1.[2,3]
- * Write the DRAM training pattern to the test address
- */
- write_dram_dqs_training_pattern_fam15(pMCTstat, pDCTstat, Channel, current_worst_case_total_delay_dimm << 1, 0xff, 0);
-
- /* 2.10.5.8.5.1.4
- * Incrementally test each MaxRdLatency candidate
- */
- for (; pDCTstat->CH_MaxRdLat[Channel][0] < 0x3ff; pDCTstat->CH_MaxRdLat[Channel][0]++) {
- write_max_read_latency_to_registers(pMCTstat, pDCTstat, Channel, pDCTstat->CH_MaxRdLat[Channel]);
- read_dram_dqs_training_pattern_fam15(pMCTstat, pDCTstat, Channel, current_worst_case_total_delay_dimm << 1, 0xff, 0);
- dword = Get_NB32_DCT(dev, Channel, 0x268) & 0x3ffff;
- if (!dword)
- break;
- Set_NB32_index_wait_DCT(dev, Channel, index_reg, 0x00000050, 0x13131313);
- }
- dword = Get_NB32_DCT(dev, Channel, 0x268) & 0x3ffff;
- if (dword)
- printk(BIOS_ERR, "WARNING: MaxRdLatency training FAILED! Attempting to continue but your system may be unstable...\n");
-
- /* 2.10.5.8.5.1.5 */
- nb_pstate = 0;
- mem_clk = Get_NB32_DCT(dev, Channel, 0x94) & 0x1f;
- if (fam15h_freq_tab[mem_clk] == 0) {
- return;
- }
- dword = Get_NB32(pDCTstat->dev_nbctl, (0x160 + (nb_pstate * 4))); /* Retrieve NbDid, NbFid */
- nb_clk = (200 * (((dword >> 1) & 0x1f) + 0x4)) / (((dword >> 7) & 0x1)?2:1);
-
- pDCTstat->CH_MaxRdLat[Channel][0]++;
- pDCTstat->CH_MaxRdLat[Channel][0] += ((((uint64_t)15 * 100000000000ULL) / ((uint64_t)fam15h_freq_tab[mem_clk] * 1000000ULL))
- * ((uint64_t)nb_clk * 1000)) / 1000000000ULL;
-
- write_max_read_latency_to_registers(pMCTstat, pDCTstat, Channel, pDCTstat->CH_MaxRdLat[Channel]);
- }
-
- if (_DisableDramECC) {
- mct_EnableDimmEccEn_D(pMCTstat, pDCTstat, _DisableDramECC);
- }
-
- if (!_Wrap32Dis) {
- msr = HWCR_MSR;
- _RDMSR(msr, &lo, &hi);
- lo &= ~(1<<17); /* restore HWCR.wrap32dis */
- _WRMSR(msr, lo, hi);
- }
- if (!_SSE2) {
- cr4 = read_cr4();
- cr4 &= ~(1<<9); /* restore cr4.OSFXSR */
- write_cr4(cr4);
- }
-
-#if DQS_TRAIN_DEBUG > 0
- {
- u8 ChannelDTD;
- printk(BIOS_DEBUG, "TrainMaxRdLatency: CH_MaxRdLat:\n");
- for (ChannelDTD = 0; ChannelDTD < 2; ChannelDTD++) {
- printk(BIOS_DEBUG, "Channel:%x: %x\n",
- ChannelDTD, pDCTstat->CH_MaxRdLat[ChannelDTD][0]);
- }
- }
-#endif
-
- printk(BIOS_DEBUG, "TrainMaxRdLatency: Status %x\n", pDCTstat->Status);
- printk(BIOS_DEBUG, "TrainMaxRdLatency: ErrStatus %x\n", pDCTstat->ErrStatus);
- printk(BIOS_DEBUG, "TrainMaxRdLatency: ErrCode %x\n", pDCTstat->ErrCode);
- printk(BIOS_DEBUG, "TrainMaxRdLatency: Done\n\n");
-}
-
-u8 mct_InitReceiver_D(struct DCTStatStruc *pDCTstat, u8 dct)
-{
- if (pDCTstat->DIMMValidDCT[dct] == 0) {
- return 8;
- } else {
- return 0;
- }
-}
-
-static void mct_DisableDQSRcvEn_D(struct DCTStatStruc *pDCTstat)
-{
- u8 ch_end, ch;
- u32 reg;
- u32 dev;
- u32 val;
-
- dev = pDCTstat->dev_dct;
- if (pDCTstat->GangedMode) {
- ch_end = 1;
- } else {
- ch_end = 2;
- }
-
- for (ch = 0; ch < ch_end; ch++) {
- reg = 0x78;
- val = Get_NB32_DCT(dev, ch, reg);
- val &= ~(1 << DqsRcvEnTrain);
- Set_NB32_DCT(dev, ch, reg, val);
- }
-}
-
-/* mct_ModifyIndex_D
- * Function only used once so it was inlined.
- */
-
-/* mct_GetInitFlag_D
- * Function only used once so it was inlined.
- */
-
-/* Set F2x[1, 0]9C_x[2B:10] DRAM DQS Receiver Enable Timing Control Registers
- * See BKDG Rev. 3.62 page 268 for more information
- */
-void mct_SetRcvrEnDly_D(struct DCTStatStruc *pDCTstat, u16 RcvrEnDly,
- u8 FinalValue, u8 Channel, u8 Receiver, u32 dev,
- u32 index_reg, u8 Addl_Index, u8 Pass)
-{
- u32 index;
- u8 i;
- u16 *p;
- u32 val;
-
- if (RcvrEnDly == 0x1fe) {
- /*set the boundary flag */
- pDCTstat->Status |= 1 << SB_DQSRcvLimit;
- }
-
- /* DimmOffset not needed for CH_D_B_RCVRDLY array */
- for (i = 0; i < 8; i++) {
- if (FinalValue) {
- /*calculate dimm offset */
- p = pDCTstat->CH_D_B_RCVRDLY[Channel][Receiver >> 1];
- RcvrEnDly = p[i];
- }
-
- /* if flag = 0, set DqsRcvEn value to reg. */
- /* get the register index from table */
- index = Table_DQSRcvEn_Offset[i >> 1];
- index += Addl_Index; /* DIMMx DqsRcvEn byte0 */
- val = Get_NB32_index_wait_DCT(dev, Channel, index_reg, index);
- if (i & 1) {
- /* odd byte lane */
- val &= ~(0x1ff << 16);
- val |= ((RcvrEnDly & 0x1ff) << 16);
- } else {
- /* even byte lane */
- val &= ~0x1ff;
- val |= (RcvrEnDly & 0x1ff);
- }
- Set_NB32_index_wait_DCT(dev, Channel, index_reg, index, val);
- }
-
-}
-
-/* Calculate MaxRdLatency
- * Algorithm detailed in the Fam10h BKDG Rev. 3.62 section 2.8.9.9.5
- */
-static void mct_SetMaxLatency_D(struct DCTStatStruc *pDCTstat, u8 Channel, u16 DQSRcvEnDly)
-{
- u32 dev;
- u32 reg;
- u32 SubTotal;
- u32 index_reg;
- u32 val;
-
- uint8_t cpu_val_n;
- uint8_t cpu_val_p;
-
- u16 freq_tab[] = {400, 533, 667, 800};
-
- /* Set up processor-dependent values */
- if (pDCTstat->LogicalCPUID & AMD_DR_Dx) {
- /* Revision D and above */
- cpu_val_n = 4;
- cpu_val_p = 29;
- } else if (pDCTstat->LogicalCPUID & AMD_DR_Cx) {
- /* Revision C */
- uint8_t package_type = mctGet_NVbits(NV_PACK_TYPE);
- if ((package_type == PT_L1) /* Socket F (1207) */
- || (package_type == PT_M2) /* Socket AM3 */
- || (package_type == PT_S1)) { /* Socket S1g <x> */
- cpu_val_n = 10;
- cpu_val_p = 11;
- } else {
- cpu_val_n = 4;
- cpu_val_p = 29;
- }
- } else {
- /* Revision B and below */
- cpu_val_n = 10;
- cpu_val_p = 11;
- }
-
- if (pDCTstat->GangedMode)
- Channel = 0;
-
- dev = pDCTstat->dev_dct;
- index_reg = 0x98;
-
- /* Multiply the CAS Latency by two to get a number of 1/2 MEMCLKs units.*/
- val = Get_NB32_DCT(dev, Channel, 0x88);
- SubTotal = ((val & 0x0f) + 4) << 1; /* SubTotal is 1/2 Memclk unit */
-
- /* If registered DIMMs are being used then
- * add 1 MEMCLK to the sub-total.
- */
- val = Get_NB32_DCT(dev, Channel, 0x90);
- if (!(val & (1 << UnBuffDimm)))
- SubTotal += 2;
-
- /* If the address prelaunch is setup for 1/2 MEMCLKs then
- * add 1, else add 2 to the sub-total.
- * if (AddrCmdSetup || CsOdtSetup || CkeSetup) then K := K + 2;
- */
- val = Get_NB32_index_wait_DCT(dev, Channel, index_reg, 0x04);
- if (!(val & 0x00202020))
- SubTotal += 1;
- else
- SubTotal += 2;
-
- /* If the F2x[1, 0]78[RdPtrInit] field is 4, 5, 6 or 7 MEMCLKs,
- * then add 4, 3, 2, or 1 MEMCLKs, respectively to the sub-total. */
- val = Get_NB32_DCT(dev, Channel, 0x78);
- SubTotal += 8 - (val & 0x0f);
-
- /* Convert bits 7-5 (also referred to as the coarse delay) of
- * the current (or worst case) DQS receiver enable delay to
- * 1/2 MEMCLKs units, rounding up, and add this to the sub-total.
- */
- SubTotal += DQSRcvEnDly >> 5; /* Retrieve gross delay portion of value */
-
- /* Add "P" to the sub-total. "P" represents part of the
- * processor specific constant delay value in the DRAM
- * clock domain.
- */
- SubTotal <<= 1; /*scale 1/2 MemClk to 1/4 MemClk */
- SubTotal += cpu_val_p; /*add "P" 1/2MemClk */
- SubTotal >>= 1; /*scale 1/4 MemClk back to 1/2 MemClk */
-
- /* Convert the sub-total (in 1/2 MEMCLKs) to northbridge
- * clocks (NCLKs)
- */
- SubTotal *= 200 * ((Get_NB32(pDCTstat->dev_nbmisc, 0xd4) & 0x1f) + 4);
- SubTotal /= freq_tab[((Get_NB32_DCT(pDCTstat->dev_dct, Channel, 0x94) & 0x7) - 3)];
- SubTotal = (SubTotal + (2 - 1)) / 2; /* Round up */
-
- /* Add "N" NCLKs to the sub-total. "N" represents part of the
- * processor specific constant value in the northbridge
- * clock domain.
- */
- SubTotal += (cpu_val_n) / 2;
-
- pDCTstat->CH_MaxRdLat[Channel][0] = SubTotal;
- if (pDCTstat->GangedMode) {
- pDCTstat->CH_MaxRdLat[1][0] = SubTotal;
- }
-
- /* Program the F2x[1, 0]78[MaxRdLatency] register with
- * the total delay value (in NCLKs).
- */
- reg = 0x78;
- val = Get_NB32_DCT(dev, Channel, reg);
- val &= ~(0x3ff << 22);
- val |= (SubTotal & 0x3ff) << 22;
-
- /* program MaxRdLatency to correspond with current delay */
- Set_NB32_DCT(dev, Channel, reg, val);
-}
-
-static void mct_InitDQSPos4RcvrEn_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat)
-{
- /* Initialize the DQS Positions in preparation for
- * Receiver Enable Training.
- * Write Position is 1/2 Memclock Delay
- * Read Position is 1/2 Memclock Delay
- */
- u8 i;
- for (i = 0; i < 2; i++) {
- InitDQSPos4RcvrEn_D(pMCTstat, pDCTstat, i);
- }
-}
-
-static void InitDQSPos4RcvrEn_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 Channel)
-{
- /* Initialize the DQS Positions in preparation for
- * Receiver Enable Training.
- * Write Position is no Delay
- * Read Position is 1/2 Memclock Delay
- */
-
- u8 i, j;
- u32 dword;
- u8 dn = 4; /* TODO: Rev C could be 4 */
- u32 dev = pDCTstat->dev_dct;
- u32 index_reg = 0x98;
-
- /* FIXME: add Cx support */
- dword = 0x00000000;
- for (i = 1; i <= 3; i++) {
- for (j = 0; j < dn; j++)
- /* DIMM0 Write Data Timing Low */
- /* DIMM0 Write ECC Timing */
- Set_NB32_index_wait_DCT(dev, Channel, index_reg, i + 0x100 * j, dword);
- }
-
- /* errata #180 */
- dword = 0x2f2f2f2f;
- for (i = 5; i <= 6; i++) {
- for (j = 0; j < dn; j++)
- /* DIMM0 Read DQS Timing Control Low */
- Set_NB32_index_wait_DCT(dev, Channel, index_reg, i + 0x100 * j, dword);
- }
-
- dword = 0x0000002f;
- for (j = 0; j < dn; j++)
- /* DIMM0 Read DQS ECC Timing Control */
- Set_NB32_index_wait_DCT(dev, Channel, index_reg, 7 + 0x100 * j, dword);
-}
-
-void SetEccDQSRcvrEn_D(struct DCTStatStruc *pDCTstat, u8 Channel)
-{
- u32 dev;
- u32 index_reg;
- u32 index;
- u8 ChipSel;
- u16 *p;
- u32 val;
-
- dev = pDCTstat->dev_dct;
- index_reg = 0x98;
- index = 0x12;
- p = pDCTstat->CH_D_BC_RCVRDLY[Channel];
- print_debug_dqs("\t\tSetEccDQSRcvrPos: Channel ", Channel, 2);
- for (ChipSel = 0; ChipSel < MAX_CS_SUPPORTED; ChipSel += 2) {
- val = p[ChipSel>>1];
- Set_NB32_index_wait_DCT(dev, Channel, index_reg, index, val);
- print_debug_dqs_pair("\t\tSetEccDQSRcvrPos: ChipSel ",
- ChipSel, " rcvr_delay ", val, 2);
- index += 3;
- }
-}
-
-static void CalcEccDQSRcvrEn_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 Channel)
-{
- u8 ChipSel;
- u16 EccDQSLike;
- u8 EccDQSScale;
- u32 val, val0, val1;
- int16_t delay_differential;
-
- EccDQSLike = pDCTstat->CH_EccDQSLike[Channel];
- EccDQSScale = pDCTstat->CH_EccDQSScale[Channel];
-
- for (ChipSel = 0; ChipSel < MAX_CS_SUPPORTED; ChipSel += 2) {
- if (mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, Channel, ChipSel)) {
- u16 *p;
- p = pDCTstat->CH_D_B_RCVRDLY[Channel][ChipSel>>1];
-
- if (pDCTstat->Status & (1 << SB_Registered)) {
- val0 = p[0x2];
- val1 = p[0x3];
-
- delay_differential = (int16_t)val1 - (int16_t)val0;
- delay_differential += (int16_t)val1;
-
- val = delay_differential;
- } else {
- /* DQS Delay Value of Data Bytelane
- * most like ECC byte lane */
- val0 = p[EccDQSLike & 0x07];
- /* DQS Delay Value of Data Bytelane
- * 2nd most like ECC byte lane */
- val1 = p[(EccDQSLike>>8) & 0x07];
-
- if (val0 > val1) {
- val = val0 - val1;
- } else {
- val = val1 - val0;
- }
-
- val *= ~EccDQSScale;
- val >>= 8; /* /256 */
-
- if (val0 > val1) {
- val -= val1;
- } else {
- val += val0;
- }
- }
-
- pDCTstat->CH_D_BC_RCVRDLY[Channel][ChipSel>>1] = val;
- }
- }
- SetEccDQSRcvrEn_D(pDCTstat, Channel);
-}
-
-/* 2.8.9.9.4
- * ECC Byte Lane Training
- * DQS Receiver Enable Delay
- */
-void mctSetEccDQSRcvrEn_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstatA)
-{
- u8 Node;
- u8 i;
-
- for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
- struct DCTStatStruc *pDCTstat;
- pDCTstat = pDCTstatA + Node;
- if (!pDCTstat->NodePresent)
- break;
- if (pDCTstat->DCTSysLimit) {
- for (i = 0; i < 2; i++)
- CalcEccDQSRcvrEn_D(pMCTstat, pDCTstat, i);
- }
- }
-}
-
-void phyAssistedMemFnceTraining(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstatA, int16_t single_node_number)
-{
- u8 Node = 0;
- struct DCTStatStruc *pDCTstat;
-
- printk(BIOS_DEBUG, "%s: Start\n", __func__);
-
- uint8_t start_node = 0;
- uint8_t end_node = MAX_NODES_SUPPORTED;
-
- if (single_node_number >= 0) {
- start_node = single_node_number;
- end_node = single_node_number + 1;
- }
-
- /* FIXME: skip for Ax */
- for (Node = start_node; Node < end_node; Node++) {
- pDCTstat = pDCTstatA + Node;
- if (!pDCTstat->NodePresent)
- continue;
-
- if (pDCTstat->DCTSysLimit) {
- if (is_fam15h()) {
- /* Fam15h BKDG v3.14 section 2.10.5.3.3
- * This picks up where InitDDRPhy left off
- */
- uint8_t dct;
- uint8_t index;
- uint32_t dword;
- uint32_t datc_backup;
- uint32_t training_dword;
- uint32_t fence2_config_dword;
- uint32_t fence_tx_pad_config_dword;
- uint32_t index_reg = 0x98;
- uint32_t dev = pDCTstat->dev_dct;
-
- for (dct = 0; dct < 2; dct++) {
- if (!pDCTstat->DIMMValidDCT[dct])
- continue;
-
- printk(BIOS_SPEW, "%s: training node %d DCT %d\n", __func__, Node, dct);
-
- /* Back up D18F2x9C_x0000_0004_dct[1:0] */
- datc_backup = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x00000004);
-
- /* FenceTrSel = 0x2 */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x00000008);
- dword &= ~(0x3 << 6);
- dword |= (0x2 << 6);
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x00000008, dword);
-
- /* Set phase recovery seed values */
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x00000050, 0x13131313);
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x00000051, 0x13131313);
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x00000052, 0x00000013);
-
- training_dword = fenceDynTraining_D(pMCTstat, pDCTstat, dct);
-
- /* Save calculated fence value to the TX DLL */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000c);
- dword &= ~(0x1f << 26);
- dword |= ((training_dword & 0x1f) << 26);
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000c, dword);
-
- /* D18F2x9C_x0D0F_0[F,8:0]0F_dct[1:0][AlwaysEnDllClks]=0x1 */
- for (index = 0; index < 0x9; index++) {
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f000f | (index << 8));
- dword &= ~(0x7 << 12);
- dword |= (0x1 << 12);
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f000f | (index << 8), dword);
- }
-
- /* FenceTrSel = 0x1 */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x00000008);
- dword &= ~(0x3 << 6);
- dword |= (0x1 << 6);
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x00000008, dword);
-
- /* Set phase recovery seed values */
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x00000050, 0x13131313);
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x00000051, 0x13131313);
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x00000052, 0x00000013);
-
- training_dword = fenceDynTraining_D(pMCTstat, pDCTstat, dct);
-
- /* Save calculated fence value to the RX DLL */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000c);
- dword &= ~(0x1f << 21);
- dword |= ((training_dword & 0x1f) << 21);
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000c, dword);
-
- /* D18F2x9C_x0D0F_0[F,8:0]0F_dct[1:0][AlwaysEnDllClks]=0x0 */
- for (index = 0; index < 0x9; index++) {
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f000f | (index << 8));
- dword &= ~(0x7 << 12);
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f000f | (index << 8), dword);
- }
-
- /* FenceTrSel = 0x3 */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x00000008);
- dword &= ~(0x3 << 6);
- dword |= (0x3 << 6);
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x00000008, dword);
-
- /* Set phase recovery seed values */
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x00000050, 0x13131313);
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x00000051, 0x13131313);
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x00000052, 0x00000013);
-
- fence_tx_pad_config_dword = fenceDynTraining_D(pMCTstat, pDCTstat, dct);
-
- /* Save calculated fence value to the TX Pad */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000c);
- dword &= ~(0x1f << 16);
- dword |= ((fence_tx_pad_config_dword & 0x1f) << 16);
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000c, dword);
-
- /* Program D18F2x9C_x0D0F_[C,8,2][2:0]31_dct[1:0] */
- training_dword = fence_tx_pad_config_dword;
- if (fence_tx_pad_config_dword < 16)
- training_dword |= (0x1 << 4);
- else
- training_dword = 0;
- for (index = 0; index < 0x3; index++) {
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2031 | (index << 8));
- dword &= ~(0x1f);
- dword |= (training_dword & 0x1f);
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2031 | (index << 8), dword);
- }
- for (index = 0; index < 0x3; index++) {
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8031 | (index << 8));
- dword &= ~(0x1f);
- dword |= (training_dword & 0x1f);
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8031 | (index << 8), dword);
- }
- for (index = 0; index < 0x3; index++) {
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc031 | (index << 8));
- dword &= ~(0x1f);
- dword |= (training_dword & 0x1f);
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc031 | (index << 8), dword);
- }
-
- /* Assemble Fence2 configuration word (Fam15h BKDG v3.14 page 331) */
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0000000c);
- fence2_config_dword = 0;
-
- /* TxPad */
- training_dword = (dword >> 16) & 0x1f;
- if (training_dword < 16)
- training_dword |= 0x10;
- else
- training_dword = 0;
- fence2_config_dword |= training_dword;
-
- /* RxDll */
- training_dword = (dword >> 21) & 0x1f;
- if (training_dword < 16)
- training_dword |= 0x10;
- else
- training_dword = 0;
- fence2_config_dword |= (training_dword << 10);
-
- /* TxDll */
- training_dword = (dword >> 26) & 0x1f;
- if (training_dword < 16)
- training_dword |= 0x10;
- else
- training_dword = 0;
- fence2_config_dword |= (training_dword << 5);
-
- /* Program D18F2x9C_x0D0F_0[F,8:0]31_dct[1:0] */
- for (index = 0; index < 0x9; index++) {
- dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0031 | (index << 8));
- dword &= ~(0x7fff);
- dword |= fence2_config_dword;
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0031 | (index << 8), dword);
- }
-
- /* Restore D18F2x9C_x0000_0004_dct[1:0] */
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x00000004, datc_backup);
-
- printk(BIOS_SPEW, "%s: done training node %d DCT %d\n", __func__, Node, dct);
- }
- } else {
- fenceDynTraining_D(pMCTstat, pDCTstat, 0);
- fenceDynTraining_D(pMCTstat, pDCTstat, 1);
- }
- }
- }
-
- printk(BIOS_DEBUG, "%s: Done\n", __func__);
-}
-
-uint32_t fenceDynTraining_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, uint8_t dct)
-{
- u16 avRecValue;
- u32 val;
- u32 dev;
- u32 index_reg = 0x98;
- u32 index;
-
- dev = pDCTstat->dev_dct;
-
- if (is_fam15h()) {
- /* Set F2x[1,0]9C_x08[PhyFenceTrEn] */
- val = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x08);
- val |= 1 << PhyFenceTrEn;
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x08, val);
-
- /* Wait 2000 MEMCLKs */
- precise_memclk_delay_fam15(pMCTstat, pDCTstat, dct, 2000);
-
- /* Clear F2x[1,0]9C_x08[PhyFenceTrEn] */
- val = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x08);
- val &= ~(1 << PhyFenceTrEn);
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x08, val);
-
- /* BIOS reads the phase recovery engine registers
- * F2x[1,0]9C_x[51:50] and F2x[1,0]9C_x52.
- * Average the fine delay components only.
- */
- avRecValue = 0;
- for (index = 0x50; index <= 0x52; index++) {
- val = Get_NB32_index_wait_DCT(dev, dct, index_reg, index);
- avRecValue += val & 0x1f;
- if (index != 0x52) {
- avRecValue += (val >> 8) & 0x1f;
- avRecValue += (val >> 16) & 0x1f;
- avRecValue += (val >> 24) & 0x1f;
- }
- }
-
- val = avRecValue / 9;
- if (avRecValue % 9)
- val++;
- avRecValue = val;
-
- if (avRecValue < 6)
- avRecValue = 0;
- else
- avRecValue -= 6;
-
- return avRecValue;
- } else {
- /* BIOS first programs a seed value to the phase recovery engine
- * (recommended 19) registers.
- * Dram Phase Recovery Control Register (F2x[1,0]9C_x[51:50] and
- * F2x[1,0]9C_x52.) .
- */
- for (index = 0x50; index <= 0x52; index ++) {
- val = (FenceTrnFinDlySeed & 0x1F);
- if (index != 0x52) {
- val |= val << 8 | val << 16 | val << 24;
- }
- Set_NB32_index_wait_DCT(dev, dct, index_reg, index, val);
- }
-
- /* Set F2x[1,0]9C_x08[PhyFenceTrEn]=1. */
- val = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x08);
- val |= 1 << PhyFenceTrEn;
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x08, val);
-
- /* Wait 200 MEMCLKs. */
- mct_Wait(50000); /* wait 200us */
-
- /* Clear F2x[1,0]9C_x08[PhyFenceTrEn]=0. */
- val = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x08);
- val &= ~(1 << PhyFenceTrEn);
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x08, val);
-
- /* BIOS reads the phase recovery engine registers
- * F2x[1,0]9C_x[51:50] and F2x[1,0]9C_x52. */
- avRecValue = 0;
- for (index = 0x50; index <= 0x52; index ++) {
- val = Get_NB32_index_wait_DCT(dev, dct, index_reg, index);
- avRecValue += val & 0x7F;
- if (index != 0x52) {
- avRecValue += (val >> 8) & 0x7F;
- avRecValue += (val >> 16) & 0x7F;
- avRecValue += (val >> 24) & 0x7F;
- }
- }
-
- val = avRecValue / 9;
- if (avRecValue % 9)
- val++;
- avRecValue = val;
-
- /* Write the (averaged value -8) to F2x[1,0]9C_x0C[PhyFence]. */
- /* inlined mct_AdjustFenceValue() */
- /* TODO: The RBC0 is not supported. */
- /* if (pDCTstat->LogicalCPUID & AMD_RB_C0)
- avRecValue -= 3;
- else
- */
- if (pDCTstat->LogicalCPUID & AMD_DR_Dx)
- avRecValue -= 8;
- else if (pDCTstat->LogicalCPUID & AMD_DR_Cx)
- avRecValue -= 8;
- else if (pDCTstat->LogicalCPUID & AMD_DR_Bx)
- avRecValue -= 8;
-
- val = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0C);
- val &= ~(0x1F << 16);
- val |= (avRecValue & 0x1F) << 16;
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0C, val);
-
- /* Rewrite F2x[1,0]9C_x04-DRAM Address/Command Timing Control Register
- * delays (both channels).
- */
- val = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x04);
- Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x04, val);
-
- return avRecValue;
- }
-}
-
-void mct_Wait(u32 cycles)
-{
- u32 saved;
- u32 hi, lo, msr;
-
- /* Wait # of 50ns cycles
- This seems like a hack to me... */
-
- cycles <<= 3; /* x8 (number of 1.25ns ticks) */
-
- msr = TSC_MSR; /* TSC */
- _RDMSR(msr, &lo, &hi);
- saved = lo;
- do {
- _RDMSR(msr, &lo, &hi);
- } while (lo - saved < cycles);
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctsrc1p.c b/src/northbridge/amd/amdmct/mct_ddr3/mctsrc1p.c
deleted file mode 100644
index 98aadddc6c..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctsrc1p.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
- *
- * 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.
- */
-
-#include <arch/cpu.h>
-#include <stdint.h>
-
-#include "mct_d.h"
-#include "mct_d_gcc.h"
-
-static uint8_t is_fam15h(void)
-{
- uint8_t fam15h = 0;
- uint32_t family;
-
- family = cpuid_eax(0x80000001);
- family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);
-
- if (family >= 0x6f)
- /* Family 15h or later */
- fam15h = 1;
-
- return fam15h;
-}
-
-u8 mct_checkNumberOfDqsRcvEn_1Pass(u8 pass)
-{
- u8 ret = 1;
-
- if (is_fam15h()) {
- /* Fam15h needs two passes */
- ret = 1;
- } else {
- if (pass == SecondPass)
- ret = 0;
- }
-
- return ret;
-}
-
-u32 SetupDqsPattern_1PassA(u8 pass)
-{
- return (u32) TestPattern1_D;
-}
-
-u32 SetupDqsPattern_1PassB(u8 pass)
-{
- return (u32) TestPattern0_D;
-}
-
-static u16 mct_Average_RcvrEnDly_1Pass(struct DCTStatStruc *pDCTstat, u8 Channel, u8 Receiver,
- u8 Pass)
-{
- u16 i, MaxValue;
- u16 *p;
- u16 val;
-
- MaxValue = 0;
- p = pDCTstat->CH_D_B_RCVRDLY[Channel][Receiver >> 1];
-
- for (i = 0; i < 8; i++) {
- /* get left value from DCTStatStruc.CHA_D0_B0_RCVRDLY*/
- val = p[i];
- /* get right value from DCTStatStruc.CHA_D0_B0_RCVRDLY_1*/
- val += Pass1MemClkDly;
- /* write back the value to stack */
- if (val > MaxValue)
- MaxValue = val;
-
- p[i] = val;
- }
- /* pDCTstat->DimmTrainFail &= ~(1<<Receiver+Channel); */
-
- return MaxValue;
-}
-
-u8 mct_SaveRcvEnDly_D_1Pass(struct DCTStatStruc *pDCTstat, u8 pass)
-{
- u8 ret;
- ret = 0;
- if ((pDCTstat->DqsRcvEn_Pass == 0xff) && (pass== FirstPass))
- ret = 2;
- return ret;
-}
-
-u16 mct_Average_RcvrEnDly_Pass(struct DCTStatStruc *pDCTstat,
- u16 RcvrEnDly, u16 RcvrEnDlyLimit,
- u8 Channel, u8 Receiver, u8 Pass)
-
-{
- return mct_Average_RcvrEnDly_1Pass(pDCTstat, Channel, Receiver, Pass);
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctsrc2p.c b/src/northbridge/amd/amdmct/mct_ddr3/mctsrc2p.c
deleted file mode 100644
index 8eeb93ff78..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctsrc2p.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
- *
- * 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; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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.
- */
-
-u8 mct_checkNumberOfDqsRcvEn_Pass(u8 pass)
-{
- return 1;
-}
-
-u32 SetupDqsPattern_PassA(u8 Pass)
-{
- u32 ret;
- if (Pass == FirstPass)
- ret = (u32) TestPattern1_D;
- else
- ret = (u32) TestPattern2_D;
-
- return ret;
-}
-
-u32 SetupDqsPattern_PassB(u8 Pass)
-{
- u32 ret;
- if (Pass == FirstPass)
- ret = (u32) TestPattern0_D;
- else
- ret = (u32) TestPattern2_D;
-
- return ret;
-}
-
-u8 mct_Get_Start_RcvrEnDly_Pass(struct DCTStatStruc *pDCTstat,
- u8 Channel, u8 Receiver,
- u8 Pass)
-{
- u8 RcvrEnDly;
-
- if (Pass == FirstPass)
- RcvrEnDly = 0;
- else {
- u8 max = 0;
- u8 val;
- u8 i;
- u8 *p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][Receiver>>1];
- u8 bn;
- bn = 8;
-
- for (i = 0; i < bn; i++) {
- val = p[i];
-
- if (val > max) {
- max = val;
- }
- }
- RcvrEnDly = max;
- }
-
- return RcvrEnDly;
-}
-
-u16 mct_Average_RcvrEnDly_Pass(struct DCTStatStruc *pDCTstat,
- u16 RcvrEnDly, u16 RcvrEnDlyLimit,
- u8 Channel, u8 Receiver, u8 Pass)
-{
- u8 i;
- u16 *p;
- u16 *p_1;
- u16 val;
- u16 val_1;
- u8 valid = 1;
- u8 bn;
-
- bn = 8;
-
- p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][Receiver>>1];
-
- if (Pass == SecondPass) { /* second pass must average values */
- /* FIXME: which byte? */
- p_1 = pDCTstat->B_RCVRDLY_1;
- /* p_1 = pDCTstat->persistentData.CH_D_B_RCVRDLY_1[Channel][Receiver>>1]; */
- for (i = 0; i < bn; i++) {
- val = p[i];
- /* left edge */
- if (val != (RcvrEnDlyLimit - 1)) {
- val -= Pass1MemClkDly;
- val_1 = p_1[i];
- val += val_1;
- val >>= 1;
- p[i] = val;
- } else {
- valid = 0;
- break;
- }
- }
- if (!valid) {
- pDCTstat->ErrStatus |= 1<<SB_NORCVREN;
- } else {
- pDCTstat->DimmTrainFail &= ~(1<<(Receiver + Channel));
- }
- } else {
- for (i = 0; i < bn; i++) {
- val = p[i];
- /* Add 1/2 Memlock delay */
- /* val += Pass1MemClkDly; */
- val += 0x5; /* NOTE: middle value with DQSRCVEN_SAVED_GOOD_TIMES */
- /* val += 0x02; */
- p[i] = val;
- pDCTstat->DimmTrainFail &= ~(1<<(Receiver + Channel));
- }
- }
-
- return RcvrEnDly;
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mcttmrl.c b/src/northbridge/amd/amdmct/mct_ddr3/mcttmrl.c
deleted file mode 100644
index b6ab65e2f8..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mcttmrl.c
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
- *
- * 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: Max Read Latency Training feature for DDR 3 MCT
- */
-
-#include <stdint.h>
-#include <console/console.h>
-#include <cpu/amd/msr.h>
-#include <cpu/x86/cr.h>
-#include "mct_d.h"
-#include "mct_d_gcc.h"
-
-static u8 CompareMaxRdLatTestPattern_D(u32 pattern_buf, u32 addr);
-static u32 GetMaxRdLatTestAddr_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 Channel,
- u8 *MaxRcvrEnDly, u8 *valid);
-u8 mct_GetStartMaxRdLat_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 Channel,
- u8 DQSRcvEnDly, u32 *Margin);
-static void maxRdLatencyTrain_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat);
-static void mct_setMaxRdLatTrnVal_D(struct DCTStatStruc *pDCTstat, u8 Channel,
- u16 MaxRdLatVal);
-
-/*Warning: These must be located so they do not cross a logical 16-bit
- segment boundary!*/
-static const u32 TestMaxRdLAtPattern_D[] = {
- 0x6E0E3FAC, 0x0C3CFF52,
- 0x4A688181, 0x49C5B613,
- 0x7C780BA6, 0x5C1650E3,
- 0x0C4F9D76, 0x0C6753E6,
- 0x205535A5, 0xBABFB6CA,
- 0x610E6E5F, 0x0C5F1C87,
- 0x488493CE, 0x14C9C383,
- 0xF5B9A5CD, 0x9CE8F615,
-
- 0xAAD714B5, 0xC38F1B4C,
- 0x72ED647C, 0x669F7562,
- 0x5233F802, 0x4A898B30,
- 0x10A40617, 0x3326B465,
- 0x55386E04, 0xC807E3D3,
- 0xAB49E193, 0x14B4E63A,
- 0x67DF2495, 0xEA517C45,
- 0x7624CE51, 0xF8140C51,
-
- 0x4824BD23, 0xB61DD0C9,
- 0x072BCFBE, 0xE8F3807D,
- 0x919EA373, 0x25E30C47,
- 0xFEB12958, 0x4DA80A5A,
- 0xE9A0DDF8, 0x792B0076,
- 0xE81C73DC, 0xF025B496,
- 0x1DB7E627, 0x808594FE,
- 0x82668268, 0x655C7783,
-};
-
-static u32 SetupMaxRdPattern(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat,
- u32 *buffer)
-{
- /* 1. Copy the alpha and Beta patterns from ROM to Cache,
- * aligning on 16 byte boundary
- * 2. Set the ptr to Cacheable copy in DCTStatstruc.PtrPatternBufA
- * for Alpha
- * 3. Set the ptr to Cacheable copy in DCTStatstruc.PtrPatternBufB
- * for Beta
- */
- u32 *buf;
- u8 i;
-
- buf = (u32 *)(((u32)buffer + 0x10) & (0xfffffff0));
-
- for (i = 0; i < (16 * 3); i++) {
- buf[i] = TestMaxRdLAtPattern_D[i];
- }
-
- return (u32)buf;
-}
-
-void TrainMaxReadLatency_D(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)
- break;
-
- if (pDCTstat->DCTSysLimit)
- maxRdLatencyTrain_D(pMCTstat, pDCTstat);
- }
-}
-
-static void maxRdLatencyTrain_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat)
-{
- u8 Channel;
- u32 TestAddr0;
- u8 _DisableDramECC = 0, _Wrap32Dis = 0, _SSE2 = 0;
- u16 MaxRdLatDly;
- u8 RcvrEnDly = 0;
- u32 PatternBuffer[60]; /* FIXME: why not 48 + 4 */
- u32 Margin;
- u32 addr;
- CRx_TYPE cr4;
- u32 lo, hi;
-
- u8 valid;
- u32 pattern_buf;
-
- cr4 = read_cr4();
- if (cr4 & (1<<9)) { /* save the old value */
- _SSE2 = 1;
- }
- cr4 |= (1<<9); /* OSFXSR enable SSE2 */
- write_cr4(cr4);
-
- addr = HWCR_MSR;
- _RDMSR(addr, &lo, &hi);
- if (lo & (1<<17)) { /* save the old value */
- _Wrap32Dis = 1;
- }
- lo |= (1<<17); /* HWCR.wrap32dis */
- lo &= ~(1<<15); /* SSEDIS */
- /* Setting wrap32dis allows 64-bit memory references in
- real mode */
- _WRMSR(addr, lo, hi);
-
- _DisableDramECC = mct_DisableDimmEccEn_D(pMCTstat, pDCTstat);
-
- pattern_buf = SetupMaxRdPattern(pMCTstat, pDCTstat, PatternBuffer);
-
- for (Channel = 0; Channel < 2; Channel++) {
- print_debug_dqs("\tMaxRdLatencyTrain51: Channel ",Channel, 1);
- pDCTstat->Channel = Channel;
-
- if ((pDCTstat->Status & (1 << SB_128bitmode)) && Channel)
- break; /*if ganged mode, skip DCT 1 */
-
- TestAddr0 = GetMaxRdLatTestAddr_D(pMCTstat, pDCTstat, Channel, &RcvrEnDly, &valid);
- if (!valid) /* Address not supported on current CS */
- continue;
- /* rank 1 of DIMM, testpattern 0 */
- WriteMaxRdLat1CLTestPattern_D(pattern_buf, TestAddr0);
-
- MaxRdLatDly = mct_GetStartMaxRdLat_D(pMCTstat, pDCTstat, Channel, RcvrEnDly, &Margin);
- print_debug_dqs("\tMaxRdLatencyTrain52: MaxRdLatDly start ", MaxRdLatDly, 2);
- print_debug_dqs("\tMaxRdLatencyTrain52: MaxRdLatDly Margin ", Margin, 2);
- while (MaxRdLatDly < MAX_RD_LAT) { /* sweep Delay value here */
- mct_setMaxRdLatTrnVal_D(pDCTstat, Channel, MaxRdLatDly);
- ReadMaxRdLat1CLTestPattern_D(TestAddr0);
- if (CompareMaxRdLatTestPattern_D(pattern_buf, TestAddr0) == DQS_PASS)
- break;
- SetTargetWTIO_D(TestAddr0);
- FlushMaxRdLatTestPattern_D(TestAddr0);
- ResetTargetWTIO_D();
- MaxRdLatDly++;
- }
- print_debug_dqs("\tMaxRdLatencyTrain53: MaxRdLatDly end ", MaxRdLatDly, 2);
- mct_setMaxRdLatTrnVal_D(pDCTstat, Channel, MaxRdLatDly + Margin);
- }
-
- if (_DisableDramECC) {
- mct_EnableDimmEccEn_D(pMCTstat, pDCTstat, _DisableDramECC);
- }
-
- if (!_Wrap32Dis) {
- addr = HWCR_MSR;
- _RDMSR(addr, &lo, &hi);
- lo &= ~(1<<17); /* restore HWCR.wrap32dis */
- _WRMSR(addr, lo, hi);
- }
- if (!_SSE2) {
- cr4 = read_cr4();
- cr4 &= ~(1<<9); /* restore cr4.OSFXSR */
- write_cr4(cr4);
- }
-
-#if DQS_TRAIN_DEBUG > 0
- {
- u8 ChannelDTD;
- printk(BIOS_DEBUG, "maxRdLatencyTrain: CH_MaxRdLat:\n");
- for (ChannelDTD = 0; ChannelDTD < 2; ChannelDTD++) {
- printk(BIOS_DEBUG, "Channel: %02x: %02x\n", ChannelDTD, pDCTstat->CH_MaxRdLat[ChannelDTD][0]);
- }
- }
-#endif
-}
-
-static void mct_setMaxRdLatTrnVal_D(struct DCTStatStruc *pDCTstat,
- u8 Channel, u16 MaxRdLatVal)
-{
- u8 i;
- u32 reg;
- u32 dev;
- u32 val;
-
- if (pDCTstat->GangedMode) {
- Channel = 0; /* for safe */
- for (i = 0; i < 2; i++)
- pDCTstat->CH_MaxRdLat[i][0] = MaxRdLatVal;
- } else {
- pDCTstat->CH_MaxRdLat[Channel][0] = MaxRdLatVal;
- }
-
- dev = pDCTstat->dev_dct;
- reg = 0x78;
- val = Get_NB32_DCT(dev, Channel, reg);
- val &= ~(0x3ff<<22);
- val |= MaxRdLatVal<<22;
- /* program MaxRdLatency to correspond with current delay */
- Set_NB32_DCT(dev, Channel, reg, val);
-}
-
-static u8 CompareMaxRdLatTestPattern_D(u32 pattern_buf, u32 addr)
-{
- /* Compare only the first beat of data. Since target addrs are cache
- * line aligned, the Channel parameter is used to determine which cache
- * QW to compare.
- */
-
- u32 *test_buf = (u32 *)pattern_buf;
- u32 addr_lo;
- u32 val, val_test;
- int i;
- u8 ret = DQS_PASS;
-
- SetUpperFSbase(addr);
- addr_lo = addr<<8;
-
- _EXECFENCE;
- for (i = 0; i < 16*3; i++) {
- val = read32_fs(addr_lo);
- val_test = test_buf[i];
-
- print_debug_dqs_pair("\t\t\t\t\t\ttest_buf = ", (u32)test_buf, " value = ", val_test, 5);
- print_debug_dqs_pair("\t\t\t\t\t\ttaddr_lo = ", addr_lo, " value = ", val, 5);
- if (val != val_test) {
- ret = DQS_FAIL;
- break;
- }
- addr_lo += 4;
- }
-
- return ret;
-}
-
-static u32 GetMaxRdLatTestAddr_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat,
- u8 Channel, u8 *MaxRcvrEnDly,
- u8 *valid)
-{
- u8 Max = 0;
-
- u8 Channel_Max = 0;
- u8 d;
- u8 d_Max = 0;
-
- u8 Byte;
- u32 TestAddr0 = 0;
- u8 ch, ch_start, ch_end;
- u8 bn;
-
- bn = 8;
-
- if (pDCTstat->Status & (1 << SB_128bitmode)) {
- ch_start = 0;
- ch_end = 2;
- } else {
- ch_start = Channel;
- ch_end = Channel + 1;
- }
-
- *valid = 0;
-
- for (ch = ch_start; ch < ch_end; ch++) {
- for (d = 0; d < 4; d++) {
- for (Byte = 0; Byte < bn; Byte++) {
- u8 tmp;
- tmp = pDCTstat->CH_D_B_RCVRDLY[ch][d][Byte];
- if (tmp > Max) {
- Max = tmp;
- Channel_Max = Channel;
- d_Max = d;
- }
- }
- }
- }
-
- if (mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, Channel_Max, d_Max << 1)) {
- TestAddr0 = mct_GetMCTSysAddr_D(pMCTstat, pDCTstat, Channel_Max, d_Max << 1, valid);
- }
-
- if (*valid)
- *MaxRcvrEnDly = Max;
-
- return TestAddr0;
-}
-
-u8 mct_GetStartMaxRdLat_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat,
- u8 Channel, u8 DQSRcvEnDly, u32 *Margin)
-{
- u32 SubTotal;
- u32 val;
- u32 valx;
- u32 valxx;
- u32 index_reg;
- u32 dev;
-
- if (pDCTstat->GangedMode)
- Channel = 0;
-
- index_reg = 0x98;
-
- dev = pDCTstat->dev_dct;
-
- /* Multiply the CAS Latency by two to get a number of 1/2 MEMCLKs units.*/
- val = Get_NB32_DCT(dev, Channel, 0x88);
- SubTotal = ((val & 0x0f) + 1) << 1; /* SubTotal is 1/2 Memclk unit */
-
- /* If registered DIMMs are being used then add 1 MEMCLK to the sub-total*/
- val = Get_NB32_DCT(dev, Channel, 0x90);
- if (!(val & (1 << UnBuffDimm)))
- SubTotal += 2;
-
- /*If the address prelaunch is setup for 1/2 MEMCLKs then add 1,
- * else add 2 to the sub-total. if (AddrCmdSetup || CsOdtSetup
- * || CkeSetup) then K := K + 2; */
- val = Get_NB32_index_wait_DCT(dev, Channel, index_reg, 0x04);
- if (!(val & 0x00202020))
- SubTotal += 1;
- else
- SubTotal += 2;
-
- /* If the F2x[1, 0]78[RdPtrInit] field is 4, 5, 6 or 7 MEMCLKs,
- * then add 4, 3, 2, or 1 MEMCLKs, respectively to the sub-total. */
- val = Get_NB32_DCT(dev, Channel, 0x78);
- SubTotal += 8 - (val & 0x0f);
-
- /* Convert bits 7-5 (also referred to as the course delay) of the current
- * (or worst case) DQS receiver enable delay to 1/2 MEMCLKs units,
- * rounding up, and add this to the sub-total. */
- SubTotal += DQSRcvEnDly >> 5; /*BOZO-no rounding up */
-
- SubTotal <<= 1; /*scale 1/2 MemClk to 1/4 MemClk */
-
- /* Convert the sub-total (in 1/2 MEMCLKs) to northbridge clocks (NCLKs)
- * as follows (assuming DDR400 and assuming that no P-state or link speed
- * changes have occurred). */
-
- /*New formula:
- SubTotal *= 3*(Fn2xD4[NBFid]+4)/(3+Fn2x94[MemClkFreq])/2 */
- val = Get_NB32_DCT(dev, Channel, 0x94);
- /* SubTotal div 4 to scale 1/4 MemClk back to MemClk */
- val &= 7;
- if (val >= 3) {
- val <<= 1;
- } else
- val += 3;
- valx = (val) << 2; /* SubTotal div 4 to scale 1/4 MemClk back to MemClk */
-
- val = Get_NB32(pDCTstat->dev_nbmisc, 0xD4);
- val = ((val & 0x1f) + 4) * 3;
-
- /* Calculate 1 MemClk + 1 NCLK delay in NCLKs for margin */
- valxx = val << 2;
- valxx /= valx;
- if (valxx % valx)
- valxx++; /* round up */
- valxx++; /* add 1NCLK */
- *Margin = valxx; /* one MemClk delay in NCLKs and one additional NCLK */
-
- val *= SubTotal;
-
- val /= valx;
- if (val % valx)
- val++; /* round up */
-
- return val;
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctwl.c b/src/northbridge/amd/amdmct/mct_ddr3/mctwl.c
deleted file mode 100644
index 82523e01b8..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctwl.c
+++ /dev/null
@@ -1,509 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- * Copyright (C) 2015 - 2016 Raptor Engineering, LLC
- *
- * 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.
- */
-
-#include <arch/cpu.h>
-#include <stdint.h>
-#include <console/console.h>
-
-#include "mct_d.h"
-#include "mct_d_gcc.h"
-
-static uint8_t is_fam15h(void)
-{
- uint8_t fam15h = 0;
- uint32_t family;
-
- family = cpuid_eax(0x80000001);
- family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);
-
- if (family >= 0x6f)
- /* Family 15h or later */
- fam15h = 1;
-
- return fam15h;
-}
-
-static void AgesaDelay(u32 msec)
-{
- mct_Wait(msec*10);
-}
-
-void PrepareC_MCT(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat)
-{
- pDCTstat->C_MCTPtr->AgesaDelay = AgesaDelay;
-}
-
-void PrepareC_DCT(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dct)
-{
- u8 dimm;
- u16 DimmValid;
- u16 Dimmx8Present;
-
- dct &= 1;
-
- pDCTstat->C_DCTPtr[dct]->DctTrain = dct;
-
- if (dct == 1) {
- Dimmx8Present = pDCTstat->Dimmx8Present >> 1;
- } else
- Dimmx8Present = pDCTstat->Dimmx8Present;
- Dimmx8Present &= 0x55;
-
- pDCTstat->C_DCTPtr[dct]->MaxDimmsInstalled = pDCTstat->MAdimms[dct];
- DimmValid = pDCTstat->DIMMValidDCT[dct];
-
- pDCTstat->C_DCTPtr[dct]->NodeId = pDCTstat->Node_ID;
- pDCTstat->C_DCTPtr[dct]->LogicalCPUID = pDCTstat->LogicalCPUID;
-
- for (dimm = 0; dimm < MAX_DIMMS; dimm++) {
- if (DimmValid & (1 << (dimm << 1)))
- pDCTstat->C_DCTPtr[dct]->DimmPresent[dimm] = 1;
- if (Dimmx8Present & (1 << (dimm << 1)))
- pDCTstat->C_DCTPtr[dct]->DimmX8Present[dimm] = 1;
- }
-
- if (pDCTstat->GangedMode & (1 << 0))
- pDCTstat->C_DCTPtr[dct]->CurrDct = 0;
- else
- pDCTstat->C_DCTPtr[dct]->CurrDct = dct;
-
- pDCTstat->C_DCTPtr[dct]->DctCSPresent = pDCTstat->CSPresent_DCT[dct];
- if (!(pDCTstat->GangedMode & (1 << 0)) && (dct == 1))
- pDCTstat->C_DCTPtr[dct]->DctCSPresent = pDCTstat->CSPresent_DCT[0];
-
- if (pDCTstat->Status & (1 << SB_Registered)) {
- pDCTstat->C_DCTPtr[dct]->Status[DCT_STATUS_REGISTERED] = 1;
- pDCTstat->C_DCTPtr[dct]->Status[DCT_STATUS_OnDimmMirror] = 0;
- } else {
- if (pDCTstat->MirrPresU_NumRegR > 0)
- pDCTstat->C_DCTPtr[dct]->Status[DCT_STATUS_OnDimmMirror] = 1;
- pDCTstat->C_DCTPtr[dct]->Status[DCT_STATUS_REGISTERED] = 0;
- }
-
- if (pDCTstat->Status & (1 << SB_LoadReduced)) {
- pDCTstat->C_DCTPtr[dct]->Status[DCT_STATUS_LOAD_REDUCED] = 1;
- } else {
- pDCTstat->C_DCTPtr[dct]->Status[DCT_STATUS_LOAD_REDUCED] = 0;
- }
-
- pDCTstat->C_DCTPtr[dct]->RegMan1Present = pDCTstat->RegMan1Present;
-
- for (dimm = 0; dimm < MAX_TOTAL_DIMMS; dimm++) {
- u8 DimmRanks;
- if (DimmValid & (1 << (dimm << 1))) {
- DimmRanks = 1;
- if (pDCTstat->DimmDRPresent & (1 << ((dimm << 1) + dct)))
- DimmRanks = 2;
- else if (pDCTstat->DimmQRPresent & (1 << ((dimm << 1) + dct)))
- DimmRanks = 4;
- } else
- DimmRanks = 0;
- pDCTstat->C_DCTPtr[dct]->DimmRanks[dimm] = DimmRanks;
- }
-}
-
-void EnableZQcalibration(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat)
-{
- u32 val;
-
- val = Get_NB32_DCT(pDCTstat->dev_dct, 0, 0x94);
- val |= 1 << 11;
- Set_NB32_DCT(pDCTstat->dev_dct, 0, 0x94, val);
-
- val = Get_NB32_DCT(pDCTstat->dev_dct, 1, 0x94);
- val |= 1 << 11;
- Set_NB32_DCT(pDCTstat->dev_dct, 1, 0x94, val);
-}
-
-void DisableZQcalibration(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat)
-{
- u32 val;
-
- val = Get_NB32_DCT(pDCTstat->dev_dct, 0, 0x94);
- val &= ~(1 << 11);
- val &= ~(1 << 10);
- Set_NB32_DCT(pDCTstat->dev_dct, 0, 0x94, val);
-
- val = Get_NB32_DCT(pDCTstat->dev_dct, 1, 0x94);
- val &= ~(1 << 11);
- val &= ~(1 << 10);
- Set_NB32_DCT(pDCTstat->dev_dct, 1, 0x94, val);
-}
-
-static void EnterSelfRefresh(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat)
-{
- u8 DCT0Present, DCT1Present;
- u32 val;
-
- DCT0Present = pDCTstat->DIMMValidDCT[0];
- if (pDCTstat->GangedMode)
- DCT1Present = 0;
- else
- DCT1Present = pDCTstat->DIMMValidDCT[1];
-
- /* Program F2x[1, 0]90[EnterSelfRefresh]=1. */
- if (DCT0Present) {
- val = Get_NB32_DCT(pDCTstat->dev_dct, 0, 0x90);
- val |= 1 << EnterSelfRef;
- Set_NB32_DCT(pDCTstat->dev_dct, 0, 0x90, val);
- }
- if (DCT1Present) {
- val = Get_NB32_DCT(pDCTstat->dev_dct, 1, 0x90);
- val |= 1 << EnterSelfRef;
- Set_NB32_DCT(pDCTstat->dev_dct, 1, 0x90, val);
- }
- /* Wait until the hardware resets F2x[1, 0]90[EnterSelfRefresh]=0. */
- if (DCT0Present)
- do {
- val = Get_NB32_DCT(pDCTstat->dev_dct, 0, 0x90);
- } while (val & (1 <<EnterSelfRef));
- if (DCT1Present)
- do {
- val = Get_NB32_DCT(pDCTstat->dev_dct, 1, 0x90);
- } while (val & (1 <<EnterSelfRef));
-}
-
-/*
- * Change memclk for write levelization pass 2
- */
-static void ChangeMemClk(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat)
-{
- printk(BIOS_DEBUG, "%s: Start\n", __func__);
-
- uint8_t DCT0Present;
- uint8_t DCT1Present;
- uint32_t dword;
- uint32_t mask;
- uint32_t offset;
-
- DCT0Present = pDCTstat->DIMMValidDCT[0];
- if (pDCTstat->GangedMode)
- DCT1Present = 0;
- else
- DCT1Present = pDCTstat->DIMMValidDCT[1];
-
- if (is_fam15h()) {
- /* Program D18F2x9C_x0D0F_E006_dct[1:0][PllLockTime] = 0x190 */
- if (DCT0Present) {
- dword = Get_NB32_index_wait_DCT(pDCTstat->dev_dct, 0, 0x98, 0x0d0fe006);
- dword &= ~(0x0000ffff);
- dword |= 0x00000190;
- Set_NB32_index_wait_DCT(pDCTstat->dev_dct, 0, 0x98, 0x0d0fe006, dword);
- }
- if (DCT1Present) {
- dword = Get_NB32_index_wait_DCT(pDCTstat->dev_dct, 1, 0x98, 0x0d0fe006);
- dword &= ~(0x0000ffff);
- dword |= 0x00000190;
- Set_NB32_index_wait_DCT(pDCTstat->dev_dct, 1, 0x98, 0x0d0fe006, dword);
- }
- } else {
- /* Program F2x[1, 0]9C[DisAutoComp]=1. */
- if (DCT0Present) {
- dword = Get_NB32_index_wait_DCT(pDCTstat->dev_dct, 0, 0x98, 8);
- dword |= 1 << DisAutoComp;
- Set_NB32_index_wait_DCT(pDCTstat->dev_dct, 0, 0x98, 8, dword);
- mct_Wait(100); /* Wait for 5us */
- }
- if (DCT1Present) {
- dword = Get_NB32_index_wait_DCT(pDCTstat->dev_dct, 1, 0x98, 8);
- dword |= 1 << DisAutoComp;
- Set_NB32_index_wait_DCT(pDCTstat->dev_dct, 1, 0x98, 8, dword);
- mct_Wait(100); /* Wait for 5us */
- }
- }
-
- /* Program F2x[1, 0]94[MemClkFreqVal] = 0. */
- if (DCT0Present) {
- dword = Get_NB32_DCT(pDCTstat->dev_dct, 0, 0x94);
- dword &= ~(1 << MemClkFreqVal);
- Set_NB32_DCT(pDCTstat->dev_dct, 0, 0x94, dword);
- }
- if (DCT1Present) {
- dword = Get_NB32_DCT(pDCTstat->dev_dct, 1, 0x94);
- dword &= ~(1 << MemClkFreqVal);
- Set_NB32_DCT(pDCTstat->dev_dct, 1, 0x94, dword);
- }
-
- /* Program F2x[1, 0]94[MemClkFreq] to specify the target MEMCLK frequency. */
- if (is_fam15h()) {
- offset = 0x0;
- mask = 0x1f;
- } else {
- offset = 0x1;
- mask = 0x7;
- }
- if (DCT0Present) {
- dword = Get_NB32_DCT(pDCTstat->dev_dct, 0, 0x94);
- dword &= ~mask;
- dword |= (pDCTstat->TargetFreq - offset) & mask;
- Set_NB32_DCT(pDCTstat->dev_dct, 0, 0x94, dword);
- }
- if (DCT1Present) {
- dword = Get_NB32_DCT(pDCTstat->dev_dct, 1, 0x94);
- dword &= ~mask;
- dword |= (pDCTstat->TargetFreq - offset) & mask;
- Set_NB32_DCT(pDCTstat->dev_dct, 1, 0x94, dword);
- }
-
- if (is_fam15h()) {
- if (DCT0Present) {
- mctGet_PS_Cfg_D(pMCTstat, pDCTstat, 0);
- set_2t_configuration(pMCTstat, pDCTstat, 0);
- mct_BeforePlatformSpec(pMCTstat, pDCTstat, 0);
- mct_PlatformSpec(pMCTstat, pDCTstat, 0);
- }
- if (DCT1Present) {
- mctGet_PS_Cfg_D(pMCTstat, pDCTstat, 1);
- set_2t_configuration(pMCTstat, pDCTstat, 1);
- mct_BeforePlatformSpec(pMCTstat, pDCTstat, 1);
- mct_PlatformSpec(pMCTstat, pDCTstat, 1);
- }
- }
-
- /* Program F2x[1, 0]94[MemClkFreqVal] = 1. */
- if (DCT0Present) {
- dword = Get_NB32_DCT(pDCTstat->dev_dct, 0, 0x94);
- dword |= 1 << MemClkFreqVal;
- Set_NB32_DCT(pDCTstat->dev_dct, 0, 0x94, dword);
- }
- if (DCT1Present) {
- dword = Get_NB32_DCT(pDCTstat->dev_dct, 1, 0x94);
- dword |= 1 << MemClkFreqVal;
- Set_NB32_DCT(pDCTstat->dev_dct, 1, 0x94, dword);
- }
-
- /* Wait until F2x[1, 0]94[FreqChgInProg]=0. */
- if (DCT0Present)
- do {
- dword = Get_NB32_DCT(pDCTstat->dev_dct, 0, 0x94);
- } while (dword & (1 << FreqChgInProg));
- if (DCT1Present)
- do {
- dword = Get_NB32_DCT(pDCTstat->dev_dct, 1, 0x94);
- } while (dword & (1 << FreqChgInProg));
-
- if (is_fam15h()) {
- /* Program D18F2x9C_x0D0F_E006_dct[1:0][PllLockTime] = 0xf */
- if (DCT0Present) {
- dword = Get_NB32_index_wait_DCT(pDCTstat->dev_dct, 0, 0x98, 0x0d0fe006);
- dword &= ~(0x0000ffff);
- dword |= 0x0000000f;
- Set_NB32_index_wait_DCT(pDCTstat->dev_dct, 0, 0x98, 0x0d0fe006, dword);
- }
- if (DCT1Present) {
- dword = Get_NB32_index_wait_DCT(pDCTstat->dev_dct, 1, 0x98, 0x0d0fe006);
- dword &= ~(0x0000ffff);
- dword |= 0x0000000f;
- Set_NB32_index_wait_DCT(pDCTstat->dev_dct, 1, 0x98, 0x0d0fe006, dword);
- }
- } else {
- /* Program F2x[1, 0]9C[DisAutoComp] = 0. */
- if (DCT0Present) {
- dword = Get_NB32_index_wait_DCT(pDCTstat->dev_dct, 0, 0x98, 8);
- dword &= ~(1 << DisAutoComp);
- Set_NB32_index_wait_DCT(pDCTstat->dev_dct, 0, 0x98, 8, dword);
- mct_Wait(15000); /* Wait for 750us */
- }
- if (DCT1Present) {
- dword = Get_NB32_index_wait_DCT(pDCTstat->dev_dct, 1, 0x98, 8);
- dword &= ~(1 << DisAutoComp);
- Set_NB32_index_wait_DCT(pDCTstat->dev_dct, 1, 0x98, 8, dword);
- mct_Wait(15000); /* Wait for 750us */
- }
- }
-
- printk(BIOS_DEBUG, "%s: Done\n", __func__);
-}
-
-/*
- * the DRAM controller to bring the DRAMs out of self refresh mode.
- */
-static void ExitSelfRefresh(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat)
-{
- u8 DCT0Present, DCT1Present;
- u32 val;
-
- DCT0Present = pDCTstat->DIMMValidDCT[0];
- if (pDCTstat->GangedMode)
- DCT1Present = 0;
- else
- DCT1Present = pDCTstat->DIMMValidDCT[1];
-
- /* Program F2x[1, 0]90[ExitSelfRef]=1 for both DCTs. */
- if (DCT0Present) {
- val = Get_NB32_DCT(pDCTstat->dev_dct, 0, 0x90);
- val |= 1 << ExitSelfRef;
- Set_NB32_DCT(pDCTstat->dev_dct, 0, 0x90, val);
- }
- if (DCT1Present) {
- val = Get_NB32_DCT(pDCTstat->dev_dct, 1, 0x90);
- val |= 1 << ExitSelfRef;
- Set_NB32_DCT(pDCTstat->dev_dct, 1, 0x90, val);
- }
- /* Wait until the hardware resets F2x[1, 0]90[ExitSelfRef]=0. */
- if (DCT0Present)
- do {
- val = Get_NB32_DCT(pDCTstat->dev_dct, 0, 0x90);
- } while (val & (1 << ExitSelfRef));
- if (DCT1Present)
- do {
- val = Get_NB32_DCT(pDCTstat->dev_dct, 1, 0x90);
- } while (val & (1 << ExitSelfRef));
-}
-
-void SetTargetFreq(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstatA, uint8_t Node)
-{
- uint32_t dword;
- uint8_t package_type = mctGet_NVbits(NV_PACK_TYPE);
-
- printk(BIOS_DEBUG, "%s: Start\n", __func__);
-
- struct DCTStatStruc *pDCTstat;
- pDCTstat = pDCTstatA + Node;
-
- printk(BIOS_DEBUG, "%s: Node %d: New frequency code: %04x\n", __func__, Node, pDCTstat->TargetFreq);
-
- if (is_fam15h()) {
- /* Program F2x[1, 0]90[DisDllShutDownSR]=1. */
- if (pDCTstat->DIMMValidDCT[0]) {
- dword = Get_NB32_DCT(pDCTstat->dev_dct, 0, 0x90);
- dword |= (0x1 << 27);
- Set_NB32_DCT(pDCTstat->dev_dct, 0, 0x90, dword);
- }
- if (pDCTstat->DIMMValidDCT[1]) {
- dword = Get_NB32_DCT(pDCTstat->dev_dct, 1, 0x90);
- dword |= (0x1 << 27);
- Set_NB32_DCT(pDCTstat->dev_dct, 1, 0x90, dword);
- }
- }
-
- /* Program F2x[1,0]90[EnterSelfRefresh]=1.
- * Wait until the hardware resets F2x[1,0]90[EnterSelfRefresh]=0.
- */
- EnterSelfRefresh(pMCTstat, pDCTstat);
-
- /*
- * Program F2x[1,0]9C_x08[DisAutoComp]=1
- * Program F2x[1,0]94[MemClkFreqVal] = 0.
- * Program F2x[1,0]94[MemClkFreq] to specify the target MEMCLK frequency.
- * Program F2x[1,0]94[MemClkFreqVal] = 1.
- * Wait until F2x[1,0]94[FreqChgInProg]=0.
- * Program F2x[1,0]9C_x08[DisAutoComp]=0
- */
- ChangeMemClk(pMCTstat, pDCTstat);
-
- if (is_fam15h()) {
- uint8_t dct;
- for (dct = 0; dct < 2; dct++) {
- if (pDCTstat->DIMMValidDCT[dct]) {
- phyAssistedMemFnceTraining(pMCTstat, pDCTstatA, Node);
- InitPhyCompensation(pMCTstat, pDCTstat, dct);
- }
- }
- }
-
- /* Program F2x[1,0]90[ExitSelfRef]=1 for both DCTs.
- * Wait until the hardware resets F2x[1, 0]90[ExitSelfRef]=0.
- */
- ExitSelfRefresh(pMCTstat, pDCTstat);
-
- if (is_fam15h()) {
- if ((package_type == PT_C3) || (package_type == PT_GR)) {
- /* Socket C32 or G34 */
- /* Program F2x[1, 0]90[DisDllShutDownSR]=0. */
- if (pDCTstat->DIMMValidDCT[0]) {
- dword = Get_NB32_DCT(pDCTstat->dev_dct, 0, 0x90);
- dword &= ~(0x1 << 27);
- Set_NB32_DCT(pDCTstat->dev_dct, 0, 0x90, dword);
- }
- if (pDCTstat->DIMMValidDCT[1]) {
- dword = Get_NB32_DCT(pDCTstat->dev_dct, 1, 0x90);
- dword &= ~(0x1 << 27);
- Set_NB32_DCT(pDCTstat->dev_dct, 1, 0x90, dword);
- }
- }
- }
-
- /* wait for 500 MCLKs after ExitSelfRef, 500*2.5ns = 1250ns */
- mct_Wait(250);
-
- if (pDCTstat->Status & (1 << SB_Registered)) {
- u8 DCT0Present, DCT1Present;
-
- DCT0Present = pDCTstat->DIMMValidDCT[0];
- if (pDCTstat->GangedMode)
- DCT1Present = 0;
- else
- DCT1Present = pDCTstat->DIMMValidDCT[1];
-
- if (!DCT1Present)
- pDCTstat->CSPresent = pDCTstat->CSPresent_DCT[0];
- else if (pDCTstat->GangedMode)
- pDCTstat->CSPresent = 0;
- else
- pDCTstat->CSPresent = pDCTstat->CSPresent_DCT[1];
-
- if (pDCTstat->DIMMValidDCT[0]) {
- FreqChgCtrlWrd(pMCTstat, pDCTstat, 0);
- }
- if (pDCTstat->DIMMValidDCT[1]) {
- FreqChgCtrlWrd(pMCTstat, pDCTstat, 1);
- }
- }
-
- printk(BIOS_DEBUG, "%s: Done\n", __func__);
-}
-
-static void Modify_OnDimmMirror(struct DCTStatStruc *pDCTstat, u8 dct, u8 set)
-{
- u32 val;
- u32 reg = 0x44;
- while (reg < 0x60) {
- val = Get_NB32_DCT(pDCTstat->dev_dct, dct, reg);
- if (val & (1 << CSEnable))
- set ? (val |= 1 << onDimmMirror) : (val &= ~(1<<onDimmMirror));
- Set_NB32_DCT(pDCTstat->dev_dct, dct, reg, val);
- reg += 8;
- }
-}
-
-void Restore_OnDimmMirror(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat)
-{
- if (pDCTstat->LogicalCPUID & (AMD_DR_Bx /* | AMD_RB_C0 */)) { /* We dont support RB-C0 now */
- if (pDCTstat->MirrPresU_NumRegR & 0x55)
- Modify_OnDimmMirror(pDCTstat, 0, 1); /* dct = 0, set */
- if (pDCTstat->MirrPresU_NumRegR & 0xAA)
- Modify_OnDimmMirror(pDCTstat, 1, 1); /* dct = 1, set */
- }
-}
-void Clear_OnDimmMirror(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat)
-{
- if (pDCTstat->LogicalCPUID & (AMD_DR_Bx /* | AMD_RB_C0 */)) { /* We dont support RB-C0 now */
- if (pDCTstat->MirrPresU_NumRegR & 0x55)
- Modify_OnDimmMirror(pDCTstat, 0, 0); /* dct = 0, clear */
- if (pDCTstat->MirrPresU_NumRegR & 0xAA)
- Modify_OnDimmMirror(pDCTstat, 1, 0); /* dct = 1, clear */
- }
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mhwlc_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mhwlc_d.c
deleted file mode 100644
index 353aa7a1cf..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mhwlc_d.c
+++ /dev/null
@@ -1,1519 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- * Copyright (C) 2015 - 2016 Raptor Engineering, LLC
- *
- * 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.
- */
-
-#include <stdint.h>
-#include <assert.h>
-#include <console/console.h>
-#include <northbridge/amd/amdfam10/amdfam10.h>
-
-#include "mct_d.h"
-#include "mct_d_gcc.h"
-#include "mwlc_d.h"
-
-u32 swapAddrBits_wl(struct DCTStatStruc *pDCTstat, uint8_t dct, uint32_t MRSValue);
-u32 swapBankBits(struct DCTStatStruc *pDCTstat, uint8_t dct, uint32_t MRSValue);
-void prepareDimms(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat,
- u8 dct, u8 dimm, BOOL wl);
-void programODT(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, uint8_t dct, u8 dimm);
-void procConfig(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t dimm, uint8_t pass, uint8_t nibble);
-void setWLByteDelay(struct DCTStatStruc *pDCTstat, uint8_t dct, u8 ByteLane, u8 dimm, u8 targetAddr, uint8_t pass, uint8_t lane_count);
-void getWLByteDelay(struct DCTStatStruc *pDCTstat, uint8_t dct, u8 ByteLane, u8 dimm, uint8_t pass, uint8_t nibble, uint8_t lane_count);
-
-#define MAX_LANE_COUNT 9
-
-/*-----------------------------------------------------------------------------
- * uint8_t AgesaHwWlPhase1(SPDStruct *SPDData,MCTStruct *MCTData, DCTStruct *DCTData,
- * u8 Dimm, u8 Pass)
- *
- * Description:
- * This function initialized Hardware based write levelization phase 1
- *
- * Parameters:
- * IN OUT *SPDData - Pointer to buffer with information about each DIMMs
- * SPD information
- * *MCTData - Pointer to buffer with runtime parameters,
- * *DCTData - Pointer to buffer with information about each DCT
- *
- * IN DIMM - Logical DIMM number
- * Pass - First or Second Pass
- * OUT
- *-----------------------------------------------------------------------------
- */
-uint8_t AgesaHwWlPhase1(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat,
- u8 dct, u8 dimm, u8 pass)
-{
- u8 ByteLane;
- u32 Value, Addr;
- uint8_t nibble = 0;
- uint8_t train_both_nibbles;
- u16 Addl_Data_Offset, Addl_Data_Port;
- sMCTStruct *pMCTData = pDCTstat->C_MCTPtr;
- sDCTStruct *pDCTData = pDCTstat->C_DCTPtr[dct];
- uint8_t lane_count;
-
- lane_count = get_available_lane_count(pMCTstat, pDCTstat);
-
- pDCTData->WLPass = pass;
- /* 1. Specify the target DIMM that is to be trained by programming
- * F2x[1, 0]9C_x08[TrDimmSel].
- */
- set_DCT_ADDR_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_ADD_DCT_PHY_CONTROL_REG, TrDimmSelStart,
- TrDimmSelEnd, (u32)dimm);
-
- train_both_nibbles = 0;
- if (pDCTstat->Dimmx4Present)
- if (is_fam15h())
- train_both_nibbles = 1;
-
- for (nibble = 0; nibble < (train_both_nibbles + 1); nibble++) {
- printk(BIOS_SPEW, "AgesaHwWlPhase1: training nibble %d\n", nibble);
-
- if (is_fam15h()) {
- /* Program F2x[1, 0]9C_x08[WrtLvTrEn]=0 */
- set_DCT_ADDR_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_ADD_DCT_PHY_CONTROL_REG, WrtLvTrEn, WrtLvTrEn, 0);
-
- /* Set TrNibbleSel */
- set_DCT_ADDR_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_ADD_DCT_PHY_CONTROL_REG, 2,
- 2, (uint32_t)nibble);
- }
-
- /* 2. Prepare the DIMMs for write levelization using DDR3-defined
- * MR commands. */
- prepareDimms(pMCTstat, pDCTstat, dct, dimm, TRUE);
-
- /* 3. After the DIMMs are configured, BIOS waits 40 MEMCLKs to
- * satisfy DDR3-defined internal DRAM timing.
- */
- if (is_fam15h())
- precise_memclk_delay_fam15(pMCTstat, pDCTstat, dct, 40);
- else
- pMCTData->AgesaDelay(40);
-
- /* 4. Configure the processor's DDR phy for write levelization training: */
- procConfig(pMCTstat, pDCTstat, dct, dimm, pass, nibble);
-
- /* 5. Begin write levelization training:
- * Program F2x[1, 0]9C_x08[WrtLvTrEn]=1. */
- if (pDCTData->LogicalCPUID & (AMD_DR_Cx | AMD_DR_Dx | AMD_FAM15_ALL))
- {
- set_DCT_ADDR_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_ADD_DCT_PHY_CONTROL_REG, WrtLvTrEn, WrtLvTrEn, 1);
- }
- else
- {
- /* Broadcast write to all D3Dbyte chipset register offset 0xc
- * Set bit 0 (wrTrain)
- * Program bit 4 to nibble being trained (only matters for x4dimms)
- * retain value of 3:2 (Trdimmsel)
- * reset bit 5 (FrzPR)
- */
- if (dct)
- {
- Addl_Data_Offset = 0x198;
- Addl_Data_Port = 0x19C;
- }
- else
- {
- Addl_Data_Offset = 0x98;
- Addl_Data_Port = 0x9C;
- }
- Addr = 0x0D00000C;
- AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+(pDCTData->NodeId),FUN_DCT,Addl_Data_Offset), 31, 0, &Addr);
- while ((get_Bits(pDCTData,FUN_DCT,pDCTData->NodeId, FUN_DCT, Addl_Data_Offset,
- DctAccessDone, DctAccessDone)) == 0);
- AmdMemPCIReadBits(MAKE_SBDFO(0,0,24+(pDCTData->NodeId),FUN_DCT,Addl_Data_Port), 31, 0, &Value);
- Value = bitTestSet(Value, 0); /* enable WL training */
- Value = bitTestReset(Value, 4); /* for x8 only */
- Value = bitTestReset(Value, 5); /* for hardware WL training */
- AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+(pDCTData->NodeId),FUN_DCT,Addl_Data_Port), 31, 0, &Value);
- Addr = 0x4D030F0C;
- AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+(pDCTData->NodeId),FUN_DCT,Addl_Data_Offset), 31, 0, &Addr);
- while ((get_Bits(pDCTData,FUN_DCT,pDCTData->NodeId, FUN_DCT, Addl_Data_Offset,
- DctAccessDone, DctAccessDone)) == 0);
- }
-
- if (is_fam15h())
- proc_MFENCE();
-
- /* Wait 200 MEMCLKs. If executing pass 2, wait 32 MEMCLKs. */
- if (is_fam15h())
- precise_memclk_delay_fam15(pMCTstat, pDCTstat, dct, 200);
- else
- pMCTData->AgesaDelay(140);
-
- /* Program F2x[1, 0]9C_x08[WrtLevelTrEn]=0. */
- set_DCT_ADDR_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_ADD_DCT_PHY_CONTROL_REG, WrtLvTrEn, WrtLvTrEn, 0);
-
- /* Read from registers F2x[1, 0]9C_x[51:50] and F2x[1, 0]9C_x52
- * to get the gross and fine delay settings
- * for the target DIMM and save these values. */
- for (ByteLane = 0; ByteLane < lane_count; ByteLane++) {
- getWLByteDelay(pDCTstat, dct, ByteLane, dimm, pass, nibble, lane_count);
- }
-
- pDCTData->WLCriticalGrossDelayPrevPass = 0x0;
-
- /* Exit nibble training if current DIMM is not x4 */
- if ((pDCTstat->Dimmx4Present & (1 << (dimm + dct))) == 0)
- break;
- }
-
- return 0;
-}
-
-uint8_t AgesaHwWlPhase2(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat,
- uint8_t dct, uint8_t dimm, uint8_t pass)
-{
- u8 ByteLane;
- uint8_t status = 0;
- sDCTStruct *pDCTData = pDCTstat->C_DCTPtr[dct];
- uint8_t lane_count;
-
- lane_count = get_available_lane_count(pMCTstat, pDCTstat);
-
- assert(lane_count <= MAX_LANE_COUNT);
-
- if (is_fam15h()) {
- int32_t gross_diff[MAX_LANE_COUNT];
- int32_t cgd = pDCTData->WLCriticalGrossDelayPrevPass;
- uint8_t index = (uint8_t)(lane_count * dimm);
-
- printk(BIOS_SPEW, "\toriginal critical gross delay: %d\n", cgd);
-
- /* FIXME
- * For now, disable CGD adjustment as it seems to interfere with registered DIMM training
- */
-
- /* Calculate the Critical Gross Delay */
- for (ByteLane = 0; ByteLane < lane_count; ByteLane++) {
- /* Calculate the gross delay differential for this lane */
- gross_diff[ByteLane] = pDCTData->WLSeedGrossDelay[index+ByteLane] + pDCTData->WLGrossDelay[index+ByteLane];
- gross_diff[ByteLane] -= pDCTData->WLSeedPreGrossDelay[index+ByteLane];
-
- /* WrDqDqsEarly values greater than 2 are reserved */
- if (gross_diff[ByteLane] < -2)
- gross_diff[ByteLane] = -2;
-
- /* Update the Critical Gross Delay */
- if (gross_diff[ByteLane] < cgd)
- cgd = gross_diff[ByteLane];
- }
-
- printk(BIOS_SPEW, "\tnew critical gross delay: %d\n", cgd);
-
- pDCTData->WLCriticalGrossDelayPrevPass = cgd;
-
- if (pDCTstat->Speed != pDCTstat->TargetFreq) {
- /* FIXME
- * Using the Pass 1 training values causes major phy training problems on
- * all Family 15h processors I tested (Pass 1 values are randomly too high,
- * and Pass 2 cannot lock).
- * Figure out why this is and fix it, then remove the bypass code below...
- */
- if (pass == FirstPass) {
- for (ByteLane = 0; ByteLane < lane_count; ByteLane++) {
- pDCTData->WLGrossDelay[index+ByteLane] = pDCTData->WLSeedGrossDelay[index+ByteLane];
- pDCTData->WLFineDelay[index+ByteLane] = pDCTData->WLSeedFineDelay[index+ByteLane];
- }
- return 0;
- }
- }
-
- /* Compensate for occasional noise/instability causing sporadic training failure */
- for (ByteLane = 0; ByteLane < lane_count; ByteLane++) {
- uint8_t faulty_value_detected = 0;
- uint16_t total_delay_seed = ((pDCTData->WLSeedGrossDelay[index+ByteLane] & 0x1f) << 5) | (pDCTData->WLSeedFineDelay[index+ByteLane] & 0x1f);
- uint16_t total_delay_phy = ((pDCTData->WLGrossDelay[index+ByteLane] & 0x1f) << 5) | (pDCTData->WLFineDelay[index+ByteLane] & 0x1f);
- if (pass == FirstPass) {
- /* Allow a somewhat higher step threshold on the first pass
- * For the most part, as long as the phy isn't stepping
- * several clocks at once the values are probably valid.
- */
- if (abs(total_delay_phy - total_delay_seed) > 0x30)
- faulty_value_detected = 1;
- } else {
- /* Stepping memory clocks between adjacent allowed frequencies
- * should not yield large phy value differences...
- */
-
- if (abs(total_delay_phy - total_delay_seed) > 0x20)
- faulty_value_detected = 1;
- }
- if (faulty_value_detected) {
- printk(BIOS_INFO, "%s: overriding faulty phy value (seed: %04x phy: %04x step: %04x)\n", __func__,
- total_delay_seed, total_delay_phy, abs(total_delay_phy - total_delay_seed));
- pDCTData->WLGrossDelay[index+ByteLane] = pDCTData->WLSeedGrossDelay[index+ByteLane];
- pDCTData->WLFineDelay[index+ByteLane] = pDCTData->WLSeedFineDelay[index+ByteLane];
- status = 1;
- }
- }
- }
-
- return status;
-}
-
-uint8_t AgesaHwWlPhase3(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat,
- u8 dct, u8 dimm, u8 pass)
-{
- u8 ByteLane;
- sMCTStruct *pMCTData = pDCTstat->C_MCTPtr;
- sDCTStruct *pDCTData = pDCTstat->C_DCTPtr[dct];
- uint8_t lane_count;
-
- lane_count = get_available_lane_count(pMCTstat, pDCTstat);
-
- assert(lane_count <= MAX_LANE_COUNT);
-
- if (is_fam15h()) {
- uint32_t dword;
- int32_t gross_diff[MAX_LANE_COUNT];
- int32_t cgd = pDCTData->WLCriticalGrossDelayPrevPass;
- uint8_t index = (uint8_t)(lane_count * dimm);
-
- /* Apply offset(s) if needed */
- if (cgd < 0) {
- dword = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0xa8);
- dword &= ~(0x3 << 24); /* WrDqDqsEarly = abs(cgd) */
- dword |= ((abs(cgd) & 0x3) << 24);
- Set_NB32_DCT(pDCTstat->dev_dct, dct, 0xa8, dword);
-
- for (ByteLane = 0; ByteLane < lane_count; ByteLane++) {
- /* Calculate the gross delay differential for this lane */
- gross_diff[ByteLane] = pDCTData->WLSeedGrossDelay[index+ByteLane] + pDCTData->WLGrossDelay[index+ByteLane];
- gross_diff[ByteLane] -= pDCTData->WLSeedPreGrossDelay[index+ByteLane];
-
- /* Prevent underflow in the presence of noise / instability */
- if (gross_diff[ByteLane] < cgd)
- gross_diff[ByteLane] = cgd;
-
- pDCTData->WLGrossDelay[index+ByteLane] = (gross_diff[ByteLane] + (abs(cgd) & 0x3));
- }
- } else {
- dword = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0xa8);
- dword &= ~(0x3 << 24); /* WrDqDqsEarly = pDCTData->WrDqsGrossDlyBaseOffset */
- dword |= ((pDCTData->WrDqsGrossDlyBaseOffset & 0x3) << 24);
- Set_NB32_DCT(pDCTstat->dev_dct, dct, 0xa8, dword);
- }
- }
-
- /* Write the adjusted gross and fine delay settings
- * to the target DIMM. */
- for (ByteLane = 0; ByteLane < lane_count; ByteLane++) {
- setWLByteDelay(pDCTstat, dct, ByteLane, dimm, 1, pass, lane_count);
- }
-
- /* 6. Configure DRAM Phy Control Register so that the phy stops driving
- * write levelization ODT. */
- set_DCT_ADDR_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_ADD_DCT_PHY_CONTROL_REG, WrLvOdtEn, WrLvOdtEn, 0);
-
- if (is_fam15h())
- proc_MFENCE();
-
- /* Wait 10 MEMCLKs to allow for ODT signal settling. */
- if (is_fam15h())
- precise_memclk_delay_fam15(pMCTstat, pDCTstat, dct, 10);
- else
- pMCTData->AgesaDelay(10);
-
- /* 7. Program the target DIMM back to normal operation by configuring
- * the following (See section 2.8.5.4.1.1
- * [Phy Assisted Write Levelization] on page 97 pass 1, step #2):
- * Configure all ranks of the target DIMM for normal operation.
- * Enable the output drivers of all ranks of the target DIMM.
- * For a two DIMM system, program the Rtt value for the target DIMM
- * to the normal operating termination:
- */
- prepareDimms(pMCTstat, pDCTstat, dct, dimm, FALSE);
-
- return 0;
-}
-
-/*----------------------------------------------------------------------------
- * LOCAL FUNCTIONS
- *
- *----------------------------------------------------------------------------
- */
-
-/*-----------------------------------------------------------------------------
- * u32 swapAddrBits_wl(struct DCTStatStruc *pDCTstat, uint8_t dct, u32 MRSValue)
- *
- * Description:
- * This function swaps the bits in MSR register value
- *
- * Parameters:
- * IN OUT *DCTData - Pointer to buffer with information about each DCT
- * IN u32: MRS value
- * OUT u32: Swapped BANK BITS
- *
- * ----------------------------------------------------------------------------
- */
-u32 swapAddrBits_wl(struct DCTStatStruc *pDCTstat, uint8_t dct, uint32_t MRSValue)
-{
- sDCTStruct *pDCTData = pDCTstat->C_DCTPtr[dct];
- u32 tempW, tempW1;
-
- if (is_fam15h())
- tempW1 = get_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, DRAM_INIT, MrsChipSelStartFam15, MrsChipSelEndFam15);
- else
- tempW1 = get_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, DRAM_INIT, MrsChipSelStartFam10, MrsChipSelEndFam10);
- if (tempW1 & 1)
- {
- if ((pDCTData->Status[DCT_STATUS_OnDimmMirror]))
- {
- /* swap A3/A4,A5/A6,A7/A8 */
- tempW = MRSValue;
- tempW1 = MRSValue;
- tempW &= 0x0A8;
- tempW1 &= 0x0150;
- MRSValue &= 0xFE07;
- MRSValue |= (tempW << 1);
- MRSValue |= (tempW1 >> 1);
- }
- }
- return MRSValue;
-}
-
-/*-----------------------------------------------------------------------------
- * u32 swapBankBits(struct DCTStatStruc *pDCTstat, uint8_t dct, u32 MRSValue)
- *
- * Description:
- * This function swaps the bits in MSR register value
- *
- * Parameters:
- * IN OUT *DCTData - Pointer to buffer with information about each DCT
- * IN u32: MRS value
- * OUT u32: Swapped BANK BITS
- *
- * ----------------------------------------------------------------------------
- */
-u32 swapBankBits(struct DCTStatStruc *pDCTstat, uint8_t dct, u32 MRSValue)
-{
- sDCTStruct *pDCTData = pDCTstat->C_DCTPtr[dct];
- u32 tempW, tempW1;
-
- if (is_fam15h())
- tempW1 = get_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, DRAM_INIT, MrsChipSelStartFam15, MrsChipSelEndFam15);
- else
- tempW1 = get_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, DRAM_INIT, MrsChipSelStartFam10, MrsChipSelEndFam10);
- if (tempW1 & 1)
- {
- if ((pDCTData->Status[DCT_STATUS_OnDimmMirror]))
- {
- /* swap BA0/BA1 */
- tempW = MRSValue;
- tempW1 = MRSValue;
- tempW &= 0x01;
- tempW1 &= 0x02;
- MRSValue = 0;
- MRSValue |= (tempW << 1);
- MRSValue |= (tempW1 >> 1);
- }
- }
- return MRSValue;
-}
-
-static uint16_t unbuffered_dimm_nominal_termination_emrs(uint8_t number_of_dimms, uint8_t frequency_index, uint8_t rank_count, uint8_t rank)
-{
- uint16_t term;
-
- uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH);
-
- if (number_of_dimms == 1) {
- if (MaxDimmsInstallable < 3) {
- term = 0x04; /* Rtt_Nom = RZQ/4 = 60 Ohm */
- } else {
- if (rank_count == 1) {
- term = 0x04; /* Rtt_Nom = RZQ/4 = 60 Ohm */
- } else {
- if (rank == 0)
- term = 0x04; /* Rtt_Nom = RZQ/4 = 60 Ohm */
- else
- term = 0x00; /* Rtt_Nom = OFF */
- }
- }
- } else {
- if (frequency_index < 5)
- term = 0x0044; /* Rtt_Nom = RZQ/6 = 40 Ohm */
- else
- term = 0x0204; /* Rtt_Nom = RZQ/8 = 30 Ohm */
- }
-
- return term;
-}
-
-static uint16_t unbuffered_dimm_dynamic_termination_emrs(uint8_t number_of_dimms, uint8_t frequency_index, uint8_t rank_count)
-{
- uint16_t term;
-
- uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH);
-
- if (number_of_dimms == 1) {
- if (MaxDimmsInstallable < 3) {
- term = 0x00; /* Rtt_WR = off */
- } else {
- if (rank_count == 1)
- term = 0x00; /* Rtt_WR = off */
- else
- term = 0x200; /* Rtt_WR = RZQ/4 = 60 Ohm */
- }
- } else {
- term = 0x400; /* Rtt_WR = RZQ/2 = 120 Ohm */
- }
-
- return term;
-}
-
-/*-----------------------------------------------------------------------------
- * void prepareDimms(sMCTStruct *pMCTData, sDCTStruct *DCTData, u8 Dimm, BOOL WL)
- *
- * Description:
- * This function prepares DIMMS for training
- * Fam10h: BKDG Rev. 3.62 section 2.8.9.9.1
- * Fam15h: BKDG Rev. 3.14 section 2.10.5.8.1
- * ----------------------------------------------------------------------------
- */
-void prepareDimms(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat,
- u8 dct, u8 dimm, BOOL wl)
-{
- u32 tempW, tempW1, tempW2, MrsBank;
- u8 rank, currDimm, MemClkFreq;
- sMCTStruct *pMCTData = pDCTstat->C_MCTPtr;
- sDCTStruct *pDCTData = pDCTstat->C_DCTPtr[dct];
- uint8_t package_type = mctGet_NVbits(NV_PACK_TYPE);
- uint8_t number_of_dimms = pDCTData->MaxDimmsInstalled;
-
- if (is_fam15h()) {
- MemClkFreq = get_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, DRAM_CONFIG_HIGH, 0, 4);
- } else {
- MemClkFreq = get_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, DRAM_CONFIG_HIGH, 0, 2);
- }
- /* Configure the DCT to send initialization MR commands to the target DIMM
- * by programming the F2x[1,0]7C register using the following steps.
- */
- rank = 0;
- while ((rank < pDCTData->DimmRanks[dimm]) && (rank < 2))
- {
- /* Program F2x[1, 0]7C[MrsChipSel[2:0]] for the current rank to be trained. */
- if (is_fam15h())
- set_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_INIT, MrsChipSelStartFam15, MrsChipSelEndFam15, dimm*2+rank);
- else
- set_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_INIT, MrsChipSelStartFam10, MrsChipSelEndFam10, dimm*2+rank);
-
- /* Program F2x[1, 0]7C[MrsBank[2:0]] for the appropriate internal DRAM
- * register that defines the required DDR3-defined function for write
- * levelization.
- */
- MrsBank = swapBankBits(pDCTstat, dct, 1);
- if (is_fam15h())
- set_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_INIT, MrsBankStartFam15, MrsBankEndFam15, MrsBank);
- else
- set_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_INIT, MrsBankStartFam10, MrsBankEndFam10, MrsBank);
-
- /* Program F2x[1, 0]7C[MrsAddress[15:0]] to the required DDR3-defined function
- * for write levelization.
- */
- tempW = 0;/* DLL_DIS = 0, DIC = 0, AL = 0, TDQS = 0 */
-
- /* Retrieve normal settings of the MRS control word and clear Rtt_Nom */
- if (is_fam15h()) {
- tempW = mct_MR1(pMCTstat, pDCTstat, dct, dimm*2+rank) & 0xffff;
- tempW &= ~(0x0244);
- } else {
- /* Set TDQS = 1b for x8 DIMM, TDQS = 0b for x4 DIMM, when mixed x8 & x4 */
- tempW2 = get_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, DRAM_CONFIG_HIGH, RDqsEn, RDqsEn);
- if (tempW2)
- {
- if (pDCTData->DimmX8Present[dimm])
- tempW |= 0x800;
- }
- }
-
- /* determine Rtt_Nom for WL & Normal mode */
- if (is_fam15h()) {
- if (wl) {
- if (number_of_dimms > 1) {
- if (rank == 0) {
- /* Get Rtt_WR for the current DIMM and rank */
- tempW2 = fam15_rttwr(pDCTstat, dct, dimm, rank, package_type);
- } else {
- tempW2 = fam15_rttnom(pDCTstat, dct, dimm, rank, package_type);
- }
- } else {
- tempW2 = fam15_rttnom(pDCTstat, dct, dimm, rank, package_type);
- }
- } else {
- tempW2 = fam15_rttnom(pDCTstat, dct, dimm, rank, package_type);
- }
- tempW1 = 0;
- tempW1 |= ((tempW2 & 0x4) >> 2) << 9;
- tempW1 |= ((tempW2 & 0x2) >> 1) << 6;
- tempW1 |= ((tempW2 & 0x1) >> 0) << 2;
- } else {
- if (pDCTData->Status[DCT_STATUS_REGISTERED]) {
- tempW1 = RttNomTargetRegDimm(pMCTData, pDCTData, dimm, wl, MemClkFreq, rank);
- } else {
- if (wl) {
- if (number_of_dimms > 1) {
- if (rank == 0) {
- /* Get Rtt_WR for the current DIMM and rank */
- uint16_t dynamic_term = unbuffered_dimm_dynamic_termination_emrs(pDCTData->MaxDimmsInstalled, MemClkFreq, pDCTData->DimmRanks[dimm]);
-
- /* Convert dynamic termination code to corresponding nominal termination code */
- if (dynamic_term == 0x200)
- tempW1 = 0x04;
- else if (dynamic_term == 0x400)
- tempW1 = 0x40;
- else
- tempW1 = 0x0;
- } else {
- tempW1 = unbuffered_dimm_nominal_termination_emrs(pDCTData->MaxDimmsInstalled, MemClkFreq, pDCTData->DimmRanks[dimm], rank);
- }
- } else {
- tempW1 = unbuffered_dimm_nominal_termination_emrs(pDCTData->MaxDimmsInstalled, MemClkFreq, pDCTData->DimmRanks[dimm], rank);
- }
- } else {
- tempW1 = unbuffered_dimm_nominal_termination_emrs(pDCTData->MaxDimmsInstalled, MemClkFreq, pDCTData->DimmRanks[dimm], rank);
- }
- }
- }
-
- /* Apply Rtt_Nom to the MRS control word */
- tempW = tempW|tempW1;
-
- /* All ranks of the target DIMM are set to write levelization mode. */
- if (wl)
- {
- tempW1 = bitTestSet(tempW, MRS_Level);
- if (rank == 0)
- {
- /* Enable the output driver of the first rank of the target DIMM. */
- tempW = tempW1;
- }
- else
- {
- /* Disable the output drivers of all other ranks for
- * the target DIMM.
- */
- tempW = bitTestSet(tempW1, Qoff);
- }
- }
-
- /* Program MrsAddress[5,1]=output driver impedance control (DIC) */
- if (is_fam15h()) {
- tempW1 = fam15_dimm_dic(pDCTstat, dct, dimm, rank, package_type);
- } else {
- /* Read DIC from F2x[1,0]84[DrvImpCtrl] */
- tempW1 = get_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, DRAM_MRS_REGISTER, DrvImpCtrlStart, DrvImpCtrlEnd);
- }
-
- /* Apply DIC to the MRS control word */
- if (bitTest(tempW1, 1))
- tempW = bitTestSet(tempW, 5);
- if (bitTest(tempW1, 0))
- tempW = bitTestSet(tempW, 1);
-
- tempW = swapAddrBits_wl(pDCTstat, dct, tempW);
-
- if (is_fam15h())
- set_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_INIT, MrsAddressStartFam15, MrsAddressEndFam15, tempW);
- else
- set_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_INIT, MrsAddressStartFam10, MrsAddressEndFam10, tempW);
-
- /* Program F2x[1, 0]7C[SendMrsCmd]=1 to initiate the command to
- * the specified DIMM.
- */
- set_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_INIT, SendMrsCmd, SendMrsCmd, 1);
- /* Wait for F2x[1, 0]7C[SendMrsCmd] to be cleared by hardware. */
- while ((get_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, DRAM_INIT, SendMrsCmd, SendMrsCmd)) == 0x1)
- {
- }
-
- /* Program F2x[1, 0]7C[MrsBank[2:0]] for the appropriate internal DRAM
- * register that defines the required DDR3-defined function for Rtt_WR.
- */
- MrsBank = swapBankBits(pDCTstat, dct, 2);
- if (is_fam15h())
- set_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_INIT, MrsBankStartFam15, MrsBankEndFam15, MrsBank);
- else
- set_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_INIT, MrsBankStartFam10, MrsBankEndFam10, MrsBank);
-
- /* Program F2x[1, 0]7C[MrsAddress[15:0]] to the required DDR3-defined function
- * for Rtt_WR (DRAMTermDyn).
- */
- tempW = 0;/* PASR = 0,*/
-
- /* Retrieve normal settings of the MRS control word and clear Rtt_WR */
- if (is_fam15h()) {
- tempW = mct_MR2(pMCTstat, pDCTstat, dct, dimm*2+rank) & 0xffff;
- tempW &= ~(0x0600);
- } else {
- /* program MrsAddress[7,6,5:3]=SRT,ASR,CWL,
- * based on F2x[1,0]84[19,18,22:20]=,SRT,ASR,Tcwl */
- tempW1 = get_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, DRAM_MRS_REGISTER, PCI_MIN_LOW, PCI_MAX_HIGH);
- if (bitTest(tempW1,19))
- {tempW = bitTestSet(tempW, 7);}
- if (bitTest(tempW1,18))
- {tempW = bitTestSet(tempW, 6);}
- /* tempW = tempW|(((tempW1 >> 20) & 0x7)<< 3); */
- tempW = tempW|((tempW1&0x00700000) >> 17);
- /* workaround for DR-B0 */
- if ((pDCTData->LogicalCPUID & AMD_DR_Bx) && (pDCTData->Status[DCT_STATUS_REGISTERED]))
- tempW+=0x8;
- }
-
- /* determine Rtt_WR for WL & Normal mode */
- if (is_fam15h()) {
- tempW1 = (fam15_rttwr(pDCTstat, dct, dimm, rank, package_type) << 9);
- } else {
- if (pDCTData->Status[DCT_STATUS_REGISTERED])
- tempW1 = RttWrRegDimm(pMCTData, pDCTData, dimm, wl, MemClkFreq, rank);
- else
- tempW1 = unbuffered_dimm_dynamic_termination_emrs(pDCTData->MaxDimmsInstalled, MemClkFreq, pDCTData->DimmRanks[dimm]);
- }
-
- /* Apply Rtt_WR to the MRS control word */
- tempW = tempW|tempW1;
- tempW = swapAddrBits_wl(pDCTstat, dct, tempW);
- if (is_fam15h())
- set_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_INIT, MrsAddressStartFam15, MrsAddressEndFam15, tempW);
- else
- set_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_INIT, MrsAddressStartFam10, MrsAddressEndFam10, tempW);
-
- /* Program F2x[1, 0]7C[SendMrsCmd]=1 to initiate the command to
- the specified DIMM.*/
- set_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_INIT, SendMrsCmd, SendMrsCmd, 1);
-
- /* Wait for F2x[1, 0]7C[SendMrsCmd] to be cleared by hardware. */
- while ((get_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, DRAM_INIT, SendMrsCmd, SendMrsCmd)) == 0x1)
- {
- }
-
- rank++;
- }
-
- /* Configure the non-target DIMM normally. */
- currDimm = 0;
- while (currDimm < MAX_LDIMMS)
- {
- if (pDCTData->DimmPresent[currDimm])
- {
- if (currDimm != dimm)
- {
- rank = 0;
- while ((rank < pDCTData->DimmRanks[currDimm]) && (rank < 2))
- {
- /* Program F2x[1, 0]7C[MrsChipSel[2:0]] for the current rank
- * to be trained.
- */
- if (is_fam15h())
- set_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, DRAM_INIT, MrsChipSelStartFam15, MrsChipSelEndFam15, currDimm*2+rank);
- else
- set_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, DRAM_INIT, MrsChipSelStartFam10, MrsChipSelEndFam10, currDimm*2+rank);
-
- /* Program F2x[1, 0]7C[MrsBank[2:0]] for the appropriate internal
- * DRAM register that defines the required DDR3-defined function
- * for write levelization.
- */
- MrsBank = swapBankBits(pDCTstat, dct, 1);
- if (is_fam15h())
- set_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, DRAM_INIT, MrsBankStartFam15, MrsBankEndFam15, MrsBank);
- else
- set_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, DRAM_INIT, MrsBankStartFam10, MrsBankEndFam10, MrsBank);
-
- /* Program F2x[1, 0]7C[MrsAddress[15:0]] to the required
- * DDR3-defined function for write levelization.
- */
- tempW = 0;/* DLL_DIS = 0, DIC = 0, AL = 0, TDQS = 0, Level = 0, Qoff = 0 */
-
- /* Retrieve normal settings of the MRS control word and clear Rtt_Nom */
- if (is_fam15h()) {
- tempW = mct_MR1(pMCTstat, pDCTstat, dct, currDimm*2+rank) & 0xffff;
- tempW &= ~(0x0244);
- } else {
- /* Set TDQS = 1b for x8 DIMM, TDQS = 0b for x4 DIMM, when mixed x8 & x4 */
- tempW2 = get_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, DRAM_CONFIG_HIGH, RDqsEn, RDqsEn);
- if (tempW2)
- {
- if (pDCTData->DimmX8Present[currDimm])
- tempW |= 0x800;
- }
- }
-
- /* determine Rtt_Nom for WL & Normal mode */
- if (is_fam15h()) {
- tempW2 = fam15_rttnom(pDCTstat, dct, dimm, rank, package_type);
- tempW1 = 0;
- tempW1 |= ((tempW2 & 0x4) >> 2) << 9;
- tempW1 |= ((tempW2 & 0x2) >> 1) << 6;
- tempW1 |= ((tempW2 & 0x1) >> 0) << 2;
- } else {
- if (pDCTData->Status[DCT_STATUS_REGISTERED])
- tempW1 = RttNomNonTargetRegDimm(pMCTData, pDCTData, currDimm, wl, MemClkFreq, rank);
- else
- tempW1 = unbuffered_dimm_nominal_termination_emrs(pDCTData->MaxDimmsInstalled, MemClkFreq, pDCTData->DimmRanks[currDimm], rank);
- }
-
- /* Apply Rtt_Nom to the MRS control word */
- tempW = tempW|tempW1;
-
- /* Program MrsAddress[5,1]=output driver impedance control (DIC) */
- if (is_fam15h()) {
- tempW1 = fam15_dimm_dic(pDCTstat, dct, dimm, rank, package_type);
- } else {
- /* Read DIC from F2x[1,0]84[DrvImpCtrl] */
- tempW1 = get_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, DRAM_MRS_REGISTER, DrvImpCtrlStart, DrvImpCtrlEnd);
- }
-
- /* Apply DIC to the MRS control word */
- if (bitTest(tempW1,1))
- {tempW = bitTestSet(tempW, 5);}
- if (bitTest(tempW1,0))
- {tempW = bitTestSet(tempW, 1);}
-
- tempW = swapAddrBits_wl(pDCTstat, dct, tempW);
-
- if (is_fam15h())
- set_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, DRAM_INIT, MrsAddressStartFam15, MrsAddressEndFam15, tempW);
- else
- set_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, DRAM_INIT, MrsAddressStartFam10, MrsAddressEndFam10, tempW);
-
- /* Program F2x[1, 0]7C[SendMrsCmd]=1 to initiate the command
- * to the specified DIMM.
- */
- set_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, DRAM_INIT, SendMrsCmd, SendMrsCmd, 1);
-
- /* Wait for F2x[1, 0]7C[SendMrsCmd] to be cleared by hardware. */
- while ((get_Bits(pDCTData, dct,
- pDCTData->NodeId, FUN_DCT, DRAM_INIT,
- SendMrsCmd, SendMrsCmd)) == 1);
-
- /* Program F2x[1, 0]7C[MrsBank[2:0]] for the appropriate internal DRAM
- * register that defines the required DDR3-defined function for Rtt_WR.
- */
- MrsBank = swapBankBits(pDCTstat, dct, 2);
- if (is_fam15h())
- set_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_INIT, MrsBankStartFam15, MrsBankEndFam15, MrsBank);
- else
- set_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_INIT, MrsBankStartFam10, MrsBankEndFam10, MrsBank);
-
- /* Program F2x[1, 0]7C[MrsAddress[15:0]] to the required DDR3-defined function
- * for Rtt_WR (DRAMTermDyn).
- */
- tempW = 0;/* PASR = 0,*/
-
- /* Retrieve normal settings of the MRS control word and clear Rtt_WR */
- if (is_fam15h()) {
- tempW = mct_MR2(pMCTstat, pDCTstat, dct, currDimm*2+rank) & 0xffff;
- tempW &= ~(0x0600);
- } else {
- /* program MrsAddress[7,6,5:3]=SRT,ASR,CWL,
- * based on F2x[1,0]84[19,18,22:20]=,SRT,ASR,Tcwl */
- tempW1 = get_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, DRAM_MRS_REGISTER, PCI_MIN_LOW, PCI_MAX_HIGH);
- if (bitTest(tempW1,19))
- {tempW = bitTestSet(tempW, 7);}
- if (bitTest(tempW1,18))
- {tempW = bitTestSet(tempW, 6);}
- /* tempW = tempW|(((tempW1 >> 20) & 0x7) << 3); */
- tempW = tempW|((tempW1&0x00700000) >> 17);
- /* workaround for DR-B0 */
- if ((pDCTData->LogicalCPUID & AMD_DR_Bx) && (pDCTData->Status[DCT_STATUS_REGISTERED]))
- tempW+=0x8;
- }
-
- /* determine Rtt_WR for WL & Normal mode */
- if (is_fam15h()) {
- tempW1 = (fam15_rttwr(pDCTstat, dct, dimm, rank, package_type) << 9);
- } else {
- if (pDCTData->Status[DCT_STATUS_REGISTERED])
- tempW1 = RttWrRegDimm(pMCTData, pDCTData, currDimm, wl, MemClkFreq, rank);
- else
- tempW1 = unbuffered_dimm_dynamic_termination_emrs(pDCTData->MaxDimmsInstalled, MemClkFreq, pDCTData->DimmRanks[currDimm]);
- }
-
- /* Apply Rtt_WR to the MRS control word */
- tempW = tempW|tempW1;
- tempW = swapAddrBits_wl(pDCTstat, dct, tempW);
- if (is_fam15h())
- set_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_INIT, MrsAddressStartFam15, MrsAddressEndFam15, tempW);
- else
- set_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_INIT, MrsAddressStartFam10, MrsAddressEndFam10, tempW);
-
- /* Program F2x[1, 0]7C[SendMrsCmd]=1 to initiate the command to
- the specified DIMM.*/
- set_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_INIT, SendMrsCmd, SendMrsCmd, 1);
-
- /* Wait for F2x[1, 0]7C[SendMrsCmd] to be cleared by hardware. */
- while ((get_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, DRAM_INIT, SendMrsCmd, SendMrsCmd)) == 0x1)
- {
- }
- rank++;
- }
- }
- }
- currDimm++;
- }
-}
-
-/*-----------------------------------------------------------------------------
- * void programODT(sMCTStruct *pMCTData, DCTStruct *DCTData, u8 dimm)
- *
- * Description:
- * This function programs the ODT values for the NB
- *
- * Parameters:
- * IN OUT *DCTData - Pointer to buffer with information about each DCT
- * IN
- * OUT
- * ----------------------------------------------------------------------------
- */
-void programODT(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t dimm)
-{
- sMCTStruct *pMCTData = pDCTstat->C_MCTPtr;
- sDCTStruct *pDCTData = pDCTstat->C_DCTPtr[dct];
-
- u8 WrLvOdt1 = 0;
-
- if (is_fam15h()) {
- /* On Family15h processors, the value for the specific CS being targeted
- * is taken from F2x238 / F2x23C as appropriate, then loaded into F2x9C_x0000_0008
- */
-
- /* Convert DIMM number to CS */
- uint32_t dword;
- uint8_t cs;
- uint8_t rank = 0;
-
- cs = (dimm * 2) + rank;
-
- /* Fetch preprogammed ODT pattern from configuration registers */
- dword = Get_NB32_DCT(pDCTstat->dev_dct, dct, ((cs > 3)?0x23c:0x238));
- if ((cs == 7) || (cs == 3))
- WrLvOdt1 = ((dword >> 24) & 0xf);
- else if ((cs == 6) || (cs == 2))
- WrLvOdt1 = ((dword >> 16) & 0xf);
- else if ((cs == 5) || (cs == 1))
- WrLvOdt1 = ((dword >> 8) & 0xf);
- else if ((cs == 4) || (cs == 0))
- WrLvOdt1 = (dword & 0xf);
- } else {
- if (pDCTData->Status[DCT_STATUS_REGISTERED]) {
- WrLvOdt1 = WrLvOdtRegDimm(pMCTData, pDCTData, dimm);
- } else {
- if ((pDCTData->DctCSPresent & 0x05) == 0x05) {
- WrLvOdt1 = 0x03;
- } else if (bitTest((u32)pDCTData->DctCSPresent,(u8)(dimm*2+1))) {
- WrLvOdt1 = (u8)bitTestSet(WrLvOdt1, dimm+2);
- } else {
- WrLvOdt1 = (u8)bitTestSet(WrLvOdt1, dimm);
- }
- }
- }
-
- set_DCT_ADDR_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_ADD_DCT_PHY_CONTROL_REG, 8, 11, (u32)WrLvOdt1);
-
- printk(BIOS_SPEW, "Programmed DCT %d write levelling ODT pattern %08x from DIMM %d data\n", dct, WrLvOdt1, dimm);
-
-}
-
-#ifdef UNUSED_CODE
-static uint16_t fam15h_next_lowest_memclk_freq(uint16_t memclk_freq)
-{
- uint16_t fam15h_next_lowest_freq_tab[] = {0, 0, 0, 0, 0x4, 0, 0x4, 0, 0, 0, 0x6, 0, 0, 0, 0xa, 0, 0, 0, 0xe, 0, 0, 0, 0x12};
- return fam15h_next_lowest_freq_tab[memclk_freq];
-}
-#endif
-
-/*-----------------------------------------------------------------------------
- * void procConfig(MCTStruct *MCTData,DCTStruct *DCTData, u8 Dimm, u8 Pass, u8 Nibble)
- *
- * Description:
- * This function programs the ODT values for the NB
- *
- * Parameters:
- * IN OUT *DCTData - Pointer to buffer with information about each DCT
- * *MCTData - Pointer to buffer with runtime parameters,
- * IN Dimm - Logical DIMM
- * Pass - First of Second Pass
- * OUT
- * ----------------------------------------------------------------------------
- */
-void procConfig(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t dimm, uint8_t pass, uint8_t nibble)
-{
- u8 ByteLane, MemClkFreq;
- int32_t Seed_Gross;
- int32_t Seed_Fine;
- uint8_t Seed_PreGross;
- u32 Value, Addr;
- uint32_t dword;
- u16 Addl_Data_Offset, Addl_Data_Port;
- sMCTStruct *pMCTData = pDCTstat->C_MCTPtr;
- sDCTStruct *pDCTData = pDCTstat->C_DCTPtr[dct];
- uint16_t fam10h_freq_tab[] = {0, 0, 0, 400, 533, 667, 800};
- 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};
- uint8_t lane_count;
-
- lane_count = get_available_lane_count(pMCTstat, pDCTstat);
-
- assert(lane_count <= MAX_LANE_COUNT);
-
- if (is_fam15h()) {
- /* MemClkFreq: 0x4: 333MHz; 0x6: 400MHz; 0xa: 533MHz; 0xe: 667MHz; 0x12: 800MHz; 0x16: 933MHz */
- MemClkFreq = get_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, DRAM_CONFIG_HIGH, 0, 4);
- } else {
- /* MemClkFreq: 3: 400MHz; 4: 533MHz; 5: 667MHz; 6: 800MHz */
- MemClkFreq = get_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, DRAM_CONFIG_HIGH, 0, 2);
- }
-
- /* Program F2x[1, 0]9C_x08[WrLvOdt[3:0]] to the proper ODT settings for the
- * current memory subsystem configuration.
- */
- programODT(pMCTstat, pDCTstat, dct, dimm);
-
- /* Program F2x[1,0]9C_x08[WrLvOdtEn]=1 */
- if (pDCTData->LogicalCPUID & (AMD_DR_Cx | AMD_DR_Dx | AMD_FAM15_ALL)) {
- set_DCT_ADDR_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_ADD_DCT_PHY_CONTROL_REG, WrLvOdtEn, WrLvOdtEn, (u32)1);
- }
- else
- {
- /* Program WrLvOdtEn = 1 through set bit 12 of D3CSODT reg offset 0 for Rev.B */
- if (dct)
- {
- Addl_Data_Offset = 0x198;
- Addl_Data_Port = 0x19C;
- }
- else
- {
- Addl_Data_Offset = 0x98;
- Addl_Data_Port = 0x9C;
- }
- Addr = 0x0D008000;
- AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+(pDCTData->NodeId),FUN_DCT,Addl_Data_Offset), 31, 0, &Addr);
- while ((get_Bits(pDCTData,FUN_DCT,pDCTData->NodeId, FUN_DCT, Addl_Data_Offset,
- DctAccessDone, DctAccessDone)) == 0);
- AmdMemPCIReadBits(MAKE_SBDFO(0,0,24+(pDCTData->NodeId),FUN_DCT,Addl_Data_Port), 31, 0, &Value);
- Value = bitTestSet(Value, 12);
- AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+(pDCTData->NodeId),FUN_DCT,Addl_Data_Port), 31, 0, &Value);
- Addr = 0x4D088F00;
- AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+(pDCTData->NodeId),FUN_DCT,Addl_Data_Offset), 31, 0, &Addr);
- while ((get_Bits(pDCTData,FUN_DCT,pDCTData->NodeId, FUN_DCT, Addl_Data_Offset,
- DctAccessDone, DctAccessDone)) == 0);
- }
-
- if (is_fam15h())
- proc_MFENCE();
-
- /* Wait 10 MEMCLKs to allow for ODT signal settling. */
- if (is_fam15h())
- precise_memclk_delay_fam15(pMCTstat, pDCTstat, dct, 10);
- else
- pMCTData->AgesaDelay(10);
-
- /* Program write levelling seed values */
- if (pass == 1)
- {
- /* Pass 1 */
- if (is_fam15h()) {
- uint8_t AddrCmdPrelaunch = 0; /* TODO: Fetch the correct value from RC2[0] */
- uint8_t package_type = mctGet_NVbits(NV_PACK_TYPE);
- uint16_t Seed_Total = 0;
- pDCTData->WrDqsGrossDlyBaseOffset = 0x0;
- if (package_type == PT_GR) {
- /* Socket G34: Fam15h BKDG v3.14 Table 96 */
- if (pDCTData->Status[DCT_STATUS_REGISTERED]) {
- /* TODO
- * Implement mainboard-specific seed and
- * WrDqsGrossDly base overrides.
- * 0x41 and 0x0 are the "stock" values
- */
- Seed_Total = 0x41;
- pDCTData->WrDqsGrossDlyBaseOffset = 0x2;
- } else if (pDCTData->Status[DCT_STATUS_LOAD_REDUCED]) {
- Seed_Total = 0x0;
- } else {
- Seed_Total = 0xf;
- }
- } else if (package_type == PT_C3) {
- /* Socket C32: Fam15h BKDG v3.14 Table 97 */
- if (pDCTData->Status[DCT_STATUS_REGISTERED]) {
- Seed_Total = 0x3e;
- } else if (pDCTData->Status[DCT_STATUS_LOAD_REDUCED]) {
- Seed_Total = 0x0;
- } else {
- Seed_Total = 0x12;
- }
- } else if (package_type == PT_M2) {
- /* Socket AM3: Fam15h BKDG v3.14 Table 98 */
- Seed_Total = 0xf;
- } else if (package_type == PT_FM2) {
- /* Socket FM2: Fam15h M10 BKDG 3.12 Table 42 */
- Seed_Total = 0x15;
- }
- if (pDCTData->Status[DCT_STATUS_REGISTERED])
- Seed_Total += ((AddrCmdPrelaunch)?0x10:0x0);
-
- /* Adjust seed for the minimum platform supported frequency */
- Seed_Total = (int32_t) (((((int64_t) Seed_Total) *
- fam15h_freq_tab[MemClkFreq] * 100) / (mctGet_NVbits(NV_MIN_MEMCLK) * 100)));
-
- Seed_Gross = (Seed_Total >> 5) & 0x1f;
- Seed_Fine = Seed_Total & 0x1f;
-
- /* Save seed values for later use */
- for (ByteLane = 0; ByteLane < lane_count; ByteLane++) {
- pDCTData->WLSeedGrossDelay[lane_count*dimm+ByteLane] = Seed_Gross;
- pDCTData->WLSeedFineDelay[lane_count*dimm+ByteLane] = Seed_Fine;
-
- if (Seed_Gross == 0)
- Seed_PreGross = 0;
- else if (Seed_Gross & 0x1)
- Seed_PreGross = 1;
- else
- Seed_PreGross = 2;
-
- pDCTData->WLSeedPreGrossDelay[lane_count*dimm+ByteLane] = Seed_PreGross;
- }
- } else {
- if (pDCTData->Status[DCT_STATUS_REGISTERED]) {
- uint8_t AddrCmdPrelaunch = 0; /* TODO: Fetch the correct value from RC2[0] */
-
- /* The seed values below assume Pass 1 utilizes a 400MHz clock frequency (DDR3-800) */
- if (AddrCmdPrelaunch == 0) {
- Seed_Gross = 0x02;
- Seed_Fine = 0x01;
- } else {
- Seed_Gross = 0x02;
- Seed_Fine = 0x11;
- }
- } else {
- if (MemClkFreq == 6) {
- /* DDR-800 */
- Seed_Gross = 0x00;
- Seed_Fine = 0x1a;
- } else {
- /* Use settings for DDR-400 (interpolated from BKDG) */
- Seed_Gross = 0x00;
- Seed_Fine = 0x0d;
- }
- }
- }
- for (ByteLane = 0; ByteLane < lane_count; ByteLane++)
- {
- /* Program an initialization value to registers F2x[1, 0]9C_x[51:50] and
- * F2x[1, 0]9C_x52 to set the gross and fine delay for all the byte lane fields
- * If the target frequency is different than 400MHz, BIOS must
- * execute two training passes for each DIMM.
- * For pass 1 at a 400MHz MEMCLK frequency, use an initial total delay value
- * of 01Fh. This represents a 1UI (UI=.5MEMCLK) delay and is determined
- * by design.
- */
- pDCTData->WLGrossDelay[lane_count*dimm+ByteLane] = Seed_Gross;
- pDCTData->WLFineDelay[lane_count*dimm+ByteLane] = Seed_Fine;
- printk(BIOS_SPEW, "\tLane %02x initial seed: %04x\n", ByteLane, ((Seed_Gross & 0x1f) << 5) | (Seed_Fine & 0x1f));
- }
- } else {
- if (nibble == 0) {
- /* Pass 2 */
- /* From BKDG, Write Leveling Seed Value. */
- if (is_fam15h()) {
- uint32_t RegisterDelay;
- int32_t SeedTotal[MAX_LANE_COUNT];
- int32_t SeedTotalPreScaling[MAX_LANE_COUNT];
- uint32_t WrDqDqsEarly;
- uint8_t AddrCmdPrelaunch = 0; /* TODO: Fetch the correct value from RC2[0] */
-
- if (pDCTData->Status[DCT_STATUS_REGISTERED]) {
- if (AddrCmdPrelaunch)
- RegisterDelay = 0x30;
- else
- RegisterDelay = 0x20;
- } else {
- RegisterDelay = 0;
- }
-
- /* Retrieve WrDqDqsEarly */
- dword = Get_NB32_DCT(pDCTstat->dev_dct, dct, 0xa8);
- WrDqDqsEarly = (dword >> 24) & 0x3;
-
- /* FIXME
- * Ignore WrDqDqsEarly for now to work around training issues
- */
- WrDqDqsEarly = 0;
-
- /* Generate new seed values */
- for (ByteLane = 0; ByteLane < lane_count; ByteLane++) {
- /* Calculate adjusted seed values */
- SeedTotal[ByteLane] = (pDCTData->WLFineDelayPrevPass[lane_count*dimm+ByteLane] & 0x1f) |
- ((pDCTData->WLGrossDelayPrevPass[lane_count*dimm+ByteLane] & 0x1f) << 5);
- SeedTotalPreScaling[ByteLane] = (SeedTotal[ByteLane] - RegisterDelay - (0x20 * WrDqDqsEarly));
- SeedTotal[ByteLane] = (int32_t) (RegisterDelay + ((((int64_t) SeedTotalPreScaling[ByteLane]) *
- fam15h_freq_tab[MemClkFreq] * 100) / (fam15h_freq_tab[pDCTData->WLPrevMemclkFreq[dimm]] * 100)));
- }
-
- /* Generate register values from seeds */
- for (ByteLane = 0; ByteLane < lane_count; ByteLane++) {
- printk(BIOS_SPEW, "\tLane %02x scaled delay: %04x\n", ByteLane, SeedTotal[ByteLane]);
-
- if (SeedTotal[ByteLane] >= 0) {
- Seed_Gross = SeedTotal[ByteLane] / 32;
- Seed_Fine = SeedTotal[ByteLane] % 32;
- } else {
- Seed_Gross = (SeedTotal[ByteLane] / 32) - 1;
- Seed_Fine = (SeedTotal[ByteLane] % 32) + 32;
- }
-
- /* The BKDG-recommended algorithm causes problems with registered DIMMs on some systems
- * due to the long register delays causing premature total delay wrap-around.
- * Attempt to work around this...
- */
- Seed_PreGross = Seed_Gross;
-
- /* Save seed values for later use */
- pDCTData->WLSeedGrossDelay[lane_count*dimm+ByteLane] = Seed_Gross;
- pDCTData->WLSeedFineDelay[lane_count*dimm+ByteLane] = Seed_Fine;
- pDCTData->WLSeedPreGrossDelay[lane_count*dimm+ByteLane] = Seed_PreGross;
-
- pDCTData->WLGrossDelay[lane_count*dimm+ByteLane] = Seed_PreGross;
- pDCTData->WLFineDelay[lane_count*dimm+ByteLane] = Seed_Fine;
-
- printk(BIOS_SPEW, "\tLane %02x new seed: %04x\n", ByteLane, ((pDCTData->WLGrossDelay[lane_count*dimm+ByteLane] & 0x1f) << 5) | (pDCTData->WLFineDelay[lane_count*dimm+ByteLane] & 0x1f));
- }
- } else {
- uint32_t RegisterDelay;
- uint32_t SeedTotalPreScaling;
- uint32_t SeedTotal;
- uint8_t AddrCmdPrelaunch = 0; /* TODO: Fetch the correct value from RC2[0] */
- for (ByteLane = 0; ByteLane < lane_count; ByteLane++)
- {
- if (pDCTData->Status[DCT_STATUS_REGISTERED]) {
- if (AddrCmdPrelaunch == 0)
- RegisterDelay = 0x20;
- else
- RegisterDelay = 0x30;
- } else {
- RegisterDelay = 0;
- }
- SeedTotalPreScaling = ((pDCTData->WLFineDelay[lane_count*dimm+ByteLane] & 0x1f) |
- (pDCTData->WLGrossDelay[lane_count*dimm+ByteLane] << 5)) - RegisterDelay;
- /* SeedTotalPreScaling = (the total delay value in F2x[1, 0]9C_x[4A:30] from pass 1 of write levelization
- training) - RegisterDelay. */
- SeedTotal = (uint16_t) ((((uint64_t) SeedTotalPreScaling) *
- fam10h_freq_tab[MemClkFreq] * 100) / (fam10h_freq_tab[3] * 100));
- Seed_Gross = SeedTotal / 32;
- Seed_Fine = SeedTotal & 0x1f;
- if (Seed_Gross == 0)
- Seed_Gross = 0;
- else if (Seed_Gross & 0x1)
- Seed_Gross = 1;
- else
- Seed_Gross = 2;
-
- /* The BKDG-recommended algorithm causes problems with registered DIMMs on some systems
- * due to the long register delays causing premature total delay wrap-around.
- * Attempt to work around this...
- */
- SeedTotal = ((Seed_Gross & 0x1f) << 5) | (Seed_Fine & 0x1f);
- SeedTotal += RegisterDelay;
- Seed_Gross = SeedTotal / 32;
- Seed_Fine = SeedTotal & 0x1f;
-
- pDCTData->WLGrossDelay[lane_count*dimm+ByteLane] = Seed_Gross;
- pDCTData->WLFineDelay[lane_count*dimm+ByteLane] = Seed_Fine;
-
- printk(BIOS_SPEW, "\tLane %02x new seed: %04x\n", ByteLane, ((pDCTData->WLGrossDelay[lane_count*dimm+ByteLane] & 0x1f) << 5) | (pDCTData->WLFineDelay[lane_count*dimm+ByteLane] & 0x1f));
- }
- }
-
- /* Save initial seeds for upper nibble pass */
- for (ByteLane = 0; ByteLane < lane_count; ByteLane++) {
- pDCTData->WLSeedPreGrossPrevNibble[lane_count*dimm+ByteLane] = pDCTData->WLSeedPreGrossDelay[lane_count*dimm+ByteLane];
- pDCTData->WLSeedGrossPrevNibble[lane_count*dimm+ByteLane] = pDCTData->WLGrossDelay[lane_count*dimm+ByteLane];
- pDCTData->WLSeedFinePrevNibble[lane_count*dimm+ByteLane] = pDCTData->WLFineDelay[lane_count*dimm+ByteLane];
- }
- } else {
- /* Restore seed values from lower nibble pass */
- if (is_fam15h()) {
- for (ByteLane = 0; ByteLane < lane_count; ByteLane++) {
- pDCTData->WLSeedGrossDelay[lane_count*dimm+ByteLane] = pDCTData->WLSeedGrossPrevNibble[lane_count*dimm+ByteLane];
- pDCTData->WLSeedFineDelay[lane_count*dimm+ByteLane] = pDCTData->WLSeedFinePrevNibble[lane_count*dimm+ByteLane];
- pDCTData->WLSeedPreGrossDelay[lane_count*dimm+ByteLane] = pDCTData->WLSeedPreGrossPrevNibble[lane_count*dimm+ByteLane];
-
- pDCTData->WLGrossDelay[lane_count*dimm+ByteLane] = pDCTData->WLSeedPreGrossPrevNibble[lane_count*dimm+ByteLane];
- pDCTData->WLFineDelay[lane_count*dimm+ByteLane] = pDCTData->WLSeedFinePrevNibble[lane_count*dimm+ByteLane];
-
- printk(BIOS_SPEW, "\tLane %02x new seed: %04x\n", ByteLane, ((pDCTData->WLGrossDelay[lane_count*dimm+ByteLane] & 0x1f) << 5) | (pDCTData->WLFineDelay[lane_count*dimm+ByteLane] & 0x1f));
- }
- } else {
- for (ByteLane = 0; ByteLane < lane_count; ByteLane++) {
- pDCTData->WLGrossDelay[lane_count*dimm+ByteLane] = pDCTData->WLSeedGrossPrevNibble[lane_count*dimm+ByteLane];
- pDCTData->WLFineDelay[lane_count*dimm+ByteLane] = pDCTData->WLSeedFinePrevNibble[lane_count*dimm+ByteLane];
-
- printk(BIOS_SPEW, "\tLane %02x new seed: %04x\n", ByteLane, ((pDCTData->WLGrossDelay[lane_count*dimm+ByteLane] & 0x1f) << 5) | (pDCTData->WLFineDelay[lane_count*dimm+ByteLane] & 0x1f));
- }
- }
- }
- }
-
- pDCTData->WLPrevMemclkFreq[dimm] = MemClkFreq;
- setWLByteDelay(pDCTstat, dct, ByteLane, dimm, 0, pass, lane_count);
-}
-
-/*-----------------------------------------------------------------------------
- * void setWLByteDelay(struct DCTStatStruc *pDCTstat, uint8_t dct, u8 ByteLane, u8 Dimm, uint8_t lane_count){
- *
- * Description:
- * This function writes the write levelization byte delay for the Phase
- * Recovery control registers
- *
- * Parameters:
- * IN OUT *DCTData - Pointer to buffer with information about each DCT
- * IN Dimm - Dimm Number
- * DCTData->WLGrossDelay[index+ByteLane] - gross write delay for each
- * logical DIMM
- * DCTData->WLFineDelay[index+ByteLane] - fine write delay for each
- * logical DIMM
- * ByteLane - target byte lane to write
- * targetAddr - 0: write to DRAM phase recovery control register
- * 1: write to DQS write register
- * OUT
- *
- *-----------------------------------------------------------------------------
- */
-void setWLByteDelay(struct DCTStatStruc *pDCTstat, uint8_t dct, u8 ByteLane, u8 dimm, u8 targetAddr, uint8_t pass, uint8_t lane_count)
-{
- sDCTStruct *pDCTData = pDCTstat->C_DCTPtr[dct];
- u8 fineStartLoc, fineEndLoc, grossStartLoc, grossEndLoc, tempB, index, offsetAddr;
- u32 addr, fineDelayValue, grossDelayValue, ValueLow, ValueHigh, EccValue, tempW;
-
- if (targetAddr == 0)
- {
- index = (u8)(lane_count * dimm);
- ValueLow = 0;
- ValueHigh = 0;
- ByteLane = 0;
- EccValue = 0;
- while (ByteLane < lane_count)
- {
- /* This subtract 0xC workaround might be temporary. */
- if ((pDCTData->WLPass == 2) && (pDCTData->RegMan1Present & (1 << (dimm*2+dct)))) {
- tempW = (pDCTData->WLGrossDelay[index+ByteLane] << 5) | pDCTData->WLFineDelay[index+ByteLane];
- tempW -= 0xC;
- pDCTData->WLGrossDelay[index+ByteLane] = (u8)(tempW >> 5);
- pDCTData->WLFineDelay[index+ByteLane] = (u8)(tempW & 0x1F);
- }
- grossDelayValue = pDCTData->WLGrossDelay[index+ByteLane];
- /* Adjust seed gross delay overflow (greater than 3):
- * - Program seed gross delay as 2 (gross is 4 or 6) or 1 (gross is 5).
- * - Keep original seed gross delay for later reference.
- */
- if (grossDelayValue >= 3)
- grossDelayValue = (grossDelayValue&1)? 1 : 2;
- fineDelayValue = pDCTData->WLFineDelay[index+ByteLane];
- if (ByteLane < 4)
- ValueLow |= ((grossDelayValue << 5) | fineDelayValue) << 8*ByteLane;
- else if (ByteLane < 8)
- ValueHigh |= ((grossDelayValue << 5) | fineDelayValue) << 8*(ByteLane-4);
- else
- EccValue = ((grossDelayValue << 5) | fineDelayValue);
- ByteLane++;
- }
- set_DCT_ADDR_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_CONT_ADD_PHASE_REC_CTRL_LOW, 0, 31, (u32)ValueLow);
- set_DCT_ADDR_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_CONT_ADD_PHASE_REC_CTRL_HIGH, 0, 31, (u32)ValueHigh);
- set_DCT_ADDR_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- DRAM_CONT_ADD_ECC_PHASE_REC_CTRL, 0, 31, (u32)EccValue);
- }
- else
- {
- /* Fam10h BKDG: Rev. 3.62 2.8.9.9.1 (6)
- * Fam15h BKDG: Rev. 3.14 2.10.5.8.1
- */
- index = (u8)(lane_count * dimm);
- grossDelayValue = pDCTData->WLGrossDelay[index+ByteLane];
- fineDelayValue = pDCTData->WLFineDelay[index+ByteLane];
-
- tempB = 0;
- offsetAddr = (u8)(3 * dimm);
- if (ByteLane < 2) {
- tempB = (u8)(16 * ByteLane);
- addr = DRAM_CONT_ADD_DQS_TIMING_CTRL_BL_01;
- } else if (ByteLane <4) {
- tempB = (u8)(16 * ByteLane);
- addr = DRAM_CONT_ADD_DQS_TIMING_CTRL_BL_01 + 1;
- } else if (ByteLane <6) {
- tempB = (u8)(16 * ByteLane);
- addr = DRAM_CONT_ADD_DQS_TIMING_CTRL_BL_45;
- } else if (ByteLane <8) {
- tempB = (u8)(16 * ByteLane);
- addr = DRAM_CONT_ADD_DQS_TIMING_CTRL_BL_45 + 1;
- } else {
- tempB = 0;
- addr = DRAM_CONT_ADD_DQS_TIMING_CTRL_BL_01 + 2;
- }
- addr += offsetAddr;
-
- fineStartLoc = (u8)(tempB % 32);
- fineEndLoc = (u8)(fineStartLoc + 4);
- grossStartLoc = (u8)(fineEndLoc + 1);
- grossEndLoc = (u8)(grossStartLoc + 2);
-
- set_DCT_ADDR_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- (u16)addr, fineStartLoc, fineEndLoc,(u32)fineDelayValue);
- set_DCT_ADDR_Bits(pDCTData, dct, pDCTData->NodeId, FUN_DCT,
- (u16)addr, grossStartLoc, grossEndLoc, (u32)grossDelayValue);
-
- pDCTData->WLFineDelayPrevPass[index+ByteLane] = fineDelayValue;
- pDCTData->WLGrossDelayPrevPass[index+ByteLane] = grossDelayValue;
- if (pass == FirstPass) {
- pDCTData->WLFineDelayFirstPass[index+ByteLane] = fineDelayValue;
- pDCTData->WLGrossDelayFirstPass[index+ByteLane] = grossDelayValue;
- pDCTData->WLCriticalGrossDelayFirstPass = pDCTData->WLCriticalGrossDelayPrevPass;
- }
- }
-
-}
-
-/*-----------------------------------------------------------------------------
- * void getWLByteDelay(struct DCTStatStruc *pDCTstat, uint8_t dct, u8 ByteLane, u8 Dimm, u8 Nibble, uint8_t lane_count)
- *
- * Description:
- * This function reads the write levelization byte delay from the Phase
- * Recovery control registers
- *
- * Parameters:
- * IN OUT *DCTData - Pointer to buffer with information about each DCT
- * IN Dimm - Dimm Number
- * ByteLane - target byte lane to read
- * OUT
- * DCTData->WLGrossDelay[index+ByteLane] - gross write delay for current
- * byte for logical DIMM
- * DCTData->WLFineDelay[index+ByteLane] - fine write delay for current
- * byte for logical DIMM
- *
- *-----------------------------------------------------------------------------
- */
-void getWLByteDelay(struct DCTStatStruc *pDCTstat, uint8_t dct, u8 ByteLane, u8 dimm, uint8_t pass, uint8_t nibble, uint8_t lane_count)
-{
- sDCTStruct *pDCTData = pDCTstat->C_DCTPtr[dct];
- u8 fineStartLoc, fineEndLoc, grossStartLoc, grossEndLoc, tempB, tempB1, index;
- u32 addr, fine, gross;
- tempB = 0;
- index = (u8)(lane_count*dimm);
- if (ByteLane < 4) {
- tempB = (u8)(8 * ByteLane);
- addr = DRAM_CONT_ADD_PHASE_REC_CTRL_LOW;
- } else if (ByteLane < 8) {
- tempB1 = (u8)(ByteLane - 4);
- tempB = (u8)(8 * tempB1);
- addr = DRAM_CONT_ADD_PHASE_REC_CTRL_HIGH;
- } else {
- tempB = 0;
- addr = DRAM_CONT_ADD_ECC_PHASE_REC_CTRL;
- }
- fineStartLoc = tempB;
- fineEndLoc = (u8)(fineStartLoc + 4);
- grossStartLoc = (u8)(fineEndLoc + 1);
- grossEndLoc = (u8)(grossStartLoc + 1);
-
- fine = get_ADD_DCT_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, (u16)addr, fineStartLoc, fineEndLoc);
- gross = get_ADD_DCT_Bits(pDCTData, dct, pDCTData->NodeId,
- FUN_DCT, (u16)addr, grossStartLoc, grossEndLoc);
-
- printk(BIOS_SPEW, "\tLane %02x nibble %01x raw readback: %04x\n", ByteLane, nibble, ((gross & 0x1f) << 5) | (fine & 0x1f));
-
- /* Adjust seed gross delay overflow (greater than 3):
- * - Adjust the trained gross delay to the original seed gross delay.
- */
- if (pDCTData->WLGrossDelay[index+ByteLane] >= 3)
- {
- gross += pDCTData->WLGrossDelay[index+ByteLane];
- if (pDCTData->WLGrossDelay[index+ByteLane] & 1)
- gross -= 1;
- else
- gross -= 2;
- }
- else if ((pDCTData->WLGrossDelay[index+ByteLane] == 0) && (gross == 3))
- {
- /* If seed gross delay is 0 but PRE result gross delay is 3, it is negative.
- * We will then round the negative number to 0.
- */
- gross = 0;
- fine = 0;
- }
- printk(BIOS_SPEW, "\tLane %02x nibble %01x adjusted value (pre nibble): %04x\n", ByteLane, nibble, ((gross & 0x1f) << 5) | (fine & 0x1f));
-
- /* Nibble adjustments */
- if (nibble == 0) {
- pDCTData->WLFineDelay[index+ByteLane] = (uint8_t)fine;
- pDCTData->WLGrossDelay[index+ByteLane] = (uint8_t)gross;
- } else {
- uint32_t WLTotalDelay = ((pDCTData->WLGrossDelay[index+ByteLane] & 0x1f) << 5) | (pDCTData->WLFineDelay[index+ByteLane] & 0x1f);
- WLTotalDelay += ((gross & 0x1f) << 5) | (fine & 0x1f);
- WLTotalDelay /= 2;
- pDCTData->WLFineDelay[index+ByteLane] = (uint8_t)(WLTotalDelay & 0x1f);
- pDCTData->WLGrossDelay[index+ByteLane] = (uint8_t)((WLTotalDelay >> 5) & 0x1f);
- }
- printk(BIOS_SPEW, "\tLane %02x nibble %01x adjusted value (post nibble): %04x\n", ByteLane, nibble, ((pDCTData->WLGrossDelay[index+ByteLane] & 0x1f) << 5) | (pDCTData->WLFineDelay[index+ByteLane] & 0x1f));
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/modtrd.c b/src/northbridge/amd/amdmct/mct_ddr3/modtrd.c
deleted file mode 100644
index 954dd6f2ef..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/modtrd.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * 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.
- */
-
-#include <stdint.h>
-
-#include "mct_d.h"
-#include "mct_d_gcc.h"
-
-u32 mct_MR1Odt_RDimm(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dct, u32 MrsChipSel)
-{
- u8 Speed = pDCTstat->Speed;
- u32 ret;
- u8 DimmsInstalled, DimmNum, ChipSelect;
-
- ChipSelect = (MrsChipSel >> 20) & 0xF;
- DimmNum = ChipSelect & 0xFE;
- DimmsInstalled = pDCTstat->MAdimms[dct];
- if (dct == 1)
- DimmNum ++;
- ret = 0;
-
- if (mctGet_NVbits(NV_MAX_DIMMS) == 4) {
- if (DimmsInstalled == 1)
- ret |= 1 << 2;
- else {
- if (pDCTstat->CSPresent & 0xF0) {
- if (pDCTstat->DimmQRPresent & (1 << DimmNum)) {
- if (!(ChipSelect & 1))
- ret |= 1 << 2;
- } else
- ret |= 0x204;
- } else {
- if (Speed < 6)
- ret |= 0x44;
- else
- ret |= 0x204;
- }
- }
- } else if (DimmsInstalled == 1)
- ret |= 1 << 2;
- else if (Speed < 6)
- ret |= 0x44;
- else
- ret |= 0x204;
-
- //ret = 0;
- return ret;
-}
-
-u32 mct_DramTermDyn_RDimm(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat, u8 dimm)
-{
- u8 DimmsInstalled = dimm;
- u32 DramTermDyn = 0;
- u8 Speed = pDCTstat->Speed;
-
- if (mctGet_NVbits(NV_MAX_DIMMS) == 4) {
- if (pDCTstat->CSPresent & 0xF0) {
- if (DimmsInstalled == 1)
- if (Speed == 7)
- DramTermDyn |= 1 << 10;
- else
- DramTermDyn |= 1 << 11;
- else
- if (Speed == 4)
- DramTermDyn |= 1 << 11;
- else
- DramTermDyn |= 1 << 10;
- } else {
- if (DimmsInstalled != 1) {
- if (Speed == 7)
- DramTermDyn |= 1 << 10;
- else
- DramTermDyn |= 1 << 11;
- }
- }
- } else {
- if (DimmsInstalled != 1)
- DramTermDyn |= 1 << 11;
- }
- return DramTermDyn;
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/modtrdim.c b/src/northbridge/amd/amdmct/mct_ddr3/modtrdim.c
deleted file mode 100644
index 06bfdba84f..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/modtrdim.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
- *
- * 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.
- */
-
-/* This file contains functions for odt setting on registered DDR3 dimms */
-
-#include <stdint.h>
-#include <console/console.h>
-
-#include "mct_d.h"
-#include "mct_d_gcc.h"
-
-/**
- *
- *
- * This function set Rtt_Nom for registered DDR3 dimms on targeted dimm.
- *
- * @param *pMCTData
- * @param[in] *pDCTData - Pointer to buffer with information about each DCT
- * @param dimm - targeted dimm
- * @param wl - current mode, either write levelization mode or normal mode
- * @param MemClkFreq - current frequency
- * @param rank
- *
- * @return tempW1 - Rtt_Nom
- */
-u32 RttNomTargetRegDimm (sMCTStruct *pMCTData, sDCTStruct *pDCTData, u8 dimm, BOOL wl, u8 MemClkFreq, u8 rank)
-{
- u32 tempW1;
- tempW1 = 0;
- if (wl) {
- switch (mctGet_NVbits(NV_MAX_DIMMS_PER_CH)) {
- case 2:
- /* 2 dimms per channel */
- if (pDCTData->MaxDimmsInstalled == 1) {
- if ((pDCTData->DimmRanks[dimm] == 2) && (rank == 0)) {
- tempW1 = 0x00; /* Rtt_Nom = OFF */
- } else if (pDCTData->DimmRanks[dimm] == 4) {
- if (rank == 1) {
- tempW1 = 0x00; /* Rtt_Nom = OFF on second and forth rank of QR dimm */
- } else {
- if (MemClkFreq == 6) {
- tempW1 = 0x04; /* Rtt_Nom = 60 ohms */
- } else {
- tempW1 = 0x40; /* Rtt_Nom = 120 ohms */
- }
- }
- } else {
- tempW1 = 0x04; /* Rtt_Nom = 60 ohms */
- }
- } else if (pDCTData->MaxDimmsInstalled == 2) {
- if (((pDCTData->DimmRanks[dimm] == 2) || (pDCTData->DimmRanks[dimm] == 4)) && (rank == 1)) {
- tempW1 = 0x00; /* Rtt_Nom = OFF */
- } else if ((pDCTData->DimmRanks[dimm] == 4) || (pDCTData->DctCSPresent & 0xF0)) {
- if (MemClkFreq == 3) {
- tempW1 = 0x40; /* Rtt_Nom = 120 ohms */
- } else {
- tempW1 = 0x04; /* Rtt_Nom = 60 ohms */
- }
- } else {
- if (MemClkFreq == 6) {
- tempW1 = 0x04; /* Rtt_Nom = 60 ohms */
- } else {
- tempW1 = 0x40; /* Rtt_Nom = 120 ohms */
- }
- }
- }
- break;
- case 3:
- /* 3 dimms per channel */
- /* QR not supported in this case on L1 package. */
- if (pDCTData->MaxDimmsInstalled == 1) {
- if ((pDCTData->DimmRanks[dimm] == 2) && (rank == 1)) {
- tempW1 = 0x00; /* Rtt_Nom = OFF */
- } else {
- tempW1 = 0x04; /* Rtt_Nom = 60 ohms */
- }
- } else {
- tempW1 = 0x40; /* Rtt_Nom = 120 ohms */
- }
- break;
- default:
- die("modtrdim.c: WTF?");
- }
- } else {
- switch (mctGet_NVbits(NV_MAX_DIMMS_PER_CH)) {
- case 2:
- /* 2 dimms per channel */
- if ((pDCTData->DimmRanks[dimm] == 4) && (rank == 1)) {
- tempW1 = 0x00; /* Rtt_Nom = OFF */
- } else if ((pDCTData->MaxDimmsInstalled == 1) || (pDCTData->DimmRanks[dimm] == 4)) {
- tempW1 = 0x04; /* Rtt_Nom = 60 ohms */
- } else {
- if (pDCTData->DctCSPresent & 0xF0) {
- tempW1 = 0x0204; /* Rtt_Nom = 30 ohms */
- } else {
- if (MemClkFreq < 5) {
- tempW1 = 0x44; /* Rtt_Nom = 40 ohms */
- } else {
- tempW1 = 0x0204; /* Rtt_Nom = 30 ohms */
- }
- }
- }
- break;
- case 3:
- /* 3 dimms per channel */
- /* L1 package does not support QR dimms this case. */
- if (rank == 1) {
- tempW1 = 0x00; /* Rtt_Nom = OFF */
- } else if (pDCTData->MaxDimmsInstalled == 1) {
- tempW1 = 0x04; /* Rtt_Nom = 60 ohms */
- } else if ((MemClkFreq < 5) || (pDCTData->MaxDimmsInstalled == 3)) {
- tempW1 = 0x44; /* Rtt_Nom = 40 ohms */
- } else {
- tempW1 = 0x0204; /* Rtt_Nom = 30 ohms */
- }
- break;
- default:
- die("modtrdim.c: WTF?");
- }
- }
- return tempW1;
-}
-
-/* -----------------------------------------------------------------------------*/
-/**
- *
- *
- * This function set Rtt_Nom for registered DDR3 dimms on non-targeted dimm.
- *
- * @param *pMCTData
- * @param[in] *pDCTData - Pointer to buffer with information about each DCT
- * @param dimm - non-targeted dimm
- * @param wl - current mode, either write levelization mode or normal mode
- * @param MemClkFreq - current frequency
- * @param rank
- *
- * @return tempW1 - Rtt_Nom
- */
-u32 RttNomNonTargetRegDimm (sMCTStruct *pMCTData, sDCTStruct *pDCTData, u8 dimm, BOOL wl, u8 MemClkFreq, u8 rank)
-{
- if ((wl) && (mctGet_NVbits(NV_MAX_DIMMS_PER_CH) == 2) && (pDCTData->DimmRanks[dimm] == 2) && (rank == 1)) {
- return 0x00; /* for non-target dimm during WL, the second rank of a DR dimm need to have Rtt_Nom = OFF */
- } else {
- return RttNomTargetRegDimm (pMCTData, pDCTData, dimm, FALSE, MemClkFreq, rank); /* otherwise, the same as target dimm in normal mode. */
- }
-}
-
-/* -----------------------------------------------------------------------------*/
-/**
- *
- *
- * This function set Rtt_Wr for registered DDR3 dimms.
- *
- * @param pMCTData
- * @param[in] *pDCTData - Pointer to buffer with information about each DCT
- * @param dimm - targeted dimm
- * @param wl - current mode, either write levelization mode or normal mode
- * @param MemClkFreq - current frequency
- * @param rank
- *
- * @return tempW1 - Rtt_Wr
- */
-
-u32 RttWrRegDimm (sMCTStruct *pMCTData, sDCTStruct *pDCTData, u8 dimm, BOOL wl, u8 MemClkFreq, u8 rank)
-{
- u32 tempW1;
- tempW1 = 0;
- if (wl) {
- tempW1 = 0x00; /* Rtt_WR = OFF */
- } else {
- switch (mctGet_NVbits(NV_MAX_DIMMS_PER_CH)) {
- case 2:
- if (pDCTData->MaxDimmsInstalled == 1) {
- if (pDCTData->DimmRanks[dimm] != 4) {
- tempW1 = 0x00;
- } else {
- if (MemClkFreq == 6) {
- tempW1 = 0x200; /* Rtt_WR = 60 ohms */
- } else {
- tempW1 = 0x400; /* Rtt_WR = 120 ohms */
- }
- }
- } else {
- if ((pDCTData->DimmRanks[dimm] == 4) || (pDCTData->DctCSPresent & 0xF0)) {
- if (MemClkFreq == 3) {
- tempW1 = 0x400; /* Rtt_WR = 120 ohms */
- } else {
- tempW1 = 0x200; /* Rtt_WR = 60 ohms */
- }
- } else {
- if (MemClkFreq == 6) {
- tempW1 = 0x200; /* Rtt_WR = 60 ohms */
- } else {
- tempW1 = 0x400; /* Rtt_Nom = 120 ohms */
- }
- }
- }
- break;
- case 3:
- if (pDCTData->MaxDimmsInstalled == 1) {
- tempW1 = 0x00; /* Rtt_WR = OFF */
- } else {
- tempW1 = 0x400; /* Rtt_Nom = 120 ohms */
- }
- break;
- default:
- die("modtrdim.c: WTF?");
- }
- }
- return tempW1;
-}
-
-/* -----------------------------------------------------------------------------*/
-/**
- *
- *
- * This function set WrLvOdt for registered DDR3 dimms.
- *
- * @param *pMCTData
- * @param[in] *pDCTData - Pointer to buffer with information about each DCT
- * @param dimm - targeted dimm
- *
- * @return WrLvOdt
- */
-u8 WrLvOdtRegDimm (sMCTStruct *pMCTData, sDCTStruct *pDCTData, u8 dimm)
-{
- u8 WrLvOdt1, i;
- WrLvOdt1 = 0;
- i = 0;
- while (i < 8) {
- if (pDCTData->DctCSPresent & (1 << i)) {
- WrLvOdt1 = (u8)bitTestSet(WrLvOdt1, i/2);
- }
- i += 2;
- }
- if (mctGet_NVbits(NV_MAX_DIMMS_PER_CH) == 2) {
- if ((pDCTData->DimmRanks[dimm] == 4) && (pDCTData->MaxDimmsInstalled != 1)) {
- if (dimm >= 2) {
- WrLvOdt1 = (u8)bitTestReset (WrLvOdt1, (dimm - 2));
- } else {
- WrLvOdt1 = (u8)bitTestReset (WrLvOdt1, (dimm + 2));
- }
- } else if ((pDCTData->DimmRanks[dimm] == 2) && (pDCTData->MaxDimmsInstalled == 1)) {
- /* the case for one DR on a 2 dimms per channel is special */
- WrLvOdt1 = 0x8;
- }
- }
- return WrLvOdt1;
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mport_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mport_d.c
deleted file mode 100644
index 999cb94f24..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mport_d.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * 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.
- */
-
-#include <arch/io.h>
-#include <stdint.h>
-
-#include "mct_d.h"
-#include "mct_d_gcc.h"
-#include "mwlc_d.h"
-
-void AmdMemPCIRead(SBDFO loc, u32 *Value)
-{
- /* Convert SBDFO into a CF8 Address */
- loc = (loc >> 4 & 0xFFFFFF00) | (loc & 0xFF) | ((loc & 0xF00) << 16);
- loc |= 0x80000000;
-
- outl(loc, 0xCF8);
-
- *Value = inl(0xCFC);
-}
-
-void AmdMemPCIWrite(SBDFO loc, u32 *Value)
-{
- /* Convert SBDFO into a CF8 Address */
- loc = (loc >> 4 & 0xFFFFFF00) | (loc & 0xFF) | ((loc & 0xF00) << 16);
- loc |= 0x80000000;
-
- outl(loc, 0xCF8);
- outl(*Value, 0xCFC);
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mutilc_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mutilc_d.c
deleted file mode 100644
index 0420b660b9..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mutilc_d.c
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
- *
- * 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.
- */
-
-/* This file contains functions for common utility functions */
-
-#include <arch/cpu.h>
-#include <stdint.h>
-
-#include "mct_d.h"
-#include "mct_d_gcc.h"
-#include "mwlc_d.h"
-
-static uint8_t is_fam15h(void)
-{
- uint8_t fam15h = 0;
- uint32_t family;
-
- family = cpuid_eax(0x80000001);
- family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);
-
- if (family >= 0x6f)
- /* Family 15h or later */
- fam15h = 1;
-
- return fam15h;
-}
-
-void AmdMemPCIReadBits(SBDFO loc, u8 highbit, u8 lowbit, u32 *pValue)
-{
- /* ASSERT(highbit < 32 && lowbit < 32 && highbit >= lowbit && (loc & 3) == 0); */
-
- AmdMemPCIRead(loc, pValue);
- *pValue = *pValue >> lowbit; /* Shift */
-
- /* A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case */
- if ((highbit-lowbit) != 31)
- *pValue &= (((u32)1 << (highbit-lowbit+1))-1);
-}
-
-void AmdMemPCIWriteBits(SBDFO loc, u8 highbit, u8 lowbit, u32 *pValue)
-{
- u32 temp, mask;
-
- /* ASSERT(highbit < 32 && lowbit < 32 && highbit >= lowbit && (loc & 3) == 0); */
-
- /* A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case */
- if ((highbit-lowbit) != 31)
- mask = (((u32)1 << (highbit-lowbit+1))-1);
- else
- mask = (u32)0xFFFFFFFF;
-
- AmdMemPCIRead(loc, &temp);
- temp &= ~(mask << lowbit);
- temp |= (*pValue & mask) << lowbit;
- AmdMemPCIWrite(loc, &temp);
-}
-
-/*-----------------------------------------------------------------------------
- * u32 bitTestSet(u32 csMask,u32 tempD)
- *
- * Description:
- * This routine sets a bit in a u32
- *
- * Parameters:
- * IN csMask = Target value in which the bit will be set
- * IN tempD = Bit that will be set
- * OUT value = Target value with the bit set
- *-----------------------------------------------------------------------------
- */
-u32 bitTestSet(u32 csMask,u32 tempD)
-{
- u32 localTemp;
- /* ASSERT(tempD < 32); */
- localTemp = 1;
- csMask |= localTemp << tempD;
- return csMask;
-}
-
-/*-----------------------------------------------------------------------------
- * u32 bitTestReset(u32 csMask,u32 tempD)
- *
- * Description:
- * This routine re-sets a bit in a u32
- *
- * Parameters:
- * IN csMask = Target value in which the bit will be re-set
- * IN tempD = Bit that will be re-set
- * OUT value = Target value with the bit re-set
- *-----------------------------------------------------------------------------
- */
-u32 bitTestReset(u32 csMask,u32 tempD)
-{
- u32 temp, localTemp;
- /* ASSERT(tempD < 32); */
- localTemp = 1;
- temp = localTemp << tempD;
- temp = ~temp;
- csMask &= temp;
- return csMask;
-}
-
-/*-----------------------------------------------------------------------------
- * u32 get_Bits(DCTStruct *DCTData, u8 DCT, u8 Node, u8 func, u16 offset,
- * u8 low, u8 high)
- *
- * Description:
- * This routine Gets the PCT bits from the specified Node, DCT and PCI address
- *
- * Parameters:
- * IN OUT *DCTData - Pointer to buffer with information about each DCT
- * IN DCT - DCT number
- * - 1 indicates DCT 1
- * - 0 indicates DCT 0
- * - 2 both DCTs
- * Node - Node number
- * Func - PCI Function number
- * Offset - PCI register number
- * Low - Low bit of the bit field
- * High - High bit of the bit field
- *
- * OUT value = Value read from PCI space
- *-----------------------------------------------------------------------------
- */
-u32 get_Bits(sDCTStruct *pDCTData,
- u8 dct, u8 node, u8 func,
- u16 offset, u8 low, u8 high)
-{
- u32 temp;
- uint32_t dword;
-
- /* ASSERT(node < MAX_NODES); */
- if (dct == BOTH_DCTS)
- {
- /* Registers exist on DCT0 only */
- if (is_fam15h())
- {
- /* Select DCT 0 */
- AmdMemPCIRead(MAKE_SBDFO(0,0,24+node,1,0x10c), &dword);
- dword &= ~0x1;
- AmdMemPCIWrite(MAKE_SBDFO(0,0,24+node,1,0x10c), &dword);
- }
-
- AmdMemPCIReadBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
- }
- else
- {
- if (is_fam15h())
- {
- /* Select DCT */
- AmdMemPCIRead(MAKE_SBDFO(0,0,24+node,1,0x10c), &dword);
- dword &= ~0x1;
- dword |= (dct & 0x1);
- AmdMemPCIWrite(MAKE_SBDFO(0,0,24+node,1,0x10c), &dword);
-
- /* Read from the selected DCT */
- AmdMemPCIReadBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
- }
- else
- {
- if (dct == 1)
- {
- /* Read from dct 1 */
- offset += 0x100;
- AmdMemPCIReadBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
- }
- else
- {
- /* Read from dct 0 */
- AmdMemPCIReadBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
- }
- }
- }
- return temp;
-}
-
-/*-----------------------------------------------------------------------------
- * void set_Bits(DCTStruct *DCTData,u8 DCT,u8 Node,u8 func, u16 offset,
- * u8 low, u8 high, u32 value)
- *
- * Description:
- * This routine Sets the PCT bits from the specified Node, DCT and PCI address
- *
- * Parameters:
- * IN OUT *DCTData - Pointer to buffer with information about each DCT
- * IN DCT - DCT number
- * - 1 indicates DCT 1
- * - 0 indicates DCT 0
- * - 2 both DCTs
- * Node - Node number
- * Func - PCI Function number
- * Offset - PCI register number
- * Low - Low bit of the bit field
- * High - High bit of the bit field
- *
- * OUT
- *-----------------------------------------------------------------------------
- */
-void set_Bits(sDCTStruct *pDCTData,
- u8 dct, u8 node, u8 func,
- u16 offset, u8 low, u8 high, u32 value)
-{
- u32 temp;
- uint32_t dword;
-
- temp = value;
-
- if (dct == BOTH_DCTS)
- {
- /* Registers exist on DCT0 only */
- if (is_fam15h())
- {
- /* Select DCT 0 */
- AmdMemPCIRead(MAKE_SBDFO(0,0,24+node,1,0x10c), &dword);
- dword &= ~0x1;
- AmdMemPCIWrite(MAKE_SBDFO(0,0,24+node,1,0x10c), &dword);
- }
-
- AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
- }
- else
- {
- if (is_fam15h())
- {
- /* Select DCT */
- AmdMemPCIRead(MAKE_SBDFO(0,0,24+node,1,0x10c), &dword);
- dword &= ~0x1;
- dword |= (dct & 0x1);
- AmdMemPCIWrite(MAKE_SBDFO(0,0,24+node,1,0x10c), &dword);
-
- /* Write to the selected DCT */
- AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
- }
- else
- {
- if (dct == 1)
- {
- /* Write to dct 1 */
- offset += 0x100;
- AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
- }
- else
- {
- /* Write to dct 0 */
- AmdMemPCIWriteBits(MAKE_SBDFO(0,0,24+node,func,offset), high, low, &temp);
- }
- }
- }
-}
-
-/*-------------------------------------------------
- * u32 get_ADD_DCT_Bits(DCTStruct *DCTData,u8 DCT,u8 Node,u8 func,
- * u16 offset,u8 low, u8 high)
- *
- * Description:
- * This routine gets the Additional PCT register from Function 2 by specified
- * Node, DCT and PCI address
- *
- * Parameters:
- * IN OUT *DCTData - Pointer to buffer with information about each DCT
- * IN DCT - DCT number
- * - 1 indicates DCT 1
- * - 0 indicates DCT 0
- * - 2 both DCTs
- * Node - Node number
- * Func - PCI Function number
- * Offset - Additional PCI register number
- * Low - Low bit of the bit field
- * High - High bit of the bit field
- *
- * OUT
- *-------------------------------------------------
- */
-u32 get_ADD_DCT_Bits(sDCTStruct *pDCTData,
- u8 dct, u8 node, u8 func,
- u16 offset, u8 low, u8 high)
-{
- u32 tempD;
- tempD = offset;
- tempD = bitTestReset(tempD,DctAccessWrite);
- set_Bits(pDCTData, dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_OFFSET_REG,
- PCI_MIN_LOW, PCI_MAX_HIGH, offset);
- while ((get_Bits(pDCTData,dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_OFFSET_REG,
- DctAccessDone, DctAccessDone)) == 0);
- return (get_Bits(pDCTData, dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_PORT_REG,
- low, high));
-}
-
-/*-------------------------------------------------
- * void set_DCT_ADDR_Bits(DCTStruct *DCTData, u8 DCT,u8 Node,u8 func,
- * u16 offset,u8 low, u8 high, u32 value)
- *
- * Description:
- * This routine sets the Additional PCT register from Function 2 by specified
- * Node, DCT and PCI address
- *
- * Parameters:
- * IN OUT *DCTData - Pointer to buffer with information about each DCT
- * IN DCT - DCT number
- * - 1 indicates DCT 1
- * - 0 indicates DCT 0
- * - 2 both DCTs
- * Node - Node number
- * Func - PCI Function number
- * Offset - Additional PCI register number
- * Low - Low bit of the bit field
- * High - High bit of the bit field
- *
- * OUT
- *-------------------------------------------------
- */
-void set_DCT_ADDR_Bits(sDCTStruct *pDCTData,
- u8 dct, u8 node, u8 func,
- u16 offset, u8 low, u8 high, u32 value)
-{
- u32 tempD;
-
- set_Bits(pDCTData, dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_OFFSET_REG,
- PCI_MIN_LOW, PCI_MAX_HIGH, offset);
- while ((get_Bits(pDCTData,dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_OFFSET_REG,
- DctAccessDone, DctAccessDone)) == 0);
-
- set_Bits(pDCTData, dct, node, FUN_DCT, DRAM_CONTROLLER_ADD_DATA_PORT_REG,
- low, high, value);
- tempD = offset;
- tempD = bitTestSet(tempD,DctAccessWrite);
- set_Bits(pDCTData, dct, node, FUN_DCT,DRAM_CONTROLLER_ADD_DATA_OFFSET_REG,
- PCI_MIN_LOW, PCI_MAX_HIGH, tempD);
- while ((get_Bits(pDCTData,dct, pDCTData->NodeId, FUN_DCT,
- DRAM_CONTROLLER_ADD_DATA_OFFSET_REG, DctAccessDone,
- DctAccessDone)) == 0);
-}
-
-/*-------------------------------------------------
- * BOOL bitTest(u32 value, u8 bitLoc)
- *
- * Description:
- * This routine tests the value to determine if the bitLoc is set
- *
- * Parameters:
- * IN Value - value to be tested
- * bitLoc - bit location to be tested
- * OUT TRUE - bit is set
- * FALSE - bit is clear
- *-------------------------------------------------
- */
-BOOL bitTest(u32 value, u8 bitLoc)
-{
- u32 tempD, compD;
- tempD = value;
- compD = 0;
- compD = bitTestSet(compD,bitLoc);
- tempD &= compD;
- if (compD == tempD)
- {
- return TRUE;
- }
- else
- {
- return FALSE;
- }
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mwlc_d.h b/src/northbridge/amd/amdmct/mct_ddr3/mwlc_d.h
deleted file mode 100644
index aa0446f090..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/mwlc_d.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
- *
- * 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.
- */
-/* IBV defined Structure */ /* IBV Specific Options */
-#ifndef MWLC_D_H
-#define MWLC_D_H
-
-#include <northbridge/amd/amdht/porting.h>
-
-#define MAX_TOTAL_DIMMS 8 /* Maximum Number of DIMMs in systems */
- /* (DCT0 + DCT1) */
-#define MAX_DIMMS 4 /* Maximum Number of DIMMs on each DCT */
-#define MAX_LDIMMS 4 /* Maximum number of Logical DIMMs per DCT */
-
-/*MCT Max variables */
-#define MAX_ERRORS 32 /* Maximum number of Errors Reported */
-#define MAX_STATUS 32 /* Maximum number of Status variables*/
-#define MAX_BYTE_LANES (8+1) /* Maximum number of Byte Lanes - include ECC */
-
-#define C_MAX_DIMMS 4 /* Maximum Number of DIMMs on each DCT */
-
-/* STATUS Definition */
-#define DCT_STATUS_REGISTERED 3 /* Registered DIMMs support */
-#define DCT_STATUS_LOAD_REDUCED 4 /* Load-Reduced DIMMs support */
-#define DCT_STATUS_OnDimmMirror 24 /* OnDimmMirror support */
-
-/* PCI Definitions */
-#define FUN_HT 0 /* Function 0 Access */
-#define FUN_MAP 1 /* Function 1 Access */
-#define FUN_DCT 2 /* Function 2 Access */
-#define FUN_MISC 3 /* Function 3 Access */
-#define FUN_ADD_DCT 0xF /* Function 2 Additional Register Access */
-#define BOTH_DCTS 2 /* The access is independent of DCTs */
-#define PCI_MIN_LOW 0 /* Lowest possible PCI register location */
-#define PCI_MAX_HIGH 31 /* Highest possible PCI register location */
-
-/*Function 2 */
-/* #define DRAM_INIT 0x7C */
-#define DRAM_MRS_REGISTER 0x84
-#define DRAM_CONFIG_HIGH 0x94
-#define DRAM_CONTROLLER_ADD_DATA_OFFSET_REG 0x98
-#define DRAM_CONTROLLER_ADD_DATA_PORT_REG 0x9C
-
-/*Function 2 Additional DRAM control registers */
-#define DRAM_ADD_DCT_PHY_CONTROL_REG 0x8
-#define DRAM_CONT_ADD_DQS_TIMING_CTRL_BL_01 0x30
-#define DRAM_CONT_ADD_DQS_TIMING_CTRL_BL_45 0x40
-#define DRAM_CONT_ADD_PHASE_REC_CTRL_LOW 0x50
-#define DRAM_CONT_ADD_PHASE_REC_CTRL_HIGH 0x51
-#define DRAM_CONT_ADD_ECC_PHASE_REC_CTRL 0x52
-#define DRAM_CONT_ADD_WRITE_LEV_ERROR_REG 0x53
-
-/* CPU Register definitions */
-
-/* Register Bit Location */
-#define DctAccessDone 31
-#define DctAccessWrite 30
-#define RDqsEn 12
-#define TrDimmSelStart 4
-#define TrDimmSelEnd 5
-#define WrLvTrMode 1
-#define TrNibbleSel 2
-#define WrLvOdtEn 12
-#define WrLvErrStart 0
-#define WrLvErrEnd 8
-#define SendMrsCmd 26
-#define Qoff 12
-#define MRS_Level 7
-#define MrsAddressStartFam10 0
-#define MrsAddressEndFam10 15
-#define MrsAddressStartFam15 0
-#define MrsAddressEndFam15 17
-#define MrsBankStartFam10 16
-#define MrsBankEndFam10 18
-#define MrsBankStartFam15 18
-#define MrsBankEndFam15 20
-#define MrsChipSelStartFam10 20
-#define MrsChipSelEndFam10 22
-#define MrsChipSelStartFam15 21
-#define MrsChipSelEndFam15 23
-#define ASR 18
-#define SRT 19
-#define DramTermDynStart 10
-#define DramTermDynEnd 11
-#define WrtLvTrMode 1
-#define TrNibbleSel 2
-#define TrDimmSelStart 4
-#define TrDimmSelEnd 5
-#define WrtLvTrEn 0
-#define DrvImpCtrlStart 2
-#define DrvImpCtrlEnd 3
-#define DramTermNbStart 7
-#define DramTermNbEnd 9
-#define onDimmMirror 3
-
-typedef struct _sMCTStruct
-{
- void (*AgesaDelay)(u32 delayval); /* IBV defined Delay Function */
-} __attribute__((packed, aligned(4))) sMCTStruct;
-
-/* DCT 0 and DCT 1 Data structure */
-typedef struct _sDCTStruct
-{
- u8 NodeId; /* Node ID */
- u8 DctTrain; /* Current DCT being trained */
- u8 CurrDct; /* Current DCT number (0 or 1) */
- u8 DctCSPresent; /* Current DCT CS mapping */
- uint8_t WrDqsGrossDlyBaseOffset;
- int32_t WLSeedGrossDelay[MAX_BYTE_LANES*MAX_LDIMMS]; /* Write Levelization Seed Gross Delay */
- /* per byte Lane Per Logical DIMM*/
- int32_t WLSeedFineDelay[MAX_BYTE_LANES*MAX_LDIMMS]; /* Write Levelization Seed Fine Delay */
- /* per byte Lane Per Logical DIMM*/
- int32_t WLSeedPreGrossDelay[MAX_BYTE_LANES*MAX_LDIMMS]; /* Write Levelization Seed Pre-Gross Delay */
- /* per byte Lane Per Logical DIMM*/
- uint8_t WLSeedPreGrossPrevNibble[MAX_BYTE_LANES*MAX_LDIMMS];
- uint8_t WLSeedGrossPrevNibble[MAX_BYTE_LANES*MAX_LDIMMS];
- uint8_t WLSeedFinePrevNibble[MAX_BYTE_LANES*MAX_LDIMMS];
- /* per byte Lane Per Logical DIMM*/
- u8 WLGrossDelay[MAX_BYTE_LANES*MAX_LDIMMS]; /* Write Levelization Gross Delay */
- /* per byte Lane Per Logical DIMM*/
- u8 WLFineDelay[MAX_BYTE_LANES*MAX_LDIMMS]; /* Write Levelization Fine Delay */
- /* per byte Lane Per Logical DIMM*/
- u8 WLGrossDelayFirstPass[MAX_BYTE_LANES*MAX_LDIMMS]; /* First-Pass Write Levelization Gross Delay */
- /* per byte Lane Per Logical DIMM*/
- u8 WLFineDelayFirstPass[MAX_BYTE_LANES*MAX_LDIMMS]; /* First-Pass Write Levelization Fine Delay */
- /* per byte Lane Per Logical DIMM*/
- u8 WLGrossDelayPrevPass[MAX_BYTE_LANES*MAX_LDIMMS]; /* Previous Pass Write Levelization Gross Delay */
- /* per byte Lane Per Logical DIMM*/
- u8 WLFineDelayPrevPass[MAX_BYTE_LANES*MAX_LDIMMS]; /* Previous Pass Write Levelization Fine Delay */
- /* per byte Lane Per Logical DIMM*/
- u8 WLGrossDelayFinalPass[MAX_BYTE_LANES*MAX_LDIMMS]; /* Final-Pass Write Levelization Gross Delay */
- /* per byte Lane Per Logical DIMM*/
- u8 WLFineDelayFinalPass[MAX_BYTE_LANES*MAX_LDIMMS]; /* Final-Pass Write Levelization Fine Delay */
- /* per byte Lane Per Logical DIMM*/
- int32_t WLCriticalGrossDelayFirstPass;
- int32_t WLCriticalGrossDelayPrevPass;
- int32_t WLCriticalGrossDelayFinalPass;
- uint16_t WLPrevMemclkFreq[MAX_TOTAL_DIMMS];
- u16 RegMan1Present;
- u8 DimmPresent[MAX_TOTAL_DIMMS];/* Indicates which DIMMs are present */
- /* from Total Number of DIMMs(per Node)*/
- u8 DimmX8Present[MAX_TOTAL_DIMMS]; /* Which DIMMs x8 devices */
- u8 Status[MAX_STATUS]; /* Status for DCT0 and 1 */
- u8 ErrCode[MAX_ERRORS]; /* Major Error codes for DCT0 and 1 */
- u8 ErrStatus[MAX_ERRORS]; /* Minor Error codes for DCT0 and 1 */
- u8 DimmValid[MAX_TOTAL_DIMMS]; /* Indicates which DIMMs are valid for */
- /* Total Number of DIMMs(per Node) */
- u8 WLTotalDelay[MAX_BYTE_LANES];/* Write Levelization Total Delay */
- /* per byte lane */
- u8 MaxDimmsInstalled; /* Max Dimms Installed for current DCT */
- u8 DimmRanks[MAX_TOTAL_DIMMS]; /* Total Number of Ranks(per Dimm) */
- uint64_t LogicalCPUID;
- u8 WLPass;
-} __attribute__((packed, aligned(4))) sDCTStruct;
-
-void set_DCT_ADDR_Bits(sDCTStruct *pDCTData,
- u8 dct, u8 node, u8 func,
- u16 offset, u8 low, u8 high, u32 value);
-void AmdMemPCIWriteBits(SBDFO loc, u8 highbit, u8 lowbit, u32 *pValue);
-u32 get_Bits(sDCTStruct *pDCTData,
- u8 dct, u8 node, u8 func,
- u16 offset, u8 low, u8 high);
-void AmdMemPCIReadBits(SBDFO loc, u8 highbit, u8 lowbit, u32 *pValue);
-u32 bitTestSet(u32 csMask,u32 tempD);
-u32 bitTestReset(u32 csMask,u32 tempD);
-void set_Bits(sDCTStruct *pDCTData,
- u8 dct, u8 node, u8 func,
- u16 offset, u8 low, u8 high, u32 value);
-BOOL bitTest(u32 value, u8 bitLoc);
-u32 RttNomNonTargetRegDimm (sMCTStruct *pMCTData, sDCTStruct *pDCTData, u8 dimm, BOOL wl, u8 MemClkFreq, u8 rank);
-u32 RttNomTargetRegDimm (sMCTStruct *pMCTData, sDCTStruct *pDCTData, u8 dimm, BOOL wl, u8 MemClkFreq, u8 rank);
-u32 RttWrRegDimm (sMCTStruct *pMCTData, sDCTStruct *pDCTData, u8 dimm, BOOL wl, u8 MemClkFreq, u8 rank);
-u8 WrLvOdtRegDimm (sMCTStruct *pMCTData, sDCTStruct *pDCTData, u8 dimm);
-u32 get_ADD_DCT_Bits(sDCTStruct *pDCTData,
- u8 dct, u8 node, u8 func,
- u16 offset, u8 low, u8 high);
-void AmdMemPCIRead(SBDFO loc, u32 *Value);
-void AmdMemPCIWrite(SBDFO loc, u32 *Value);
-
-#endif
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c b/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c
deleted file mode 100644
index 52032e9362..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c
+++ /dev/null
@@ -1,1237 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
- *
- * 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.
- */
-
-#include <string.h>
-#include <arch/cpu.h>
-#include <arch/acpi.h>
-#include <cpu/x86/msr.h>
-#include <cpu/amd/msr.h>
-#include <cpu/x86/mtrr.h>
-#include <cpu/amd/mtrr.h>
-#include <device/device.h>
-#include <device/pci_def.h>
-#include <device/pci_ops.h>
-#include <console/console.h>
-#include <cbfs.h>
-#include <cbmem.h>
-#include <spi-generic.h>
-#include <spi_flash.h>
-#include <pc80/mc146818rtc.h>
-#include <stdint.h>
-#include <types.h>
-
-#include "mct_d.h"
-#include "mct_d_gcc.h"
-
-#include "s3utils.h"
-
-#define S3NV_FILE_NAME "s3nv"
-
-static uint8_t is_fam15h(void)
-{
- uint8_t fam15h = 0;
- uint32_t family;
-
- family = cpuid_eax(0x80000001);
- family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);
-
- if (family >= 0x6f)
- /* Family 15h or later */
- fam15h = 1;
-
- return fam15h;
-}
-
-static ssize_t get_s3nv_file_offset(void);
-
-ssize_t get_s3nv_file_offset(void)
-{
- struct region_device s3nv_region;
- struct cbfsf s3nv_cbfs_file;
- if (cbfs_boot_locate(&s3nv_cbfs_file, S3NV_FILE_NAME, NULL)) {
- printk(BIOS_DEBUG, "S3 state file not found in CBFS: %s\n", S3NV_FILE_NAME);
- return -1;
- }
- cbfs_file_data(&s3nv_region, &s3nv_cbfs_file);
-
- return s3nv_region.region.offset;
-}
-
-#if ENV_PCI_SIMPLE_DEVICE
-static uint32_t read_config32_dct(pci_devfn_t dev, uint8_t node, uint8_t dct,
- uint32_t reg)
-#else
-static uint32_t read_config32_dct(struct device *dev, uint8_t node, uint8_t dct,
- uint32_t reg)
-#endif
-{
- if (is_fam15h()) {
- uint32_t dword;
-#if ENV_PCI_SIMPLE_DEVICE
- pci_devfn_t dev_fn1 = PCI_DEV(0, 0x18 + node, 1);
-#else
- struct device *dev_fn1 = pcidev_on_root(0x18 + node, 1);
-#endif
-
- /* Select DCT */
- dword = pci_read_config32(dev_fn1, 0x10c);
- dword &= ~0x1;
- dword |= (dct & 0x1);
- pci_write_config32(dev_fn1, 0x10c, dword);
- } else {
- /* Apply offset */
- reg += dct * 0x100;
- }
-
- return pci_read_config32(dev, reg);
-}
-
-#if ENV_PCI_SIMPLE_DEVICE
-static void write_config32_dct(pci_devfn_t dev, uint8_t node, uint8_t dct,
- uint32_t reg, uint32_t value)
-#else
-static void write_config32_dct(struct device *dev, uint8_t node, uint8_t dct,
- uint32_t reg, uint32_t value)
-#endif
-{
- if (is_fam15h()) {
- uint32_t dword;
-#if ENV_PCI_SIMPLE_DEVICE
- pci_devfn_t dev_fn1 = PCI_DEV(0, 0x18 + node, 1);
-#else
- struct device *dev_fn1 = pcidev_on_root(0x18 + node, 1);
-#endif
-
- /* Select DCT */
- dword = pci_read_config32(dev_fn1, 0x10c);
- dword &= ~0x1;
- dword |= (dct & 0x1);
- pci_write_config32(dev_fn1, 0x10c, dword);
- } else {
- /* Apply offset */
- reg += dct * 0x100;
- }
-
- pci_write_config32(dev, reg, value);
-}
-
-#if ENV_PCI_SIMPLE_DEVICE
-static uint32_t read_amd_dct_index_register(pci_devfn_t dev,
- uint32_t index_ctl_reg, uint32_t index)
-#else
-static uint32_t read_amd_dct_index_register(struct device *dev,
- uint32_t index_ctl_reg, uint32_t index)
-#endif
-{
- uint32_t dword;
-
- index &= ~(1 << 30);
- pci_write_config32(dev, index_ctl_reg, index);
- do {
- dword = pci_read_config32(dev, index_ctl_reg);
- } while (!(dword & (1 << 31)));
- dword = pci_read_config32(dev, index_ctl_reg + 0x04);
-
- return dword;
-}
-
-#if ENV_PCI_SIMPLE_DEVICE
-static uint32_t read_amd_dct_index_register_dct(pci_devfn_t dev, uint8_t node,
- uint8_t dct, uint32_t index_ctl_reg, uint32_t index)
-#else
-static uint32_t read_amd_dct_index_register_dct(struct device *dev,
- uint8_t node, uint8_t dct, uint32_t index_ctl_reg,
- uint32_t index)
-#endif
-{
- if (is_fam15h()) {
- uint32_t dword;
-#if ENV_PCI_SIMPLE_DEVICE
- pci_devfn_t dev_fn1 = PCI_DEV(0, 0x18 + node, 1);
-#else
- struct device *dev_fn1 = pcidev_on_root(0x18 + node, 1);
-#endif
-
- /* Select DCT */
- dword = pci_read_config32(dev_fn1, 0x10c);
- dword &= ~0x1;
- dword |= (dct & 0x1);
- pci_write_config32(dev_fn1, 0x10c, dword);
- } else {
- /* Apply offset */
- index_ctl_reg += dct * 0x100;
- }
-
- return read_amd_dct_index_register(dev, index_ctl_reg, index);
-}
-
-/* Non-cryptographic 64-bit hash function taken from Stack Overflow:
- * http://stackoverflow.com/a/13326345
- * Any 64-bit hash with sufficiently low collision potential
- * could be used instead.
- */
-void calculate_spd_hash(uint8_t *spd_data, uint64_t *spd_hash)
-{
- const unsigned long long prime = 2654435789ULL;
- uint16_t byte;
- *spd_hash = 104395301;
-
- for (byte = 0; byte < 256; byte++)
- *spd_hash += (spd_data[byte] * prime) ^ (*spd_hash >> 23);
-
- *spd_hash = *spd_hash ^ (*spd_hash << 37);
-}
-
-uint16_t calculate_nvram_mct_hash(void)
-{
- uint32_t nvram;
- uint16_t ret;
-
- ret = 0;
- if (get_option(&nvram, "max_mem_clock") == CB_SUCCESS)
- ret |= nvram & 0xf;
- if (get_option(&nvram, "minimum_memory_voltage") == CB_SUCCESS)
- ret |= (nvram & 0x3) << 4;
- if (get_option(&nvram, "ECC_memory") == CB_SUCCESS)
- ret |= (nvram & 0x1) << 6;
- if (get_option(&nvram, "ECC_redirection") == CB_SUCCESS)
- ret |= (nvram & 0x1) << 7;
- if (get_option(&nvram, "ecc_scrub_rate") == CB_SUCCESS)
- ret |= (nvram & 0x1) << 8;
- if (get_option(&nvram, "interleave_chip_selects") == CB_SUCCESS)
- ret |= (nvram & 0x1) << 9;
- if (get_option(&nvram, "interleave_nodes") == CB_SUCCESS)
- ret |= (nvram & 0x1) << 10;
- if (get_option(&nvram, "interleave_memory_channels") == CB_SUCCESS)
- ret |= (nvram & 0x1) << 11;
- if (get_option(&nvram, "cpu_c_states") == CB_SUCCESS)
- ret |= (nvram & 0x1) << 12;
- if (get_option(&nvram, "cpu_cc6_state") == CB_SUCCESS)
- ret |= (nvram & 0x1) << 13;
-
- return ret;
-}
-
-static struct amd_s3_persistent_data *map_s3nv_in_nvram(void)
-{
- ssize_t s3nv_offset;
- ssize_t s3nv_file_offset;
- void *s3nv_cbfs_file_ptr;
- struct amd_s3_persistent_data *persistent_data;
-
- /* Obtain CBFS file offset */
- s3nv_offset = get_s3nv_file_offset();
- if (s3nv_offset == -1)
- return NULL;
-
- /* Align flash pointer to nearest boundary */
- s3nv_file_offset = s3nv_offset;
- s3nv_offset &= ~(CONFIG_S3_DATA_SIZE-1);
- s3nv_offset += CONFIG_S3_DATA_SIZE;
- s3nv_file_offset = s3nv_offset - s3nv_file_offset;
-
- /* Map data structure in CBFS and restore settings */
- s3nv_cbfs_file_ptr = cbfs_boot_map_with_leak(S3NV_FILE_NAME, CBFS_TYPE_RAW, NULL);
- if (!s3nv_cbfs_file_ptr) {
- printk(BIOS_DEBUG, "S3 state file could not be mapped: %s\n", S3NV_FILE_NAME);
- return NULL;
- }
- persistent_data = (s3nv_cbfs_file_ptr + s3nv_file_offset);
-
- return persistent_data;
-}
-
-int8_t load_spd_hashes_from_nvram(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat)
-{
- struct amd_s3_persistent_data *persistent_data;
-
- persistent_data = map_s3nv_in_nvram();
- if (!persistent_data)
- return -1;
-
- memcpy(pDCTstat->spd_data.nvram_spd_hash, persistent_data->node[pDCTstat->Node_ID].spd_hash, sizeof(pDCTstat->spd_data.nvram_spd_hash));
- memcpy(pDCTstat->spd_data.nvram_memclk, persistent_data->node[pDCTstat->Node_ID].memclk, sizeof(pDCTstat->spd_data.nvram_memclk));
-
- pMCTstat->nvram_checksum = persistent_data->nvram_checksum;
-
- return 0;
-}
-
-static uint64_t rdmsr_uint64_t(unsigned long index) {
- msr_t msr = rdmsr(index);
- return (((uint64_t)msr.hi) << 32) | ((uint64_t)msr.lo);
-}
-
-static void wrmsr_uint64_t(unsigned long index, uint64_t value)
-{
- msr_t msr;
- msr.hi = (value & 0xffffffff00000000ULL) >> 32;
- msr.lo = (value & 0xffffffff);
- wrmsr(index, msr);
-}
-
-static uint32_t read_config32_dct_nbpstate(struct device *dev, uint8_t node,
- uint8_t dct, uint8_t nb_pstate,
- uint32_t reg)
-{
- uint32_t dword;
- struct device *dev_fn1 = pcidev_on_root(0x18 + node, 1);
-
- /* Select DCT */
- dword = pci_read_config32(dev_fn1, 0x10c);
- dword &= ~0x1;
- dword |= (dct & 0x1);
- pci_write_config32(dev_fn1, 0x10c, dword);
-
- /* Select NB Pstate index */
- dword = pci_read_config32(dev_fn1, 0x10c);
- dword &= ~(0x3 << 4);
- dword |= (nb_pstate & 0x3) << 4;
- pci_write_config32(dev_fn1, 0x10c, dword);
-
- return pci_read_config32(dev, reg);
-}
-
-static void copy_cbmem_spd_data_to_save_variable(struct amd_s3_persistent_data *persistent_data, uint8_t *restored)
-{
- uint8_t node;
- uint8_t dimm;
- uint8_t channel;
- struct amdmct_memory_info *mem_info;
- mem_info = cbmem_find(CBMEM_ID_AMDMCT_MEMINFO);
- if (mem_info == NULL) {
- /* can't find amdmct information in cbmem */
- for (node = 0; node < MAX_NODES_SUPPORTED; node++)
- for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++)
- persistent_data->node[node].spd_hash[dimm] = 0xffffffffffffffffULL;
-
- return;
- }
-
- for (node = 0; node < MAX_NODES_SUPPORTED; node++)
- for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++)
- calculate_spd_hash(mem_info->dct_stat[node].spd_data.spd_bytes[dimm], &persistent_data->node[node].spd_hash[dimm]);
-
- for (node = 0; node < MAX_NODES_SUPPORTED; node++)
- for (channel = 0; channel < 2; channel++)
- persistent_data->node[node].memclk[channel] = mem_info->dct_stat[node].Speed;
-
- persistent_data->nvram_checksum = calculate_nvram_mct_hash();
-
- if (restored) {
- if (mem_info->mct_stat.GStatus & (1 << GSB_ConfigRestored))
- *restored = 1;
- else
- *restored = 0;
- }
-}
-
-void copy_mct_data_to_save_variable(struct amd_s3_persistent_data *persistent_data)
-{
- uint8_t i;
- uint8_t j;
- uint8_t node;
- uint8_t channel;
-
- /* Zero out data structure */
- memset(persistent_data, 0, sizeof(struct amd_s3_persistent_data));
-
- /* Load data from DCTs into data structure */
- for (node = 0; node < MAX_NODES_SUPPORTED; node++) {
- struct device *dev_fn1 = pcidev_on_root(0x18 + node, 1);
- struct device *dev_fn2 = pcidev_on_root(0x18 + node, 2);
- struct device *dev_fn3 = pcidev_on_root(0x18 + node, 3);
- /* Test for node presence */
- if ((!dev_fn1) || (pci_read_config32(dev_fn1, PCI_VENDOR_ID) == 0xffffffff)) {
- persistent_data->node[node].node_present = 0;
- continue;
- }
- persistent_data->node[node].node_present = 1;
-
- for (channel = 0; channel < 2; channel++) {
- struct amd_s3_persistent_mct_channel_data *data = &persistent_data->node[node].channel[channel];
-
- /* Stage 1 */
- data->f2x110 = pci_read_config32(dev_fn2, 0x110);
-
- /* Stage 2 */
- data->f1x40 = read_config32_dct(dev_fn1, node, channel, 0x40);
- data->f1x44 = read_config32_dct(dev_fn1, node, channel, 0x44);
- data->f1x48 = read_config32_dct(dev_fn1, node, channel, 0x48);
- data->f1x4c = read_config32_dct(dev_fn1, node, channel, 0x4c);
- data->f1x50 = read_config32_dct(dev_fn1, node, channel, 0x50);
- data->f1x54 = read_config32_dct(dev_fn1, node, channel, 0x54);
- data->f1x58 = read_config32_dct(dev_fn1, node, channel, 0x58);
- data->f1x5c = read_config32_dct(dev_fn1, node, channel, 0x5c);
- data->f1x60 = read_config32_dct(dev_fn1, node, channel, 0x60);
- data->f1x64 = read_config32_dct(dev_fn1, node, channel, 0x64);
- data->f1x68 = read_config32_dct(dev_fn1, node, channel, 0x68);
- data->f1x6c = read_config32_dct(dev_fn1, node, channel, 0x6c);
- data->f1x70 = read_config32_dct(dev_fn1, node, channel, 0x70);
- data->f1x74 = read_config32_dct(dev_fn1, node, channel, 0x74);
- data->f1x78 = read_config32_dct(dev_fn1, node, channel, 0x78);
- data->f1x7c = read_config32_dct(dev_fn1, node, channel, 0x7c);
- data->f1xf0 = pci_read_config32(dev_fn1, 0xf0);
- data->f1x120 = pci_read_config32(dev_fn1, 0x120);
- data->f1x124 = pci_read_config32(dev_fn1, 0x124);
- data->f2x10c = pci_read_config32(dev_fn2, 0x10c);
- data->f2x114 = pci_read_config32(dev_fn2, 0x114);
- data->f2x118 = pci_read_config32(dev_fn2, 0x118);
- data->f2x11c = pci_read_config32(dev_fn2, 0x11c);
- data->f2x1b0 = pci_read_config32(dev_fn2, 0x1b0);
- data->f3x44 = pci_read_config32(dev_fn3, 0x44);
- for (i = 0; i < 16; i++) {
- data->msr0000020[i] =
- rdmsr_uint64_t(MTRR_PHYS_BASE(0) | i);
- }
- data->msr00000250 = rdmsr_uint64_t(MTRR_FIX_64K_00000);
- data->msr00000258 = rdmsr_uint64_t(MTRR_FIX_16K_80000);
- for (i = 0; i < 8; i++)
- data->msr0000026[i] = rdmsr_uint64_t(0x00000260 | (i + 8));
- data->msr000002ff = rdmsr_uint64_t(MTRR_DEF_TYPE_MSR);
- data->msrc0010010 = rdmsr_uint64_t(SYSCFG_MSR);
- data->msrc001001a = rdmsr_uint64_t(TOP_MEM);
- data->msrc001001d = rdmsr_uint64_t(TOP_MEM2);
- data->msrc001001f = rdmsr_uint64_t(NB_CFG_MSR);
-
- /* Stage 3 */
- data->f2x40 = read_config32_dct(dev_fn2, node, channel, 0x40);
- data->f2x44 = read_config32_dct(dev_fn2, node, channel, 0x44);
- data->f2x48 = read_config32_dct(dev_fn2, node, channel, 0x48);
- data->f2x4c = read_config32_dct(dev_fn2, node, channel, 0x4c);
- data->f2x50 = read_config32_dct(dev_fn2, node, channel, 0x50);
- data->f2x54 = read_config32_dct(dev_fn2, node, channel, 0x54);
- data->f2x58 = read_config32_dct(dev_fn2, node, channel, 0x58);
- data->f2x5c = read_config32_dct(dev_fn2, node, channel, 0x5c);
- data->f2x60 = read_config32_dct(dev_fn2, node, channel, 0x60);
- data->f2x64 = read_config32_dct(dev_fn2, node, channel, 0x64);
- data->f2x68 = read_config32_dct(dev_fn2, node, channel, 0x68);
- data->f2x6c = read_config32_dct(dev_fn2, node, channel, 0x6c);
- data->f2x78 = read_config32_dct(dev_fn2, node, channel, 0x78);
- data->f2x7c = read_config32_dct(dev_fn2, node, channel, 0x7c);
- data->f2x80 = read_config32_dct(dev_fn2, node, channel, 0x80);
- data->f2x84 = read_config32_dct(dev_fn2, node, channel, 0x84);
- data->f2x88 = read_config32_dct(dev_fn2, node, channel, 0x88);
- data->f2x8c = read_config32_dct(dev_fn2, node, channel, 0x8c);
- data->f2x90 = read_config32_dct(dev_fn2, node, channel, 0x90);
- data->f2xa4 = read_config32_dct(dev_fn2, node, channel, 0xa4);
- data->f2xa8 = read_config32_dct(dev_fn2, node, channel, 0xa8);
-
- /* Family 15h-specific configuration */
- if (is_fam15h()) {
- data->f2x200 = read_config32_dct(dev_fn2, node, channel, 0x200);
- data->f2x204 = read_config32_dct(dev_fn2, node, channel, 0x204);
- data->f2x208 = read_config32_dct(dev_fn2, node, channel, 0x208);
- data->f2x20c = read_config32_dct(dev_fn2, node, channel, 0x20c);
- for (i = 0; i < 4; i++)
- data->f2x210[i] = read_config32_dct_nbpstate(dev_fn2, node, channel, i, 0x210);
- data->f2x214 = read_config32_dct(dev_fn2, node, channel, 0x214);
- data->f2x218 = read_config32_dct(dev_fn2, node, channel, 0x218);
- data->f2x21c = read_config32_dct(dev_fn2, node, channel, 0x21c);
- data->f2x22c = read_config32_dct(dev_fn2, node, channel, 0x22c);
- data->f2x230 = read_config32_dct(dev_fn2, node, channel, 0x230);
- data->f2x234 = read_config32_dct(dev_fn2, node, channel, 0x234);
- data->f2x238 = read_config32_dct(dev_fn2, node, channel, 0x238);
- data->f2x23c = read_config32_dct(dev_fn2, node, channel, 0x23c);
- data->f2x240 = read_config32_dct(dev_fn2, node, channel, 0x240);
-
- data->f2x9cx0d0fe003 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0fe003);
- data->f2x9cx0d0fe013 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0fe013);
- for (i = 0; i < 9; i++)
- data->f2x9cx0d0f0_8_0_1f[i] = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f001f | (i << 8));
- data->f2x9cx0d0f201f = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f201f);
- data->f2x9cx0d0f211f = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f211f);
- data->f2x9cx0d0f221f = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f221f);
- data->f2x9cx0d0f801f = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f801f);
- data->f2x9cx0d0f811f = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f811f);
- data->f2x9cx0d0f821f = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f821f);
- data->f2x9cx0d0fc01f = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0fc01f);
- data->f2x9cx0d0fc11f = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0fc11f);
- data->f2x9cx0d0fc21f = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0fc21f);
- data->f2x9cx0d0f4009 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f4009);
- for (i = 0; i < 9; i++)
- data->f2x9cx0d0f0_8_0_02[i] = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f0002 | (i << 8));
- for (i = 0; i < 9; i++)
- data->f2x9cx0d0f0_8_0_06[i] = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f0006 | (i << 8));
- for (i = 0; i < 9; i++)
- data->f2x9cx0d0f0_8_0_0a[i] = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f000a | (i << 8));
-
- data->f2x9cx0d0f2002 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f2002);
- data->f2x9cx0d0f2102 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f2102);
- data->f2x9cx0d0f2202 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f2202);
- data->f2x9cx0d0f8002 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f8002);
- data->f2x9cx0d0f8006 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f8006);
- data->f2x9cx0d0f800a = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f800a);
- data->f2x9cx0d0f8102 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f8102);
- data->f2x9cx0d0f8106 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f8106);
- data->f2x9cx0d0f810a = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f810a);
- data->f2x9cx0d0fc002 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0fc002);
- data->f2x9cx0d0fc006 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0fc006);
- data->f2x9cx0d0fc00a = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0fc00a);
- data->f2x9cx0d0fc00e = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0fc00e);
- data->f2x9cx0d0fc012 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0fc012);
-
- data->f2x9cx0d0f2031 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f2031);
- data->f2x9cx0d0f2131 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f2131);
- data->f2x9cx0d0f2231 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f2231);
- data->f2x9cx0d0f8031 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f8031);
- data->f2x9cx0d0f8131 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f8131);
- data->f2x9cx0d0f8231 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f8231);
- data->f2x9cx0d0fc031 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0fc031);
- data->f2x9cx0d0fc131 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0fc131);
- data->f2x9cx0d0fc231 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0fc231);
- for (i = 0; i < 9; i++)
- data->f2x9cx0d0f0_0_f_31[i] = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f0031 | (i << 8));
-
- data->f2x9cx0d0f8021 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f8021);
-
- if (channel == 1)
- data->f2x9cx0d0fe00a = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0fe00a);
- }
-
- /* Stage 4 */
- data->f2x94 = read_config32_dct(dev_fn2, node, channel, 0x94);
-
- /* Stage 6 */
- for (i = 0; i < 9; i++)
- for (j = 0; j < 3; j++)
- data->f2x9cx0d0f0_f_8_0_0_8_4_0[i][j] = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f0000 | (i << 8) | (j * 4));
- data->f2x9cx00 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x00);
- data->f2x9cx0a = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0a);
- data->f2x9cx0c = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0c);
-
- /* Stage 7 */
- data->f2x9cx04 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x04);
-
- /* Stage 9 */
- data->f2x9cx0d0fe006 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0fe006);
- data->f2x9cx0d0fe007 = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0fe007);
-
- /* Stage 10 */
- for (i = 0; i < 12; i++)
- data->f2x9cx10[i] = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x10 + i);
- for (i = 0; i < 12; i++)
- data->f2x9cx20[i] = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x20 + i);
- for (i = 0; i < 4; i++)
- for (j = 0; j < 3; j++)
- data->f2x9cx3_0_0_3_1[i][j] = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, (0x01 + i) + (0x100 * j));
- for (i = 0; i < 4; i++)
- for (j = 0; j < 3; j++)
- data->f2x9cx3_0_0_7_5[i][j] = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, (0x05 + i) + (0x100 * j));
- data->f2x9cx0d = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d);
- for (i = 0; i < 9; i++)
- data->f2x9cx0d0f0_f_0_13[i] = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f0013 | (i << 8));
- for (i = 0; i < 9; i++)
- data->f2x9cx0d0f0_f_0_30[i] = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f0030 | (i << 8));
- for (i = 0; i < 4; i++)
- data->f2x9cx0d0f2_f_0_30[i] = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f2030 | (i << 8));
- for (i = 0; i < 2; i++)
- for (j = 0; j < 3; j++)
- data->f2x9cx0d0f8_8_4_0[i][j] = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f0000 | (i << 8) | (j * 4));
- data->f2x9cx0d0f812f = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x0d0f812f);
-
- /* Stage 11 */
- if (CONFIG(DIMM_DDR3)) {
- for (i = 0; i < 12; i++)
- data->f2x9cx30[i] = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x30 + i);
- for (i = 0; i < 12; i++)
- data->f2x9cx40[i] = read_amd_dct_index_register_dct(dev_fn2, node, channel, 0x98, 0x40 + i);
- }
-
- /* Other */
- /* ECC scrub rate control */
- data->f3x58 = read_config32_dct(dev_fn3, node, 0, 0x58);
-
- /* ECC scrub location */
- write_config32_dct(dev_fn3, node, 0, 0x58, 0x0); /* Disable sequential scrub to work around non-atomic location read */
- data->f3x5c = read_config32_dct(dev_fn3, node, 0, 0x5c);
- data->f3x60 = read_config32_dct(dev_fn3, node, 0, 0x60);
- write_config32_dct(dev_fn3, node, 0, 0x58, data->f3x58); /* Re-enable sequential scrub */
- }
- }
-}
-
-static void write_config32_dct_nbpstate(pci_devfn_t dev, uint8_t node,
- uint8_t dct, uint8_t nb_pstate,
- uint32_t reg, uint32_t value)
-{
- uint32_t dword;
- pci_devfn_t dev_fn1 = PCI_DEV(0, 0x18 + node, 1);
-
- /* Select DCT */
- dword = pci_read_config32(dev_fn1, 0x10c);
- dword &= ~0x1;
- dword |= (dct & 0x1);
- pci_write_config32(dev_fn1, 0x10c, dword);
-
- /* Select NB Pstate index */
- dword = pci_read_config32(dev_fn1, 0x10c);
- dword &= ~(0x3 << 4);
- dword |= (nb_pstate & 0x3) << 4;
- pci_write_config32(dev_fn1, 0x10c, dword);
-
- pci_write_config32(dev, reg, value);
-}
-
-static void write_amd_dct_index_register(pci_devfn_t dev,
- uint32_t index_ctl_reg, uint32_t index,
- uint32_t value)
-{
- uint32_t dword;
-
- pci_write_config32(dev, index_ctl_reg + 0x04, value);
- index |= (1 << 30);
- pci_write_config32(dev, index_ctl_reg, index);
- do {
- dword = pci_read_config32(dev, index_ctl_reg);
- } while (!(dword & (1 << 31)));
-}
-
-static void write_amd_dct_index_register_dct(pci_devfn_t dev, uint8_t node,
- uint8_t dct,
- uint32_t index_ctl_reg,
- uint32_t index, uint32_t value)
-{
- if (is_fam15h()) {
- uint32_t dword;
- pci_devfn_t dev_fn1 = PCI_DEV(0, 0x18 + node, 1);
-
- /* Select DCT */
- dword = pci_read_config32(dev_fn1, 0x10c);
- dword &= ~0x1;
- dword |= (dct & 0x1);
- pci_write_config32(dev_fn1, 0x10c, dword);
- } else {
- /* Apply offset */
- index_ctl_reg += dct * 0x100;
- }
-
- return write_amd_dct_index_register(dev, index_ctl_reg, index, value);
-}
-
-void restore_mct_data_from_save_variable(struct amd_s3_persistent_data *persistent_data, uint8_t training_only)
-{
- uint8_t i;
- uint8_t j;
- uint8_t node;
- uint8_t channel;
- uint8_t ganged;
- uint8_t dct_enabled;
- uint32_t dword;
-
- if (training_only) {
- /* Only restore the Receiver Enable and DQS training registers */
- for (node = 0; node < MAX_NODES_SUPPORTED; node++) {
- for (channel = 0; channel < 2; channel++) {
- struct amd_s3_persistent_mct_channel_data *data = &persistent_data->node[node].channel[channel];
- if (!persistent_data->node[node].node_present)
- continue;
-
- /* Restore training parameters */
- for (i = 0; i < 4; i++)
- for (j = 0; j < 3; j++)
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, (0x01 + i) + (0x100 * j), data->f2x9cx3_0_0_3_1[i][j]);
- for (i = 0; i < 4; i++)
- for (j = 0; j < 3; j++)
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, (0x05 + i) + (0x100 * j), data->f2x9cx3_0_0_7_5[i][j]);
-
- for (i = 0; i < 12; i++)
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x10 + i, data->f2x9cx10[i]);
- for (i = 0; i < 12; i++)
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x20 + i, data->f2x9cx20[i]);
-
- if (CONFIG(DIMM_DDR3)) {
- for (i = 0; i < 12; i++)
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x30 + i, data->f2x9cx30[i]);
- for (i = 0; i < 12; i++)
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x40 + i, data->f2x9cx40[i]);
- }
-
- /* Restore MaxRdLatency */
- if (is_fam15h()) {
- for (i = 0; i < 4; i++)
- write_config32_dct_nbpstate(PCI_DEV(0, 0x18 + node, 2), node, channel, i, 0x210, data->f2x210[i]);
- } else {
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x78, data->f2x78);
- }
-
- /* Other timing control registers */
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x8c, data->f2x8c);
- }
- }
-
- return;
- }
-
- /* Load data from data structure into DCTs */
- /* Stage 1 */
- for (node = 0; node < MAX_NODES_SUPPORTED; node++) {
- for (channel = 0; channel < 2; channel++) {
- struct amd_s3_persistent_mct_channel_data *data = &persistent_data->node[node].channel[channel];
- if (!persistent_data->node[node].node_present)
- continue;
-
- pci_write_config32(PCI_DEV(0, 0x18 + node, 2), 0x110, data->f2x110);
- }
- }
-
- /* Stage 2 */
- for (node = 0; node < MAX_NODES_SUPPORTED; node++) {
- for (channel = 0; channel < 2; channel++) {
- struct amd_s3_persistent_mct_channel_data *data = &persistent_data->node[node].channel[channel];
- if (!persistent_data->node[node].node_present)
- continue;
-
- write_config32_dct(PCI_DEV(0, 0x18 + node, 1), node, channel, 0x40, data->f1x40);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 1), node, channel, 0x44, data->f1x44);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 1), node, channel, 0x48, data->f1x48);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 1), node, channel, 0x4c, data->f1x4c);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 1), node, channel, 0x50, data->f1x50);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 1), node, channel, 0x54, data->f1x54);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 1), node, channel, 0x58, data->f1x58);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 1), node, channel, 0x5c, data->f1x5c);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 1), node, channel, 0x60, data->f1x60);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 1), node, channel, 0x64, data->f1x64);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 1), node, channel, 0x68, data->f1x68);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 1), node, channel, 0x6c, data->f1x6c);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 1), node, channel, 0x70, data->f1x70);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 1), node, channel, 0x74, data->f1x74);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 1), node, channel, 0x78, data->f1x78);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 1), node, channel, 0x7c, data->f1x7c);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 1), node, channel, 0xf0, data->f1xf0);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 1), node, channel, 0x120, data->f1x120);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 1), node, channel, 0x124, data->f1x124);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x10c, data->f2x10c);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x114, data->f2x114);
- if (is_fam15h())
- /* Do not set LockDramCfg or CC6SaveEn at this time */
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x118, data->f2x118 & ~(0x3 << 18));
- else
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x118, data->f2x118);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x11c, data->f2x11c);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x1b0, data->f2x1b0);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 3), node, channel, 0x44, data->f3x44);
- for (i = 0; i < 16; i++) {
- wrmsr_uint64_t(MTRR_PHYS_BASE(0) | i,
- data->msr0000020[i]);
- }
- wrmsr_uint64_t(MTRR_FIX_64K_00000, data->msr00000250);
- wrmsr_uint64_t(MTRR_FIX_16K_80000, data->msr00000258);
- /* FIXME
- * Restoring these MSRs causes a hang on resume due to
- * destroying CAR while still executing from CAR!
- * For now, skip restoration...
- */
- // for (i = 0; i < 8; i++)
- // wrmsr_uint64_t(0x00000260 | (i + 8), data->msr0000026[i]);
- wrmsr_uint64_t(MTRR_DEF_TYPE_MSR, data->msr000002ff);
- wrmsr_uint64_t(SYSCFG_MSR, data->msrc0010010);
- wrmsr_uint64_t(TOP_MEM, data->msrc001001a);
- wrmsr_uint64_t(TOP_MEM2, data->msrc001001d);
- wrmsr_uint64_t(NB_CFG_MSR, data->msrc001001f);
- }
- }
-
- /* Stage 3 */
- for (node = 0; node < MAX_NODES_SUPPORTED; node++) {
- for (channel = 0; channel < 2; channel++) {
- struct amd_s3_persistent_mct_channel_data *data = &persistent_data->node[node].channel[channel];
- if (!persistent_data->node[node].node_present)
- continue;
-
- if (is_fam15h())
- ganged = 0;
- else
- ganged = !!(data->f2x110 & 0x10);
- if ((ganged == 1) && (channel > 0))
- continue;
-
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x40, data->f2x40);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x44, data->f2x44);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x48, data->f2x48);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x4c, data->f2x4c);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x50, data->f2x50);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x54, data->f2x54);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x58, data->f2x58);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x5c, data->f2x5c);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x60, data->f2x60);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x64, data->f2x64);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x68, data->f2x68);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x6c, data->f2x6c);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x78, data->f2x78);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x7c, data->f2x7c);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x80, data->f2x80);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x84, data->f2x84);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x88, data->f2x88);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x8c, data->f2x8c);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x90, data->f2x90);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0xa4, data->f2xa4);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0xa8, data->f2xa8);
- }
- }
-
- /* Family 15h-specific configuration */
- if (is_fam15h()) {
- for (node = 0; node < MAX_NODES_SUPPORTED; node++) {
- for (channel = 0; channel < 2; channel++) {
- struct amd_s3_persistent_mct_channel_data *data = &persistent_data->node[node].channel[channel];
- if (!persistent_data->node[node].node_present)
- continue;
-
- /* Initialize DCT */
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0000000b, 0x80000000);
- dword = read_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fe013);
- dword &= ~0xffff;
- dword |= 0x118;
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fe013, dword);
-
- /* Restore values */
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x200, data->f2x200);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x204, data->f2x204);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x208, data->f2x208);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x20c, data->f2x20c);
- for (i = 0; i < 4; i++)
- write_config32_dct_nbpstate(PCI_DEV(0, 0x18 + node, 2), node, channel, i, 0x210, data->f2x210[i]);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x214, data->f2x214);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x218, data->f2x218);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x21c, data->f2x21c);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x22c, data->f2x22c);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x230, data->f2x230);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x234, data->f2x234);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x238, data->f2x238);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x23c, data->f2x23c);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x240, data->f2x240);
-
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fe013, data->f2x9cx0d0fe013);
- for (i = 0; i < 9; i++)
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f001f | (i << 8), data->f2x9cx0d0f0_8_0_1f[i]);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f201f, data->f2x9cx0d0f201f);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f211f, data->f2x9cx0d0f211f);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f221f, data->f2x9cx0d0f221f);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f801f, data->f2x9cx0d0f801f);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f811f, data->f2x9cx0d0f811f);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f821f, data->f2x9cx0d0f821f);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fc01f, data->f2x9cx0d0fc01f);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fc11f, data->f2x9cx0d0fc11f);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fc21f, data->f2x9cx0d0fc21f);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f4009, data->f2x9cx0d0f4009);
-
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f2031, data->f2x9cx0d0f2031);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f2131, data->f2x9cx0d0f2131);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f2231, data->f2x9cx0d0f2231);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f8031, data->f2x9cx0d0f8031);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f8131, data->f2x9cx0d0f8131);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f8231, data->f2x9cx0d0f8231);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fc031, data->f2x9cx0d0fc031);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fc131, data->f2x9cx0d0fc131);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fc231, data->f2x9cx0d0fc231);
- for (i = 0; i < 9; i++)
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f0031 | (i << 8), data->f2x9cx0d0f0_0_f_31[i]);
-
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f8021, data->f2x9cx0d0f8021);
-
- if (channel == 1)
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fe00a, data->f2x9cx0d0fe00a);
- }
- }
- }
-
- /* Stage 4 */
- for (node = 0; node < MAX_NODES_SUPPORTED; node++) {
- for (channel = 0; channel < 2; channel++) {
- struct amd_s3_persistent_mct_channel_data *data = &persistent_data->node[node].channel[channel];
- if (!persistent_data->node[node].node_present)
- continue;
-
- if (is_fam15h())
- ganged = 0;
- else
- ganged = !!(data->f2x110 & 0x10);
- if ((ganged == 1) && (channel > 0))
- continue;
-
- if (is_fam15h()) {
- /* Program PllLockTime = 0x190 */
- dword = read_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fe006);
- dword &= ~0xffff;
- dword |= 0x190;
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fe006, dword);
-
- /* Program MemClkFreqVal = 0 */
- dword = read_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x94);
- dword &= (0x1 << 7);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x94, dword);
-
- /* Restore DRAM Address/Timing Control Register */
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x04, data->f2x9cx04);
- } else {
- /* Disable PHY auto-compensation engine */
- dword = read_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x08);
- if (!(dword & (1 << 30))) {
- dword |= (1 << 30);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x08, dword);
-
- /* Wait for 5us */
- mct_Wait(100);
- }
- }
-
- /* Restore DRAM Configuration High Register */
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x94, data->f2x94);
- }
- }
-
- /* Stage 5 */
- for (node = 0; node < MAX_NODES_SUPPORTED; node++) {
- for (channel = 0; channel < 2; channel++) {
- struct amd_s3_persistent_mct_channel_data *data = &persistent_data->node[node].channel[channel];
- if (!persistent_data->node[node].node_present)
- continue;
-
- if (is_fam15h())
- ganged = 0;
- else
- ganged = !!(data->f2x110 & 0x10);
- if ((ganged == 1) && (channel > 0))
- continue;
-
- dct_enabled = !(data->f2x94 & (1 << 14));
- if (!dct_enabled)
- continue;
-
- /* Wait for any pending PHY frequency changes to complete */
- do {
- dword = read_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x94);
- } while (dword & (1 << 21));
-
- if (is_fam15h()) {
- /* Program PllLockTime = 0xf */
- dword = read_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fe006);
- dword &= ~0xffff;
- dword |= 0xf;
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fe006, dword);
- } else {
- /* Enable PHY auto-compensation engine */
- dword = read_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x08);
- dword &= ~(1 << 30);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x08, dword);
- }
- }
- }
-
- /* Wait for 750us */
- mct_Wait(15000);
-
- /* Stage 6 */
- for (node = 0; node < MAX_NODES_SUPPORTED; node++) {
- for (channel = 0; channel < 2; channel++) {
- struct amd_s3_persistent_mct_channel_data *data = &persistent_data->node[node].channel[channel];
- if (!persistent_data->node[node].node_present)
- continue;
-
- for (i = 0; i < 9; i++)
- for (j = 0; j < 3; j++)
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f0000 | (i << 8) | (j * 4), data->f2x9cx0d0f0_f_8_0_0_8_4_0[i][j]);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x00, data->f2x9cx00);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0a, data->f2x9cx0a);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0c, data->f2x9cx0c);
- }
- }
-
- /* Family 15h-specific configuration */
- if (is_fam15h()) {
- for (node = 0; node < MAX_NODES_SUPPORTED; node++) {
- for (channel = 0; channel < 2; channel++) {
- struct amd_s3_persistent_mct_channel_data *data = &persistent_data->node[node].channel[channel];
- if (!persistent_data->node[node].node_present)
- continue;
-
- dword = read_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fe003);
- dword |= (0x3 << 13); /* DisAutoComp, DisablePredriverCal = 1 */
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fe003, dword);
-
- for (i = 0; i < 9; i++)
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f0006 | (i << 8), data->f2x9cx0d0f0_8_0_06[i]);
- for (i = 0; i < 9; i++)
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f000a | (i << 8), data->f2x9cx0d0f0_8_0_0a[i]);
- for (i = 0; i < 9; i++)
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f0002 | (i << 8), (0x8000 | data->f2x9cx0d0f0_8_0_02[i]));
-
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f8006, data->f2x9cx0d0f8006);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f800a, data->f2x9cx0d0f800a);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f8106, data->f2x9cx0d0f8106);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f810a, data->f2x9cx0d0f810a);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fc006, data->f2x9cx0d0fc006);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fc00a, data->f2x9cx0d0fc00a);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fc00e, data->f2x9cx0d0fc00e);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fc012, data->f2x9cx0d0fc012);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f8002, (0x8000 | data->f2x9cx0d0f8002));
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f8102, (0x8000 | data->f2x9cx0d0f8102));
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fc002, (0x8000 | data->f2x9cx0d0fc002));
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f2002, (0x8000 | data->f2x9cx0d0f2002));
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f2102, (0x8000 | data->f2x9cx0d0f2102));
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f2202, (0x8000 | data->f2x9cx0d0f2202));
-
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fe003, data->f2x9cx0d0fe003);
- }
- }
- }
-
- /* Stage 7 */
- for (node = 0; node < MAX_NODES_SUPPORTED; node++) {
- for (channel = 0; channel < 2; channel++) {
- struct amd_s3_persistent_mct_channel_data *data = &persistent_data->node[node].channel[channel];
- if (!persistent_data->node[node].node_present)
- continue;
-
- if (is_fam15h())
- ganged = 0;
- else
- ganged = !!(data->f2x110 & 0x10);
- if ((ganged == 1) && (channel > 0))
- continue;
-
- if (!is_fam15h())
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x04, data->f2x9cx04);
- }
- }
-
- /* Stage 8 */
- for (node = 0; node < MAX_NODES_SUPPORTED; node++) {
- for (channel = 0; channel < 2; channel++) {
- struct amd_s3_persistent_mct_channel_data *data = &persistent_data->node[node].channel[channel];
- if (!persistent_data->node[node].node_present)
- continue;
-
- dct_enabled = !(data->f2x94 & (1 << 14));
- if (!dct_enabled)
- continue;
-
- if (is_fam15h())
- ganged = 0;
- else
- ganged = !!(data->f2x110 & 0x10);
- if ((ganged == 1) && (channel > 0))
- continue;
-
- printk(BIOS_SPEW, "Taking DIMMs out of self refresh node: %d channel: %d\n", node, channel);
-
- /* Exit self refresh mode */
- dword = read_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x90);
- dword |= (1 << 1);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x90, dword);
- }
- }
-
- /* Stage 9 */
- for (node = 0; node < MAX_NODES_SUPPORTED; node++) {
- for (channel = 0; channel < 2; channel++) {
- struct amd_s3_persistent_mct_channel_data *data = &persistent_data->node[node].channel[channel];
- if (!persistent_data->node[node].node_present)
- continue;
-
- dct_enabled = !(data->f2x94 & (1 << 14));
- if (!dct_enabled)
- continue;
-
- printk(BIOS_SPEW, "Waiting for DIMMs to exit self refresh node: %d channel: %d\n", node, channel);
-
- /* Wait for transition from self refresh mode to complete */
- do {
- dword = read_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x90);
- } while (dword & (1 << 1));
-
- /* Restore registers */
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fe006, data->f2x9cx0d0fe006);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0fe007, data->f2x9cx0d0fe007);
- }
- }
-
- /* Stage 10 */
- for (node = 0; node < MAX_NODES_SUPPORTED; node++) {
- for (channel = 0; channel < 2; channel++) {
- struct amd_s3_persistent_mct_channel_data *data = &persistent_data->node[node].channel[channel];
- if (!persistent_data->node[node].node_present)
- continue;
-
- for (i = 0; i < 12; i++)
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x10 + i, data->f2x9cx10[i]);
- for (i = 0; i < 12; i++)
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x20 + i, data->f2x9cx20[i]);
- for (i = 0; i < 4; i++)
- for (j = 0; j < 3; j++)
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, (0x01 + i) + (0x100 * j), data->f2x9cx3_0_0_3_1[i][j]);
- for (i = 0; i < 4; i++)
- for (j = 0; j < 3; j++)
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, (0x05 + i) + (0x100 * j), data->f2x9cx3_0_0_7_5[i][j]);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d, data->f2x9cx0d);
- for (i = 0; i < 9; i++)
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f0013 | (i << 8), data->f2x9cx0d0f0_f_0_13[i]);
- for (i = 0; i < 9; i++)
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f0030 | (i << 8), data->f2x9cx0d0f0_f_0_30[i]);
- for (i = 0; i < 4; i++)
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f2030 | (i << 8), data->f2x9cx0d0f2_f_0_30[i]);
- for (i = 0; i < 2; i++)
- for (j = 0; j < 3; j++)
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f0000 | (i << 8) | (j * 4), data->f2x9cx0d0f8_8_4_0[i][j]);
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x0d0f812f, data->f2x9cx0d0f812f);
- }
- }
-
- /* Stage 11 */
- if (CONFIG(DIMM_DDR3)) {
- for (node = 0; node < MAX_NODES_SUPPORTED; node++) {
- for (channel = 0; channel < 2; channel++) {
- struct amd_s3_persistent_mct_channel_data *data = &persistent_data->node[node].channel[channel];
- if (!persistent_data->node[node].node_present)
- continue;
-
- for (i = 0; i < 12; i++)
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x30 + i, data->f2x9cx30[i]);
- for (i = 0; i < 12; i++)
- write_amd_dct_index_register_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x98, 0x40 + i, data->f2x9cx40[i]);
- }
- }
- }
-
- /* Other */
- for (node = 0; node < MAX_NODES_SUPPORTED; node++) {
- for (channel = 0; channel < 2; channel++) {
- struct amd_s3_persistent_mct_channel_data *data = &persistent_data->node[node].channel[channel];
- if (!persistent_data->node[node].node_present)
- continue;
-
- /* ECC scrub location */
- write_config32_dct(PCI_DEV(0, 0x18 + node, 3), node, 0, 0x5c, data->f3x5c);
- write_config32_dct(PCI_DEV(0, 0x18 + node, 3), node, 0, 0x60, data->f3x60);
-
- /* ECC scrub rate control */
- write_config32_dct(PCI_DEV(0, 0x18 + node, 3), node, 0, 0x58, data->f3x58);
-
- if (is_fam15h())
- /* Set LockDramCfg and CC6SaveEn */
- write_config32_dct(PCI_DEV(0, 0x18 + node, 2), node, channel, 0x118, data->f2x118);
- }
- }
-}
-
-int8_t save_mct_information_to_nvram(void)
-{
- uint8_t nvram;
- uint8_t restored = 0;
-
- if (acpi_is_wakeup_s3())
- return 0;
-
- printk(BIOS_DEBUG, "Writing AMD DCT configuration to Flash\n");
-
- struct spi_flash flash;
- ssize_t s3nv_offset;
- struct amd_s3_persistent_data *persistent_data;
-
- /* Allocate temporary data structures */
- persistent_data = malloc(sizeof(struct amd_s3_persistent_data));
- if (!persistent_data) {
- printk(BIOS_DEBUG, "Could not allocate S3 data structure in RAM\n");
- return -1;
- }
-
- /* Obtain MCT configuration data */
- copy_mct_data_to_save_variable(persistent_data);
-
- /* Save RAM SPD data at the same time */
- copy_cbmem_spd_data_to_save_variable(persistent_data, &restored);
-
- if (restored) {
- /* Allow training bypass if DIMM configuration is unchanged on next boot */
- nvram = 1;
- set_option("allow_spd_nvram_cache_restore", &nvram);
-
- printk(BIOS_DEBUG, "Hardware configuration unchanged since last boot; skipping write\n");
- free(persistent_data);
- return 0;
- }
-
- /* Obtain CBFS file offset */
- s3nv_offset = get_s3nv_file_offset();
- if (s3nv_offset == -1) {
- free(persistent_data);
- return -1;
- }
-
- /* Align flash pointer to nearest boundary */
- s3nv_offset &= ~(CONFIG_S3_DATA_SIZE-1);
- s3nv_offset += CONFIG_S3_DATA_SIZE;
-
- /* Initialize SPI and detect devices */
- spi_init();
- if (spi_flash_probe(0, 0, &flash)) {
- printk(BIOS_DEBUG, "Could not find SPI device\n");
- return -1;
- }
-
- spi_flash_volatile_group_begin(&flash);
-
- /* Erase and write data structure */
- spi_flash_erase(&flash, s3nv_offset, CONFIG_S3_DATA_SIZE);
- spi_flash_write(&flash, s3nv_offset,
- sizeof(struct amd_s3_persistent_data), persistent_data);
-
- /* Deallocate temporary data structures */
- free(persistent_data);
-
- spi_flash_volatile_group_end(&flash);
-
- /* Allow training bypass if DIMM configuration is unchanged on next boot */
- nvram = 1;
- set_option("allow_spd_nvram_cache_restore", &nvram);
-
- return 0;
-}
-
-int8_t restore_mct_information_from_nvram(uint8_t training_only)
-{
- struct amd_s3_persistent_data *persistent_data;
-
- persistent_data = map_s3nv_in_nvram();
- if (!persistent_data)
- return -1;
-
- restore_mct_data_from_save_variable(persistent_data, training_only);
-
- return 0;
-}
-
-void calculate_and_store_spd_hashes(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat)
-{
- uint8_t dimm;
-
- for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) {
- calculate_spd_hash(pDCTstat->spd_data.spd_bytes[dimm], &pDCTstat->spd_data.spd_hash[dimm]);
- }
-}
-
-void compare_nvram_spd_hashes(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat)
-{
- uint8_t dimm;
-
- pDCTstat->spd_data.nvram_spd_match = 1;
- for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm++) {
- if (pDCTstat->spd_data.spd_hash[dimm] != pDCTstat->spd_data.nvram_spd_hash[dimm])
- pDCTstat->spd_data.nvram_spd_match = 0;
- }
-}
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/s3utils.h b/src/northbridge/amd/amdmct/mct_ddr3/s3utils.h
deleted file mode 100644
index d13cb23c80..0000000000
--- a/src/northbridge/amd/amdmct/mct_ddr3/s3utils.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
- *
- * 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.
- */
-#ifndef S3UTILS_H
-#define S3UTILS_H
-
-#include "../wrappers/mcti.h"
-#include "mct_d.h"
-
-#ifdef __RAMSTAGE__
-int8_t save_mct_information_to_nvram(void);
-void copy_mct_data_to_save_variable(struct amd_s3_persistent_data* persistent_data);
-#endif
-
-void calculate_and_store_spd_hashes(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat);
-void compare_nvram_spd_hashes(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstat);
-
-#endif