From 75a3d1fb7c31bc5bd287bf6579ff70c5da9275a7 Mon Sep 17 00:00:00 2001 From: Damien Zammit Date: Mon, 28 Nov 2016 00:29:10 +1100 Subject: amdfam10: Perform major include ".c" cleanup Previously, all romstages for this northbridge family would compile via 1 single C file with everything included into the romstage.c file (!) This patch separates the build into separate .o modules and links them accordingly. Currently compiles and links all fam10 roms without breaking other roms. Both DDR2 and DDR3 have been completed TESTED on REACTS: passes all boot tests for 2 boards ASUS KGPE-D16 ASUS KFSN4-DRE Some extra changes were required to make it compile otherwise there were unused functions in included "c" files. This is because I needed to exchange CIMX for the native southbridge routines. See in particular: advansus/a785e-i asus/m5a88-v avalue/eax-785e A followup patch may be required to fix the above boards. See FIXME, XXX tags Change-Id: Id0f9849578fd0f8b1eab83aed910902c27354426 Signed-off-by: Damien Zammit Reviewed-on: https://review.coreboot.org/17625 Tested-by: build bot (Jenkins) Tested-by: Raptor Engineering Automated Test Stand Reviewed-by: Timothy Pearson --- src/northbridge/amd/amdmct/amddefs.h | 28 ++ src/northbridge/amd/amdmct/mct/Makefile.inc | 16 + src/northbridge/amd/amdmct/mct/mct_d.c | 29 +- src/northbridge/amd/amdmct/mct/mct_d.h | 47 ++- src/northbridge/amd/amdmct/mct/mct_d_gcc.c | 351 +++++++++++++++++++++ src/northbridge/amd/amdmct/mct/mct_d_gcc.h | 368 ++--------------------- src/northbridge/amd/amdmct/mct/mctardk3.c | 2 + src/northbridge/amd/amdmct/mct/mctardk4.c | 2 + src/northbridge/amd/amdmct/mct/mctchi_d.c | 2 +- src/northbridge/amd/amdmct/mct/mctcsi_d.c | 1 + src/northbridge/amd/amdmct/mct/mctdqs_d.c | 28 +- src/northbridge/amd/amdmct/mct/mcthdi.c | 1 + src/northbridge/amd/amdmct/mct/mctndi_d.c | 2 +- src/northbridge/amd/amdmct/mct/mctpro_d.c | 15 +- src/northbridge/amd/amdmct/mct/mctsrc.c | 10 +- src/northbridge/amd/amdmct/mct/mctsrc1p.c | 1 + src/northbridge/amd/amdmct/mct/mcttmrl.c | 2 + src/northbridge/amd/amdmct/mct_ddr3/Makefile.inc | 31 ++ src/northbridge/amd/amdmct/mct_ddr3/mct_d.c | 135 +++------ src/northbridge/amd/amdmct/mct_ddr3/mct_d.h | 137 ++++++++- src/northbridge/amd/amdmct/mct_ddr3/mct_d_gcc.c | 296 ++++++++++++++++++ src/northbridge/amd/amdmct/mct_ddr3/mct_d_gcc.h | 325 ++------------------ src/northbridge/amd/amdmct/mct_ddr3/mctardk5.c | 19 ++ src/northbridge/amd/amdmct/mct_ddr3/mctchi_d.c | 5 + src/northbridge/amd/amdmct/mct_ddr3/mctcsi_d.c | 6 + src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c | 69 +++-- src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c | 19 ++ src/northbridge/amd/amdmct/mct_ddr3/mcthdi.c | 4 + src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c | 32 +- src/northbridge/amd/amdmct/mct_ddr3/mctmtr_d.c | 5 + src/northbridge/amd/amdmct/mct_ddr3/mctndi_d.c | 6 + src/northbridge/amd/amdmct/mct_ddr3/mctprob.c | 6 + src/northbridge/amd/amdmct/mct_ddr3/mctproc.c | 6 + src/northbridge/amd/amdmct/mct_ddr3/mctprod.c | 6 + src/northbridge/amd/amdmct/mct_ddr3/mctrci.c | 21 ++ src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c | 38 ++- src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c | 45 ++- src/northbridge/amd/amdmct/mct_ddr3/mctsrc1p.c | 21 ++ src/northbridge/amd/amdmct/mct_ddr3/mcttmrl.c | 6 + src/northbridge/amd/amdmct/mct_ddr3/mctwl.c | 21 +- src/northbridge/amd/amdmct/mct_ddr3/mhwlc_d.c | 32 +- src/northbridge/amd/amdmct/mct_ddr3/modtrd.c | 10 +- src/northbridge/amd/amdmct/mct_ddr3/modtrdim.c | 37 +-- src/northbridge/amd/amdmct/mct_ddr3/mport_d.c | 11 +- src/northbridge/amd/amdmct/mct_ddr3/mutilc_d.c | 49 +-- src/northbridge/amd/amdmct/mct_ddr3/mwlc_d.h | 26 ++ src/northbridge/amd/amdmct/mct_ddr3/s3utils.c | 31 +- src/northbridge/amd/amdmct/mct_ddr3/s3utils.h | 20 +- src/northbridge/amd/amdmct/wrappers/Makefile.inc | 5 + src/northbridge/amd/amdmct/wrappers/mcti.h | 78 ++++- src/northbridge/amd/amdmct/wrappers/mcti_d.c | 106 ++++--- 51 files changed, 1557 insertions(+), 1012 deletions(-) create mode 100644 src/northbridge/amd/amdmct/mct/Makefile.inc create mode 100644 src/northbridge/amd/amdmct/mct/mct_d_gcc.c create mode 100644 src/northbridge/amd/amdmct/mct_ddr3/Makefile.inc create mode 100644 src/northbridge/amd/amdmct/mct_ddr3/mct_d_gcc.c create mode 100644 src/northbridge/amd/amdmct/wrappers/Makefile.inc (limited to 'src/northbridge/amd/amdmct') diff --git a/src/northbridge/amd/amdmct/amddefs.h b/src/northbridge/amd/amdmct/amddefs.h index 9d3e86a2a1..58f43f1500 100644 --- a/src/northbridge/amd/amdmct/amddefs.h +++ b/src/northbridge/amd/amdmct/amddefs.h @@ -13,6 +13,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ +#ifndef AMDDEFS_H +#define AMDDEFS_H /* FIXME: this file should be moved to include/cpu/amd/amddefs.h */ @@ -163,3 +165,29 @@ #define AMD_PKGTYPE_ASB2 4 #define AMD_PKGTYPE_C32 5 #define AMD_PKGTYPE_FM2 6 + +//DDR2 REG and unbuffered : Socket F 1027 and AM3 +/* every channel have 4 DDR2 DIMM for socket F + * 2 for socket M2/M3 + * 1 for socket s1g1 + */ +#define DIMM_SOCKETS 4 +struct mem_controller { + u32 node_id; + pci_devfn_t f0, f1, f2, f3, f4, f5; + /* channel0 is DCT0 --- channelA + * channel1 is DCT1 --- channelB + * can be ganged, a single dual-channel DCT ---> 128 bit + * or unganged a two single-channel DCTs ---> 64bit + * When the DCTs are ganged, the writes to DCT1 set of registers + * (F2x1XX) are ignored and reads return all 0's + * The exception is the DCT phy registers, F2x[1,0]98, F2x[1,0]9C, + * and all the associated indexed registers, are still + * independently accessiable + */ + /* FIXME: I will only support ganged mode for easy support */ + u8 spd_switch_addr; + u8 spd_addr[DIMM_SOCKETS*2]; +}; + +#endif diff --git a/src/northbridge/amd/amdmct/mct/Makefile.inc b/src/northbridge/amd/amdmct/mct/Makefile.inc new file mode 100644 index 0000000000..f986201c6d --- /dev/null +++ b/src/northbridge/amd/amdmct/mct/Makefile.inc @@ -0,0 +1,16 @@ +ifeq ($(CONFIG_NORTHBRIDGE_AMD_AMDFAM10),y) + +# DDR2 +romstage-y += mct_d.c mct_d_gcc.c mctcsi_d.c mctmtr_d.c mctecc_d.c +romstage-y += mctpro_d.c mctdqs_d.c mctsrc.c mctsrc1p.c mcttmrl.c +romstage-y += mcthdi.c mctndi_d.c mctchi_d.c + +ifeq ($(CONFIG_CPU_SOCKET_TYPE), 0x10) +romstage-y += mctardk3.c +endif + +ifeq ($(CONFIG_CPU_SOCKET_TYPE), 0x11) +romstage-y += mctardk4.c +endif + +endif diff --git a/src/northbridge/amd/amdmct/mct/mct_d.c b/src/northbridge/amd/amdmct/mct/mct_d.c index 62fc626e8a..73aa20b329 100644 --- a/src/northbridge/amd/amdmct/mct/mct_d.c +++ b/src/northbridge/amd/amdmct/mct/mct_d.c @@ -33,6 +33,8 @@ * supported. */ +#include "mct_d.h" + static u8 ReconfigureDIMMspare_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); static void DQSTiming_D(struct MCTStatStruc *pMCTstat, @@ -41,15 +43,8 @@ static void LoadDQSSigTmgRegs_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); static void HTMemMapInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); -static void MCTMemClr_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA); -static void DCTMemClr_Init_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); static void DCTMemClr_Sync_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat); -static void MCTMemClrSync_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA); -static u8 NodePresent_D(u8 Node); static void SyncDCTsReady_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); static void StartupDCT_D(struct MCTStatStruc *pMCTstat, @@ -66,6 +61,8 @@ static u8 AutoConfig_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct); static u8 PlatformSpec_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct); +static u8 mct_PlatformSpec(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, @@ -81,8 +78,6 @@ static void mct_initDCT(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat); static void mct_DramInit(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct); -static u8 mct_PlatformSpec(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); @@ -175,7 +170,9 @@ 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}; -static void mctAutoInitMCT_D(struct MCTStatStruc *pMCTstat, +const u8 Table_DQSRcvEn_Offset[] = {0x00,0x01,0x10,0x11,0x2}; + +void mctAutoInitMCT_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA) { /* @@ -661,7 +658,7 @@ static void HTMemMapInit_D(struct MCTStatStruc *pMCTstat, } -static void MCTMemClr_D(struct MCTStatStruc *pMCTstat, +void MCTMemClr_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA) { @@ -693,7 +690,7 @@ static void MCTMemClr_D(struct MCTStatStruc *pMCTstat, } -static void DCTMemClr_Init_D(struct MCTStatStruc *pMCTstat, +void DCTMemClr_Init_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat) { u32 val; @@ -716,7 +713,7 @@ static void DCTMemClr_Init_D(struct MCTStatStruc *pMCTstat, } -static void MCTMemClrSync_D(struct MCTStatStruc *pMCTstat, +void MCTMemClrSync_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA) { /* Ensures that memory clear has completed on all node.*/ @@ -768,7 +765,7 @@ static void DCTMemClr_Sync_D(struct MCTStatStruc *pMCTstat, } -static u8 NodePresent_D(u8 Node) +u8 NodePresent_D(u8 Node) { /* * Determine if a single Hammer Node exists within the network. @@ -3655,7 +3652,7 @@ static void mct_BeforeDramInit_Prod_D(struct MCTStatStruc *pMCTstat, } -static void mct_AdjustDelayRange_D(struct MCTStatStruc *pMCTstat, +void mct_AdjustDelayRange_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 *dqs_pos) { // FIXME: Skip for Ax @@ -3907,7 +3904,7 @@ static void mct_ResetDLL_D(struct MCTStatStruc *pMCTstat, } -static void mct_EnableDatIntlv_D(struct MCTStatStruc *pMCTstat, +void mct_EnableDatIntlv_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat) { u32 dev = pDCTstat->dev_dct; diff --git a/src/northbridge/amd/amdmct/mct/mct_d.h b/src/northbridge/amd/amdmct/mct/mct_d.h index 4e1a909472..75c4d6278e 100644 --- a/src/northbridge/amd/amdmct/mct/mct_d.h +++ b/src/northbridge/amd/amdmct/mct/mct_d.h @@ -20,7 +20,18 @@ #ifndef MCT_D_H #define MCT_D_H +#define DQS_TRAIN_DEBUG 0 +#include +#include "mct_d_gcc.h" +#include +#include +#include + +extern const u8 Table_DQSRcvEn_Offset[]; +extern const u32 TestPattern0_D[]; +extern const u32 TestPattern1_D[]; +extern const u32 TestPattern2_D[]; /*=========================================================================== CPU - K8/FAM10 @@ -689,6 +700,8 @@ struct DCTStatStruc { /* A per Node structure*/ #define NV_MAX_DIMMS_PER_CH 64 /* Maximum number of DIMMs per channel */ +#include + /*=============================================================================== CBMEM storage ===============================================================================*/ @@ -735,9 +748,6 @@ void mct_TrainRcvrEn_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTs 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 mctGet_DIMMAddr(struct DCTStatStruc *pDCTstat, u32 node); -void mctSMBhub_Init(u32 node); -int mctRead_SPD(u32 smaddr, u32 reg); 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); @@ -753,4 +763,35 @@ u8 mct_RcvrRankEnabled_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDC 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 EarlySampleSupport_D(void); + +void mctAutoInitMCT_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); +void mct_AdjustDelayRange_D(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstat, u8 *dqs_pos); +void mct_EnableDatIntlv_D(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstat); +void MCTMemClrSync_D(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstatA); +void beforeInterleaveChannels_D(struct DCTStatStruc *pDCTstatA, u8 *enabled); +u8 mct_checkFenceHoleAdjust_D(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstat, u8 DQSDelay, + u8 ChipSel, u8 *result); +void proc_IOCLFLUSH_D(u32 addr_hi); +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 MCTMemClr_D(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstatA); +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, u32 index_reg, u32 index); +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); #endif diff --git a/src/northbridge/amd/amdmct/mct/mct_d_gcc.c b/src/northbridge/amd/amdmct/mct/mct_d_gcc.c new file mode 100644 index 0000000000..59618f6cc0 --- /dev/null +++ b/src/northbridge/amd/amdmct/mct/mct_d_gcc.c @@ -0,0 +1,351 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 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 "mct_d_gcc.h" + +inline void _WRMSR(u32 addr, u32 lo, u32 hi) +{ + __asm__ volatile ( + "wrmsr" + : + :"c"(addr),"a"(lo), "d" (hi) + ); +} + + +inline void _RDMSR(u32 addr, u32 *lo, u32 *hi) +{ + __asm__ volatile ( + "rdmsr" + :"=a"(*lo), "=d" (*hi) + :"c"(addr) + ); +} + + +inline void _RDTSC(u32 *lo, u32 *hi) +{ + __asm__ volatile ( + "rdtsc" + : "=a" (*lo), "=d"(*hi) + ); +} + + +inline 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< + +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) +{ + __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" (16), "c" (line_num * 4), "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; +} + +#ifdef UNUSED_CODE +static u8 read8_fs(u32 addr_lo) +{ + u8 byte; + __asm__ volatile ( + "outb %%al, $0xed\n\t" /* _EXECFENCE */ + "movb %%fs:(%1), %b0\n\t" + "mfence\n\t" + :"=b"(byte): "a" (addr_lo) + ); + return byte; +} +#endif + +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 ReadL18TestPattern(u32 addr_lo) +{ + // set fs and use fs prefix to access the mem + __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 + "movl %%fs:64(%%esi), %%eax\n\t" //+3 + + "movl %%fs:-128(%%edi), %%eax\n\t" //+4 + "movl %%fs:-64(%%edi), %%eax\n\t" //+5 + "movl %%fs:(%%edi), %%eax\n\t" //+6 + "movl %%fs:64(%%edi), %%eax\n\t" //+7 + + "movl %%fs:-128(%%ebx), %%eax\n\t" //+8 + "movl %%fs:-64(%%ebx), %%eax\n\t" //+9 + "movl %%fs:(%%ebx), %%eax\n\t" //+10 + "movl %%fs:64(%%ebx), %%eax\n\t" //+11 + + "movl %%fs:-128(%%ecx), %%eax\n\t" //+12 + "movl %%fs:-64(%%ecx), %%eax\n\t" //+13 + "movl %%fs:(%%ecx), %%eax\n\t" //+14 + "movl %%fs:64(%%ecx), %%eax\n\t" //+15 + + "movl %%fs:-128(%%edx), %%eax\n\t" //+16 + "movl %%fs:-64(%%edx), %%eax\n\t" //+17 + "mfence\n\t" + + :: "a"(0), "b" (addr_lo+128+8*64), "c" (addr_lo+128+12*64), + "d" (addr_lo +128+16*64), "S"(addr_lo+128), + "D"(addr_lo+128+4*64) + ); + +} + +void ReadL9TestPattern(u32 addr_lo) +{ + + // set fs and use fs prefix to access the mem + __asm__ volatile ( + "outb %%al, $0xed\n\t" /* _EXECFENCE */ + + "movl %%fs:-128(%%ecx), %%eax\n\t" //TestAddr cache line + "movl %%fs:-64(%%ecx), %%eax\n\t" //+1 + "movl %%fs:(%%ecx), %%eax\n\t" //+2 + "movl %%fs:64(%%ecx), %%eax\n\t" //+3 + + "movl %%fs:-128(%%edx), %%eax\n\t" //+4 + "movl %%fs:-64(%%edx), %%eax\n\t" //+5 + "movl %%fs:(%%edx), %%eax\n\t" //+6 + "movl %%fs:64(%%edx), %%eax\n\t" //+7 + + "movl %%fs:-128(%%ebx), %%eax\n\t" //+8 + "mfence\n\t" + + :: "a"(0), "b" (addr_lo+128+8*64), "c"(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) +{ + 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<<8), "d" (16), "c" (3 * 4), "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 const *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/mct_d_gcc.h b/src/northbridge/amd/amdmct/mct/mct_d_gcc.h index fbfe988ab2..0b9a7d19f1 100644 --- a/src/northbridge/amd/amdmct/mct/mct_d_gcc.h +++ b/src/northbridge/amd/amdmct/mct/mct_d_gcc.h @@ -13,362 +13,36 @@ * GNU General Public License for more details. */ +#ifndef MCT_D_GCC_H +#define MCT_D_GCC_H -static inline void _WRMSR(u32 addr, u32 lo, u32 hi) -{ - __asm__ volatile ( - "wrmsr" - : - :"c"(addr),"a"(lo), "d" (hi) - ); -} +#include - -static inline void _RDMSR(u32 addr, u32 *lo, u32 *hi) -{ - __asm__ volatile ( - "rdmsr" - :"=a"(*lo), "=d" (*hi) - :"c"(addr) - ); -} - - -static inline void _RDTSC(u32 *lo, u32 *hi) -{ - __asm__ volatile ( - "rdtsc" - : "=a" (*lo), "=d"(*hi) - ); -} - - -static inline void _cpu_id(u32 addr, u32 *val) -{ - __asm__ volatile( - "cpuid" - : "=a" (val[0]), - "=b" (val[1]), - "=c" (val[2]), - "=d" (val[3]) - : "0" (addr)); - -} - - -static u32 bsr(u32 x) -{ - u8 i; - u32 ret = 0; - - for (i = 31; i > 0; i--) { - if (x & (1< - u32 SetUpperFSbase(u32 addr_hi); +void proc_CLFLUSH(u32 addr_hi); +void WriteLNTestPattern(u32 addr_lo, u8 *buf_a, u32 line_num); +u32 read32_fs(u32 addr_lo); +void FlushDQSTestPattern_L9(u32 addr_lo); +__attribute__((noinline)) void FlushDQSTestPattern_L18(u32 addr_lo); +void ReadL18TestPattern(u32 addr_lo); +void ReadL9TestPattern(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 const *p); +u8 oemNodePresent_D(u8 Node, u8 *ret); - -static 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) - ); -} - - -static void WriteLNTestPattern(u32 addr_lo, u8 *buf_a, u32 line_num) -{ - __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" (16), "c" (line_num * 4), "b"(buf_a) - ); - -} - - -static 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; -} - -#ifdef UNUSED_CODE -static u8 read8_fs(u32 addr_lo) -{ - u8 byte; - __asm__ volatile ( - "outb %%al, $0xed\n\t" /* _EXECFENCE */ - "movb %%fs:(%1), %b0\n\t" - "mfence\n\t" - :"=b"(byte): "a" (addr_lo) - ); - return byte; -} #endif - -static 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) - ); - -} - - -static __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) - ); -} - - -static void ReadL18TestPattern(u32 addr_lo) -{ - // set fs and use fs prefix to access the mem - __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 - "movl %%fs:64(%%esi), %%eax\n\t" //+3 - - "movl %%fs:-128(%%edi), %%eax\n\t" //+4 - "movl %%fs:-64(%%edi), %%eax\n\t" //+5 - "movl %%fs:(%%edi), %%eax\n\t" //+6 - "movl %%fs:64(%%edi), %%eax\n\t" //+7 - - "movl %%fs:-128(%%ebx), %%eax\n\t" //+8 - "movl %%fs:-64(%%ebx), %%eax\n\t" //+9 - "movl %%fs:(%%ebx), %%eax\n\t" //+10 - "movl %%fs:64(%%ebx), %%eax\n\t" //+11 - - "movl %%fs:-128(%%ecx), %%eax\n\t" //+12 - "movl %%fs:-64(%%ecx), %%eax\n\t" //+13 - "movl %%fs:(%%ecx), %%eax\n\t" //+14 - "movl %%fs:64(%%ecx), %%eax\n\t" //+15 - - "movl %%fs:-128(%%edx), %%eax\n\t" //+16 - "movl %%fs:-64(%%edx), %%eax\n\t" //+17 - "mfence\n\t" - - :: "a"(0), "b" (addr_lo+128+8*64), "c" (addr_lo+128+12*64), - "d" (addr_lo +128+16*64), "S"(addr_lo+128), - "D"(addr_lo+128+4*64) - ); - -} - - -static void ReadL9TestPattern(u32 addr_lo) -{ - - // set fs and use fs prefix to access the mem - __asm__ volatile ( - "outb %%al, $0xed\n\t" /* _EXECFENCE */ - - "movl %%fs:-128(%%ecx), %%eax\n\t" //TestAddr cache line - "movl %%fs:-64(%%ecx), %%eax\n\t" //+1 - "movl %%fs:(%%ecx), %%eax\n\t" //+2 - "movl %%fs:64(%%ecx), %%eax\n\t" //+3 - - "movl %%fs:-128(%%edx), %%eax\n\t" //+4 - "movl %%fs:-64(%%edx), %%eax\n\t" //+5 - "movl %%fs:(%%edx), %%eax\n\t" //+6 - "movl %%fs:64(%%edx), %%eax\n\t" //+7 - - "movl %%fs:-128(%%ebx), %%eax\n\t" //+8 - "mfence\n\t" - - :: "a"(0), "b" (addr_lo+128+8*64), "c"(addr_lo+128), - "d"(addr_lo+128+4*64) - ); - -} - - -static 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) - ); - -} - - -static void WriteMaxRdLat1CLTestPattern_D(u32 buf, u32 addr) -{ - 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<<8), "d" (16), "c" (3 * 4), "b"(buf) - ); -} - - -static 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) - ); -} - - -static u32 stream_to_int(u8 const *p) -{ - int i; - u32 val; - u32 valx; - - val = 0; - - for (i = 3; i >= 0; i--) { - val <<= 8; - valx = *(p+i); - val |= valx; - } - - return val; -} - - -#ifdef UNUSED_CODE -static void oemSet_NB32(u32 addr, u32 val, u8 *valid) -{ -} - - -static u32 oemGet_NB32(u32 addr, u8 *valid) -{ - *valid = 0; - return 0xffffffff; -} -#endif - - -static u8 oemNodePresent_D(u8 Node, u8 *ret) -{ - *ret = 0; - return 0; -} diff --git a/src/northbridge/amd/amdmct/mct/mctardk3.c b/src/northbridge/amd/amdmct/mct/mctardk3.c index e2903337f9..fe57d31f05 100644 --- a/src/northbridge/amd/amdmct/mct/mctardk3.c +++ b/src/northbridge/amd/amdmct/mct/mctardk3.c @@ -13,6 +13,8 @@ * GNU General Public License for more details. */ +#include +#include "mct_d.h" static void Get_ChannelPS_Cfg0_D(u8 MAAdimms, u8 Speed, u8 MAAload, u8 DATAAload, u32 *AddrTmgCTL, u32 *ODC_CTL); diff --git a/src/northbridge/amd/amdmct/mct/mctardk4.c b/src/northbridge/amd/amdmct/mct/mctardk4.c index 8815943c72..b35f7baa07 100644 --- a/src/northbridge/amd/amdmct/mct/mctardk4.c +++ b/src/northbridge/amd/amdmct/mct/mctardk4.c @@ -13,6 +13,8 @@ * GNU General Public License for more details. */ +#include +#include "mct_d.h" static void Get_ChannelPS_Cfg0_D(u8 MAAdimms, u8 Speed, u8 MAAload, u8 DATAAload, u32 *AddrTmgCTL, u32 *ODC_CTL, diff --git a/src/northbridge/amd/amdmct/mct/mctchi_d.c b/src/northbridge/amd/amdmct/mct/mctchi_d.c index 705bd915f4..d2acc15118 100644 --- a/src/northbridge/amd/amdmct/mct/mctchi_d.c +++ b/src/northbridge/amd/amdmct/mct/mctchi_d.c @@ -13,7 +13,7 @@ * GNU General Public License for more details. */ - +#include "mct_d.h" void InterleaveChannels_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA) diff --git a/src/northbridge/amd/amdmct/mct/mctcsi_d.c b/src/northbridge/amd/amdmct/mct/mctcsi_d.c index 1c86239cfc..6a19788ab3 100644 --- a/src/northbridge/amd/amdmct/mct/mctcsi_d.c +++ b/src/northbridge/amd/amdmct/mct/mctcsi_d.c @@ -13,6 +13,7 @@ * GNU General Public License for more details. */ +#include "mct_d.h" /* 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 diff --git a/src/northbridge/amd/amdmct/mct/mctdqs_d.c b/src/northbridge/amd/amdmct/mct/mctdqs_d.c index 63631623cf..ec77c490d7 100644 --- a/src/northbridge/amd/amdmct/mct/mctdqs_d.c +++ b/src/northbridge/amd/amdmct/mct/mctdqs_d.c @@ -13,6 +13,9 @@ * GNU General Public License for more details. */ +#include "mct_d.h" +#include +#include static void CalcEccDQSPos_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u16 like, @@ -38,30 +41,20 @@ static u8 CompareDQSTestPattern_D(struct MCTStatStruc *pMCTstat, u32 addr_lo); static void FlushDQSTestPattern_D(struct DCTStatStruc *pDCTstat, u32 addr_lo); -static void SetTargetWTIO_D(u32 TestAddr); -static void ResetTargetWTIO_D(void); static void ReadDQSTestPattern_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u32 TestAddr_lo); -void ResetDCTWrPtr_D(u32 dev, u32 index_reg, u32 index); -u8 mct_DisableDimmEccEn_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); static void mct_SetDQSDelayCSR_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 ChipSel); static void mct_SetDQSDelayAllCSR_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 cs_start); -u32 mct_GetMCTSysAddr_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 Channel, - u8 receiver, u8 *valid); static void SetupDqsPattern_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u32 *buffer); -#define DQS_TRAIN_DEBUG 0 - -static void print_debug_dqs(const char *str, u32 val, u8 level) +void print_debug_dqs(const char *str, u32 val, u8 level) { #if DQS_TRAIN_DEBUG > 0 if (DQS_TRAIN_DEBUG >= level) { @@ -70,7 +63,7 @@ static void print_debug_dqs(const char *str, u32 val, u8 level) #endif } -static void print_debug_dqs_pair(const char *str, u32 val, const char *str2, u32 val2, u8 level) +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) { @@ -193,9 +186,6 @@ static const u32 TestPatternJD1b_D[] = { 0x80808080,0x80808080,0x80808080,0x80808080 /* QW7,CHA-B, DQ7-ODD */ }; -const u8 Table_DQSRcvEn_Offset[] = {0x00,0x01,0x10,0x11}; - - void TrainReceiverEn_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA, u8 Pass) { @@ -653,7 +643,7 @@ static void TrainWriteDQS_D(struct MCTStatStruc *pMCTstat, } -static void proc_IOCLFLUSH_D(u32 addr_hi) +void proc_IOCLFLUSH_D(u32 addr_hi) { SetTargetWTIO_D(addr_hi); proc_CLFLUSH(addr_hi); @@ -820,7 +810,7 @@ static void FlushDQSTestPattern_D(struct DCTStatStruc *pDCTstat, } } -static void SetTargetWTIO_D(u32 TestAddr) +void SetTargetWTIO_D(u32 TestAddr) { u32 lo, hi; hi = TestAddr >> 24; @@ -832,7 +822,7 @@ static void SetTargetWTIO_D(u32 TestAddr) } -static void ResetTargetWTIO_D(void) +void ResetTargetWTIO_D(void) { u32 lo, hi; @@ -1173,7 +1163,7 @@ exitGetAddr: } -static void mct_Write1LTestPattern_D(struct MCTStatStruc *pMCTstat, +void mct_Write1LTestPattern_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u32 TestAddr, u8 pattern) { diff --git a/src/northbridge/amd/amdmct/mct/mcthdi.c b/src/northbridge/amd/amdmct/mct/mcthdi.c index d9d87af82e..b67282ef60 100644 --- a/src/northbridge/amd/amdmct/mct/mcthdi.c +++ b/src/northbridge/amd/amdmct/mct/mcthdi.c @@ -13,6 +13,7 @@ * GNU General Public License for more details. */ +#include "mct_d.h" void mct_DramInit_Hw_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct) diff --git a/src/northbridge/amd/amdmct/mct/mctndi_d.c b/src/northbridge/amd/amdmct/mct/mctndi_d.c index 389d56b77f..3f09f4a472 100644 --- a/src/northbridge/amd/amdmct/mct/mctndi_d.c +++ b/src/northbridge/amd/amdmct/mct/mctndi_d.c @@ -14,7 +14,7 @@ * GNU General Public License for more details. */ - +#include "mct_d.h" void InterleaveNodes_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA) diff --git a/src/northbridge/amd/amdmct/mct/mctpro_d.c b/src/northbridge/amd/amdmct/mct/mctpro_d.c index 6802a76dec..0acb6f4ff4 100644 --- a/src/northbridge/amd/amdmct/mct/mctpro_d.c +++ b/src/northbridge/amd/amdmct/mct/mctpro_d.c @@ -14,6 +14,8 @@ * GNU General Public License for more details. */ +#include "mct_d.h" + void EarlySampleSupport_D(void) { } @@ -321,7 +323,7 @@ static u8 mct_AdjustDelay_D(struct DCTStatStruc *pDCTstat, u8 dly) } #endif -static u8 mct_checkFenceHoleAdjust_D(struct MCTStatStruc *pMCTstat, +u8 mct_checkFenceHoleAdjust_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 DQSDelay, u8 ChipSel, u8 *result) { @@ -365,12 +367,6 @@ u8 mct_AdjustDQSPosDelay_D(struct DCTStatStruc *pDCTstat, u8 dly) } -static void beforeInterleaveChannels_D(struct DCTStatStruc *pDCTstatA, u8 *enabled) { - - if (pDCTstatA->LogicalCPUID & (AMD_DR_Ax)) - *enabled = 0; -} - #ifdef UNUSED_CODE static u8 mctDoAxRdPtrInit_D(struct DCTStatStruc *pDCTstat, u8 *Rdtr) { @@ -394,3 +390,8 @@ void mct_AdjustScrub_D(struct DCTStatStruc *pDCTstat, u16 *scrub_request) { pDCTstat->ErrStatus |= 1 << SB_DCBKScrubDis; } } + +void beforeInterleaveChannels_D(struct DCTStatStruc *pDCTstatA, u8 *enabled) { + if (pDCTstatA->LogicalCPUID & (AMD_DR_Ax)) + *enabled = 0; +} diff --git a/src/northbridge/amd/amdmct/mct/mctsrc.c b/src/northbridge/amd/amdmct/mct/mctsrc.c index a87cea81c0..3b7cff87db 100644 --- a/src/northbridge/amd/amdmct/mct/mctsrc.c +++ b/src/northbridge/amd/amdmct/mct/mctsrc.c @@ -14,6 +14,9 @@ * GNU General Public License for more details. */ +#include "mct_d.h" +#include + /****************************************************************************** Description: Receiver En and DQS Timing Training feature for DDR 2 MCT ******************************************************************************/ @@ -43,22 +46,21 @@ static void fenceDynTraining_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct); static void mct_DisableDQSRcvEn_D(struct DCTStatStruc *pDCTstat); - /* Warning: These must be located so they do not cross a logical 16-bit segment boundary! */ -static const u32 TestPattern0_D[] = { +const u32 TestPattern0_D[] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, }; -static const u32 TestPattern1_D[] = { +const u32 TestPattern1_D[] = { 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, }; -static const u32 TestPattern2_D[] = { +const u32 TestPattern2_D[] = { 0x12345678, 0x87654321, 0x23456789, 0x98765432, 0x59385824, 0x30496724, 0x24490795, 0x99938733, 0x40385642, 0x38465245, 0x29432163, 0x05067894, diff --git a/src/northbridge/amd/amdmct/mct/mctsrc1p.c b/src/northbridge/amd/amdmct/mct/mctsrc1p.c index bfd103b311..31a3a5d21f 100644 --- a/src/northbridge/amd/amdmct/mct/mctsrc1p.c +++ b/src/northbridge/amd/amdmct/mct/mctsrc1p.c @@ -13,6 +13,7 @@ * GNU General Public License for more details. */ +#include "mct_d.h" u8 mct_checkNumberOfDqsRcvEn_1Pass(u8 pass) { diff --git a/src/northbridge/amd/amdmct/mct/mcttmrl.c b/src/northbridge/amd/amdmct/mct/mcttmrl.c index 1095259238..67397fc83a 100644 --- a/src/northbridge/amd/amdmct/mct/mcttmrl.c +++ b/src/northbridge/amd/amdmct/mct/mcttmrl.c @@ -13,6 +13,8 @@ * GNU General Public License for more details. */ +#include "mct_d.h" +#include /* * Description: Max Read Latency Training feature for DDR 2 MCT diff --git a/src/northbridge/amd/amdmct/mct_ddr3/Makefile.inc b/src/northbridge/amd/amdmct/mct_ddr3/Makefile.inc new file mode 100644 index 0000000000..65c146a662 --- /dev/null +++ b/src/northbridge/amd/amdmct/mct_ddr3/Makefile.inc @@ -0,0 +1,31 @@ +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 index f3fba25ca1..d1d6e8f455 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c @@ -32,7 +32,17 @@ * supported. */ +#include "mct_d_gcc.h" +#include "mct_d.h" +#include +#include +#include +#include #include +#include +#include +#include +#include "s3utils.h" static u8 ReconfigureDIMMspare_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); @@ -43,17 +53,8 @@ static void LoadDQSSigTmgRegs_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); static void HTMemMapInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); -static void MCTMemClr_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA); -static void DCTMemClr_Init_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -static void DCTMemClr_Sync_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -static u8 NodePresent_D(u8 Node); static void SyncDCTsReady_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); -static void StartupDCT_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); static void ClearDCT_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct); static u8 AutoCycTiming_D(struct MCTStatStruc *pMCTstat, @@ -64,8 +65,6 @@ 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 u8 PlatformSpec_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, @@ -78,10 +77,6 @@ static void mct_initDCT(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat); static void mct_DramInit(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct); -static u8 mct_PlatformSpec(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static u8 mct_BeforePlatformSpec(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); @@ -129,8 +124,6 @@ static void SetODTTriState(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct); static void InitDDRPhy(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct); -static void InitPhyCompensation(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); static u32 mct_NodePresent_D(void); static void mct_OtherTiming(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); @@ -153,49 +146,24 @@ static void mct_BeforeDQSTrain_D(struct MCTStatStruc *pMCTstat, static void AfterDramInit_D(struct DCTStatStruc *pDCTstat, u8 dct); static void mct_ResetDLL_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct); -static void ProgDramMRSReg_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static void mct_DramInit_Sw_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); -static void ChangeMemClk(struct MCTStatStruc *pMCTstat, +void ChangeMemClk(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat); -void SetTargetFreq(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA, uint8_t Node); - -static u32 mct_MR1Odt_RDimm(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct, u32 MrsChipSel); -static u32 mct_DramTermDyn_RDimm(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dimm); -static u32 mct_SetDramConfigMisc2(struct DCTStatStruc *pDCTstat, - uint8_t dct, uint32_t misc2, uint32_t DramControl); -static void mct_BeforeDQSTrainSamp(struct DCTStatStruc *pDCTstat); -static void mct_WriteLevelization_HW(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA, uint8_t Pass); + 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); -static void mct_ExtMCTConfig_Bx(struct DCTStatStruc *pDCTstat); -static void mct_ExtMCTConfig_Cx(struct DCTStatStruc *pDCTstat); -static void mct_ExtMCTConfig_Dx(struct DCTStatStruc *pDCTstat); uint8_t is_ecc_enabled(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat); -uint8_t get_available_lane_count(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat); - -static 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); - -static 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); /*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}; -static const u8 Table_DQSRcvEn_Offset[] = {0x00,0x01,0x10,0x11,0x2}; +const u8 Table_DQSRcvEn_Offset[] = {0x00,0x01,0x10,0x11,0x2}; /**************************************************************************** Describe how platform maps MemClk pins to logical DIMMs. The MemClk pins @@ -255,7 +223,7 @@ 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}; -static uint8_t dct_ddr_voltage_index(struct DCTStatStruc *pDCTstat, uint8_t dct) +uint8_t dct_ddr_voltage_index(struct DCTStatStruc *pDCTstat, uint8_t dct) { uint8_t dimm; uint8_t ddr_voltage_index = 0; @@ -354,7 +322,7 @@ uint8_t get_available_lane_count(struct MCTStatStruc *pMCTstat, struct DCTStatSt return 8; } -static uint16_t mhz_to_memclk_config(uint16_t freq) +uint16_t mhz_to_memclk_config(uint16_t freq) { if (is_fam15h()) return fam15h_mhz_to_memclk_config(freq); @@ -362,7 +330,7 @@ static uint16_t mhz_to_memclk_config(uint16_t freq) return fam10h_mhz_to_memclk_config(freq) + 1; } -static uint32_t fam10h_address_timing_compensation_code(struct DCTStatStruc *pDCTstat, uint8_t dct) +uint32_t fam10h_address_timing_compensation_code(struct DCTStatStruc *pDCTstat, uint8_t dct) { uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH); @@ -985,7 +953,7 @@ static uint32_t fam15h_phy_predriver_clk_calibration_code(struct DCTStatStruc *p return calibration_code; } -static uint32_t fam15h_output_driver_compensation_code(struct DCTStatStruc *pDCTstat, uint8_t dct) +uint32_t fam15h_output_driver_compensation_code(struct DCTStatStruc *pDCTstat, uint8_t dct) { uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH); @@ -1367,7 +1335,7 @@ static uint32_t fam15h_output_driver_compensation_code(struct DCTStatStruc *pDCT return calibration_code; } -static uint32_t fam15h_address_timing_compensation_code(struct DCTStatStruc *pDCTstat, uint8_t dct) +uint32_t fam15h_address_timing_compensation_code(struct DCTStatStruc *pDCTstat, uint8_t dct) { uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH); @@ -1756,7 +1724,7 @@ static uint32_t fam15h_address_timing_compensation_code(struct DCTStatStruc *pDC return calibration_code; } -static uint8_t fam15h_slow_access_mode(struct DCTStatStruc *pDCTstat, uint8_t dct) +uint8_t fam15h_slow_access_mode(struct DCTStatStruc *pDCTstat, uint8_t dct) { uint8_t MaxDimmsInstallable = mctGet_NVbits(NV_MAX_DIMMS_PER_CH); @@ -2357,7 +2325,7 @@ static uint8_t fam15h_cs_tristate_enable_code(struct DCTStatStruc *pDCTstat, uin return cs_tristate_code; } -static void set_2t_configuration(struct MCTStatStruc *pMCTstat, +void set_2t_configuration(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct) { printk(BIOS_DEBUG, "%s: Start\n", __func__); @@ -2388,7 +2356,7 @@ static void set_2t_configuration(struct MCTStatStruc *pMCTstat, printk(BIOS_DEBUG, "%s: Done\n", __func__); } -static void precise_ndelay_fam15(struct MCTStatStruc *pMCTstat, uint32_t nanoseconds) { +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; @@ -2402,7 +2370,7 @@ static void precise_ndelay_fam15(struct MCTStatStruc *pMCTstat, uint32_t nanosec } while ((current_timestamp - start_timestamp) < cycle_count); } -static void precise_memclk_delay_fam15(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, uint8_t dct, uint32_t clocks) { +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}; @@ -2451,30 +2419,6 @@ static void dump_spd_bytes(struct MCTStatStruc *pMCTstat, } #endif -#if IS_ENABLED(CONFIG_HAVE_ACPI_RESUME) -static 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]); - } -} - -static 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; - } -} -#endif - static void set_up_cc6_storage_fam15(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, uint8_t num_nodes) { @@ -2599,7 +2543,7 @@ static void set_cc6_save_enable(struct MCTStatStruc *pMCTstat, Set_NB32(pDCTstat->dev_dct, 0x118, dword); } -static void mctAutoInitMCT_D(struct MCTStatStruc *pMCTstat, +void mctAutoInitMCT_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA) { /* @@ -2988,7 +2932,7 @@ static u8 ReconfigureDIMMspare_D(struct MCTStatStruc *pMCTstat, * Write Levelization Training (2.10.5.8.1) * DQS Receiver Enable Training (2.10.5.8.2) */ -static void fam15EnableTrainingMode(struct MCTStatStruc *pMCTstat, +void fam15EnableTrainingMode(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t enable) { uint8_t index; @@ -3987,7 +3931,7 @@ static void HTMemMapInit_D(struct MCTStatStruc *pMCTstat, mct_HTMemMapExt(pMCTstat, pDCTstatA); } -static void MCTMemClr_D(struct MCTStatStruc *pMCTstat, +void MCTMemClr_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA) { @@ -4029,7 +3973,7 @@ static void MCTMemClr_D(struct MCTStatStruc *pMCTstat, } } -static void DCTMemClr_Init_D(struct MCTStatStruc *pMCTstat, +void DCTMemClr_Init_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat) { u32 val; @@ -4055,7 +3999,7 @@ static void DCTMemClr_Init_D(struct MCTStatStruc *pMCTstat, } } -static void DCTMemClr_Sync_D(struct MCTStatStruc *pMCTstat, +void DCTMemClr_Sync_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat) { uint32_t dword; @@ -4089,7 +4033,7 @@ static void DCTMemClr_Sync_D(struct MCTStatStruc *pMCTstat, printk(BIOS_DEBUG, "%s: Done\n", __func__); } -static u8 NodePresent_D(u8 Node) +u8 NodePresent_D(u8 Node) { /* * Determine if a single Hammer Node exists within the network. @@ -4254,7 +4198,7 @@ static void SyncDCTsReady_D(struct MCTStatStruc *pMCTstat, mct_Wait(15000); } -static void StartupDCT_D(struct MCTStatStruc *pMCTstat, +void StartupDCT_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct) { /* Read MemClkFreqVal bit to see if the DIMMs are present in this node. @@ -4322,7 +4266,7 @@ static void ClearDCT_D(struct MCTStatStruc *pMCTstat, Set_NB32(dev, reg, val); } -static void SPD2ndTiming(struct MCTStatStruc *pMCTstat, +void SPD2ndTiming(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct) { u8 i; @@ -5048,7 +4992,7 @@ static void SPDGetTCL_D(struct MCTStatStruc *pMCTstat, printk(BIOS_DEBUG, "SPDGetTCL_D: Done\n\n"); } -static u8 PlatformSpec_D(struct MCTStatStruc *pMCTstat, +u8 PlatformSpec_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct) { if (!is_fam15h()) { @@ -6056,7 +6000,7 @@ void Set_NB32_index_wait(u32 dev, u32 index_reg, u32 index, u32 data) } -static u8 mct_BeforePlatformSpec(struct MCTStatStruc *pMCTstat, +u8 mct_BeforePlatformSpec(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct) { printk(BIOS_DEBUG, "%s: Start\n", __func__); @@ -6081,7 +6025,7 @@ static u8 mct_BeforePlatformSpec(struct MCTStatStruc *pMCTstat, return pDCTstat->ErrCode; } -static u8 mct_PlatformSpec(struct MCTStatStruc *pMCTstat, +u8 mct_PlatformSpec(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct) { /* Get platform specific config/timing values from the interface layer @@ -7147,7 +7091,7 @@ static void InitDDRPhy(struct MCTStatStruc *pMCTstat, printk(BIOS_DEBUG, "%s: Done\n", __func__); } -static void InitPhyCompensation(struct MCTStatStruc *pMCTstat, +void InitPhyCompensation(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct) { u8 i; @@ -8150,7 +8094,7 @@ static void mct_ResetDLL_D(struct MCTStatStruc *pMCTstat, } } -static void mct_EnableDatIntlv_D(struct MCTStatStruc *pMCTstat, +void mct_EnableDatIntlv_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat) { u32 dev = pDCTstat->dev_dct; @@ -8172,7 +8116,7 @@ static void mct_EnableDatIntlv_D(struct MCTStatStruc *pMCTstat, } } -static void SetDllSpeedUp_D(struct MCTStatStruc *pMCTstat, +void SetDllSpeedUp_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct) { if (!is_fam15h()) { @@ -8305,3 +8249,10 @@ uint8_t crcCheck(struct DCTStatStruc *pDCTstat, uint8_t dimm) } return CRC == (pDCTstat->spd_data.spd_bytes[dimm][SPD_byte_127] << 8 | pDCTstat->spd_data.spd_bytes[dimm][SPD_byte_126]); } + +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 index c42e452300..575a9d61bf 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h +++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h @@ -20,7 +20,10 @@ #ifndef MCT_D_H #define MCT_D_H -#include +#define DQS_TRAIN_DEBUG 0 + +#include +#include /*=========================================================================== CPU - K8/FAM10 @@ -974,6 +977,11 @@ struct amdmct_memory_info { 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); @@ -1013,10 +1021,7 @@ void mct_TrainRcvrEn_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTs 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 mctGet_DIMMAddr(struct DCTStatStruc *pDCTstat, u32 node); -void mctSMBhub_Init(u32 node); void DIMMSetVoltages(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); -int mctRead_SPD(u32 smaddr, u32 reg); 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); @@ -1028,5 +1033,127 @@ 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 new file mode 100644 index 0000000000..82911c02d5 --- /dev/null +++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d_gcc.c @@ -0,0 +1,296 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2010 Advanced Micro Devices, Inc. + * Copyright (C) 2015 Timothy Pearson , 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 +#include + +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<= 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 index 74fadde1f7..f0d0f76d69 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d_gcc.h +++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d_gcc.h @@ -3,6 +3,7 @@ * * Copyright (C) 2010 Advanced Micro Devices, Inc. * Copyright (C) 2015 Timothy Pearson , Raptor Engineering + * Copyright (C) 2016 Damien Zammit * * 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 @@ -13,317 +14,37 @@ * 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 -static inline void _WRMSR(u32 addr, u32 lo, u32 hi) -{ - __asm__ volatile ( - "wrmsr" - : - :"c"(addr),"a"(lo), "d" (hi) - ); -} - -static inline void _RDMSR(u32 addr, u32 *lo, u32 *hi) -{ - __asm__ volatile ( - "rdmsr" - :"=a"(*lo), "=d" (*hi) - :"c"(addr) - ); -} - -static inline void _RDTSC(u32 *lo, u32 *hi) -{ - __asm__ volatile ( - "rdtsc" - : "=a" (*lo), "=d"(*hi) - ); -} - -static inline void _cpu_id(u32 addr, u32 *val) -{ - __asm__ volatile( - "cpuid" - : "=a" (val[0]), - "=b" (val[1]), - "=c" (val[2]), - "=d" (val[3]) - : "0" (addr)); - -} - -static u32 bsr(u32 x) -{ - u8 i; - u32 ret = 0; - - for (i = 31; i > 0; i--) { - if (x & (1< +#include +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") -#include - u32 SetUpperFSbase(u32 addr_hi); -static void proc_MFENCE(void) -{ - __asm__ volatile ( - "outb %%al, $0xed\n\t" /* _EXECFENCE */ - "mfence\n\t" - :::"memory" - ); -} - -static 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) - ); -} - - -static 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) : : - ); +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); -} - -static 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; -} - -static 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; -} - -#ifdef UNUSED_CODE -static u8 read8_fs(u32 addr_lo) -{ - u8 byte; - __asm__ volatile ( - "outb %%al, $0xed\n\t" /* _EXECFENCE */ - "movb %%fs:(%1), %b0\n\t" - "mfence\n\t" - :"=b"(byte): "a" (addr_lo) - ); - return byte; -} #endif - -static 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) - ); - -} - -static __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) - ); -} - -static 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) - ); - -} - -static 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) : : - ); -} - -static 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) - ); -} - -static 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; -} - -#ifdef UNUSED_CODE -static void oemSet_NB32(u32 addr, u32 val, u8 *valid) -{ -} - -static u32 oemGet_NB32(u32 addr, u8 *valid) -{ - *valid = 0; - return 0xffffffff; -} -#endif - -static u8 oemNodePresent_D(u8 Node, u8 *ret) -{ - *ret = 0; - return 0; -} diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctardk5.c b/src/northbridge/amd/amdmct/mct_ddr3/mctardk5.c index 3a14fd86b1..45cd124cf3 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctardk5.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctardk5.c @@ -16,6 +16,25 @@ /* AM3/ASB2/C32/G34 DDR3 */ +#include +#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); diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctchi_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mctchi_d.c index 30cf10e90c..55cf3a1eda 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctchi_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctchi_d.c @@ -13,6 +13,11 @@ * GNU General Public License for more details. */ +#include +#include "mct_d.h" +#include "mct_d_gcc.h" +#include + void InterleaveChannels_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA) { diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctcsi_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mctcsi_d.c index e42a127e33..716e419a5d 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctcsi_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctcsi_d.c @@ -19,6 +19,12 @@ * ;(2 or 3) to the number of column address bits, plus 3 (the logical * ;page size), and subtract 8. */ + +#include +#include "mct_d.h" +#include "mct_d_gcc.h" +#include + static const u8 Tab_int_D[] = {6,7,7,8,8,8,8,8,9,9,8,9}; void InterleaveBanks_D(struct MCTStatStruc *pMCTstat, diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c index 71a4b79424..69b0104973 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c @@ -14,17 +14,12 @@ * GNU General Public License for more details. */ -static 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); - -static void read_dqs_read_data_timing_registers(uint16_t* delay, uint32_t dev, - uint8_t dct, uint8_t dimm, uint32_t index_reg); - -static void write_dqs_read_data_timing_registers(uint16_t* delay, uint32_t dev, - uint8_t dct, uint8_t dimm, uint32_t index_reg); - -static void dqsTrainMaxRdLatency_SW_Fam15(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); +#include +#include +#include +#include "mct_d.h" +#include "mct_d_gcc.h" +#include static void CalcEccDQSPos_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u16 like, @@ -43,28 +38,34 @@ static u16 CompareDQSTestPattern_D(struct MCTStatStruc *pMCTstat, u32 addr_lo); static void FlushDQSTestPattern_D(struct DCTStatStruc *pDCTstat, u32 addr_lo); -static void SetTargetWTIO_D(u32 TestAddr); -static void ResetTargetWTIO_D(void); -void ResetDCTWrPtr_D(u32 dev, uint8_t dct, u32 index_reg, u32 index); -u8 mct_DisableDimmEccEn_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); static void mct_SetDQSDelayCSR_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 ChipSel); -u32 mct_GetMCTSysAddr_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 Channel, - u8 receiver, u8 *valid); static void SetupDqsPattern_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u32 *buffer); -static void proc_IOCLFLUSH_D(u32 addr_hi); 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 -static void print_debug_dqs(const char *str, u32 val, u8 level) +void print_debug_dqs(const char *str, u32 val, u8 level) { #if DQS_TRAIN_DEBUG > 0 if (DQS_TRAIN_DEBUG >= level) { @@ -73,7 +74,7 @@ static void print_debug_dqs(const char *str, u32 val, u8 level) #endif } -static void print_debug_dqs_pair(const char *str, u32 val, const char *str2, u32 val2, u8 level) +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) { @@ -850,8 +851,8 @@ static void TrainDQSRdWrPos_D_Fam10(struct MCTStatStruc *pMCTstat, /* Calcuate and set MaxRdLatency * Algorithm detailed in the Fam15h BKDG Rev. 3.14 section 2.10.5.8.5 */ -static void Calc_SetMaxRdLatency_D_Fam15(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t calc_min) +void Calc_SetMaxRdLatency_D_Fam15(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t calc_min) { uint8_t dimm; uint8_t lane; @@ -1053,8 +1054,9 @@ static void stop_dram_dqs_training_pattern_fam15(struct MCTStatStruc *pMCTstat, Set_NB32_DCT(dev, dct, 0x250, dword); } -static 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 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; @@ -1149,8 +1151,9 @@ static void read_dram_dqs_training_pattern_fam15(struct MCTStatStruc *pMCTstat, stop_dram_dqs_training_pattern_fam15(pMCTstat, pDCTstat, dct, Receiver); } -static 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 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; @@ -1944,14 +1947,14 @@ static void GetDQSDatStrucVal_D(struct MCTStatStruc *pMCTstat, /* FindDQSDatDimmVal_D is not required since we use an array */ -static void proc_IOCLFLUSH_D(u32 addr_hi) +void proc_IOCLFLUSH_D(u32 addr_hi) { SetTargetWTIO_D(addr_hi); proc_CLFLUSH(addr_hi); ResetTargetWTIO_D(); } -static u8 ChipSelPresent_D(struct MCTStatStruc *pMCTstat, +u8 ChipSelPresent_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 Channel, u8 ChipSel) { @@ -2139,7 +2142,7 @@ static void FlushDQSTestPattern_D(struct DCTStatStruc *pDCTstat, } } -static void SetTargetWTIO_D(u32 TestAddr) +void SetTargetWTIO_D(u32 TestAddr) { u32 lo, hi; hi = TestAddr >> 24; @@ -2150,7 +2153,7 @@ static void SetTargetWTIO_D(u32 TestAddr) _WRMSR(0xC0010017, lo, hi); /* IORR0 Mask */ } -static void ResetTargetWTIO_D(void) +void ResetTargetWTIO_D(void) { u32 lo, hi; @@ -2436,7 +2439,7 @@ exitGetAddr: return val; } -static void mct_Write1LTestPattern_D(struct MCTStatStruc *pMCTstat, +void mct_Write1LTestPattern_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u32 TestAddr, u8 pattern) { diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c index ca3678997b..9aad96cfbc 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c @@ -14,12 +14,31 @@ * GNU General Public License for more details. */ +#include +#include +#include #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. diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mcthdi.c b/src/northbridge/amd/amdmct/mct_ddr3/mcthdi.c index 10e9e44a6b..2038af9b6c 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mcthdi.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mcthdi.c @@ -14,6 +14,10 @@ * GNU General Public License for more details. */ +#include +#include "mct_d.h" +#include "mct_d_gcc.h" + void mct_DramInit_Hw_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct) { diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c b/src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c index a92f9e5ee8..4c6776dcf9 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c @@ -14,18 +14,26 @@ * GNU General Public License for more details. */ -static uint8_t AgesaHwWlPhase1(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct, u8 dimm, u8 pass); -static uint8_t AgesaHwWlPhase2(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t dimm, uint8_t pass); -static uint8_t AgesaHwWlPhase3(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct, u8 dimm, u8 pass); -static void EnableZQcalibration(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat); -static void DisableZQcalibration(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat); -static void PrepareC_MCT(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat); -static void PrepareC_DCT(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct); -static void Restore_OnDimmMirror(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat); -static void Clear_OnDimmMirror(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat); +#include +#include +#include +#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) { diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctmtr_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mctmtr_d.c index 558b3e3498..8a1f7362a8 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctmtr_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctmtr_d.c @@ -14,7 +14,12 @@ * GNU General Public License for more details. */ +#include +#include +#include #include "mct_d.h" +#include "mct_d_gcc.h" +#include static void SetMTRRrangeWB_D(u32 Base, u32 *pLimit, u32 *pMtrrAddr); static void SetMTRRrange_D(u32 Base, u32 *pLimit, u32 *pMtrrAddr, u16 MtrrType); diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctndi_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mctndi_d.c index bf84171255..3df032398c 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctndi_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctndi_d.c @@ -14,6 +14,12 @@ * GNU General Public License for more details. */ +#include +#include +#include +#include "mct_d.h" +#include "mct_d_gcc.h" + void InterleaveNodes_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA) { diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctprob.c b/src/northbridge/amd/amdmct/mct_ddr3/mctprob.c index 01ae874f44..9c97250ef9 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctprob.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctprob.c @@ -13,6 +13,12 @@ * GNU General Public License for more details. */ +#include +#include +#include +#include "mct_d.h" +#include "mct_d_gcc.h" + void mct_BeforeDQSTrainSamp(struct DCTStatStruc *pDCTstat) { u32 val; diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctproc.c b/src/northbridge/amd/amdmct/mct_ddr3/mctproc.c index fc62afb7b5..07bde27d37 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctproc.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctproc.c @@ -14,6 +14,12 @@ * GNU General Public License for more details. */ +#include +#include +#include +#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) diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctprod.c b/src/northbridge/amd/amdmct/mct_ddr3/mctprod.c index f41a766e31..947fa1515d 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctprod.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctprod.c @@ -14,6 +14,12 @@ * GNU General Public License for more details. */ +#include +#include +#include +#include "mct_d.h" +#include "mct_d_gcc.h" + void mct_ExtMCTConfig_Dx(struct DCTStatStruc *pDCTstat) { uint32_t dword; diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c b/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c index ac24c6d8cc..4ef6132584 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctrci.c @@ -14,6 +14,27 @@ * GNU General Public License for more details. */ +#include +#include +#include +#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); diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c b/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c index 18af172e7c..1fa0c96620 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctsdi.c @@ -14,7 +14,28 @@ * GNU General Public License for more details. */ -static uint8_t fam15_dimm_dic(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t dimm, uint8_t rank, uint8_t package_type) +#include +#include +#include +#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; @@ -31,7 +52,7 @@ static uint8_t fam15_dimm_dic(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_ return dic; } -static uint8_t fam15_rttwr(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t dimm, uint8_t rank, uint8_t package_type) +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]; @@ -265,7 +286,7 @@ static uint8_t fam15_rttwr(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t d return term; } -static uint8_t fam15_rttnom(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 term = 0; uint8_t number_of_dimms = pDCTstat->MAdimms[dct]; @@ -662,9 +683,6 @@ static uint8_t fam15_rttnom(struct DCTStatStruc *pDCTstat, uint8_t dct, uint8_t return term; } -static void mct_DramControlReg_Init_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); - static void mct_DCTAccessDone(struct DCTStatStruc *pDCTstat, u8 dct) { u32 dev = pDCTstat->dev_dct; @@ -736,8 +754,8 @@ static void mct_SendMrsCmd(struct DCTStatStruc *pDCTstat, u8 dct, u32 EMRS) printk(BIOS_DEBUG, "%s: Done\n", __func__); } -static u32 mct_MR2(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct, u32 MrsChipSel) +u32 mct_MR2(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstat, u8 dct, u32 MrsChipSel) { u32 dev = pDCTstat->dev_dct; u32 dword, ret; @@ -834,8 +852,8 @@ static u32 mct_MR3(struct MCTStatStruc *pMCTstat, return ret; } -static u32 mct_MR1(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct, u32 MrsChipSel) +u32 mct_MR1(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstat, u8 dct, u32 MrsChipSel) { u32 dev = pDCTstat->dev_dct; u32 dword, ret; diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c b/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c index 8c134c322b..fd8a8e76af 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c @@ -19,7 +19,13 @@ Description: Receiver En and DQS Timing Training feature for DDR 3 MCT ******************************************************************************/ -static int32_t abs(int32_t val); +#include +#include +#include +#include "mct_d.h" +#include "mct_d_gcc.h" +#include + static void dqsTrainRcvrEn_SW_Fam10(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 Pass); static void dqsTrainRcvrEn_SW_Fam15(struct MCTStatStruc *pMCTstat, @@ -31,25 +37,38 @@ static void InitDQSPos4RcvrEn_D(struct MCTStatStruc *pMCTstat, 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 uint32_t fenceDynTraining_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); 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! */ -static const u32 TestPattern0_D[] = { +const u32 TestPattern0_D[] = { 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, }; -static const u32 TestPattern1_D[] = { +const u32 TestPattern1_D[] = { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, }; -static const u32 TestPattern2_D[] = { +const u32 TestPattern2_D[] = { 0x12345678, 0x87654321, 0x23456789, 0x98765432, 0x59385824, 0x30496724, 0x24490795, 0x99938733, 0x40385642, 0x38465245, 0x29432163, 0x05067894, @@ -236,7 +255,7 @@ static uint16_t fam15_receiver_enable_training_seed(struct DCTStatStruc *pDCTsta return seed; } -static 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 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; @@ -334,7 +353,7 @@ static void write_write_data_timing_control_registers(uint16_t* current_total_de } } -static 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_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; @@ -368,7 +387,7 @@ static void read_dqs_receiver_enable_control_registers(uint16_t* current_total_d } } -static 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) +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; @@ -475,7 +494,7 @@ static void write_dram_phase_recovery_control_registers(uint16_t* current_total_ } } -static void read_dqs_read_data_timing_registers(uint16_t* delay, uint32_t dev, uint8_t dct, uint8_t dimm, uint32_t index_reg) +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; @@ -509,7 +528,7 @@ static void read_dqs_read_data_timing_registers(uint16_t* delay, uint32_t dev, u delay[8] = (dword & mask) >> shift; } -static void write_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) { uint8_t shift; uint32_t dword; @@ -1548,7 +1567,7 @@ static void write_max_read_latency_to_registers(struct MCTStatStruc *pMCTstat, * The Fam15h BKDG Rev. 3.14 section 2.10.5.8.5.1 * This algorithm runs at the highest supported MEMCLK. */ -static void dqsTrainMaxRdLatency_SW_Fam15(struct MCTStatStruc *pMCTstat, +void dqsTrainMaxRdLatency_SW_Fam15(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat) { u8 Channel; @@ -2270,7 +2289,7 @@ void phyAssistedMemFnceTraining(struct MCTStatStruc *pMCTstat, printk(BIOS_DEBUG, "%s: Done\n", __func__); } -static uint32_t fenceDynTraining_D(struct MCTStatStruc *pMCTstat, +uint32_t fenceDynTraining_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, uint8_t dct) { u16 avRecValue; diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctsrc1p.c b/src/northbridge/amd/amdmct/mct_ddr3/mctsrc1p.c index 30cf19ba30..2592eedab9 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctsrc1p.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctsrc1p.c @@ -14,6 +14,27 @@ * GNU General Public License for more details. */ +#include +#include +#include +#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; diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mcttmrl.c b/src/northbridge/amd/amdmct/mct_ddr3/mcttmrl.c index 78db68c9d0..039a747736 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mcttmrl.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mcttmrl.c @@ -18,6 +18,12 @@ * Description: Max Read Latency Training feature for DDR 3 MCT */ +#include +#include +#include +#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, diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctwl.c b/src/northbridge/amd/amdmct/mct_ddr3/mctwl.c index 47c5004c0c..53c4a2dbe9 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctwl.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctwl.c @@ -14,9 +14,26 @@ * GNU General Public License for more details. */ -static void FreqChgCtrlWrd(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, uint8_t dct); +#include +#include +#include +#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) { diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mhwlc_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mhwlc_d.c index dce6212996..ed942eaff2 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mhwlc_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mhwlc_d.c @@ -14,18 +14,14 @@ * GNU General Public License for more details. */ -/* - *----------------------------------------------------------------------------- - * MODULES USED - * - *----------------------------------------------------------------------------- - */ +#include +#include +#include +#include "mct_d.h" +#include "mct_d_gcc.h" +#include "mwlc_d.h" +#include -/*---------------------------------------------------------------------------- - * PROTOTYPES OF LOCAL FUNCTIONS - * - *---------------------------------------------------------------------------- - */ 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, @@ -35,20 +31,6 @@ void procConfig(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, ui 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); -static int32_t abs(int32_t val) { - if (val < 0) - val *= -1; - - return val; -} - -/* - *----------------------------------------------------------------------------- - * EXPORTED FUNCTIONS - * - *----------------------------------------------------------------------------- - */ - /*----------------------------------------------------------------------------- * uint8_t AgesaHwWlPhase1(SPDStruct *SPDData,MCTStruct *MCTData, DCTStruct *DCTData, * u8 Dimm, u8 Pass) diff --git a/src/northbridge/amd/amdmct/mct_ddr3/modtrd.c b/src/northbridge/amd/amdmct/mct_ddr3/modtrd.c index 22ff36113c..9c1ba892b7 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/modtrd.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/modtrd.c @@ -13,7 +13,13 @@ * GNU General Public License for more details. */ -static u32 mct_MR1Odt_RDimm(struct MCTStatStruc *pMCTstat, +#include +#include +#include +#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; @@ -55,7 +61,7 @@ static u32 mct_MR1Odt_RDimm(struct MCTStatStruc *pMCTstat, return ret; } -static u32 mct_DramTermDyn_RDimm(struct MCTStatStruc *pMCTstat, +u32 mct_DramTermDyn_RDimm(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dimm) { u8 DimmsInstalled = dimm; diff --git a/src/northbridge/amd/amdmct/mct_ddr3/modtrdim.c b/src/northbridge/amd/amdmct/mct_ddr3/modtrdim.c index 8ed03a0454..1c2a135975 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/modtrdim.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/modtrdim.c @@ -16,25 +16,12 @@ /* This file contains functions for odt setting on registered DDR3 dimms */ -/* - *----------------------------------------------------------------------------- - * MODULES USED - * - *----------------------------------------------------------------------------- - */ -/*---------------------------------------------------------------------------- - * PROTOTYPES OF LOCAL FUNCTIONS - * - *---------------------------------------------------------------------------- - */ +#include +#include +#include +#include "mct_d.h" +#include "mct_d_gcc.h" -/* - *----------------------------------------------------------------------------- - * EXPORTED FUNCTIONS - * - *----------------------------------------------------------------------------- - */ -/* -----------------------------------------------------------------------------*/ /** * * @@ -49,7 +36,7 @@ * * @return tempW1 - Rtt_Nom */ -static u32 RttNomTargetRegDimm (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 tempW1; tempW1 = 0; @@ -105,7 +92,7 @@ static u32 RttNomTargetRegDimm (sMCTStruct *pMCTData, sDCTStruct *pDCTData, u8 d } break; default: - ASSERT (FALSE); + die("modtrdim.c: WTF?"); } } else { switch (mctGet_NVbits(NV_MAX_DIMMS_PER_CH)) { @@ -141,7 +128,7 @@ static u32 RttNomTargetRegDimm (sMCTStruct *pMCTData, sDCTStruct *pDCTData, u8 d } break; default: - ASSERT (FALSE); + die("modtrdim.c: WTF?"); } } return tempW1; @@ -162,7 +149,7 @@ static u32 RttNomTargetRegDimm (sMCTStruct *pMCTData, sDCTStruct *pDCTData, u8 d * * @return tempW1 - Rtt_Nom */ -static u32 RttNomNonTargetRegDimm (sMCTStruct *pMCTData, sDCTStruct *pDCTData, u8 dimm, BOOL wl, u8 MemClkFreq, u8 rank) +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 */ @@ -187,7 +174,7 @@ static u32 RttNomNonTargetRegDimm (sMCTStruct *pMCTData, sDCTStruct *pDCTData, u * @return tempW1 - Rtt_Wr */ -static u32 RttWrRegDimm (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) { u32 tempW1; tempW1 = 0; @@ -230,7 +217,7 @@ static u32 RttWrRegDimm (sMCTStruct *pMCTData, sDCTStruct *pDCTData, u8 dimm, BO } break; default: - ASSERT (FALSE); + die("modtrdim.c: WTF?"); } } return tempW1; @@ -248,7 +235,7 @@ static u32 RttWrRegDimm (sMCTStruct *pMCTData, sDCTStruct *pDCTData, u8 dimm, BO * * @return WrLvOdt */ -static u8 WrLvOdtRegDimm (sMCTStruct *pMCTData, sDCTStruct *pDCTData, u8 dimm) +u8 WrLvOdtRegDimm (sMCTStruct *pMCTData, sDCTStruct *pDCTData, u8 dimm) { u8 WrLvOdt1, i; WrLvOdt1 = 0; diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mport_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mport_d.c index 3c15e3f845..41d2c27b5f 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mport_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mport_d.c @@ -13,7 +13,14 @@ * GNU General Public License for more details. */ -static void AmdMemPCIRead(SBDFO loc, u32 *Value) +#include +#include +#include +#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); @@ -24,7 +31,7 @@ static void AmdMemPCIRead(SBDFO loc, u32 *Value) *Value = inl(0xCFC); } -static void AmdMemPCIWrite(SBDFO loc, u32 *Value) +void AmdMemPCIWrite(SBDFO loc, u32 *Value) { /* Convert SBDFO into a CF8 Address */ loc = (loc >> 4 & 0xFFFFFF00) | (loc & 0xFF) | ((loc & 0xF00) << 16); diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mutilc_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mutilc_d.c index 18cad7eae7..f17e4d6758 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mutilc_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mutilc_d.c @@ -15,22 +15,29 @@ */ /* This file contains functions for common utility functions */ +#include +#include +#include +#include "mct_d.h" +#include "mct_d_gcc.h" +#include "mwlc_d.h" -/* - *----------------------------------------------------------------------------- - * MODULES USED - * - *----------------------------------------------------------------------------- - */ +static uint8_t is_fam15h(void) +{ + uint8_t fam15h = 0; + uint32_t family; -/* - *----------------------------------------------------------------------------- - * EXPORTED FUNCTIONS - * - *----------------------------------------------------------------------------- - */ + family = cpuid_eax(0x80000001); + family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8); + + if (family >= 0x6f) + /* Family 15h or later */ + fam15h = 1; + + return fam15h; +} -static void AmdMemPCIReadBits(SBDFO loc, u8 highbit, u8 lowbit, u32 *pValue) +void AmdMemPCIReadBits(SBDFO loc, u8 highbit, u8 lowbit, u32 *pValue) { /* ASSERT(highbit < 32 && lowbit < 32 && highbit >= lowbit && (loc & 3) == 0); */ @@ -42,7 +49,7 @@ static void AmdMemPCIReadBits(SBDFO loc, u8 highbit, u8 lowbit, u32 *pValue) *pValue &= (((u32)1 << (highbit-lowbit+1))-1); } -static void AmdMemPCIWriteBits(SBDFO loc, u8 highbit, u8 lowbit, u32 *pValue) +void AmdMemPCIWriteBits(SBDFO loc, u8 highbit, u8 lowbit, u32 *pValue) { u32 temp, mask; @@ -72,7 +79,7 @@ static void AmdMemPCIWriteBits(SBDFO loc, u8 highbit, u8 lowbit, u32 *pValue) * OUT value = Target value with the bit set *----------------------------------------------------------------------------- */ -static u32 bitTestSet(u32 csMask,u32 tempD) +u32 bitTestSet(u32 csMask,u32 tempD) { u32 localTemp; /* ASSERT(tempD < 32); */ @@ -93,7 +100,7 @@ static u32 bitTestSet(u32 csMask,u32 tempD) * OUT value = Target value with the bit re-set *----------------------------------------------------------------------------- */ -static u32 bitTestReset(u32 csMask,u32 tempD) +u32 bitTestReset(u32 csMask,u32 tempD) { u32 temp, localTemp; /* ASSERT(tempD < 32); */ @@ -126,7 +133,7 @@ static u32 bitTestReset(u32 csMask,u32 tempD) * OUT value = Value read from PCI space *----------------------------------------------------------------------------- */ -static u32 get_Bits(sDCTStruct *pDCTData, +u32 get_Bits(sDCTStruct *pDCTData, u8 dct, u8 node, u8 func, u16 offset, u8 low, u8 high) { @@ -200,7 +207,7 @@ static u32 get_Bits(sDCTStruct *pDCTData, * OUT *----------------------------------------------------------------------------- */ -static void set_Bits(sDCTStruct *pDCTData, +void set_Bits(sDCTStruct *pDCTData, u8 dct, u8 node, u8 func, u16 offset, u8 low, u8 high, u32 value) { @@ -275,7 +282,7 @@ static void set_Bits(sDCTStruct *pDCTData, * OUT *------------------------------------------------- */ -static u32 get_ADD_DCT_Bits(sDCTStruct *pDCTData, +u32 get_ADD_DCT_Bits(sDCTStruct *pDCTData, u8 dct, u8 node, u8 func, u16 offset, u8 low, u8 high) { @@ -313,7 +320,7 @@ static u32 get_ADD_DCT_Bits(sDCTStruct *pDCTData, * OUT *------------------------------------------------- */ -static void set_DCT_ADDR_Bits(sDCTStruct *pDCTData, +void set_DCT_ADDR_Bits(sDCTStruct *pDCTData, u8 dct, u8 node, u8 func, u16 offset, u8 low, u8 high, u32 value) { @@ -348,7 +355,7 @@ static void set_DCT_ADDR_Bits(sDCTStruct *pDCTData, * FALSE - bit is clear *------------------------------------------------- */ -static BOOL bitTest(u32 value, u8 bitLoc) +BOOL bitTest(u32 value, u8 bitLoc) { u32 tempD, compD; tempD = value; diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mwlc_d.h b/src/northbridge/amd/amdmct/mct_ddr3/mwlc_d.h index ca04d28a0a..aa0446f090 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mwlc_d.h +++ b/src/northbridge/amd/amdmct/mct_ddr3/mwlc_d.h @@ -17,6 +17,8 @@ #ifndef MWLC_D_H #define MWLC_D_H +#include + #define MAX_TOTAL_DIMMS 8 /* Maximum Number of DIMMs in systems */ /* (DCT0 + DCT1) */ #define MAX_DIMMS 4 /* Maximum Number of DIMMs on each DCT */ @@ -163,4 +165,28 @@ typedef struct _sDCTStruct 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 index d3fc53b12f..4013c2e538 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c @@ -26,13 +26,17 @@ #include #include #include +#include +#include +#include +#include "mct_d.h" +#include "mct_d_gcc.h" #include "s3utils.h" #define S3NV_FILE_NAME "s3nv" -#ifdef __RAMSTAGE__ -static inline uint8_t is_fam15h(void) +static uint8_t is_fam15h(void) { uint8_t fam15h = 0; uint32_t family; @@ -46,7 +50,6 @@ static inline uint8_t is_fam15h(void) return fam15h; } -#endif static ssize_t get_s3nv_file_offset(void); @@ -1172,3 +1175,25 @@ int8_t restore_mct_information_from_nvram(uint8_t 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 index 8a726952dd..d13cb23c80 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/s3utils.h +++ b/src/northbridge/amd/amdmct/mct_ddr3/s3utils.h @@ -12,20 +12,20 @@ * 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" -void calculate_spd_hash(uint8_t *spd_data, uint64_t *spd_hash); -uint16_t calculate_nvram_mct_hash(void); - -#ifdef __PRE_RAM__ -int8_t load_spd_hashes_from_nvram(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat); -#endif - #ifdef __RAMSTAGE__ int8_t save_mct_information_to_nvram(void); -#endif -int8_t restore_mct_information_from_nvram(uint8_t training_only); void copy_mct_data_to_save_variable(struct amd_s3_persistent_data* persistent_data); -void restore_mct_data_from_save_variable(struct amd_s3_persistent_data* persistent_data, uint8_t training_only); +#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 diff --git a/src/northbridge/amd/amdmct/wrappers/Makefile.inc b/src/northbridge/amd/amdmct/wrappers/Makefile.inc new file mode 100644 index 0000000000..5773067138 --- /dev/null +++ b/src/northbridge/amd/amdmct/wrappers/Makefile.inc @@ -0,0 +1,5 @@ +ifeq ($(CONFIG_NORTHBRIDGE_AMD_AMDFAM10),y) + +romstage-y += mcti_d.c + +endif diff --git a/src/northbridge/amd/amdmct/wrappers/mcti.h b/src/northbridge/amd/amdmct/wrappers/mcti.h index 5eaff2c75a..db92fa789e 100644 --- a/src/northbridge/amd/amdmct/wrappers/mcti.h +++ b/src/northbridge/amd/amdmct/wrappers/mcti.h @@ -3,6 +3,7 @@ * * Copyright (C) 2007 Advanced Micro Devices, Inc. * Copyright (C) 2015 Timothy Pearson , Raptor Engineering + * Copyright (C) 2016 Damien Zammit * * 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 @@ -14,6 +15,15 @@ * GNU General Public License for more details. */ +#ifndef MCTI_H +#define MCTI_H + +#include +#include +#include + +struct DCTStatStruc; +struct MCTStatStruc; #define SERVER 0 #define DESKTOP 1 @@ -22,7 +32,6 @@ #define REV_DR 1 #define REV_FDR 2 - /*---------------------------------------------------------------------------- COMMENT OUT ALL BUT 1 ----------------------------------------------------------------------------*/ @@ -63,7 +72,7 @@ UPDATE AS NEEDED #endif #ifndef MEM_MAX_LOAD_FREQ -#if (CONFIG_DIMM_SUPPORT & 0x000F) == 0x0005 /* AMD_FAM10_DDR3 */ +#if IS_ENABLED(CONFIG_DIMM_DDR3) #define MEM_MAX_LOAD_FREQ 933 #define MEM_MIN_PLATFORM_FREQ_FAM10 400 #define MEM_MIN_PLATFORM_FREQ_FAM15 333 @@ -77,3 +86,68 @@ UPDATE AS NEEDED #define MCT_TRNG_KEEPOUT_START 0x00000C00 #define MCT_TRNG_KEEPOUT_END 0x00000CFF + +#define NVRAM_DDR2_800 0 +#define NVRAM_DDR2_667 1 +#define NVRAM_DDR2_533 2 +#define NVRAM_DDR2_400 3 + +#define NVRAM_DDR3_1600 0 +#define NVRAM_DDR3_1333 1 +#define NVRAM_DDR3_1066 2 +#define NVRAM_DDR3_800 3 + +/* The recommended maximum GFX Upper Memory Area + * size is 256M, however, to be on the safe side + * move TOM down by 512M. + */ +#define MAXIMUM_GFXUMA_SIZE 0x20000000 + +/* Do not allow less than 16M of DRAM in 32-bit space. + * This number is not hardware constrained and can be + * changed as needed. + */ +#define MINIMUM_DRAM_BELOW_4G 0x1000000 + +static const uint16_t ddr2_limits[4] = {400, 333, 266, 200}; +static const uint16_t ddr3_limits[16] = {933, 800, 666, 533, 400, 333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +#if IS_ENABLED(CONFIG_DIMM_DDR3) + #include +#else + #include +#endif + +#if IS_ENABLED(CONFIG_DIMM_DDR2) +void mctSaveDQSSigTmg_D(void); +void mctGetDQSSigTmg_D(void); +u8 mctSetNodeBoundary_D(void); +#endif +u16 mctGet_NVbits(u8 index); +void mctHookAfterDIMMpre(void); +void mctGet_MaxLoadFreq(struct DCTStatStruc *pDCTstat); +void mctAdjustAutoCycTmg_D(void); +void mctHookAfterAutoCycTmg(void); +void mctGetCS_ExcludeMap(void); +void mctHookBeforeECC(void); +void mctHookAfterECC(void); +void mctHookAfterAutoCfg(void); +void mctHookAfterPSCfg(void); +void mctHookAfterHTMap(void); +void mctHookAfterCPU(void); +void mctInitMemGPIOs_A_D(void); +void mctNodeIDDebugPort_D(void); +void mctWarmReset_D(void); +void mctHookBeforeDramInit(void); +void mctHookAfterDramInit(void); +void mctHookBeforeAnyTraining(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); +void mctHookAfterAnyTraining(void); +uint64_t mctGetLogicalCPUID_D(u8 node); + +#if IS_ENABLED(CONFIG_DIMM_DDR3) +void vErratum372(struct DCTStatStruc *pDCTstat); +void vErratum414(struct DCTStatStruc *pDCTstat); +u32 mct_AdjustSPDTimings(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA, u32 val); +#endif + +#endif diff --git a/src/northbridge/amd/amdmct/wrappers/mcti_d.c b/src/northbridge/amd/amdmct/wrappers/mcti_d.c index 9cb981a32c..06e4a06bf7 100644 --- a/src/northbridge/amd/amdmct/wrappers/mcti_d.c +++ b/src/northbridge/amd/amdmct/wrappers/mcti_d.c @@ -16,6 +16,9 @@ /* Call-backs */ #include +#include +#include +#include "mcti.h" #define NVRAM_DDR2_800 0 #define NVRAM_DDR2_667 1 @@ -27,6 +30,21 @@ #define NVRAM_DDR3_1066 2 #define NVRAM_DDR3_800 3 +static inline uint8_t isfam15h(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; +} + /* The recommended maximum GFX Upper Memory Area * size is 256M, however, to be on the safe side * move TOM down by 512M. @@ -39,10 +57,7 @@ */ #define MINIMUM_DRAM_BELOW_4G 0x1000000 -static const uint16_t ddr2_limits[4] = {400, 333, 266, 200}; -static const uint16_t ddr3_limits[16] = {933, 800, 666, 533, 400, 333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -static u16 mctGet_NVbits(u8 index) +u16 mctGet_NVbits(u8 index) { u16 val = 0; int nvram; @@ -94,7 +109,7 @@ static u16 mctGet_NVbits(u8 index) break; case NV_MIN_MEMCLK: /* Minimum platform supported memclk */ - if (is_fam15h()) + if (isfam15h()) val = MEM_MIN_PLATFORM_FREQ_FAM15; else val = MEM_MIN_PLATFORM_FREQ_FAM10; @@ -312,12 +327,12 @@ static u16 mctGet_NVbits(u8 index) } -static void mctHookAfterDIMMpre(void) +void mctHookAfterDIMMpre(void) { } -static void mctGet_MaxLoadFreq(struct DCTStatStruc *pDCTstat) +void mctGet_MaxLoadFreq(struct DCTStatStruc *pDCTstat) { pDCTstat->PresetmaxFreq = mctGet_NVbits(NV_MAX_MEMCLK); @@ -347,7 +362,7 @@ static void mctGet_MaxLoadFreq(struct DCTStatStruc *pDCTstat) printk(BIOS_DEBUG, "mctGet_MaxLoadFreq: Channel 2: %d DIMM(s) detected\n", ch2_count); } -#if (CONFIG_DIMM_SUPPORT & 0x000F) == 0x0005 /* AMD_FAM10_DDR3 */ +#if IS_ENABLED(CONFIG_DIMM_DDR3) uint8_t dimm; for (i = 0; i < MAX_DIMMS_SUPPORTED; i = i + 2) { @@ -370,111 +385,92 @@ static void mctGet_MaxLoadFreq(struct DCTStatStruc *pDCTstat) pDCTstat->PresetmaxFreq = mct_MaxLoadFreq(max(ch1_count, ch2_count), max(highest_rank_count[0], highest_rank_count[1]), (ch1_registered || ch2_registered), (ch1_voltage | ch2_voltage), pDCTstat->PresetmaxFreq); } -#ifdef UNUSED_CODE -static void mctAdjustAutoCycTmg(void) -{ -} -#endif - - -static void mctAdjustAutoCycTmg_D(void) +void mctAdjustAutoCycTmg_D(void) { } -static void mctHookAfterAutoCycTmg(void) +void mctHookAfterAutoCycTmg(void) { } -static void mctGetCS_ExcludeMap(void) +void mctGetCS_ExcludeMap(void) { } -static void mctHookAfterAutoCfg(void) +void mctHookAfterAutoCfg(void) { } -static void mctHookAfterPSCfg(void) +void mctHookAfterPSCfg(void) { } -static void mctHookAfterHTMap(void) +void mctHookAfterHTMap(void) { } -static void mctHookAfterCPU(void) +void mctHookAfterCPU(void) { } #if IS_ENABLED(CONFIG_DIMM_DDR2) -static void mctSaveDQSSigTmg_D(void) +void mctSaveDQSSigTmg_D(void) { } -#endif - -#if IS_ENABLED(CONFIG_DIMM_DDR2) -static void mctGetDQSSigTmg_D(void) +void mctGetDQSSigTmg_D(void) { } #endif - -static void mctHookBeforeECC(void) +void mctHookBeforeECC(void) { } - -static void mctHookAfterECC(void) +void mctHookAfterECC(void) { } #ifdef UNUSED_CODE -static void mctInitMemGPIOs_A(void) +void mctInitMemGPIOs_A(void) { } #endif -static void mctInitMemGPIOs_A_D(void) -{ -} - - -static void mctNodeIDDebugPort_D(void) +void mctInitMemGPIOs_A_D(void) { } -#ifdef UNUSED_CODE -static void mctWarmReset(void) +void mctNodeIDDebugPort_D(void) { } -#endif -static void mctWarmReset_D(void) +void mctWarmReset_D(void) { } -static void mctHookBeforeDramInit(void) +void mctHookBeforeDramInit(void) { } -static void mctHookAfterDramInit(void) +void mctHookAfterDramInit(void) { } -#if (CONFIG_DIMM_SUPPORT & 0x000F) == 0x0005 /* AMD_FAM10_DDR3 */ -static void vErratum372(struct DCTStatStruc *pDCTstat) +#if IS_ENABLED(CONFIG_DIMM_DDR3) +void vErratum372(struct DCTStatStruc *pDCTstat) { msr_t msr = rdmsr(NB_CFG_MSR); @@ -489,7 +485,7 @@ static void vErratum372(struct DCTStatStruc *pDCTstat) } } -static void vErratum414(struct DCTStatStruc *pDCTstat) +void vErratum414(struct DCTStatStruc *pDCTstat) { int dct = 0; for (; dct < 2 ; dct++) { @@ -505,9 +501,9 @@ static void vErratum414(struct DCTStatStruc *pDCTstat) #endif -static void mctHookBeforeAnyTraining(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA) +void mctHookBeforeAnyTraining(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA) { -#if (CONFIG_DIMM_SUPPORT & 0x000F) == 0x0005 /* AMD_FAM10_DDR3 */ +#if IS_ENABLED(CONFIG_DIMM_DDR3) /* FIXME : as of 25.6.2010 errata 350 and 372 should apply to ((RB|BL|DA)-C[23])|(HY-D[01])|(PH-E0) but I don't find constants for all of them */ if (pDCTstatA->LogicalCPUID & (AMD_DRBH_Cx | AMD_DR_Dx)) { vErratum372(pDCTstatA); @@ -516,8 +512,8 @@ static void mctHookBeforeAnyTraining(struct MCTStatStruc *pMCTstat, struct DCTSt #endif } -#if (CONFIG_DIMM_SUPPORT & 0x000F) == 0x0005 /* AMD_FAM10_DDR3 */ -static u32 mct_AdjustSPDTimings(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA, u32 val) +#if IS_ENABLED(CONFIG_DIMM_DDR3) +u32 mct_AdjustSPDTimings(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA, u32 val) { if (pDCTstatA->LogicalCPUID & AMD_DR_Bx) { if (pDCTstatA->Status & (1 << SB_Registered)) { @@ -528,17 +524,17 @@ static u32 mct_AdjustSPDTimings(struct MCTStatStruc *pMCTstat, struct DCTStatStr } #endif -static void mctHookAfterAnyTraining(void) +void mctHookAfterAnyTraining(void) { } -static uint64_t mctGetLogicalCPUID_D(u8 node) +uint64_t mctGetLogicalCPUID_D(u8 node) { return mctGetLogicalCPUID(node); } -#if (CONFIG_DIMM_SUPPORT & 0x000F)!=0x0005 /* not needed for AMD_FAM10_DDR3 */ -static u8 mctSetNodeBoundary_D(void) +#if IS_ENABLED(CONFIG_DIMM_DDR2) +u8 mctSetNodeBoundary_D(void) { return 0; } -- cgit v1.2.3