diff options
author | Arthur Heymans <arthur@aheymans.xyz> | 2019-11-19 15:46:49 +0100 |
---|---|---|
committer | Kyösti Mälkki <kyosti.malkki@gmail.com> | 2019-11-20 19:08:30 +0000 |
commit | ffcac3eb502bbe0acbb30d6fe804f00e07461a7a (patch) | |
tree | d5deda572bb252a683a5ece24a5c4916ee198836 /src/northbridge/amd/amdmct/mct | |
parent | 1ca978ee6529251ed80b47da679be7adc75fa46a (diff) |
nb/amd/fam10: Drop support
Relocatable ramstage, postcar stage and C_ENVIRONMENT_BOOTBLOCK are
now mandatory features, which this platform lacks.
Change-Id: If36ef0749dbb661f731fb04829bd7e2202ebb422
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/36962
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: HAOUAS Elyes <ehaouas@noos.fr>
Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Diffstat (limited to 'src/northbridge/amd/amdmct/mct')
21 files changed, 0 insertions, 10570 deletions
diff --git a/src/northbridge/amd/amdmct/mct/Makefile.inc b/src/northbridge/amd/amdmct/mct/Makefile.inc deleted file mode 100644 index f986201c6d..0000000000 --- a/src/northbridge/amd/amdmct/mct/Makefile.inc +++ /dev/null @@ -1,16 +0,0 @@ -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.h b/src/northbridge/amd/amdmct/mct/mct.h deleted file mode 100644 index 598ab37e76..0000000000 --- a/src/northbridge/amd/amdmct/mct/mct.h +++ /dev/null @@ -1,539 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Advanced Micro Devices, Inc. - * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef MCT_H -#define MCT_H - -#include <stdint.h> - -/*=========================================================================== - CPU - K8/FAM10 -===========================================================================*/ -#define PT_L1 0 /* CPU Package Type*/ -#define PT_M2 1 -#define PT_S1 2 - -#define J_MIN 0 /* j loop constraint. 1 = CL 2.0 T*/ -#define J_MAX 4 /* j loop constraint. 4 = CL 6.0 T*/ -#define K_MIN 1 /* k loop constraint. 1 = 200 MHz*/ -#define K_MAX 4 /* k loop constraint. 9 = 400 MHz*/ -#define CL_DEF 2 /* Default value for failsafe operation. 2 = CL 4.0 T*/ -#define T_DEF 1 /* Default value for failsafe operation. 1 = 5ns (cycle time)*/ - -#define BSCRate 1 /* reg bit field = rate of dram scrubber for ecc*/ - /* memory initialization (ecc and check-bits).*/ - /* 1 = 40 ns/64 bytes.*/ -#define FirstPass 1 /* First pass through RcvEn training*/ -#define SecondPass 2 /* Second pass through Rcven training*/ - -#define RCVREN_MARGIN 6 /* number of DLL taps to delay beyond first passing position*/ -#define MAXASYNCLATCTL_3 60 /* Max Async Latency Control value (This value will be divided by 20)*/ -#define DQS_FAIL 1 -#define DQS_PASS 0 -#define DQS_WRITEDIR 0 -#define DQS_READDIR 1 -#define MIN_DQS_WNDW 3 -#define secPassOffset 6 - -#define PA_HOST (((24 << 3)+0) << 8) /* Node 0 Host Bus function PCI Address bits [15:0] */ -#define PA_MAP (((24 << 3)+1) << 8) /* Node 0 MAP function PCI Address bits [15:0] */ -#define PA_DCT (((24 << 3)+2) << 8) /* Node 0 DCT function PCI Address bits [15:0] */ -#define PA_DCTADDL (((00 << 3)+2) << 8) /* Node x DCT function, Additional Registers PCI Address bits [15:0] */ -#define PA_NBMISC (((24 << 3)+3) << 8) /* Node 0 Misc PCI Address bits [15:0] */ -#define PA_NBDEVOP (((00 << 3)+3) << 8) /* Node 0 Misc PCI Address bits [15:0] */ - -#define DCC_EN 1 /* X:2:0x94[19]*/ -#define ILD_Lmt 3 /* X:2:0x94[18:16]*/ - -#define EncodedTSPD 0x00191709 /* encodes which SPD byte to get T from*/ - /* versus CL X, CL X-.5, and CL X-1*/ - -#define Bias_TrpT 3 /* bias to convert bus clocks to bit field value*/ -#define Bias_TrrdT 2 -#define Bias_TrcdT 3 -#define Bias_TrasT 3 -#define Bias_TrcT 11 -#define Bias_TrtpT 4 -#define Bias_TwrT 3 -#define Bias_TwtrT 0 - -#define Min_TrpT 3 /* min programmable value in busclocks*/ -#define Max_TrpT 6 /* max programmable value in busclocks*/ -#define Min_TrrdT 2 -#define Max_TrrdT 5 -#define Min_TrcdT 3 -#define Max_TrcdT 6 -#define Min_TrasT 5 -#define Max_TrasT 18 -#define Min_TrcT 11 -#define Max_TrcT 26 -#define Min_TrtpT 4 -#define Max_TrtpT 5 -#define Min_TwrT 3 -#define Max_TwrT 6 -#define Min_TwtrT 1 -#define Max_TwtrT 3 - -/* common register bit names */ -#define DramHoleValid 0 /* func 1, offset F0h, bit 0 */ -#define CSEnable 0 /* func 2, offset 40h-5C, bit 0 */ -#define Spare 1 /* func 2, offset 40h-5C, bit 1 */ -#define TestFail 2 /* func 2, offset 40h-5C, bit 2 */ -#define DqsRcvEnTrain 18 /* func 2, offset 78h, bit 18 */ -#define EnDramInit 31 /* func 2, offset 7Ch, bit 31 */ -#define DisAutoRefresh 18 /* func 2, offset 8Ch, bit 18 */ -#define InitDram 0 /* func 2, offset 90h, bit 0 */ -#define BurstLength32 10 /* func 2, offset 90h, bit 10 */ -#define Width128 11 /* func 2, offset 90h, bit 11 */ -#define X4Dimm 12 /* func 2, offset 90h, bit 12 */ -#define UnBuffDimm 16 /* func 2, offset 90h, bit 16 */ -#define DimmEcEn 19 /* func 2, offset 90h, bit 19 */ -#define MemClkFreqVal 3 /* func 2, offset 94h, bit 3 */ -#define RDqsEn 12 /* func 2, offset 94h, bit 12 */ -#define DisDramInterface 14 /* func 2, offset 94h, bit 14 */ -#define DctAccessWrite 30 /* func 2, offset 98h, bit 30 */ -#define DctAccessDone 31 /* func 2, offset 98h, bit 31 */ -#define PwrSavingsEn 10 /* func 2, offset A0h, bit 10 */ -#define Mod64BitMux 4 /* func 2, offset A0h, bit 4 */ -#define DisableJitter 1 /* func 2, offset A0h, bit 1 */ -#define DramEnabled 9 /* func 2, offset A0h, bit 9 */ -#define SyncOnUcEccEn 2 /* func 3, offset 44h, bit 2 */ - -/*============================================================================= - Jedec DDR II -=============================================================================*/ -#define SPD_TYPE 2 /* SPD byte read location*/ - #define JED_DDRSDRAM 0x07 /* Jedec defined bit field*/ - #define JED_DDR2SDRAM 0x08 /* Jedec defined bit field*/ - -#define SPD_DIMMTYPE 20 -#define SPD_ATTRIB 21 - #define JED_DIFCKMSK 0x20 /* Differential Clock Input*/ - #define JED_REGADCMSK 0x11 /* Registered Address/Control*/ - #define JED_PROBEMSK 0x40 /* Analysis Probe installed*/ -#define SPD_DEVATTRIB 22 -#define SPD_EDCTYPE 11 - #define JED_ECC 0x02 - #define JED_ADRCPAR 0x04 -#define SPD_ROWSZ 3 -#define SPD_COLSZ 4 -#define SPD_LBANKS 17 /* number of [logical] banks on each device*/ -#define SPD_DMBANKS 5 /* number of physical banks on dimm*/ - #define SPDPLBit 4 /* Dram package bit*/ -#define SPD_BANKSZ 31 /* capacity of physical bank*/ -#define SPD_DEVWIDTH 13 -#define SPD_CASLAT 18 -#define SPD_TRP 27 -#define SPD_TRRD 28 -#define SPD_TRCD 29 -#define SPD_TRAS 30 -#define SPD_TWR 36 -#define SPD_TWTR 37 -#define SPD_TRTP 38 -#define SPD_TRCRFC 40 -#define SPD_TRC 41 -#define SPD_TRFC 42 - -#define SPD_MANDATEYR 93 /* Module Manufacturing Year (BCD) */ - -#define SPD_MANDATEWK 94 /* Module Manufacturing Week (BCD) */ - -/*-------------------------------------- - Jedec DDR II related equates ---------------------------------------*/ -#define MYEAR06 6 /* Manufacturing Year BCD encoding of 2006 - 06d*/ -#define MWEEK24 0x24 /* Manufacturing Week BCD encoding of June - 24d*/ - -/*============================================================================= - Macros -=============================================================================*/ - -#define _2GB_RJ8 (2<<(30-8)) -#define _4GB_RJ8 (4<<(30-8)) -#define _4GB_RJ4 (4<<(30-4)) - -#define BigPagex8_RJ8 (1<<(17+3-8)) /* 128KB * 8 >> 8 */ - -/*============================================================================= - Global MCT Status Structure -=============================================================================*/ -struct MCTStatStruc { - u32 GStatus; /* Global Status bitfield*/ - u32 HoleBase; /* If not zero, BASE[39:8] (system address) - of sub 4GB dram hole for HW remapping.*/ - u32 Sub4GCacheTop; /* If not zero, the 32-bit top of cacheable memory.*/ - u32 SysLimit; /* LIMIT[39:8] (system address)*/ -}; -/*============================================================================= - Global MCT Configuration Status Word (GStatus) -=============================================================================*/ -/*These should begin at bit 0 of GStatus[31:0]*/ -#define GSB_MTRRshort 0 /* Ran out of MTRRs while mapping memory*/ -#define GSB_ECCDIMMs 1 /* All banks of all Nodes are ECC capable*/ -#define GSB_DramECCDis 2 /* Dram ECC requested but not enabled.*/ -#define GSB_SoftHole 3 /* A Node Base gap was created*/ -#define GSB_HWHole 4 /* A HW dram remap was created*/ -#define GSB_NodeIntlv 5 /* Node Memory interleaving was enabled*/ -#define GSB_SpIntRemapHole 16 /* Special condition for Node Interleave and HW remapping*/ - - -/*=============================================================================== - Local DCT Status structure (a structure for each DCT) -===============================================================================*/ - -struct DCTStatStruc { /* A per Node structure*/ - u8 Node_ID; /* Node ID of current controller*/ - u8 ErrCode; /* Current error condition of Node - 0= no error - 1= Variance Error, DCT is running but not in an optimal configuration. - 2= Stop Error, DCT is NOT running - 3= Fatal Error, DCT/MCT initialization has been halted.*/ - u32 ErrStatus; /* Error Status bit Field */ - u32 Status; /* Status bit Field*/ - u8 DIMMAddr[8]; /* SPD address of DIMM controlled by MA0_CS_L[0,1]*/ - /* SPD address of..MB0_CS_L[0,1]*/ - /* SPD address of..MA1_CS_L[0,1]*/ - /* SPD address of..MB1_CS_L[0,1]*/ - /* SPD address of..MA2_CS_L[0,1]*/ - /* SPD address of..MB2_CS_L[0,1]*/ - /* SPD address of..MA3_CS_L[0,1]*/ - /* SPD address of..MB3_CS_L[0,1]*/ - u16 DIMMPresent; /* For each bit n 0..7, 1 = DIMM n is present. - DIMM# Select Signal - 0 MA0_CS_L[0,1] - 1 MB0_CS_L[0,1] - 2 MA1_CS_L[0,1] - 3 MB1_CS_L[0,1] - 4 MA2_CS_L[0,1] - 5 MB2_CS_L[0,1] - 6 MA3_CS_L[0,1] - 7 MB3_CS_L[0,1]*/ - u16 DIMMValid; /* For each bit n 0..7, 1 = DIMM n is valid and is/will be configured*/ - u16 DIMMSPDCSE; /* For each bit n 0..7, 1 = DIMM n SPD checksum error*/ - u16 DimmECCPresent; /* For each bit n 0..7, 1 = DIMM n is ECC capable.*/ - u16 DimmPARPresent; /* For each bit n 0..7, 1 = DIMM n is ADR/CMD Parity capable.*/ - u16 Dimmx4Present; /* For each bit n 0..7, 1 = DIMM n contains x4 data devices.*/ - u16 Dimmx8Present; /* For each bit n 0..7, 1 = DIMM n contains x8 data devices.*/ - u16 Dimmx16Present; /* For each bit n 0..7, 1 = DIMM n contains x16 data devices.*/ - u16 DIMM1Kpage; /* For each bit n 0..7, 1 = DIMM n contains 1K page devices.*/ - u8 MAload[2]; /* Number of devices loading MAA bus*/ - /* Number of devices loading MAB bus*/ - u8 MAdimms[2]; /* Number of DIMMs loading CH A*/ - /* Number of DIMMs loading CH B*/ - u8 DATAload[2]; /* Number of ranks loading CH A DATA*/ - /* Number of ranks loading CH B DATA*/ - u8 DIMMAutoSpeed; /* Max valid Mfg. Speed of DIMMs - 1 = 200MHz - 2 = 266MHz - 3 = 333MHz - 4 = 400MHz */ - u8 DIMMCASL; /* Min valid Mfg. CL bitfield - 0 = 2.0 - 1 = 3.0 - 2 = 4.0 - 3 = 5.0 - 4 = 6.0 */ - u16 DIMMTrcd; /* Minimax Trcd*40 (ns) of DIMMs*/ - u16 DIMMTrp; /* Minimax Trp*40 (ns) of DIMMs*/ - u16 DIMMTrtp; /* Minimax Trtp*40 (ns) of DIMMs*/ - u16 DIMMTras; /* Minimax Tras*40 (ns) of DIMMs*/ - u16 DIMMTrc; /* Minimax Trc*40 (ns) of DIMMs*/ - u16 DIMMTwr; /* Minimax Twr*40 (ns) of DIMMs*/ - u16 DIMMTrrd; /* Minimax Trrd*40 (ns) of DIMMs*/ - u16 DIMMTwtr; /* Minimax Twtr*40 (ns) of DIMMs*/ - u8 Speed; /* Bus Speed (to set Controller) - 1 = 200MHz - 2 = 266MHz - 3 = 333MHz - 4 = 400MHz */ - u8 CASL; /* CAS latency DCT setting - 0 = 2.0 - 1 = 3.0 - 2 = 4.0 - 3 = 5.0 - 4 = 6.0 */ - u8 Trcd; /* DCT Trcd (busclocks) */ - u8 Trp; /* DCT Trp (busclocks) */ - u8 Trtp; /* DCT Trtp (busclocks) */ - u8 Tras; /* DCT Tras (busclocks) */ - u8 Trc; /* DCT Trc (busclocks) */ - u8 Twr; /* DCT Twr (busclocks) */ - u8 Trrd; /* DCT Trrd (busclocks) */ - u8 Twtr; /* DCT Twtr (busclocks) */ - u8 Trfc[4]; /* DCT Logical DIMM0 Trfc - 0 = 75ns (for 256Mb devs) - 1 = 105ns (for 512Mb devs) - 2 = 127.5ns (for 1Gb devs) - 3 = 195ns (for 2Gb devs) - 4 = 327.5ns (for 4Gb devs) */ - /* DCT Logical DIMM1 Trfc (see Trfc0 for format) */ - /* DCT Logical DIMM2 Trfc (see Trfc0 for format) */ - /* DCT Logical DIMM3 Trfc (see Trfc0 for format) */ - u16 CSPresent; /* For each bit n 0..7, 1 = Chip-select n is present */ - u16 CSTestFail; /* For each bit n 0..7, 1 = Chip-select n is present but disabled */ - u32 DCTSysBase; /* BASE[39:8] (system address) of this Node's DCTs. */ - u32 DCTHoleBase; /* If not zero, BASE[39:8] (system address) of dram hole for HW remapping. Dram hole exists on this Node's DCTs. */ - u32 DCTSysLimit; /* LIMIT[39:8] (system address) of this Node's DCTs */ - u16 PresetmaxFreq; /* Maximum OEM defined DDR frequency - 200 = 200MHz (DDR400) - 266 = 266MHz (DDR533) - 333 = 333MHz (DDR667) - 400 = 400MHz (DDR800) */ - u8 _2Tmode; /* 1T or 2T CMD mode (slow access mode) - 1 = 1T - 2 = 2T */ - u8 TrwtTO; /* DCT TrwtTO (busclocks)*/ - u8 Twrrd; /* DCT Twrrd (busclocks)*/ - u8 Twrwr; /* DCT Twrwr (busclocks)*/ - u8 Trdrd; /* DCT Trdrd (busclocks)*/ - u32 CH_ODC_CTL[2]; /* Output Driver Strength (see BKDG FN2:Offset 9Ch, index 00h*/ - u32 CH_ADDR_TMG[2]; /* Address Bus Timing (see BKDG FN2:Offset 9Ch, index 04h*/ - /* Output Driver Strength (see BKDG FN2:Offset 9Ch, index 20h*/ - /* Address Bus Timing (see BKDG FN2:Offset 9Ch, index 24h*/ - u16 CH_EccDQSLike[2]; /* CHA DQS ECC byte like...*/ - u8 CH_EccDQSScale[2]; /* CHA DQS ECC byte scale*/ -// u8 reserved_b_1; /* Reserved*/ - /* CHB DQS ECC byte like...*/ - /* CHB DQS ECC byte scale*/ -// u8 reserved_b_2; /*Reserved*/ - u8 MaxAsyncLat; /* Max Asynchronous Latency (ns)*/ - u8 CH_B_DQS[2][2][9]; /* CHA Byte 0 - 7 and Check Write DQS Delay*/ - /* Reserved*/ - /* CHA Byte 0 - 7 and Check Read DQS Delay*/ - /* Reserved*/ - /* CHB Byte 0 - 7 and Check Write DQS Delay*/ - /* Reserved*/ - /* CHB Byte 0 - 7 and Check Read DQS Delay*/ - /* Reserved*/ - u8 CH_D_RCVRDLY[2][4]; /* CHA DIMM 0 - 3 Receiver Enable Delay*/ - /* CHB DIMM 0 - 3 Receiver Enable Delay*/ - u32 PtrPatternBufA; /* Ptr on stack to aligned DQS testing pattern*/ - u32 PtrPatternBufB; /*Ptr on stack to aligned DQS testing pattern*/ - u8 Channel; /* Current Channel (0= CH A, 1 = CH B)*/ - u8 ByteLane; /* Current Byte Lane (0..7)*/ - u8 Direction; /* Current DQS-DQ training write direction (0 = read, 1 = write)*/ - u8 Pattern; /* Current pattern*/ - u8 DQSDelay; /* Current DQS delay value*/ - u32 TrainErrors; /* Current Training Errors*/ -// u8 reserved_b_3; /* RSVD */ - u32 AMC_TSC_DeltaLo; /* Time Stamp Counter measurement of AMC, Low dword*/ - u32 AMC_TSC_DeltaHi; /* Time Stamp Counter measurement of AMC, High dword*/ - u8 CH_B_Dly[2][2][2][8]; /* CH A byte lane 0 - 7 minimum filtered window passing DQS delay value*/ - /* CH A byte lane 0 - 7 maximum filtered window passing DQS delay value*/ - /* CH B byte lane 0 - 7 minimum filtered window passing DQS delay value*/ - /* CH B byte lane 0 - 7 maximum filtered window passing DQS delay value*/ - /* CH A byte lane 0 - 7 minimum filtered window passing DQS delay value*/ - /* CH A byte lane 0 - 7 maximum filtered window passing DQS delay value*/ - /* CH B byte lane 0 - 7 minimum filtered window passing DQS delay value*/ - /* CH B byte lane 0 - 7 maximum filtered window passing DQS delay value*/ - u32 LogicalCPUID; /* The logical CPUID of the node*/ - u16 HostBiosSrvc1; /* Word sized general purpose field for use by host BIOS. Scratch space.*/ - u32 HostBiosSrvc2; /* Dword sized general purpose field for use by host BIOS. Scratch space.*/ - u16 DimmQRPresent; /* QuadRank DIMM present?*/ - u16 DimmTrainFail; /* Bitmap showing which dimms failed training*/ - u16 CSTrainFail; /* Bitmap showing which chipselects failed training*/ - u16 DimmYr06; /* Bitmap indicating which Dimms have a manufactur's year code <= 2006*/ - u16 DimmWk2406; /* Bitmap indicating which Dimms have a manufactur's week code <= 24 of 2006 (June)*/ - u16 DimmDRPresent; /* Bitmap indicating that Dual Rank Dimms are present*/ - u16 DimmPlPresent; /* Bitmap indicating that Planar (1) or Stacked (0) Dimms are present.*/ - u16 ChannelTrainFail; /* Bitmap showing the channel information about failed Chip Selects*/ - /* 0 in any bit field indicates Channel 0*/ - /* 1 in any bit field indicates Channel 1*/ -}; - -/*=============================================================================== - Local Error Status Codes (DCTStatStruc.ErrCode) -===============================================================================*/ -#define SC_RunningOK 0 -#define SC_VarianceErr 1 /* Running non-optimally*/ -#define SC_StopError 2 /* Not Running*/ -#define SC_FatalErr 3 /* Fatal Error, MCTB has exited immediately*/ - -/*=============================================================================== - Local Error Status (DCTStatStruc.ErrStatus[31:0]) - ===============================================================================*/ -#define SB_NoDimms 0 -#define SB_DIMMChkSum 1 -#define SB_DimmMismatchM 2 /* dimm module type(buffer) mismatch*/ -#define SB_DimmMismatchT 3 /* dimm CL/T mismatch*/ -#define SB_DimmMismatchO 4 /* dimm organization mismatch (128-bit)*/ -#define SB_NoTrcTrfc 5 /* SPD missing Trc or Trfc info*/ -#define SB_NoCycTime 6 /* SPD missing byte 23 or 25*/ -#define SB_BkIntDis 7 /* Bank interleave requested but not enabled*/ -#define SB_DramECCDis 8 /* Dram ECC requested but not enabled*/ -#define SB_SpareDis 9 /* Online spare requested but not enabled*/ -#define SB_MinimumMode 10 /* Running in Minimum Mode*/ -#define SB_NORCVREN 11 /* No DQS Receiver Enable pass window found*/ -#define SB_CHA2BRCVREN 12 /* DQS Rcvr En pass window CHA to CH B too large*/ -#define SB_SmallRCVR 13 /* DQS Rcvr En pass window too small (far right of dynamic range)*/ -#define SB_NODQSPOS 14 /* No DQS-DQ passing positions*/ -#define SB_SMALLDQS 15 /* DQS-DQ passing window too small*/ - -/*=============================================================================== - Local Configuration Status (DCTStatStruc.Status[31:0]) -===============================================================================*/ -#define SB_Registered 0 /* All DIMMs are Registered*/ -#define SB_ECCDIMMs 1 /* All banks ECC capable*/ -#define SB_PARDIMMs 2 /* All banks Addr/CMD Parity capable*/ -#define SB_DiagClks 3 /* Jedec ALL slots clock enable diag mode*/ -#define SB_128bitmode 4 /* DCT in 128-bit mode operation*/ -#define SB_64MuxedMode 5 /* DCT in 64-bit mux'ed mode.*/ -#define SB_2TMode 6 /* 2T CMD timing mode is enabled.*/ -#define SB_SWNodeHole 7 /* Remapping of Node Base on this Node to create a gap.*/ -#define SB_HWHole 8 /* Memory Hole created on this Node using HW remapping.*/ - - - -/*=============================================================================== - NVRAM/run-time-configurable Items -===============================================================================*/ -/* Platform Configuration */ -#define NV_PACK_TYPE 0 /* CPU Package Type (2-bits) - 0 = NPT L1 - 1 = NPT M2 - 2 = NPT S1*/ -#define NV_MAX_NODES 1 /* Number of Nodes/Sockets (4-bits)*/ -#define NV_MAX_DIMMS 2 /* Number of DIMM slots for the specified Node ID (4-bits)*/ -#define NV_MAX_MEMCLK 3 /* Maximum platform demonstrated Memclock (10-bits) - 200 = 200MHz (DDR400) - 266 = 266MHz (DDR533) - 333 = 333MHz (DDR667) - 400 = 400MHz (DDR800)*/ -#define NV_ECC_CAP 4 /* Bus ECC capable (1-bits) - 0 = Platform not capable - 1 = Platform is capable*/ -#define NV_4RANKType 5 /* Quad Rank DIMM slot type (2-bits) - 0 = Normal - 1 = R4 (4-Rank Registered DIMMs in AMD server configuration) - 2 = S4 (Unbuffered SO-DIMMs)*/ -#define NV_BYPMAX 6 /* Value to set DcqBypassMax field (See Function 2, Offset 94h, [27:24] of BKDG for field definition). - 4 = 4 times bypass (normal for non-UMA systems) - 7 = 7 times bypass (normal for UMA systems)*/ -#define NV_RDWRQBYP 7 /* Value to set RdWrQByp field (See Function 2, Offset A0h, [3:2] of BKDG for field definition). - 2 = 8 times (normal for non-UMA systems) - 3 = 16 times (normal for UMA systems)*/ - - -/* Dram Timing */ -#define NV_MCTUSRTMGMODE 10 /* User Memclock Mode (2-bits) - 0 = Auto, no user limit - 1 = Auto, user limit provided in NV_MemCkVal - 2 = Manual, user value provided in NV_MemCkVal*/ -#define NV_MemCkVal 11 /* Memory Clock Value (2-bits) - 0 = 200MHz - 1 = 266MHz - 2 = 333MHz - 3 = 400MHz*/ - -/* Dram Configuration */ -#define NV_BankIntlv 20 /* Dram Bank (chip-select) Interleaving (1-bits) - 0 = disable - 1 = enable*/ -#define NV_AllMemClks 21 /* Turn on All DIMM clocks (1-bits) - 0 = normal - 1 = enable all memclocks*/ -#define NV_SPDCHK_RESTRT 22 /* SPD Check control bitmap (1-bits) - 0 = Exit current node init if any DIMM has SPD checksum error - 1 = Ignore faulty SPD checksums (Note: DIMM cannot be enabled)*/ -#define NV_DQSTrainCTL 23 /* DQS Signal Timing Training Control - 0 = skip DQS training - 1 = perform DQS training*/ -#define NV_NodeIntlv 24 /* Node Memory Interleaving (1-bits) - 0 = disable - 1 = enable*/ -#define NV_BurstLen32 25 /* burstLength32 for 64-bit mode (1-bits) - 0 = disable (normal) - 1 = enable (4 beat burst when width is 64-bits)*/ - -/* Dram Power */ -#define NV_CKE_PDEN 30 /* CKE based power down mode (1-bits) - 0 = disable - 1 = enable*/ -#define NV_CKE_CTL 31 /* CKE based power down control (1-bits) - 0 = per Channel control - 1 = per Chip select control*/ -#define NV_CLKHZAltVidC3 32 /* Memclock tri-stating during C3 and Alt VID (1-bits) - 0 = disable - 1 = enable*/ - -/* Memory Map/Mgt.*/ -#define NV_BottomIO 40 /* Bottom of 32-bit IO space (8-bits) - NV_BottomIO[7:0]=Addr[31:24]*/ -#define NV_BottomUMA 41 /* Bottom of shared graphics dram (8-bits) - NV_BottomUMA[7:0]=Addr[31:24]*/ -#define NV_MemHole 42 /* Memory Hole Remapping (1-bits) - 0 = disable - 1 = enable */ - -/* ECC */ -#define NV_ECC 50 /* Dram ECC enable*/ -#define NV_NBECC 52 /* ECC MCE enable*/ -#define NV_ChipKill 53 /* Chip-Kill ECC Mode enable*/ -#define NV_ECCRedir 54 /* Dram ECC Redirection enable*/ -#define NV_DramBKScrub 55 /* Dram ECC Background Scrubber CTL*/ -#define NV_L2BKScrub 56 /* L2 ECC Background Scrubber CTL*/ -#define NV_DCBKScrub 57 /* DCache ECC Background Scrubber CTL*/ -#define NV_CS_SpareCTL 58 /* Chip Select Spare Control bit 0: - 0 = disable Spare - 1 = enable Spare */ - /*Chip Select Spare Control bit 1-4: - Reserved, must be zero*/ -#define NV_Parity 60 /* Parity Enable*/ -#define NV_SyncOnUnEccEn 61 /* SyncOnUnEccEn control - 0 = disable - 1 = enable*/ - - -/* global function */ -u32 NodePresent(u32 Node); -u32 Get_NB32n(struct DCTStatStruc *pDCTstat, u32 addrx); -u32 Get_NB32(u32 addr); /* NOTE: extend addr to 32 bit for bus > 0 */ -uint64_t mctGetLogicalCPUID(u32 Node); - -void K8FInterleaveBanks(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat); - -void mctInitWithWritetoCS(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat); - -void mctGet_PS_Cfg(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat); -void Get_ChannelPS_Cfg0(unsigned int MAAdimms, unsigned int Speed, unsigned int MAAload, unsigned int DATAAload, - unsigned int *AddrTmgCTL, unsigned int *ODC_CTL); -void Get_ChannelPS_Cfg1(unsigned int MAAdimms, unsigned int Speed, unsigned int MAAload, - unsigned int *AddrTmgCTL, unsigned int *ODC_CTL, unsigned int *val); -void Get_ChannelPS_Cfg2(unsigned int MAAdimms, unsigned int Speed, unsigned int MAAload, - unsigned int *AddrTmgCTL, unsigned int *ODC_CTL, unsigned int *val); - -u8 MCTDefRet(void); - -u32 Get_RcvrSysAddr(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 channel, u8 receiver, u8 *valid); -u32 Get_MCTSysAddr(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 channel, u8 chipsel, u8 *valid); -void K8FTrainReceiverEn(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA, u8 pass); -void K8FTrainDQSPos(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); -u32 SetUpperFSbase(u32 addr_hi); - - -void K8FECCInit(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); - -void amd_MCTInit(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); - -void K8FCPUMemTyping(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); -void K8FCPUMemTyping_clear(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); - -void K8FWaitMemClrDelay(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat); -unsigned int K8FCalcFinalDQSRcvValue(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, unsigned int LeftRcvEn, unsigned int RightRcvEn, unsigned int *valid); - -void K8FGetDeltaTSCPart1(struct DCTStatStruc *pDCTstat); -void K8FGetDeltaTSCPart2(struct DCTStatStruc *pDCTstat); -#endif diff --git a/src/northbridge/amd/amdmct/mct/mct_d.c b/src/northbridge/amd/amdmct/mct/mct_d.c deleted file mode 100644 index 60a2c66de3..0000000000 --- a/src/northbridge/amd/amdmct/mct/mct_d.c +++ /dev/null @@ -1,3980 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2015-2017 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * Copyright (C) 2007-2008 Advanced Micro Devices, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -/* Description: Main memory controller system configuration for DDR 2 */ - - -/* KNOWN ISSUES - ERRATA - * - * Trtp is not calculated correctly when the controller is in 64-bit mode, it - * is 1 busclock off. No fix planned. The controller is not ordinarily in - * 64-bit mode. - * - * 32 Byte burst not supported. No fix planned. The controller is not - * ordinarily in 64-bit mode. - * - * Trc precision does not use extra Jedec defined fractional component. - * Instead Trc (course) is rounded up to nearest 1 ns. - * - * Mini and Micro DIMM not supported. Only RDIMM, UDIMM, SO-DIMM defined types - * supported. - */ - -#include <string.h> -#include <console/console.h> -#include <cpu/amd/msr.h> -#include <device/pci_ops.h> - -#include "mct_d.h" - -static u8 ReconfigureDIMMspare_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA); -static void DQSTiming_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA); -static void LoadDQSSigTmgRegs_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA); -static void HTMemMapInit_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA); -static void DCTMemClr_Sync_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -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, - struct DCTStatStruc *pDCTstat, u8 dct); -static void GetPresetmaxF_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -static void SPDGetTCL_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static u8 AutoConfig_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static 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, - struct DCTStatStruc *pDCTstat, u8 dct); -static u8 Get_DefTrc_k_D(u8 k); -static u16 Get_40Tk_D(u8 k); -static u16 Get_Fk_D(u8 k); -static u8 Dimm_Supports_D(struct DCTStatStruc *pDCTstat, u8 i, u8 j, u8 k); -static u8 Sys_Capability_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, int j, int k); -static u8 Get_DIMMAddress_D(struct DCTStatStruc *pDCTstat, u8 i); -static void mct_initDCT(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -static void mct_DramInit(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static void mct_SyncDCTsReady(struct DCTStatStruc *pDCTstat); -static void Get_Trdrd(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static void mct_AfterGetCLT(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static u8 mct_SPDCalcWidth(struct MCTStatStruc *pMCTstat,\ - struct DCTStatStruc *pDCTstat, u8 dct); -static void mct_AfterStitchMemory(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static u8 mct_DIMMPresence(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static void Set_OtherTiming(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static void Get_Twrwr(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static void Get_Twrrd(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static void Get_TrwtTO(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static void Get_TrwtWB(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -static u8 Check_DqsRcvEn_Diff(struct DCTStatStruc *pDCTstat, u8 dct, - u32 dev, u32 index_reg, u32 index); -static u8 Get_DqsRcvEnGross_Diff(struct DCTStatStruc *pDCTstat, - u32 dev, u32 index_reg); -static u8 Get_WrDatGross_Diff(struct DCTStatStruc *pDCTstat, u8 dct, - u32 dev, u32 index_reg); -static u16 Get_DqsRcvEnGross_MaxMin(struct DCTStatStruc *pDCTstat, - u32 dev, u32 index_reg, u32 index); -static void mct_FinalMCT_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -static u16 Get_WrDatGross_MaxMin(struct DCTStatStruc *pDCTstat, u8 dct, - u32 dev, u32 index_reg, u32 index); -static void mct_InitialMCT_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -static void mct_init(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -static void clear_legacy_Mode(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -static void mct_HTMemMapExt(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA); -static void SetCSTriState(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static void SetODTTriState(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 WaitRoutine_D(u32 time); -static void mct_OtherTiming(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA); -static void mct_ResetDataStruct_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA); -static void mct_EarlyArbEn_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -static void mct_BeforeDramInit_Prod_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -void mct_ClrClToNB_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -static u8 CheckNBCOFEarlyArbEn(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -void mct_ClrWbEnhWsbDis_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -static void mct_BeforeDQSTrain_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA); -static void AfterDramInit_D(struct DCTStatStruc *pDCTstat, u8 dct); -static void mct_ResetDLL_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); -static u32 mct_DisDllShutdownSR(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u32 DramConfigLo, u8 dct); -static void mct_EnDllShutdownSR(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct); - -/*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 Table_T_k[] = {0x00,0x50,0x3D,0x30,0x25, 0x18 }; -static const u8 Table_CL2_j[] = {0x04,0x08,0x10,0x20,0x40, 0x80 }; -static const u8 Tab_defTrc_k[] = {0x0,0x41,0x3C,0x3C,0x3A, 0x3A }; -static const u16 Tab_40T_k[] = {00,200,150,120,100,75 }; -static const u8 Tab_BankAddr[] = {0x0,0x08,0x09,0x10,0x0C,0x0D,0x11,0x0E,0x15,0x16,0x0F,0x17}; -static const u8 Tab_tCL_j[] = {0,2,3,4,5}; -static const u8 Tab_1KTfawT_k[] = {00,8,10,13,14,20}; -static const u8 Tab_2KTfawT_k[] = {00,10,14,17,18,24}; -static const u8 Tab_L1CLKDis[] = {8,8,6,4,2,0,8,8}; -static const u8 Tab_M2CLKDis[] = {2,0,8,8,2,0,2,0}; -static const u8 Tab_S1CLKDis[] = {8,0,8,8,8,0,8,0}; -static const u8 Table_Comp_Rise_Slew_20x[] = {7, 3, 2, 2, 0xFF}; -static const u8 Table_Comp_Rise_Slew_15x[] = {7, 7, 3, 2, 0xFF}; -static const u8 Table_Comp_Fall_Slew_20x[] = {7, 5, 3, 2, 0xFF}; -static const u8 Table_Comp_Fall_Slew_15x[] = {7, 7, 5, 3, 0xFF}; - -const u8 Table_DQSRcvEn_Offset[] = {0x00,0x01,0x10,0x11,0x2}; - -void mctAutoInitMCT_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - /* - * Memory may be mapped contiguously all the way up to 4GB (depending - * on setup options). It is the responsibility of PCI subsystem to - * create an uncacheable IO region below 4GB and to adjust TOP_MEM - * downward prior to any IO mapping or accesses. It is the same - * responsibility of the CPU sub-system prior to accessing LAPIC. - * - * Slot Number is an external convention, and is determined by OEM with - * accompanying silk screening. OEM may choose to use Slot number - * convention which is consistent with DIMM number conventions. - * All AMD engineering - * platforms do. - * - * Run-Time Requirements: - * 1. Complete Hypertransport Bus Configuration - * 2. SMBus Controller Initialized - * 3. Checksummed or Valid NVRAM bits - * 4. MCG_CTL=-1, MC4_CTL_EN = 0 for all CPUs - * 5. MCi_STS from shutdown/warm reset recorded (if desired) prior to - * entry - * 6. All var MTRRs reset to zero - * 7. State of NB_CFG.DisDatMsk set properly on all CPUs - * 8. All CPUs at 2GHz Speed (unless DQS training is not installed). - * 9. All cHT links at max Speed/Width (unless DQS training is not - * installed). - * - * - * Global relationship between index values and item values: - * j CL(j) k F(k) - * -------------------------- - * 0 2.0 - - - * 1 3.0 1 200 MHz - * 2 4.0 2 266 MHz - * 3 5.0 3 333 MHz - * 4 6.0 4 400 MHz - * 5 7.0 5 533 MHz - */ - u8 Node, NodesWmem; - u32 node_sys_base; - -restartinit: - mctInitMemGPIOs_A_D(); /* Set any required GPIOs*/ - NodesWmem = 0; - node_sys_base = 0; - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - pDCTstat->Node_ID = Node; - pDCTstat->dev_host = PA_HOST(Node); - pDCTstat->dev_map = PA_MAP(Node); - pDCTstat->dev_dct = PA_DCT(Node); - pDCTstat->dev_nbmisc = PA_NBMISC(Node); - pDCTstat->NodeSysBase = node_sys_base; - - if (mctGet_NVbits(NV_PACK_TYPE) == PT_GR) { - uint32_t dword; - pDCTstat->Dual_Node_Package = 1; - - /* Get the internal node number */ - dword = Get_NB32(pDCTstat->dev_nbmisc, 0xe8); - dword = (dword >> 30) & 0x3; - pDCTstat->Internal_Node_ID = dword; - } else { - pDCTstat->Dual_Node_Package = 0; - } - - print_tx("mctAutoInitMCT_D: mct_init Node ", Node); - mct_init(pMCTstat, pDCTstat); - mctNodeIDDebugPort_D(); - pDCTstat->NodePresent = NodePresent_D(Node); - if (pDCTstat->NodePresent) { /* See if Node is there*/ - print_t("mctAutoInitMCT_D: clear_legacy_Mode\n"); - clear_legacy_Mode(pMCTstat, pDCTstat); - pDCTstat->LogicalCPUID = mctGetLogicalCPUID_D(Node); - - print_t("mctAutoInitMCT_D: mct_InitialMCT_D\n"); - mct_InitialMCT_D(pMCTstat, pDCTstat); - - print_t("mctAutoInitMCT_D: mctSMBhub_Init\n"); - mctSMBhub_Init(Node); /* Switch SMBUS crossbar to proper node*/ - - print_t("mctAutoInitMCT_D: mct_initDCT\n"); - mct_initDCT(pMCTstat, pDCTstat); - if (pDCTstat->ErrCode == SC_FatalErr) { - goto fatalexit; /* any fatal errors?*/ - } else if (pDCTstat->ErrCode < SC_StopError) { - NodesWmem++; - } - } /* if Node present */ - node_sys_base = pDCTstat->NodeSysBase; - node_sys_base += (pDCTstat->NodeSysLimit + 2) & ~0x0F; - } - if (NodesWmem == 0) { - printk(BIOS_DEBUG, "No Nodes?!\n"); - goto fatalexit; - } - - print_t("mctAutoInitMCT_D: SyncDCTsReady_D\n"); - SyncDCTsReady_D(pMCTstat, pDCTstatA); /* Make sure DCTs are ready for accesses.*/ - - print_t("mctAutoInitMCT_D: HTMemMapInit_D\n"); - HTMemMapInit_D(pMCTstat, pDCTstatA); /* Map local memory into system address space.*/ - mctHookAfterHTMap(); - - print_t("mctAutoInitMCT_D: CPUMemTyping_D\n"); - CPUMemTyping_D(pMCTstat, pDCTstatA); /* Map dram into WB/UC CPU cacheability */ - mctHookAfterCPU(); /* Setup external northbridge(s) */ - - print_t("mctAutoInitMCT_D: DQSTiming_D\n"); - DQSTiming_D(pMCTstat, pDCTstatA); /* Get Receiver Enable and DQS signal timing*/ - - print_t("mctAutoInitMCT_D: UMAMemTyping_D\n"); - UMAMemTyping_D(pMCTstat, pDCTstatA); /* Fix up for UMA sizing */ - - print_t("mctAutoInitMCT_D: :OtherTiming\n"); - mct_OtherTiming(pMCTstat, pDCTstatA); - - if (ReconfigureDIMMspare_D(pMCTstat, pDCTstatA)) { /* RESET# if 1st pass of DIMM spare enabled*/ - goto restartinit; - } - - InterleaveNodes_D(pMCTstat, pDCTstatA); - InterleaveChannels_D(pMCTstat, pDCTstatA); - - print_t("mctAutoInitMCT_D: ECCInit_D\n"); - if (ECCInit_D(pMCTstat, pDCTstatA)) { /* Setup ECC control and ECC check-bits*/ - print_t("mctAutoInitMCT_D: MCTMemClr_D\n"); - MCTMemClr_D(pMCTstat,pDCTstatA); - } - - mct_FinalMCT_D(pMCTstat, (pDCTstatA + 0)); // Node 0 - print_tx("mctAutoInitMCT_D Done: Global Status: ", pMCTstat->GStatus); - return; - -fatalexit: - die("mct_d: fatalexit"); -} - - -static u8 ReconfigureDIMMspare_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - u8 ret; - - if (mctGet_NVbits(NV_CS_SpareCTL)) { - if (MCT_DIMM_SPARE_NO_WARM) { - /* Do no warm-reset DIMM spare */ - if (pMCTstat->GStatus & (1 << GSB_EnDIMMSpareNW)) { - LoadDQSSigTmgRegs_D(pMCTstat, pDCTstatA); - ret = 0; - } else { - mct_ResetDataStruct_D(pMCTstat, pDCTstatA); - pMCTstat->GStatus |= 1 << GSB_EnDIMMSpareNW; - ret = 1; - } - } else { - /* Do warm-reset DIMM spare */ - if (mctGet_NVbits(NV_DQSTrainCTL)) - mctWarmReset_D(); - ret = 0; - } - - - } else { - ret = 0; - } - - return ret; -} - - -static void DQSTiming_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - u8 nv_DQSTrainCTL; - - if (pMCTstat->GStatus & (1 << GSB_EnDIMMSpareNW)) { - return; - } - nv_DQSTrainCTL = mctGet_NVbits(NV_DQSTrainCTL); - /* FIXME: BOZO- DQS training every time*/ - nv_DQSTrainCTL = 1; - - print_t("DQSTiming_D: mct_BeforeDQSTrain_D:\n"); - mct_BeforeDQSTrain_D(pMCTstat, pDCTstatA); - phyAssistedMemFnceTraining(pMCTstat, pDCTstatA); - - if (nv_DQSTrainCTL) { - mctHookBeforeAnyTraining(pMCTstat, pDCTstatA); - - print_t("DQSTiming_D: TrainReceiverEn_D FirstPass:\n"); - TrainReceiverEn_D(pMCTstat, pDCTstatA, FirstPass); - - print_t("DQSTiming_D: mct_TrainDQSPos_D\n"); - mct_TrainDQSPos_D(pMCTstat, pDCTstatA); - - // Second Pass never used for Barcelona! - //print_t("DQSTiming_D: TrainReceiverEn_D SecondPass:\n"); - //TrainReceiverEn_D(pMCTstat, pDCTstatA, SecondPass); - - print_t("DQSTiming_D: mctSetEccDQSRcvrEn_D\n"); - mctSetEccDQSRcvrEn_D(pMCTstat, pDCTstatA); - - print_t("DQSTiming_D: TrainMaxReadLatency_D\n"); -//FIXME - currently uses calculated value TrainMaxReadLatency_D(pMCTstat, pDCTstatA); - mctHookAfterAnyTraining(); - mctSaveDQSSigTmg_D(); - - print_t("DQSTiming_D: mct_EndDQSTraining_D\n"); - mct_EndDQSTraining_D(pMCTstat, pDCTstatA); - - print_t("DQSTiming_D: MCTMemClr_D\n"); - MCTMemClr_D(pMCTstat, pDCTstatA); - } else { - mctGetDQSSigTmg_D(); /* get values into data structure */ - LoadDQSSigTmgRegs_D(pMCTstat, pDCTstatA); /* load values into registers.*/ - //mctDoWarmResetMemClr_D(); - MCTMemClr_D(pMCTstat, pDCTstatA); - } -} - - -static void LoadDQSSigTmgRegs_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - u8 Node, Receiver, Channel, Dir, DIMM; - u32 dev; - u32 index_reg; - u32 reg; - u32 index; - u32 val; - - - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - - if (pDCTstat->DCTSysLimit) { - dev = pDCTstat->dev_dct; - for (Channel = 0;Channel < 2; Channel++) { - /* there are four receiver pairs, - loosely associated with chipselects.*/ - index_reg = 0x98 + Channel * 0x100; - for (Receiver = 0; Receiver < 8; Receiver += 2) { - /* Set Receiver Enable Values */ - mct_SetRcvrEnDly_D(pDCTstat, - 0, /* RcvrEnDly */ - 1, /* FinalValue, From stack */ - Channel, - Receiver, - dev, index_reg, - (Receiver >> 1) * 3 + 0x10, /* Addl_Index */ - 2); /* Pass Second Pass ? */ - - } - } - for (Channel = 0; Channel < 2; Channel++) { - SetEccDQSRcvrEn_D(pDCTstat, Channel); - } - - for (Channel = 0; Channel < 2; Channel++) { - u8 *p; - index_reg = 0x98 + Channel * 0x100; - - /* NOTE: - * when 400, 533, 667, it will support dimm0/1/2/3, - * and set conf for dimm0, hw will copy to dimm1/2/3 - * set for dimm1, hw will copy to dimm3 - * Rev A/B only support DIMM0/1 when 800MHz and above - * + 0x100 to next dimm - * Rev C support DIMM0/1/2/3 when 800MHz and above - * + 0x100 to next dimm - */ - for (DIMM = 0; DIMM < 2; DIMM++) { - if (DIMM == 0) { - index = 0; /* CHA Write Data Timing Low */ - } else { - if (pDCTstat->Speed >= 4) { - index = 0x100 * DIMM; - } else { - break; - } - } - for (Dir = 0; Dir < 2; Dir++) {//RD/WR - p = pDCTstat->persistentData.CH_D_DIR_B_DQS[Channel][DIMM][Dir]; - val = stream_to_int(p); /* CHA Read Data Timing High */ - Set_NB32_index_wait(dev, index_reg, index+1, val); - val = stream_to_int(p+4); /* CHA Write Data Timing High */ - Set_NB32_index_wait(dev, index_reg, index+2, val); - val = *(p+8); /* CHA Write ECC Timing */ - Set_NB32_index_wait(dev, index_reg, index+3, val); - index += 4; - } - } - } - - for (Channel = 0; Channel < 2; Channel++) { - reg = 0x78 + Channel * 0x100; - val = Get_NB32(dev, reg); - val &= ~(0x3ff<<22); - val |= ((u32) pDCTstat->CH_MaxRdLat[Channel] << 22); - val &= ~(1 << DqsRcvEnTrain); - Set_NB32(dev, reg, val); /* program MaxRdLatency to correspond with current delay*/ - } - } - } -} - -#ifdef UNUSED_CODE -static void ResetNBECCstat_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA); -static void ResetNBECCstat_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - /* Clear MC4_STS for all Nodes in the system. This is required in some - * circumstances to clear left over garbage from cold reset, shutdown, - * or normal ECC memory conditioning. - */ - - //FIXME: this function depends on pDCTstat Array (with Node id) - Is this really a problem? - - u32 dev; - u8 Node; - - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - - if (pDCTstat->NodePresent) { - dev = pDCTstat->dev_nbmisc; - /*MCA NB Status Low (alias to MC4_STS[31:0] */ - Set_NB32(dev, 0x48, 0); - /* MCA NB Status High (alias to MC4_STS[63:32] */ - Set_NB32(dev, 0x4C, 0); - } - } -} -#endif - -static void HTMemMapInit_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - u8 Node; - u32 NextBase, BottomIO; - u8 _MemHoleRemap, DramHoleBase; - u32 HoleSize, DramSelBaseAddr; - - u32 val; - u32 base; - u32 limit; - u32 dev, devx; - struct DCTStatStruc *pDCTstat; - - _MemHoleRemap = mctGet_NVbits(NV_MemHole); - - if (pMCTstat->HoleBase == 0) { - DramHoleBase = mctGet_NVbits(NV_BottomIO); - } else { - DramHoleBase = pMCTstat->HoleBase >> (24-8); - } - - BottomIO = DramHoleBase << (24-8); - - NextBase = 0; - pDCTstat = pDCTstatA + 0; - dev = pDCTstat->dev_map; - - - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - pDCTstat = pDCTstatA + Node; - devx = pDCTstat->dev_map; - DramSelBaseAddr = 0; - if (!pDCTstat->GangedMode) { - DramSelBaseAddr = pDCTstat->NodeSysLimit - pDCTstat->DCTSysLimit; - /*In unganged mode, we must add DCT0 and DCT1 to DCTSysLimit */ - val = pDCTstat->NodeSysLimit; - if ((val & 0xFF) == 0xFE) { - DramSelBaseAddr++; - val++; - } - pDCTstat->DCTSysLimit = val; - } - - base = pDCTstat->DCTSysBase; - limit = pDCTstat->DCTSysLimit; - if (limit > base) { - base += NextBase; - limit += NextBase; - DramSelBaseAddr += NextBase; - printk(BIOS_DEBUG, " Node: %02x base: %02x limit: %02x BottomIO: %02x\n", Node, base, limit, BottomIO); - - if (_MemHoleRemap) { - if ((base < BottomIO) && (limit >= BottomIO)) { - /* HW Dram Remap */ - pDCTstat->Status |= 1 << SB_HWHole; - pMCTstat->GStatus |= 1 << GSB_HWHole; - pDCTstat->DCTSysBase = base; - pDCTstat->DCTSysLimit = limit; - pDCTstat->DCTHoleBase = BottomIO; - pMCTstat->HoleBase = BottomIO; - HoleSize = _4GB_RJ8 - BottomIO; /* HoleSize[39:8] */ - if ((DramSelBaseAddr > 0) && (DramSelBaseAddr < BottomIO)) - base = DramSelBaseAddr; - val = ((base + HoleSize) >> (24-8)) & 0xFF; - val <<= 8; /* shl 16, rol 24 */ - val |= DramHoleBase << 24; - val |= 1 << DramHoleValid; - Set_NB32(devx, 0xF0, val); /* Dram Hole Address Reg */ - pDCTstat->DCTSysLimit += HoleSize; - base = pDCTstat->DCTSysBase; - limit = pDCTstat->DCTSysLimit; - } else if (base == BottomIO) { - /* SW Node Hoist */ - pMCTstat->GStatus |= 1 << GSB_SpIntRemapHole; - pDCTstat->Status |= 1 << SB_SWNodeHole; - pMCTstat->GStatus |= 1 << GSB_SoftHole; - pMCTstat->HoleBase = base; - limit -= base; - base = _4GB_RJ8; - limit += base; - pDCTstat->DCTSysBase = base; - pDCTstat->DCTSysLimit = limit; - } else { - /* No Remapping. Normal Contiguous mapping */ - pDCTstat->DCTSysBase = base; - pDCTstat->DCTSysLimit = limit; - } - } else { - /*No Remapping. Normal Contiguous mapping*/ - pDCTstat->DCTSysBase = base; - pDCTstat->DCTSysLimit = limit; - } - base |= 3; /* set WE,RE fields*/ - pMCTstat->SysLimit = limit; - } - Set_NB32(dev, 0x40 + (Node << 3), base); /* [Node] + Dram Base 0 */ - - /* if Node limit > 1GB then set it to 1GB boundary for each node */ - if ((mctSetNodeBoundary_D()) && (limit > 0x00400000)) { - limit++; - limit &= 0xFFC00000; - limit--; - } - val = limit & 0xFFFF0000; - val |= Node; - Set_NB32(dev, 0x44 + (Node << 3), val); /* set DstNode */ - - limit = pDCTstat->DCTSysLimit; - if (limit) { - NextBase = (limit & 0xFFFF0000) + 0x10000; - if ((mctSetNodeBoundary_D()) && (NextBase > 0x00400000)) { - NextBase++; - NextBase &= 0xFFC00000; - NextBase--; - } - } - } - - /* Copy dram map from Node 0 to Node 1-7 */ - for (Node = 1; Node < MAX_NODES_SUPPORTED; Node++) { - u32 reg; - pDCTstat = pDCTstatA + Node; - devx = pDCTstat->dev_map; - - if (pDCTstat->NodePresent) { - printk(BIOS_DEBUG, " Copy dram map from Node 0 to Node %02x\n", Node); - reg = 0x40; /*Dram Base 0*/ - do { - val = Get_NB32(dev, reg); - Set_NB32(devx, reg, val); - reg += 4; - } while (reg < 0x80); - } else { - break; /* stop at first absent Node */ - } - } - - /*Copy dram map to F1x120/124*/ - mct_HTMemMapExt(pMCTstat, pDCTstatA); -} - - -void MCTMemClr_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - - /* Initiates a memory clear operation for all node. The mem clr - * is done in parallel. After the memclr is complete, all processors - * status are checked to ensure that memclr has completed. - */ - u8 Node; - struct DCTStatStruc *pDCTstat; - - if (!mctGet_NVbits(NV_DQSTrainCTL)) { - // FIXME: callback to wrapper: mctDoWarmResetMemClr_D - } else { // NV_DQSTrainCTL == 1 - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - pDCTstat = pDCTstatA + Node; - - if (pDCTstat->NodePresent) { - DCTMemClr_Init_D(pMCTstat, pDCTstat); - } - } - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - pDCTstat = pDCTstatA + Node; - - if (pDCTstat->NodePresent) { - DCTMemClr_Sync_D(pMCTstat, pDCTstat); - } - } - } -} - - -void DCTMemClr_Init_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u32 val; - u32 dev; - u32 reg; - - /* Initiates a memory clear operation on one node */ - if (pDCTstat->DCTSysLimit) { - dev = pDCTstat->dev_dct; - reg = 0x110; - - do { - val = Get_NB32(dev, reg); - } while (val & (1 << MemClrBusy)); - - val |= (1 << MemClrInit); - Set_NB32(dev, reg, val); - - } -} - - -void MCTMemClrSync_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - /* Ensures that memory clear has completed on all node.*/ - u8 Node; - struct DCTStatStruc *pDCTstat; - - if (!mctGet_NVbits(NV_DQSTrainCTL)) { - // callback to wrapper: mctDoWarmResetMemClr_D - } else { // NV_DQSTrainCTL == 1 - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - pDCTstat = pDCTstatA + Node; - - if (pDCTstat->NodePresent) { - DCTMemClr_Sync_D(pMCTstat, pDCTstat); - } - } - } -} - - -static void DCTMemClr_Sync_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u32 val; - u32 dev = pDCTstat->dev_dct; - u32 reg; - - /* Ensure that a memory clear operation has completed on one node */ - if (pDCTstat->DCTSysLimit) { - reg = 0x110; - - do { - val = Get_NB32(dev, reg); - } while (val & (1 << MemClrBusy)); - - do { - val = Get_NB32(dev, reg); - } while (!(val & (1 << Dr_MemClrStatus))); - } - - /* Implement BKDG Rev 3.62 recommendations */ - val = 0x0FE40F80; - if (!(mctGetLogicalCPUID(0) & AMD_FAM10_LT_D) && mctGet_NVbits(NV_Unganged)) - val |= (0x18 << 2); - else - val |= (0x10 << 2); - val |= MCCH_FlushWrOnStpGnt; // Set for S3 - Set_NB32(dev, 0x11C, val); -} - - -u8 NodePresent_D(u8 Node) -{ - /* - * Determine if a single Hammer Node exists within the network. - */ - - u32 dev; - u32 val; - u32 dword; - u8 ret = 0; - - dev = PA_HOST(Node); /*test device/vendor id at host bridge */ - val = Get_NB32(dev, 0); - dword = mct_NodePresent_D(); /* FIXME: BOZO -11001022h rev for F */ - if (val == dword) { /* AMD Hammer Family CPU HT Configuration */ - if (oemNodePresent_D(Node, &ret)) - goto finish; - /* Node ID register */ - val = Get_NB32(dev, 0x60); - val &= 0x07; - dword = Node; - if (val == dword) /* current nodeID = requested nodeID ? */ - ret = 1; -finish: - ; - } - - return ret; -} - - -static void DCTInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct) -{ - /* - * Initialize DRAM on single Athlon 64/Opteron Node. - */ - - u8 stopDCTflag; - u32 val; - - ClearDCT_D(pMCTstat, pDCTstat, dct); - stopDCTflag = 1; /*preload flag with 'disable' */ - if (mct_DIMMPresence(pMCTstat, pDCTstat, dct) < SC_StopError) { - print_t("\t\tDCTInit_D: mct_DIMMPresence Done\n"); - if (mct_SPDCalcWidth(pMCTstat, pDCTstat, dct) < SC_StopError) { - print_t("\t\tDCTInit_D: mct_SPDCalcWidth Done\n"); - if (AutoCycTiming_D(pMCTstat, pDCTstat, dct) < SC_StopError) { - print_t("\t\tDCTInit_D: AutoCycTiming_D Done\n"); - if (AutoConfig_D(pMCTstat, pDCTstat, dct) < SC_StopError) { - print_t("\t\tDCTInit_D: AutoConfig_D Done\n"); - if (PlatformSpec_D(pMCTstat, pDCTstat, dct) < SC_StopError) { - print_t("\t\tDCTInit_D: PlatformSpec_D Done\n"); - stopDCTflag = 0; - if (!(pMCTstat->GStatus & (1 << GSB_EnDIMMSpareNW))) { - print_t("\t\tDCTInit_D: StartupDCT_D\n"); - StartupDCT_D(pMCTstat, pDCTstat, dct); /*yeaahhh! */ - } - } - } - } - } - } - if (stopDCTflag) { - u32 reg_off = dct * 0x100; - val = 1<<DisDramInterface; - Set_NB32(pDCTstat->dev_dct, reg_off+0x94, val); - /*To maximize power savings when DisDramInterface = 1b, - all of the MemClkDis bits should also be set.*/ - val = 0xFF000000; - Set_NB32(pDCTstat->dev_dct, reg_off+0x88, val); - } else { - mct_EnDllShutdownSR(pMCTstat, pDCTstat, dct); - } -} - - -static void SyncDCTsReady_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - /* Wait (and block further access to dram) for all DCTs to be ready, - * by polling all InitDram bits and waiting for possible memory clear - * operations to be complete. Read MemClkFreqVal bit to see if - * the DIMMs are present in this node. - */ - - u8 Node; - - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - mct_SyncDCTsReady(pDCTstat); - } -} - - -static void StartupDCT_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - /* Read MemClkFreqVal bit to see if the DIMMs are present in this node. - * If the DIMMs are present then set the DRAM Enable bit for this node. - * - * Setting dram init starts up the DCT state machine, initializes the - * dram devices with MRS commands, and kicks off any - * HW memory clear process that the chip is capable of. The sooner - * that dram init is set for all nodes, the faster the memory system - * initialization can complete. Thus, the init loop is unrolled into - * two loops so as to start the processes for non BSP nodes sooner. - * This procedure will not wait for the process to finish. - * Synchronization is handled elsewhere. - */ - - u32 val; - u32 dev; - u8 byte; - u32 reg; - u32 reg_off = dct * 0x100; - - dev = pDCTstat->dev_dct; - val = Get_NB32(dev, 0x94 + reg_off); - if (val & (1 << MemClkFreqVal)) { - print_t("\t\t\tStartupDCT_D: MemClkFreqVal\n"); - byte = mctGet_NVbits(NV_DQSTrainCTL); - if (byte == 1) { - /* Enable DQSRcvEn training mode */ - print_t("\t\t\tStartupDCT_D: DqsRcvEnTrain set\n"); - reg = 0x78 + reg_off; - val = Get_NB32(dev, reg); - /* Setting this bit forces a 1T window with hard left - * pass/fail edge and a probabilistic right pass/fail - * edge. LEFT edge is referenced for final - * receiver enable position.*/ - val |= 1 << DqsRcvEnTrain; - Set_NB32(dev, reg, val); - } - mctHookBeforeDramInit(); /* generalized Hook */ - print_t("\t\t\tStartupDCT_D: DramInit\n"); - mct_DramInit(pMCTstat, pDCTstat, dct); - AfterDramInit_D(pDCTstat, dct); - mctHookAfterDramInit(); /* generalized Hook*/ - } -} - - -static void ClearDCT_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u32 reg_end; - u32 dev = pDCTstat->dev_dct; - u32 reg = 0x40 + 0x100 * dct; - u32 val = 0; - - if (pMCTstat->GStatus & (1 << GSB_EnDIMMSpareNW)) { - reg_end = 0x78 + 0x100 * dct; - } else { - reg_end = 0xA4 + 0x100 * dct; - } - - while (reg < reg_end) { - Set_NB32(dev, reg, val); - reg += 4; - } - - val = 0; - dev = pDCTstat->dev_map; - reg = 0xF0; - Set_NB32(dev, reg, val); -} - - -static u8 AutoCycTiming_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - /* Initialize DCT Timing registers as per DIMM SPD. - * For primary timing (T, CL) use best case T value. - * For secondary timing params., use most aggressive settings - * of slowest DIMM. - * - * There are three components to determining "maximum frequency": - * SPD component, Bus load component, and "Preset" max frequency - * component. - * - * The SPD component is a function of the min cycle time specified - * by each DIMM, and the interaction of cycle times from all DIMMs - * in conjunction with CAS latency. The SPD component only applies - * when user timing mode is 'Auto'. - * - * The Bus load component is a limiting factor determined by electrical - * characteristics on the bus as a result of varying number of device - * loads. The Bus load component is specific to each platform but may - * also be a function of other factors. The bus load component only - * applies when user timing mode is 'Auto'. - * - * The Preset component is subdivided into three items and is the - * minimum of the set: Silicon revision, user limit setting when user - * timing mode is 'Auto' and memclock mode is 'Limit', OEM build - * specification of the maximum frequency. The Preset component is only - * applies when user timing mode is 'Auto'. - */ - - u8 i; - u8 Twr, Trtp; - u8 Trp, Trrd, Trcd, Tras, Trc, Trfc[4], Rows; - u32 DramTimingLo, DramTimingHi; - u16 Tk40; - u8 Twtr; - u8 LDIMM; - u8 DDR2_1066; - u8 byte; - u32 dword; - u32 dev; - u32 reg; - u32 reg_off; - u32 val; - u16 smbaddr; - - /* Get primary timing (CAS Latency and Cycle Time) */ - if (pDCTstat->Speed == 0) { - mctGet_MaxLoadFreq(pDCTstat); - - /* and Factor in presets (setup options, Si cap, etc.) */ - GetPresetmaxF_D(pMCTstat, pDCTstat); - - /* Go get best T and CL as specified by DIMM mfgs. and OEM */ - SPDGetTCL_D(pMCTstat, pDCTstat, dct); - /* skip callback mctForce800to1067_D */ - pDCTstat->Speed = pDCTstat->DIMMAutoSpeed; - pDCTstat->CASL = pDCTstat->DIMMCASL; - - /* if "manual" memclock mode */ - if (mctGet_NVbits(NV_MCTUSRTMGMODE) == 2) - pDCTstat->Speed = mctGet_NVbits(NV_MemCkVal) + 1; - - } - mct_AfterGetCLT(pMCTstat, pDCTstat, dct); - - /* Gather all DIMM mini-max values for cycle timing data */ - Rows = 0; - Trp = 0; - Trrd = 0; - Trcd = 0; - Trtp = 0; - Tras = 0; - Trc = 0; - Twr = 0; - Twtr = 0; - for (i = 0; i < 4; i++) - Trfc[i] = 0; - - for (i = 0; i< MAX_DIMMS_SUPPORTED; i++) { - LDIMM = i >> 1; - if (pDCTstat->DIMMValid & (1 << i)) { - smbaddr = Get_DIMMAddress_D(pDCTstat, dct + i); - byte = mctRead_SPD(smbaddr, SPD_ROWSZ); - if (Rows < byte) - Rows = byte; /* keep track of largest row sz */ - - byte = mctRead_SPD(smbaddr, SPD_TRP); - if (Trp < byte) - Trp = byte; - - byte = mctRead_SPD(smbaddr, SPD_TRRD); - if (Trrd < byte) - Trrd = byte; - - byte = mctRead_SPD(smbaddr, SPD_TRCD); - if (Trcd < byte) - Trcd = byte; - - byte = mctRead_SPD(smbaddr, SPD_TRTP); - if (Trtp < byte) - Trtp = byte; - - byte = mctRead_SPD(smbaddr, SPD_TWR); - if (Twr < byte) - Twr = byte; - - byte = mctRead_SPD(smbaddr, SPD_TWTR); - if (Twtr < byte) - Twtr = byte; - - val = mctRead_SPD(smbaddr, SPD_TRC); - if ((val == 0) || (val == 0xFF)) { - pDCTstat->ErrStatus |= 1<<SB_NoTrcTrfc; - pDCTstat->ErrCode = SC_VarianceErr; - val = Get_DefTrc_k_D(pDCTstat->Speed); - } else { - byte = mctRead_SPD(smbaddr, SPD_TRCRFC); - if (byte & 0xF0) { - val++; /* round up in case fractional extension is non-zero.*/ - } - } - if (Trc < val) - Trc = val; - - /* dev density = rank size/#devs per rank */ - byte = mctRead_SPD(smbaddr, SPD_BANKSZ); - - val = ((byte >> 5) | (byte << 3)) & 0xFF; - val <<= 2; - - byte = mctRead_SPD(smbaddr, SPD_DEVWIDTH) & 0xFE; /* dev density = 2^(rows+columns+banks) */ - if (byte == 4) { - val >>= 4; - } else if (byte == 8) { - val >>= 3; - } else if (byte == 16) { - val >>= 2; - } - - byte = bsr(val); - - if (Trfc[LDIMM] < byte) - Trfc[LDIMM] = byte; - - byte = mctRead_SPD(smbaddr, SPD_TRAS); - if (Tras < byte) - Tras = byte; - } /* Dimm Present */ - } - - /* Convert DRAM CycleTiming values and store into DCT structure */ - DDR2_1066 = 0; - byte = pDCTstat->Speed; - if (byte == 5) - DDR2_1066 = 1; - Tk40 = Get_40Tk_D(byte); - - /* Notes: - 1. All secondary time values given in SPDs are in binary with units of ns. - 2. Some time values are scaled by four, in order to have least count of 0.25 ns - (more accuracy). JEDEC SPD spec. shows which ones are x1 and x4. - 3. Internally to this SW, cycle time, Tk, is scaled by 10 to affect a - least count of 0.1 ns (more accuracy). - 4. SPD values not scaled are multiplied by 10 and then divided by 10T to find - equivalent minimum number of bus clocks (a remainder causes round-up of clocks). - 5. SPD values that are prescaled by 4 are multiplied by 10 and then divided by 40T to find - equivalent minimum number of bus clocks (a remainder causes round-up of clocks).*/ - - /* Tras */ - dword = Tras * 40; - pDCTstat->DIMMTras = (u16)dword; - val = dword / Tk40; - if (dword % Tk40) { /* round up number of busclocks */ - val++; - } - if (DDR2_1066) { - if (val < Min_TrasT_1066) - val = Min_TrasT_1066; - else if (val > Max_TrasT_1066) - val = Max_TrasT_1066; - } else { - if (val < Min_TrasT) - val = Min_TrasT; - else if (val > Max_TrasT) - val = Max_TrasT; - } - pDCTstat->Tras = val; - - /* Trp */ - dword = Trp * 10; - pDCTstat->DIMMTrp = dword; - val = dword / Tk40; - if (dword % Tk40) { /* round up number of busclocks */ - val++; - } - if (DDR2_1066) { - if (val < Min_TrasT_1066) - val = Min_TrpT_1066; - else if (val > Max_TrpT_1066) - val = Max_TrpT_1066; - } else { - if (val < Min_TrpT) - val = Min_TrpT; - else if (val > Max_TrpT) - val = Max_TrpT; - } - pDCTstat->Trp = val; - - /*Trrd*/ - dword = Trrd * 10; - pDCTstat->DIMMTrrd = dword; - val = dword / Tk40; - if (dword % Tk40) { /* round up number of busclocks */ - val++; - } - if (DDR2_1066) { - if (val < Min_TrrdT_1066) - val = Min_TrrdT_1066; - else if (val > Max_TrrdT_1066) - val = Max_TrrdT_1066; - } else { - if (val < Min_TrrdT) - val = Min_TrrdT; - else if (val > Max_TrrdT) - val = Max_TrrdT; - } - pDCTstat->Trrd = val; - - /* Trcd */ - dword = Trcd * 10; - pDCTstat->DIMMTrcd = dword; - val = dword / Tk40; - if (dword % Tk40) { /* round up number of busclocks */ - val++; - } - if (DDR2_1066) { - if (val < Min_TrcdT_1066) - val = Min_TrcdT_1066; - else if (val > Max_TrcdT_1066) - val = Max_TrcdT_1066; - } else { - if (val < Min_TrcdT) - val = Min_TrcdT; - else if (val > Max_TrcdT) - val = Max_TrcdT; - } - pDCTstat->Trcd = val; - - /* Trc */ - dword = Trc * 40; - pDCTstat->DIMMTrc = dword; - val = dword / Tk40; - if (dword % Tk40) { /* round up number of busclocks */ - val++; - } - if (DDR2_1066) { - if (val < Min_TrcT_1066) - val = Min_TrcT_1066; - else if (val > Max_TrcT_1066) - val = Max_TrcT_1066; - } else { - if (val < Min_TrcT) - val = Min_TrcT; - else if (val > Max_TrcT) - val = Max_TrcT; - } - pDCTstat->Trc = val; - - /* Trtp */ - dword = Trtp * 10; - pDCTstat->DIMMTrtp = dword; - val = pDCTstat->Speed; - if (val <= 2) { /* 7.75ns / Speed in ns to get clock # */ - val = 2; /* for DDR400/DDR533 */ - } else { /* Note a speed of 3 will be a Trtp of 3 */ - val = 3; /* for DDR667/DDR800/DDR1066 */ - } - pDCTstat->Trtp = val; - - /* Twr */ - dword = Twr * 10; - pDCTstat->DIMMTwr = dword; - val = dword / Tk40; - if (dword % Tk40) { /* round up number of busclocks */ - val++; - } - if (DDR2_1066) { - if (val < Min_TwrT_1066) - val = Min_TwrT_1066; - else if (val > Max_TwrT_1066) - val = Max_TwrT_1066; - } else { - if (val < Min_TwrT) - val = Min_TwrT; - else if (val > Max_TwrT) - val = Max_TwrT; - } - pDCTstat->Twr = val; - - /* Twtr */ - dword = Twtr * 10; - pDCTstat->DIMMTwtr = dword; - val = dword / Tk40; - if (dword % Tk40) { /* round up number of busclocks */ - val++; - } - if (DDR2_1066) { - if (val < Min_TwrT_1066) - val = Min_TwtrT_1066; - else if (val > Max_TwtrT_1066) - val = Max_TwtrT_1066; - } else { - if (val < Min_TwtrT) - val = Min_TwtrT; - else if (val > Max_TwtrT) - val = Max_TwtrT; - } - pDCTstat->Twtr = val; - - - /* Trfc0-Trfc3 */ - for (i = 0; i < 4; i++) - pDCTstat->Trfc[i] = Trfc[i]; - - mctAdjustAutoCycTmg_D(); - - /* Program DRAM Timing values */ - DramTimingLo = 0; /* Dram Timing Low init */ - val = pDCTstat->CASL; - val = Tab_tCL_j[val]; - DramTimingLo |= val; - - val = pDCTstat->Trcd; - if (DDR2_1066) - val -= Bias_TrcdT_1066; - else - val -= Bias_TrcdT; - - DramTimingLo |= val << 4; - - val = pDCTstat->Trp; - if (DDR2_1066) - val -= Bias_TrpT_1066; - else { - val -= Bias_TrpT; - val <<= 1; - } - DramTimingLo |= val << 7; - - val = pDCTstat->Trtp; - val -= Bias_TrtpT; - DramTimingLo |= val << 11; - - val = pDCTstat->Tras; - if (DDR2_1066) - val -= Bias_TrasT_1066; - else - val -= Bias_TrasT; - DramTimingLo |= val << 12; - - val = pDCTstat->Trc; - val -= Bias_TrcT; - DramTimingLo |= val << 16; - - if (!DDR2_1066) { - val = pDCTstat->Twr; - val -= Bias_TwrT; - DramTimingLo |= val << 20; - } - - val = pDCTstat->Trrd; - if (DDR2_1066) - val -= Bias_TrrdT_1066; - else - val -= Bias_TrrdT; - DramTimingLo |= val << 22; - - - DramTimingHi = 0; /* Dram Timing Low init */ - val = pDCTstat->Twtr; - if (DDR2_1066) - val -= Bias_TwtrT_1066; - else - val -= Bias_TwtrT; - DramTimingHi |= val << 8; - - val = 2; - DramTimingHi |= val << 16; - - val = 0; - for (i = 4; i > 0; i--) { - val <<= 3; - val |= Trfc[i-1]; - } - DramTimingHi |= val << 20; - - - dev = pDCTstat->dev_dct; - reg_off = 0x100 * dct; - print_tx("AutoCycTiming: DramTimingLo ", DramTimingLo); - print_tx("AutoCycTiming: DramTimingHi ", DramTimingHi); - - Set_NB32(dev, 0x88 + reg_off, DramTimingLo); /*DCT Timing Low*/ - DramTimingHi |=0x0000FC77; - Set_NB32(dev, 0x8c + reg_off, DramTimingHi); /*DCT Timing Hi*/ - - if (DDR2_1066) { - /* Twr */ - dword = pDCTstat->Twr; - dword -= Bias_TwrT_1066; - dword <<= 4; - reg = 0x84 + reg_off; - val = Get_NB32(dev, reg); - val &= 0x8F; - val |= dword; - Set_NB32(dev, reg, val); - } - - print_tx("AutoCycTiming: Status ", pDCTstat->Status); - print_tx("AutoCycTiming: ErrStatus ", pDCTstat->ErrStatus); - print_tx("AutoCycTiming: ErrCode ", pDCTstat->ErrCode); - print_t("AutoCycTiming: Done\n"); - - mctHookAfterAutoCycTmg(); - - return pDCTstat->ErrCode; -} - - -static void GetPresetmaxF_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - /* Get max frequency from OEM platform definition, from any user - * override (limiting) of max frequency, and from any Si Revision - * Specific information. Return the least of these three in - * DCTStatStruc.PresetmaxFreq. - */ - - u16 proposedFreq; - u16 word; - - /* Get CPU Si Revision defined limit (NPT) */ - proposedFreq = 533; /* Rev F0 programmable max memclock is */ - - /*Get User defined limit if "limit" mode */ - if (mctGet_NVbits(NV_MCTUSRTMGMODE) == 1) { - word = Get_Fk_D(mctGet_NVbits(NV_MemCkVal) + 1); - if (word < proposedFreq) - proposedFreq = word; - - /* Get Platform defined limit */ - word = mctGet_NVbits(NV_MAX_MEMCLK); - if (word < proposedFreq) - proposedFreq = word; - - word = pDCTstat->PresetmaxFreq; - if (word > proposedFreq) - word = proposedFreq; - - pDCTstat->PresetmaxFreq = word; - } -} - - - -static void SPDGetTCL_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - /* Find the best T and CL primary timing parameter pair, per Mfg., - * for the given set of DIMMs, and store into DCTStatStruc - * (.DIMMAutoSpeed and .DIMMCASL). See "Global relationship between - * index values and item values" for definition of CAS latency - * index (j) and Frequency index (k). - */ - int i, j, k; - u8 T1min, CL1min; - - /* i={0..7} (std. physical DIMM number) - * j is an integer which enumerates increasing CAS latency. - * k is an integer which enumerates decreasing cycle time. - * CL no. {0,1,2} corresponds to CL X, CL X-.5, or CL X-1 (per individual DIMM) - * Max timing values are per parameter, of all DIMMs, spec'd in ns like the SPD. - */ - - CL1min = 0xFF; - T1min = 0xFF; - for (k = K_MAX; k >= K_MIN; k--) { - for (j = J_MIN; j <= J_MAX; j++) { - if (Sys_Capability_D(pMCTstat, pDCTstat, j, k)) { - /* 1. check to see if DIMMi is populated. - 2. check if DIMMi supports CLj and Tjk */ - for (i = 0; i < MAX_DIMMS_SUPPORTED; i++) { - if (pDCTstat->DIMMValid & (1 << i)) { - if (Dimm_Supports_D(pDCTstat, i, j, k)) - break; - } - } /* while ++i */ - if (i == MAX_DIMMS_SUPPORTED) { - T1min = k; - CL1min = j; - goto got_TCL; - } - } - } /* while ++j */ - } /* while --k */ - -got_TCL: - if (T1min != 0xFF) { - pDCTstat->DIMMCASL = CL1min; /*mfg. optimized */ - pDCTstat->DIMMAutoSpeed = T1min; - print_tx("SPDGetTCL_D: DIMMCASL ", pDCTstat->DIMMCASL); - print_tx("SPDGetTCL_D: DIMMAutoSpeed ", pDCTstat->DIMMAutoSpeed); - - } else { - pDCTstat->DIMMCASL = CL_DEF; /* failsafe values (running in min. mode) */ - pDCTstat->DIMMAutoSpeed = T_DEF; - pDCTstat->ErrStatus |= 1 << SB_DimmMismatchT; - pDCTstat->ErrStatus |= 1 << SB_MinimumMode; - pDCTstat->ErrCode = SC_VarianceErr; - } - print_tx("SPDGetTCL_D: Status ", pDCTstat->Status); - print_tx("SPDGetTCL_D: ErrStatus ", pDCTstat->ErrStatus); - print_tx("SPDGetTCL_D: ErrCode ", pDCTstat->ErrCode); - print_t("SPDGetTCL_D: Done\n"); -} - - -static u8 PlatformSpec_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u32 dev; - u32 reg; - u32 val; - - mctGet_PS_Cfg_D(pMCTstat, pDCTstat, dct); - - if (pDCTstat->GangedMode) { - mctGet_PS_Cfg_D(pMCTstat, pDCTstat, 1); - } - - if (pDCTstat->_2Tmode == 2) { - dev = pDCTstat->dev_dct; - reg = 0x94 + 0x100 * dct; /* Dram Configuration Hi */ - val = Get_NB32(dev, reg); - val |= 1 << 20; /* 2T CMD mode */ - Set_NB32(dev, reg, val); - } - - mct_PlatformSpec(pMCTstat, pDCTstat, dct); - InitPhyCompensation(pMCTstat, pDCTstat, dct); - mctHookAfterPSCfg(); - return pDCTstat->ErrCode; -} - - -static u8 AutoConfig_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u32 DramControl, DramTimingLo, Status; - u32 DramConfigLo, DramConfigHi, DramConfigMisc, DramConfigMisc2; - u32 val; - u32 reg_off; - u32 dev; - u16 word; - u32 dword; - u8 byte; - - print_tx("AutoConfig_D: DCT: ", dct); - - DramConfigLo = 0; - DramConfigHi = 0; - DramConfigMisc = 0; - DramConfigMisc2 = 0; - - /* set bank addressing and Masks, plus CS pops */ - SPDSetBanks_D(pMCTstat, pDCTstat, dct); - if (pDCTstat->ErrCode == SC_StopError) - goto AutoConfig_exit; - - /* map chip-selects into local address space */ - StitchMemory_D(pMCTstat, pDCTstat, dct); - InterleaveBanks_D(pMCTstat, pDCTstat, dct); - - /* temp image of status (for convenience). RO usage! */ - Status = pDCTstat->Status; - - dev = pDCTstat->dev_dct; - reg_off = 0x100 * dct; - - - /* Build Dram Control Register Value */ - DramConfigMisc2 = Get_NB32 (dev, 0xA8 + reg_off); /* Dram Control*/ - DramControl = Get_NB32 (dev, 0x78 + reg_off); /* Dram Control*/ - - if (mctGet_NVbits(NV_CLKHZAltVidC3)) - DramControl |= 1<<16; - - // FIXME: Add support(skip) for Ax and Cx versions - DramControl |= 5; /* RdPtrInit */ - - - /* Build Dram Config Lo Register Value */ - DramConfigLo |= 1 << 4; /* 75 Ohms ODT */ - if (mctGet_NVbits(NV_MAX_DIMMS) == 8) { - if (pDCTstat->Speed == 3) { - if (pDCTstat->MAdimms[dct] == 4) - DramConfigLo |= 1 << 5; /* 50 Ohms ODT */ - } else if (pDCTstat->Speed == 4) { - if (pDCTstat->MAdimms[dct] != 1) - DramConfigLo |= 1 << 5; /* 50 Ohms ODT */ - } - } else { - // FIXME: Skip for Ax versions - if (pDCTstat->MAdimms[dct] == 4) { - if (pDCTstat->DimmQRPresent != 0) { - if ((pDCTstat->Speed == 3) || (pDCTstat->Speed == 4)) { - DramConfigLo |= 1 << 5; /* 50 Ohms ODT */ - } - } else if (pDCTstat->MAdimms[dct] == 4) { - if (pDCTstat->Speed == 4) { - if (pDCTstat->DimmQRPresent != 0) { - DramConfigLo |= 1 << 5; /* 50 Ohms ODT */ - } - } - } - } else if (pDCTstat->MAdimms[dct] == 2) { - DramConfigLo |= 1 << 5; /* 50 Ohms ODT */ - } - - } - - // FIXME: Skip for Ax versions - /* callback not required - if (!mctParityControl_D()) */ - if (Status & (1 << SB_PARDIMMs)) { - DramConfigLo |= 1 << ParEn; - DramConfigMisc2 |= 1 << ActiveCmdAtRst; - } else { - DramConfigLo &= ~(1 << ParEn); - DramConfigMisc2 &= ~(1 << ActiveCmdAtRst); - } - - if (mctGet_NVbits(NV_BurstLen32)) { - if (!pDCTstat->GangedMode) - DramConfigLo |= 1 << BurstLength32; - } - - if (Status & (1 << SB_128bitmode)) - DramConfigLo |= 1 << Width128; /* 128-bit mode (normal) */ - - word = dct; - dword = X4Dimm; - while (word < 8) { - if (pDCTstat->Dimmx4Present & (1 << word)) - DramConfigLo |= 1 << dword; /* X4Dimm[3:0] */ - word++; - word++; - dword++; - } - - if (!(Status & (1 << SB_Registered))) - DramConfigLo |= 1 << UnBuffDimm; /* Unbuffered DIMMs */ - - if (mctGet_NVbits(NV_ECC_CAP)) - if (Status & (1 << SB_ECCDIMMs)) - if (mctGet_NVbits(NV_ECC)) - DramConfigLo |= 1 << DimmEcEn; - - DramConfigLo = mct_DisDllShutdownSR(pMCTstat, pDCTstat, DramConfigLo, dct); - - /* Build Dram Config Hi Register Value */ - dword = pDCTstat->Speed; - DramConfigHi |= dword - 1; /* get MemClk encoding */ - DramConfigHi |= 1 << MemClkFreqVal; - - if (Status & (1 << SB_Registered)) - if ((pDCTstat->Dimmx4Present != 0) && (pDCTstat->Dimmx8Present != 0)) - /* set only if x8 Registered DIMMs in System*/ - DramConfigHi |= 1 << RDqsEn; - - if (mctGet_NVbits(NV_CKE_PDEN)) { - DramConfigHi |= 1 << 15; /* PowerDownEn */ - if (mctGet_NVbits(NV_CKE_CTL)) - /*Chip Select control of CKE*/ - DramConfigHi |= 1 << 16; - } - - /* Control Bank Swizzle */ - if (0) /* call back not needed mctBankSwizzleControl_D()) */ - DramConfigHi &= ~(1 << BankSwizzleMode); - else - DramConfigHi |= 1 << BankSwizzleMode; /* recommended setting (default) */ - - /* Check for Quadrank DIMM presence */ - if (pDCTstat->DimmQRPresent != 0) { - byte = mctGet_NVbits(NV_4RANKType); - if (byte == 2) - DramConfigHi |= 1 << 17; /* S4 (4-Rank SO-DIMMs) */ - else if (byte == 1) - DramConfigHi |= 1 << 18; /* R4 (4-Rank Registered DIMMs) */ - } - - if (0) /* call back not needed mctOverrideDcqBypMax_D) */ - val = mctGet_NVbits(NV_BYPMAX); - else - val = 0x0f; // recommended setting (default) - DramConfigHi |= val << 24; - - val = pDCTstat->DIMM2Kpage; - if (pDCTstat->GangedMode != 0) { - if (dct != 0) { - val &= 0x55; - } else { - val &= 0xAA; - } - } - if (val) - val = Tab_2KTfawT_k[pDCTstat->Speed]; - else - val = Tab_1KTfawT_k[pDCTstat->Speed]; - - if (pDCTstat->Speed == 5) - val >>= 1; - - val -= Bias_TfawT; - val <<= 28; - DramConfigHi |= val; /* Tfaw for 1K or 2K paged drams */ - - // FIXME: Skip for Ax versions - DramConfigHi |= 1 << DcqArbBypassEn; - - - /* Build MemClkDis Value from Dram Timing Lo and - Dram Config Misc Registers - 1. We will assume that MemClkDis field has been preset prior to this - point. - 2. We will only set MemClkDis bits if a DIMM is NOT present AND if: - NV_AllMemClks <>0 AND SB_DiagClks == 0 */ - - - /* Dram Timing Low (owns Clock Enable bits) */ - DramTimingLo = Get_NB32(dev, 0x88 + reg_off); - if (mctGet_NVbits(NV_AllMemClks) == 0) { - /* Special Jedec SPD diagnostic bit - "enable all clocks" */ - if (!(pDCTstat->Status & (1 << SB_DiagClks))) { - const u8 *p; - byte = mctGet_NVbits(NV_PACK_TYPE); - if (byte == PT_L1) - p = Tab_L1CLKDis; - else if (byte == PT_M2) - p = Tab_M2CLKDis; - else - p = Tab_S1CLKDis; - - dword = 0; - while (dword < MAX_DIMMS_SUPPORTED) { - val = p[dword]; - print_tx("DramTimingLo: val=", val); - if (!(pDCTstat->DIMMValid & (1 << val))) - /*disable memclk*/ - DramTimingLo |= 1 << (dword+24); - dword++; - } - } - } - - print_tx("AutoConfig_D: DramControl: ", DramControl); - print_tx("AutoConfig_D: DramTimingLo: ", DramTimingLo); - print_tx("AutoConfig_D: DramConfigMisc: ", DramConfigMisc); - print_tx("AutoConfig_D: DramConfigMisc2: ", DramConfigMisc2); - print_tx("AutoConfig_D: DramConfigLo: ", DramConfigLo); - print_tx("AutoConfig_D: DramConfigHi: ", DramConfigHi); - - /* Write Values to the registers */ - Set_NB32(dev, 0x78 + reg_off, DramControl); - Set_NB32(dev, 0x88 + reg_off, DramTimingLo); - Set_NB32(dev, 0xA0 + reg_off, DramConfigMisc); - Set_NB32(dev, 0xA8 + reg_off, DramConfigMisc2); - Set_NB32(dev, 0x90 + reg_off, DramConfigLo); - mct_SetDramConfigHi_D(pDCTstat, dct, DramConfigHi); - mct_ForceAutoPrecharge_D(pDCTstat, dct); - mct_EarlyArbEn_D(pMCTstat, pDCTstat); - mctHookAfterAutoCfg(); - - print_tx("AutoConfig: Status ", pDCTstat->Status); - print_tx("AutoConfig: ErrStatus ", pDCTstat->ErrStatus); - print_tx("AutoConfig: ErrCode ", pDCTstat->ErrCode); - print_t("AutoConfig: Done\n"); -AutoConfig_exit: - return pDCTstat->ErrCode; -} - - -static void SPDSetBanks_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - /* Set bank addressing, program Mask values and build a chip-select - * population map. This routine programs PCI 0:24N:2x80 config register - * and PCI 0:24N:2x60,64,68,6C config registers (CS Mask 0-3). - */ - - u8 ChipSel, Rows, Cols, Ranks, Banks; - u32 BankAddrReg, csMask; - - u32 val; - u32 reg; - u32 dev; - u32 reg_off; - u8 byte; - u16 word; - u32 dword; - u16 smbaddr; - - dev = pDCTstat->dev_dct; - reg_off = 0x100 * dct; - - BankAddrReg = 0; - for (ChipSel = 0; ChipSel < MAX_CS_SUPPORTED; ChipSel+=2) { - byte = ChipSel; - if ((pDCTstat->Status & (1 << SB_64MuxedMode)) && ChipSel >=4) - byte -= 3; - - if (pDCTstat->DIMMValid & (1 << byte)) { - smbaddr = Get_DIMMAddress_D(pDCTstat, (ChipSel + dct)); - - byte = mctRead_SPD(smbaddr, SPD_ROWSZ); - Rows = byte & 0x1f; - - byte = mctRead_SPD(smbaddr, SPD_COLSZ); - Cols = byte & 0x1f; - - Banks = mctRead_SPD(smbaddr, SPD_LBANKS); - - byte = mctRead_SPD(smbaddr, SPD_DEVWIDTH); - - byte = mctRead_SPD(smbaddr, SPD_DMBANKS); - Ranks = (byte & 7) + 1; - - /* Configure Bank encoding - * Use a 6-bit key into a lookup table. - * Key (index) = CCCBRR, where CCC is the number of - * Columns minus 9,RR is the number of Rows minus 13, - * and B is the number of banks minus 2. - * See "6-bit Bank Addressing Table" at the end of - * this file.*/ - byte = Cols - 9; /* 9 Cols is smallest dev size */ - byte <<= 3; /* make room for row and bank bits*/ - if (Banks == 8) - byte |= 4; - - /* 13 Rows is smallest dev size */ - byte |= Rows - 13; /* CCCBRR internal encode */ - - for (dword = 0; dword < 12; dword++) { - if (byte == Tab_BankAddr[dword]) - break; - } - - if (dword < 12) { - - /* bit no. of CS field in address mapping reg.*/ - dword <<= (ChipSel << 1); - BankAddrReg |= dword; - - /* Mask value=(2pow(rows+cols+banks+3)-1)>>8, - or 2pow(rows+cols+banks-5)-1*/ - csMask = 0; - - byte = Rows + Cols; /* cl = rows+cols*/ - if (Banks == 8) - byte -= 2; /* 3 banks - 5 */ - else - byte -= 3; /* 2 banks - 5 */ - /* mask size (64-bit rank only) */ - - if (pDCTstat->Status & (1 << SB_128bitmode)) - byte++; /* double mask size if in 128-bit mode*/ - - csMask |= 1 << byte; - csMask--; - - /*set ChipSelect population indicator even bits*/ - pDCTstat->CSPresent |= (1 << ChipSel); - if (Ranks >= 2) - /*set ChipSelect population indicator odd bits*/ - pDCTstat->CSPresent |= 1 << (ChipSel + 1); - - reg = 0x60+(ChipSel << 1) + reg_off; /*Dram CS Mask Register */ - val = csMask; - val &= 0x1FF83FE0; /* Mask out reserved bits.*/ - Set_NB32(dev, reg, val); - } - } else { - if (pDCTstat->DIMMSPDCSE & (1 << ChipSel)) - pDCTstat->CSTestFail |= (1 << ChipSel); - } /* if DIMMValid*/ - } /* while ChipSel*/ - - SetCSTriState(pMCTstat, pDCTstat, dct); - /* SetCKETriState */ - SetODTTriState(pMCTstat, pDCTstat, dct); - - if (pDCTstat->Status & (1 << SB_128bitmode)) { - SetCSTriState(pMCTstat, pDCTstat, 1); /* force dct1) */ - SetODTTriState(pMCTstat, pDCTstat, 1); /* force dct1) */ - } - word = pDCTstat->CSPresent; - mctGetCS_ExcludeMap(); /* mask out specified chip-selects */ - word ^= pDCTstat->CSPresent; - pDCTstat->CSTestFail |= word; /* enable ODT to disabled DIMMs */ - if (!pDCTstat->CSPresent) - pDCTstat->ErrCode = SC_StopError; - - reg = 0x80 + reg_off; /* Bank Addressing Register */ - Set_NB32(dev, reg, BankAddrReg); - - print_tx("SPDSetBanks: Status ", pDCTstat->Status); - print_tx("SPDSetBanks: ErrStatus ", pDCTstat->ErrStatus); - print_tx("SPDSetBanks: ErrCode ", pDCTstat->ErrCode); - print_t("SPDSetBanks: Done\n"); -} - - -static void SPDCalcWidth_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - /* Per SPDs, check the symmetry of DIMM pairs (DIMM on Channel A - * matching with DIMM on Channel B), the overall DIMM population, - * and determine the width mode: 64-bit, 64-bit muxed, 128-bit. - */ - - u8 i; - u8 smbaddr, smbaddr1; - u8 byte, byte1; - - /* Check Symmetry of Channel A and Channel B DIMMs - (must be matched for 128-bit mode).*/ - for (i = 0; i < MAX_DIMMS_SUPPORTED; i += 2) { - if ((pDCTstat->DIMMValid & (1 << i)) && (pDCTstat->DIMMValid & (1<<(i+1)))) { - smbaddr = Get_DIMMAddress_D(pDCTstat, i); - smbaddr1 = Get_DIMMAddress_D(pDCTstat, i+1); - - byte = mctRead_SPD(smbaddr, SPD_ROWSZ) & 0x1f; - byte1 = mctRead_SPD(smbaddr1, SPD_ROWSZ) & 0x1f; - if (byte != byte1) { - pDCTstat->ErrStatus |= (1 << SB_DimmMismatchO); - break; - } - - byte = mctRead_SPD(smbaddr, SPD_COLSZ) & 0x1f; - byte1 = mctRead_SPD(smbaddr1, SPD_COLSZ) & 0x1f; - if (byte != byte1) { - pDCTstat->ErrStatus |= (1 << SB_DimmMismatchO); - break; - } - - byte = mctRead_SPD(smbaddr, SPD_BANKSZ); - byte1 = mctRead_SPD(smbaddr1, SPD_BANKSZ); - if (byte != byte1) { - pDCTstat->ErrStatus |= (1 << SB_DimmMismatchO); - break; - } - - byte = mctRead_SPD(smbaddr, SPD_DEVWIDTH) & 0x7f; - byte1 = mctRead_SPD(smbaddr1, SPD_DEVWIDTH) & 0x7f; - if (byte != byte1) { - pDCTstat->ErrStatus |= (1 << SB_DimmMismatchO); - break; - } - - byte = mctRead_SPD(smbaddr, SPD_DMBANKS) & 7; /* #ranks-1 */ - byte1 = mctRead_SPD(smbaddr1, SPD_DMBANKS) & 7; /* #ranks-1 */ - if (byte != byte1) { - pDCTstat->ErrStatus |= (1 << SB_DimmMismatchO); - break; - } - - } - } - -} - - -static void StitchMemory_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - /* Requires that Mask values for each bank be programmed first and that - * the chip-select population indicator is correctly set. - */ - - u8 b = 0; - u32 nxtcsBase, curcsBase; - u8 p, q; - u32 BiggestBank; - u8 _DSpareEn; - - u16 word; - u32 dev; - u32 reg; - u32 reg_off; - u32 val; - - - dev = pDCTstat->dev_dct; - reg_off = 0x100 * dct; - - _DSpareEn = 0; - - /* CS Sparing 1 = enabled, 0 = disabled */ - if (mctGet_NVbits(NV_CS_SpareCTL) & 1) { - if (MCT_DIMM_SPARE_NO_WARM) { - /* Do no warm-reset DIMM spare */ - if (pMCTstat->GStatus & 1 << GSB_EnDIMMSpareNW) { - word = pDCTstat->CSPresent; - val = bsf(word); - word &= ~(1<<val); - if (word) - /* Make sure at least two chip-selects are available */ - _DSpareEn = 1; - else - pDCTstat->ErrStatus |= 1 << SB_SpareDis; - } - } else { - if (!mctGet_NVbits(NV_DQSTrainCTL)) { /*DQS Training 1 = enabled, 0 = disabled */ - word = pDCTstat->CSPresent; - val = bsf(word); - word &= ~(1 << val); - if (word) - /* Make sure at least two chip-selects are available */ - _DSpareEn = 1; - else - pDCTstat->ErrStatus |= 1 << SB_SpareDis; - } - } - } - - nxtcsBase = 0; /* Next available cs base ADDR[39:8] */ - for (p = 0; p < MAX_DIMMS_SUPPORTED; p++) { - BiggestBank = 0; - for (q = 0; q < MAX_CS_SUPPORTED; q++) { /* from DIMMS to CS */ - if (pDCTstat->CSPresent & (1 << q)) { /* bank present? */ - reg = 0x40 + (q << 2) + reg_off; /* Base[q] reg.*/ - val = Get_NB32(dev, reg); - if (!(val & 3)) { /* (CSEnable|Spare == 1)bank is enabled already? */ - reg = 0x60 + ((q << 1) & 0xc) + reg_off; /*Mask[q] reg.*/ - val = Get_NB32(dev, reg); - val >>= 19; - val++; - val <<= 19; - if (val > BiggestBank) { - /*Bingo! possibly Map this chip-select next! */ - BiggestBank = val; - b = q; - } - } - } /*if bank present */ - } /* while q */ - if (BiggestBank !=0) { - curcsBase = nxtcsBase; /* curcsBase = nxtcsBase*/ - /* DRAM CS Base b Address Register offset */ - reg = 0x40 + (b << 2) + reg_off; - if (_DSpareEn) { - BiggestBank = 0; - val = 1 << Spare; /* Spare Enable*/ - } else { - val = curcsBase; - val |= 1 << CSEnable; /* Bank Enable */ - } - Set_NB32(dev, reg, val); - if (_DSpareEn) - _DSpareEn = 0; - else - /* let nxtcsBase+=Size[b] */ - nxtcsBase += BiggestBank; - } - - /* bank present but disabled?*/ - if (pDCTstat->CSTestFail & (1 << p)) { - /* DRAM CS Base b Address Register offset */ - reg = (p << 2) + 0x40 + reg_off; - val = 1 << TestFail; - Set_NB32(dev, reg, val); - } - } - - if (nxtcsBase) { - pDCTstat->DCTSysLimit = nxtcsBase - 1; - mct_AfterStitchMemory(pMCTstat, pDCTstat, dct); - } - - print_tx("StitchMemory: Status ", pDCTstat->Status); - print_tx("StitchMemory: ErrStatus ", pDCTstat->ErrStatus); - print_tx("StitchMemory: ErrCode ", pDCTstat->ErrCode); - print_t("StitchMemory: Done\n"); -} - - -static u8 Get_Tk_D(u8 k) -{ - return Table_T_k[k]; -} - - -static u8 Get_CLj_D(u8 j) -{ - return Table_CL2_j[j]; -} - -static u8 Get_DefTrc_k_D(u8 k) -{ - return Tab_defTrc_k[k]; -} - - -static u16 Get_40Tk_D(u8 k) -{ - return Tab_40T_k[k]; /* FIXME: k or k<<1 ?*/ -} - - -static u16 Get_Fk_D(u8 k) -{ - return Table_F_k[k]; /* FIXME: k or k<<1 ? */ -} - - -static u8 Dimm_Supports_D(struct DCTStatStruc *pDCTstat, - u8 i, u8 j, u8 k) -{ - u8 Tk, CLj, CL_i; - u8 ret = 0; - - u32 DIMMi; - u8 byte; - u16 word, wordx; - - DIMMi = Get_DIMMAddress_D(pDCTstat, i); - - CLj = Get_CLj_D(j); - - /* check if DIMMi supports CLj */ - CL_i = mctRead_SPD(DIMMi, SPD_CASLAT); - byte = CL_i & CLj; - if (byte) { - /*find out if its CL X, CLX-1, or CLX-2 */ - word = bsr(byte); /* bit position of CLj */ - wordx = bsr(CL_i); /* bit position of CLX of CLi */ - wordx -= word; /* CL number (CL no. = 0,1, 2, or 3) */ - wordx <<= 3; /* 8 bits per SPD byte index */ - /*get T from SPD byte 9, 23, 25*/ - word = (EncodedTSPD >> wordx) & 0xFF; - Tk = Get_Tk_D(k); - byte = mctRead_SPD(DIMMi, word); /* DIMMi speed */ - if (Tk < byte) { - ret = 1; - } else if (byte == 0) { - pDCTstat->ErrStatus |= 1 << SB_NoCycTime; - ret = 1; - } else { - ret = 0; /* DIMM is capable! */ - } - } else { - ret = 1; - } - return ret; -} - - -static u8 DIMMPresence_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - /* Check DIMMs present, verify checksum, flag SDRAM type, - * build population indicator bitmaps, and preload bus loading - * of DIMMs into DCTStatStruc. - * MAAload = number of devices on the "A" bus. - * MABload = number of devices on the "B" bus. - * MAAdimms = number of DIMMs on the "A" bus slots. - * MABdimms = number of DIMMs on the "B" bus slots. - * DATAAload = number of ranks on the "A" bus slots. - * DATABload = number of ranks on the "B" bus slots. - */ - - u16 i, j, k; - u8 smbaddr, Index; - u16 Checksum; - u8 SPDCtrl; - u16 RegDIMMPresent, MaxDimms; - u8 devwidth; - u16 DimmSlots; - u8 byte = 0, bytex; - u16 word; - - /* preload data structure with addrs */ - mctGet_DIMMAddr(pDCTstat, pDCTstat->Node_ID); - - DimmSlots = MaxDimms = mctGet_NVbits(NV_MAX_DIMMS); - - SPDCtrl = mctGet_NVbits(NV_SPDCHK_RESTRT); - - RegDIMMPresent = 0; - pDCTstat->DimmQRPresent = 0; - - for (i = 0; i< MAX_DIMMS_SUPPORTED; i++) { - if (i >= MaxDimms) - break; - - if ((pDCTstat->DimmQRPresent & (1 << i)) || (i < DimmSlots)) { - print_tx("\t DIMMPresence: i=", i); - smbaddr = Get_DIMMAddress_D(pDCTstat, i); - print_tx("\t DIMMPresence: smbaddr=", smbaddr); - if (smbaddr) { - Checksum = 0; - for (Index = 0; Index < 64; Index++) { - int status; - status = mctRead_SPD(smbaddr, Index); - if (status < 0) - break; - byte = status & 0xFF; - if (Index < 63) - Checksum += byte; - } - - if (Index == 64) { - pDCTstat->DIMMPresent |= 1 << i; - if ((Checksum & 0xFF) == byte) { - byte = mctRead_SPD(smbaddr, SPD_TYPE); - if (byte == JED_DDR2SDRAM) { - /*Dimm is 'Present'*/ - pDCTstat->DIMMValid |= 1 << i; - } - } else { - pDCTstat->DIMMSPDCSE = 1 << i; - if (SPDCtrl == 0) { - pDCTstat->ErrStatus |= 1 << SB_DIMMChkSum; - pDCTstat->ErrCode = SC_StopError; - } else { - /*if NV_SPDCHK_RESTRT is set to 1, ignore faulty SPD checksum*/ - pDCTstat->ErrStatus |= 1 << SB_DIMMChkSum; - byte = mctRead_SPD(smbaddr, SPD_TYPE); - if (byte == JED_DDR2SDRAM) - pDCTstat->DIMMValid |= 1 << i; - } - } - /* Get module information for SMBIOS */ - if (pDCTstat->DIMMValid & (1 << i)) { - pDCTstat->DimmManufacturerID[i] = 0; - for (k = 0; k < 8; k++) - pDCTstat->DimmManufacturerID[i] |= ((uint64_t)mctRead_SPD(smbaddr, SPD_MANID_START + k)) << (k * 8); - for (k = 0; k < SPD_PARTN_LENGTH; k++) - pDCTstat->DimmPartNumber[i][k] = mctRead_SPD(smbaddr, SPD_PARTN_START + k); - pDCTstat->DimmPartNumber[i][SPD_PARTN_LENGTH] = 0; - pDCTstat->DimmRevisionNumber[i] = 0; - for (k = 0; k < 2; k++) - pDCTstat->DimmRevisionNumber[i] |= ((uint16_t)mctRead_SPD(smbaddr, SPD_REVNO_START + k)) << (k * 8); - pDCTstat->DimmSerialNumber[i] = 0; - for (k = 0; k < 4; k++) - pDCTstat->DimmSerialNumber[i] |= ((uint32_t)mctRead_SPD(smbaddr, SPD_SERIAL_START + k)) << (k * 8); - pDCTstat->DimmRows[i] = mctRead_SPD(smbaddr, SPD_ROWSZ) & 0xf; - pDCTstat->DimmCols[i] = mctRead_SPD(smbaddr, SPD_COLSZ) & 0xf; - pDCTstat->DimmRanks[i] = (mctRead_SPD(smbaddr, SPD_DMBANKS) & 0x7) + 1; - pDCTstat->DimmBanks[i] = mctRead_SPD(smbaddr, SPD_LBANKS); - pDCTstat->DimmWidth[i] = mctRead_SPD(smbaddr, SPD_DEVWIDTH); - } - /* Check module type */ - byte = mctRead_SPD(smbaddr, SPD_DIMMTYPE); - if (byte & JED_REGADCMSK) { - RegDIMMPresent |= 1 << i; - pDCTstat->DimmRegistered[i] = 1; - } else { - pDCTstat->DimmRegistered[i] = 0; - } - /* Check ECC capable */ - byte = mctRead_SPD(smbaddr, SPD_EDCTYPE); - if (byte & JED_ECC) { - /* DIMM is ECC capable */ - pDCTstat->DimmECCPresent |= 1 << i; - } - if (byte & JED_ADRCPAR) { - /* DIMM is ECC capable */ - pDCTstat->DimmPARPresent |= 1 << i; - } - /* Check if x4 device */ - devwidth = mctRead_SPD(smbaddr, SPD_DEVWIDTH) & 0xFE; - if (devwidth == 4) { - /* DIMM is made with x4 or x16 drams */ - pDCTstat->Dimmx4Present |= 1 << i; - } else if (devwidth == 8) { - pDCTstat->Dimmx8Present |= 1 << i; - } else if (devwidth == 16) { - pDCTstat->Dimmx16Present |= 1 << i; - } - /* check page size */ - byte = mctRead_SPD(smbaddr, SPD_COLSZ); - byte &= 0x0F; - word = 1 << byte; - word >>= 3; - word *= devwidth; /* (((2^COLBITS) / 8) * ORG) / 2048 */ - word >>= 11; - if (word) - pDCTstat->DIMM2Kpage |= 1 << i; - - /*Check if SPD diag bit 'analysis probe installed' is set */ - byte = mctRead_SPD(smbaddr, SPD_ATTRIB); - if (byte & JED_PROBEMSK) - pDCTstat->Status |= 1 << SB_DiagClks; - - byte = mctRead_SPD(smbaddr, SPD_DMBANKS); - if (!(byte & (1 << SPDPLBit))) - pDCTstat->DimmPlPresent |= 1 << i; - byte &= 7; - byte++; /* ranks */ - if (byte > 2) { - /* if any DIMMs are QR, we have to make two passes through DIMMs*/ - if (pDCTstat->DimmQRPresent == 0) { - MaxDimms <<= 1; - } - if (i < DimmSlots) { - pDCTstat->DimmQRPresent |= (1 << i) | (1 << (i+4)); - } - byte = 2; /* upper two ranks of QR DIMM will be counted on another DIMM number iteration*/ - } else if (byte == 2) { - pDCTstat->DimmDRPresent |= 1 << i; - } - bytex = devwidth; - if (devwidth == 16) - bytex = 4; - else if (devwidth == 4) - bytex = 16; - - if (byte == 2) - bytex <<= 1; /*double Addr bus load value for dual rank DIMMs*/ - - j = i & (1<<0); - pDCTstat->DATAload[j] += byte; /*number of ranks on DATA bus*/ - pDCTstat->MAload[j] += bytex; /*number of devices on CMD/ADDR bus*/ - pDCTstat->MAdimms[j]++; /*number of DIMMs on A bus */ - /*check for DRAM package Year <= 06*/ - byte = mctRead_SPD(smbaddr, SPD_MANDATEYR); - if (byte < MYEAR06) { - /*Year < 06 and hence Week < 24 of 06 */ - pDCTstat->DimmYr06 |= 1 << i; - pDCTstat->DimmWk2406 |= 1 << i; - } else if (byte == MYEAR06) { - /*Year = 06, check if Week <= 24 */ - pDCTstat->DimmYr06 |= 1 << i; - byte = mctRead_SPD(smbaddr, SPD_MANDATEWK); - if (byte <= MWEEK24) - pDCTstat->DimmWk2406 |= 1 << i; - } - } - } - } - } - print_tx("\t DIMMPresence: DIMMValid=", pDCTstat->DIMMValid); - print_tx("\t DIMMPresence: DIMMPresent=", pDCTstat->DIMMPresent); - print_tx("\t DIMMPresence: RegDIMMPresent=", RegDIMMPresent); - print_tx("\t DIMMPresence: DimmECCPresent=", pDCTstat->DimmECCPresent); - print_tx("\t DIMMPresence: DimmPARPresent=", pDCTstat->DimmPARPresent); - print_tx("\t DIMMPresence: Dimmx4Present=", pDCTstat->Dimmx4Present); - print_tx("\t DIMMPresence: Dimmx8Present=", pDCTstat->Dimmx8Present); - print_tx("\t DIMMPresence: Dimmx16Present=", pDCTstat->Dimmx16Present); - print_tx("\t DIMMPresence: DimmPlPresent=", pDCTstat->DimmPlPresent); - print_tx("\t DIMMPresence: DimmDRPresent=", pDCTstat->DimmDRPresent); - print_tx("\t DIMMPresence: DimmQRPresent=", pDCTstat->DimmQRPresent); - print_tx("\t DIMMPresence: DATAload[0]=", pDCTstat->DATAload[0]); - print_tx("\t DIMMPresence: MAload[0]=", pDCTstat->MAload[0]); - print_tx("\t DIMMPresence: MAdimms[0]=", pDCTstat->MAdimms[0]); - print_tx("\t DIMMPresence: DATAload[1]=", pDCTstat->DATAload[1]); - print_tx("\t DIMMPresence: MAload[1]=", pDCTstat->MAload[1]); - print_tx("\t DIMMPresence: MAdimms[1]=", pDCTstat->MAdimms[1]); - - if (pDCTstat->DIMMValid != 0) { /* If any DIMMs are present...*/ - if (RegDIMMPresent != 0) { - if ((RegDIMMPresent ^ pDCTstat->DIMMValid) !=0) { - /* module type DIMM mismatch (reg'ed, unbuffered) */ - pDCTstat->ErrStatus |= 1 << SB_DimmMismatchM; - pDCTstat->ErrCode = SC_StopError; - } else{ - /* all DIMMs are registered */ - pDCTstat->Status |= 1 << SB_Registered; - } - } - if (pDCTstat->DimmECCPresent != 0) { - if ((pDCTstat->DimmECCPresent ^ pDCTstat->DIMMValid) == 0) { - /* all DIMMs are ECC capable */ - pDCTstat->Status |= 1 << SB_ECCDIMMs; - } - } - if (pDCTstat->DimmPARPresent != 0) { - if ((pDCTstat->DimmPARPresent ^ pDCTstat->DIMMValid) == 0) { - /*all DIMMs are Parity capable */ - pDCTstat->Status |= 1 << SB_PARDIMMs; - } - } - } else { - /* no DIMMs present or no DIMMs that qualified. */ - pDCTstat->ErrStatus |= 1 << SB_NoDimms; - pDCTstat->ErrCode = SC_StopError; - } - - print_tx("\t DIMMPresence: Status ", pDCTstat->Status); - print_tx("\t DIMMPresence: ErrStatus ", pDCTstat->ErrStatus); - print_tx("\t DIMMPresence: ErrCode ", pDCTstat->ErrCode); - print_t("\t DIMMPresence: Done\n"); - - mctHookAfterDIMMpre(); - - return pDCTstat->ErrCode; -} - - -static u8 Sys_Capability_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, int j, int k) -{ - /* Determine if system is capable of operating at given input - * parameters for CL, and T. There are three components to - * determining "maximum frequency" in AUTO mode: SPD component, - * Bus load component, and "Preset" max frequency component. - * This procedure is used to help find the SPD component and relies - * on pre-determination of the bus load component and the Preset - * components. The generalized algorithm for finding maximum - * frequency is structured this way so as to optimize for CAS - * latency (which might get better as a result of reduced frequency). - * See "Global relationship between index values and item values" - * for definition of CAS latency index (j) and Frequency index (k). - */ - u8 freqOK, ClOK; - u8 ret = 0; - - if (Get_Fk_D(k) > pDCTstat->PresetmaxFreq) - freqOK = 0; - else - freqOK = 1; - - /* compare proposed CAS latency with AMD Si capabilities */ - if ((j < J_MIN) || (j > J_MAX)) - ClOK = 0; - else - ClOK = 1; - - if (freqOK && ClOK) - ret = 1; - - return ret; -} - - -static u8 Get_DIMMAddress_D(struct DCTStatStruc *pDCTstat, u8 i) -{ - u8 *p; - - p = pDCTstat->DIMMAddr; - return p[i]; -} - - -static void mct_initDCT(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u32 val; - u8 err_code; - - /* Config. DCT0 for Ganged or unganged mode */ - print_t("\tmct_initDCT: DCTInit_D 0\n"); - DCTInit_D(pMCTstat, pDCTstat, 0); - if (pDCTstat->ErrCode == SC_FatalErr) { - // Do nothing goto exitDCTInit; /* any fatal errors? */ - } else { - /* Configure DCT1 if unganged and enabled*/ - if (!pDCTstat->GangedMode) { - if (pDCTstat->DIMMValidDCT[1] > 0) { - print_t("\tmct_initDCT: DCTInit_D 1\n"); - err_code = pDCTstat->ErrCode; /* save DCT0 errors */ - pDCTstat->ErrCode = 0; - DCTInit_D(pMCTstat, pDCTstat, 1); - if (pDCTstat->ErrCode == 2) /* DCT1 is not Running */ - pDCTstat->ErrCode = err_code; /* Using DCT0 Error code to update pDCTstat.ErrCode */ - } else { - val = 1 << DisDramInterface; - Set_NB32(pDCTstat->dev_dct, 0x100 + 0x94, val); - } - } - } -// exitDCTInit: -} - - -static void mct_DramInit(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u32 val; - - mct_BeforeDramInit_Prod_D(pMCTstat, pDCTstat); - // FIXME: for rev A: mct_BeforeDramInit_D(pDCTstat, dct); - - /* Disable auto refresh before Dram init when in ganged mode (Erratum 278) */ - if (pDCTstat->LogicalCPUID & (AMD_DR_B0 | AMD_DR_B1 | AMD_DR_BA)) { - if (pDCTstat->GangedMode) { - val = Get_NB32(pDCTstat->dev_dct, 0x8C + (0x100 * dct)); - val |= 1 << DisAutoRefresh; - Set_NB32(pDCTstat->dev_dct, 0x8C + (0x100 * dct), val); - } - } - - mct_DramInit_Hw_D(pMCTstat, pDCTstat, dct); - - /* Re-enable auto refresh after Dram init when in ganged mode - * to ensure both DCTs are in sync (Erratum 278) - */ - - if (pDCTstat->LogicalCPUID & (AMD_DR_B0 | AMD_DR_B1 | AMD_DR_BA)) { - if (pDCTstat->GangedMode) { - do { - val = Get_NB32(pDCTstat->dev_dct, 0x90 + (0x100 * dct)); - } while (!(val & (1 << InitDram))); - - WaitRoutine_D(50); - - val = Get_NB32(pDCTstat->dev_dct, 0x8C + (0x100 * dct)); - val &= ~(1 << DisAutoRefresh); - Set_NB32(pDCTstat->dev_dct, 0x8C + (0x100 * dct), val); - val |= 1 << DisAutoRefresh; - Set_NB32(pDCTstat->dev_dct, 0x8C + (0x100 * dct), val); - val &= ~(1 << DisAutoRefresh); - Set_NB32(pDCTstat->dev_dct, 0x8C + (0x100 * dct), val); - } - } -} - - -static u8 mct_setMode(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u8 byte; - u8 bytex; - u32 val; - u32 reg; - - byte = bytex = pDCTstat->DIMMValid; - bytex &= 0x55; /* CHA DIMM pop */ - pDCTstat->DIMMValidDCT[0] = bytex; - - byte &= 0xAA; /* CHB DIMM popa */ - byte >>= 1; - pDCTstat->DIMMValidDCT[1] = byte; - - if (byte != bytex) { - pDCTstat->ErrStatus &= ~(1 << SB_DimmMismatchO); - } else { - if (mctGet_NVbits(NV_Unganged)) - pDCTstat->ErrStatus |= (1 << SB_DimmMismatchO); - - if (!(pDCTstat->ErrStatus & (1 << SB_DimmMismatchO))) { - pDCTstat->GangedMode = 1; - /* valid 128-bit mode population. */ - pDCTstat->Status |= 1 << SB_128bitmode; - reg = 0x110; - val = Get_NB32(pDCTstat->dev_dct, reg); - val |= 1 << DctGangEn; - Set_NB32(pDCTstat->dev_dct, reg, val); - print_tx("setMode: DRAM Controller Select Low Register = ", val); - } - } - return pDCTstat->ErrCode; -} - - -u32 Get_NB32(u32 dev, u32 reg) -{ - return pci_read_config32(dev, reg); -} - - -void Set_NB32(u32 dev, u32 reg, u32 val) -{ - pci_write_config32(dev, reg, val); -} - - -u32 Get_NB32_index(u32 dev, u32 index_reg, u32 index) -{ - u32 dword; - - Set_NB32(dev, index_reg, index); - dword = Get_NB32(dev, index_reg+0x4); - - return dword; -} - -void Set_NB32_index(u32 dev, u32 index_reg, u32 index, u32 data) -{ - Set_NB32(dev, index_reg, index); - Set_NB32(dev, index_reg + 0x4, data); -} - - -u32 Get_NB32_index_wait(u32 dev, u32 index_reg, u32 index) -{ - - u32 dword; - - - index &= ~(1 << DctAccessWrite); - Set_NB32(dev, index_reg, index); - do { - dword = Get_NB32(dev, index_reg); - } while (!(dword & (1 << DctAccessDone))); - dword = Get_NB32(dev, index_reg + 0x4); - - return dword; -} - - -void Set_NB32_index_wait(u32 dev, u32 index_reg, u32 index, u32 data) -{ - u32 dword; - - - Set_NB32(dev, index_reg + 0x4, data); - index |= (1 << DctAccessWrite); - Set_NB32(dev, index_reg, index); - do { - dword = Get_NB32(dev, index_reg); - } while (!(dword & (1 << DctAccessDone))); - -} - - -static u8 mct_PlatformSpec(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - /* Get platform specific config/timing values from the interface layer - * and program them into DCT. - */ - - u32 dev = pDCTstat->dev_dct; - u32 index_reg; - u8 i, i_start, i_end; - - if (pDCTstat->GangedMode) { - SyncSetting(pDCTstat); - i_start = 0; - i_end = 2; - } else { - i_start = dct; - i_end = dct + 1; - } - for (i = i_start; i < i_end; i++) { - index_reg = 0x98 + (i * 0x100); - Set_NB32_index_wait(dev, index_reg, 0x00, pDCTstat->CH_ODC_CTL[i]); /* Channel A Output Driver Compensation Control */ - Set_NB32_index_wait(dev, index_reg, 0x04, pDCTstat->CH_ADDR_TMG[i]); /* Channel A Output Driver Compensation Control */ - } - - return pDCTstat->ErrCode; - -} - - -static void mct_SyncDCTsReady(struct DCTStatStruc *pDCTstat) -{ - u32 dev; - u32 val; - - if (pDCTstat->NodePresent) { - print_tx("mct_SyncDCTsReady: Node ", pDCTstat->Node_ID); - dev = pDCTstat->dev_dct; - - if ((pDCTstat->DIMMValidDCT[0]) || (pDCTstat->DIMMValidDCT[1])) { /* This Node has dram */ - do { - val = Get_NB32(dev, 0x110); - } while (!(val & (1 << DramEnabled))); - print_t("mct_SyncDCTsReady: DramEnabled\n"); - } - } /* Node is present */ -} - - -static void mct_AfterGetCLT(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - if (!pDCTstat->GangedMode) { - if (dct == 0) { - pDCTstat->DIMMValid = pDCTstat->DIMMValidDCT[dct]; - if (pDCTstat->DIMMValidDCT[dct] == 0) - pDCTstat->ErrCode = SC_StopError; - } else { - pDCTstat->CSPresent = 0; - pDCTstat->CSTestFail = 0; - pDCTstat->DIMMValid = pDCTstat->DIMMValidDCT[dct]; - if (pDCTstat->DIMMValidDCT[dct] == 0) - pDCTstat->ErrCode = SC_StopError; - } - } -} - -static u8 mct_SPDCalcWidth(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u8 ret; - - if (dct == 0) { - SPDCalcWidth_D(pMCTstat, pDCTstat); - ret = mct_setMode(pMCTstat, pDCTstat); - } else { - ret = pDCTstat->ErrCode; - } - - print_tx("SPDCalcWidth: Status ", pDCTstat->Status); - print_tx("SPDCalcWidth: ErrStatus ", pDCTstat->ErrStatus); - print_tx("SPDCalcWidth: ErrCode ", pDCTstat->ErrCode); - print_t("SPDCalcWidth: Done\n"); - - return ret; -} - - -static void mct_AfterStitchMemory(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u32 val; - u32 dword; - u32 dev; - u32 reg; - u8 _MemHoleRemap; - u32 DramHoleBase; - - _MemHoleRemap = mctGet_NVbits(NV_MemHole); - DramHoleBase = mctGet_NVbits(NV_BottomIO); - DramHoleBase <<= 8; - /* Increase hole size so;[31:24]to[31:16] - * it has granularity of 128MB shl eax,8 - * Set 'effective' bottom IOmov DramHoleBase,eax - */ - pMCTstat->HoleBase = (DramHoleBase & 0xFFFFF800) << 8; - - /* In unganged mode, we must add DCT0 and DCT1 to DCTSysLimit */ - if (!pDCTstat->GangedMode) { - dev = pDCTstat->dev_dct; - pDCTstat->NodeSysLimit += pDCTstat->DCTSysLimit; - /* if DCT0 and DCT1 both exist, set DctSelBaseAddr[47:27] to the top of DCT0 */ - if (dct == 0) { - if (pDCTstat->DIMMValidDCT[1] > 0) { - dword = pDCTstat->DCTSysLimit + 1; - dword += pDCTstat->NodeSysBase; - dword >>= 8; /* scale [39:8] to [47:27],and to F2x110[31:11] */ - if ((dword >= DramHoleBase) && _MemHoleRemap) { - pMCTstat->HoleBase = (DramHoleBase & 0xFFFFF800) << 8; - val = pMCTstat->HoleBase; - val >>= 16; - val = (((~val) & 0xFF) + 1); - val <<= 8; - dword += val; - } - reg = 0x110; - val = Get_NB32(dev, reg); - val &= 0x7F; - val |= dword; - val |= 3; /* Set F2x110[DctSelHiRngEn], F2x110[DctSelHi] */ - Set_NB32(dev, reg, val); - print_tx("AfterStitch DCT0 and DCT1: DRAM Controller Select Low Register = ", val); - print_tx("AfterStitch DCT0 and DCT1: DRAM Controller Select High Register = ", dword); - - reg = 0x114; - val = dword; - Set_NB32(dev, reg, val); - } - } else { - /* Program the DctSelBaseAddr value to 0 - if DCT 0 is disabled */ - if (pDCTstat->DIMMValidDCT[0] == 0) { - dword = pDCTstat->NodeSysBase; - dword >>= 8; - if ((dword >= DramHoleBase) && _MemHoleRemap) { - pMCTstat->HoleBase = (DramHoleBase & 0xFFFFF800) << 8; - val = pMCTstat->HoleBase; - val >>= 8; - val &= ~(0xFFFF); - val |= (((~val) & 0xFFFF) + 1); - dword += val; - } - reg = 0x114; - val = dword; - Set_NB32(dev, reg, val); - - reg = 0x110; - val |= 3; /* Set F2x110[DctSelHiRngEn], F2x110[DctSelHi] */ - Set_NB32(dev, reg, val); - print_tx("AfterStitch DCT1 only: DRAM Controller Select Low Register = ", val); - print_tx("AfterStitch DCT1 only: DRAM Controller Select High Register = ", dword); - } - } - } else { - pDCTstat->NodeSysLimit += pDCTstat->DCTSysLimit; - } - print_tx("AfterStitch pDCTstat->NodeSysBase = ", pDCTstat->NodeSysBase); - print_tx("mct_AfterStitchMemory: pDCTstat->NodeSysLimit ", pDCTstat->NodeSysLimit); -} - - -static u8 mct_DIMMPresence(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u8 ret; - - if (dct == 0) - ret = DIMMPresence_D(pMCTstat, pDCTstat); - else - ret = pDCTstat->ErrCode; - - return ret; -} - - -/* mct_BeforeGetDIMMAddress inline in C */ - - -static void mct_OtherTiming(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - u8 Node; - - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - if (pDCTstat->NodePresent) { - if (pDCTstat->DIMMValidDCT[0]) { - pDCTstat->DIMMValid = pDCTstat->DIMMValidDCT[0]; - Set_OtherTiming(pMCTstat, pDCTstat, 0); - } - if (pDCTstat->DIMMValidDCT[1] && !pDCTstat->GangedMode) { - pDCTstat->DIMMValid = pDCTstat->DIMMValidDCT[1]; - Set_OtherTiming(pMCTstat, pDCTstat, 1); - } - } /* Node is present*/ - } /* while Node */ -} - - -static void Set_OtherTiming(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u32 reg; - u32 reg_off = 0x100 * dct; - u32 val; - u32 dword; - u32 dev = pDCTstat->dev_dct; - - Get_Trdrd(pMCTstat, pDCTstat, dct); - Get_Twrwr(pMCTstat, pDCTstat, dct); - Get_Twrrd(pMCTstat, pDCTstat, dct); - Get_TrwtTO(pMCTstat, pDCTstat, dct); - Get_TrwtWB(pMCTstat, pDCTstat); - - reg = 0x8C + reg_off; /* Dram Timing Hi */ - val = Get_NB32(dev, reg); - val &= 0xffff0300; - dword = pDCTstat->TrwtTO; //0x07 - val |= dword << 4; - dword = pDCTstat->Twrrd; //0x03 - val |= dword << 10; - dword = pDCTstat->Twrwr; //0x03 - val |= dword << 12; - dword = pDCTstat->Trdrd; //0x03 - val |= dword << 14; - dword = pDCTstat->TrwtWB; //0x07 - val |= dword; - val = OtherTiming_A_D(pDCTstat, val); - Set_NB32(dev, reg, val); - -} - - -static void Get_Trdrd(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u8 Trdrd; - u8 byte; - u32 dword; - u32 val; - u32 index_reg = 0x98 + 0x100 * dct; - u32 dev = pDCTstat->dev_dct; - - if ((pDCTstat->Dimmx4Present != 0) && (pDCTstat->Dimmx8Present != 0)) { - /* mixed (x4 or x8) DIMM types - the largest DqsRcvEnGrossDelay of any DIMM minus the DqsRcvEnGrossDelay - of any other DIMM is equal to the Critical Gross Delay Difference (CGDD) for Trdrd.*/ - byte = Get_DqsRcvEnGross_Diff(pDCTstat, dev, index_reg); - if (byte == 0) - Trdrd = 1; - else - Trdrd = 2; - - } else { - /* - Trdrd with non-mixed DIMM types - RdDqsTime are the same for all DIMMs and DqsRcvEn difference between - any two DIMMs is less than half of a MEMCLK, BIOS should program Trdrd to 0000b, - else BIOS should program Trdrd to 0001b. - - RdDqsTime are the same for all DIMMs - DDR400~DDR667 only use one set register - DDR800 have two set register for DIMM0 and DIMM1 */ - Trdrd = 1; - if (pDCTstat->Speed > 3) { - /* DIMM0+DIMM1 exist */ //NOTE it should be 5 - val = bsf(pDCTstat->DIMMValid); - dword = bsr(pDCTstat->DIMMValid); - if (dword != val && dword != 0) { - /* DCT Read DQS Timing Control - DIMM0 - Low */ - dword = Get_NB32_index_wait(dev, index_reg, 0x05); - /* DCT Read DQS Timing Control - DIMM1 - Low */ - val = Get_NB32_index_wait(dev, index_reg, 0x105); - if (val != dword) - goto Trdrd_1; - - /* DCT Read DQS Timing Control - DIMM0 - High */ - dword = Get_NB32_index_wait(dev, index_reg, 0x06); - /* DCT Read DQS Timing Control - DIMM1 - High */ - val = Get_NB32_index_wait(dev, index_reg, 0x106); - if (val != dword) - goto Trdrd_1; - } - } - - /* DqsRcvEn difference between any two DIMMs is - less than half of a MEMCLK */ - /* DqsRcvEn byte 1,0*/ - if (Check_DqsRcvEn_Diff(pDCTstat, dct, dev, index_reg, 0x10)) - goto Trdrd_1; - /* DqsRcvEn byte 3,2*/ - if (Check_DqsRcvEn_Diff(pDCTstat, dct, dev, index_reg, 0x11)) - goto Trdrd_1; - /* DqsRcvEn byte 5,4*/ - if (Check_DqsRcvEn_Diff(pDCTstat, dct, dev, index_reg, 0x20)) - goto Trdrd_1; - /* DqsRcvEn byte 7,6*/ - if (Check_DqsRcvEn_Diff(pDCTstat, dct, dev, index_reg, 0x21)) - goto Trdrd_1; - /* DqsRcvEn ECC*/ - if (Check_DqsRcvEn_Diff(pDCTstat, dct, dev, index_reg, 0x12)) - goto Trdrd_1; - Trdrd = 0; - Trdrd_1: - ; - } - pDCTstat->Trdrd = Trdrd; - -} - - -static void Get_Twrwr(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u8 Twrwr = 0; - u32 index_reg = 0x98 + 0x100 * dct; - u32 dev = pDCTstat->dev_dct; - u32 val; - u32 dword; - - /* WrDatGrossDlyByte only use one set register when DDR400~DDR667 - DDR800 have two set register for DIMM0 and DIMM1 */ - if (pDCTstat->Speed > 3) { - val = bsf(pDCTstat->DIMMValid); - dword = bsr(pDCTstat->DIMMValid); - if (dword != val && dword != 0) { - /*the largest WrDatGrossDlyByte of any DIMM minus the - WrDatGrossDlyByte of any other DIMM is equal to CGDD */ - val = Get_WrDatGross_Diff(pDCTstat, dct, dev, index_reg); - } - if (val == 0) - Twrwr = 2; - else - Twrwr = 3; - } - pDCTstat->Twrwr = Twrwr; -} - - -static void Get_Twrrd(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u8 byte, bytex, val; - u32 index_reg = 0x98 + 0x100 * dct; - u32 dev = pDCTstat->dev_dct; - - /* On any given byte lane, the largest WrDatGrossDlyByte delay of - any DIMM minus the DqsRcvEnGrossDelay delay of any other DIMM is - equal to the Critical Gross Delay Difference (CGDD) for Twrrd.*/ - - /* WrDatGrossDlyByte only use one set register when DDR400~DDR667 - DDR800 have two set register for DIMM0 and DIMM1 */ - if (pDCTstat->Speed > 3) { - val = Get_WrDatGross_Diff(pDCTstat, dct, dev, index_reg); - } else { - val = Get_WrDatGross_MaxMin(pDCTstat, dct, dev, index_reg, 1); /* WrDatGrossDlyByte byte 0,1,2,3 for DIMM0 */ - pDCTstat->WrDatGrossH = (u8) val; /* low byte = max value */ - } - - Get_DqsRcvEnGross_Diff(pDCTstat, dev, index_reg); - - bytex = pDCTstat->DqsRcvEnGrossL; - byte = pDCTstat->WrDatGrossH; - if (byte > bytex) { - byte -= bytex; - if (byte == 1) - bytex = 1; - else - bytex = 2; - } else { - bytex = 0; - } - pDCTstat->Twrrd = bytex; -} - - -static void Get_TrwtTO(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u8 byte, bytex; - u32 index_reg = 0x98 + 0x100 * dct; - u32 dev = pDCTstat->dev_dct; - - /* On any given byte lane, the largest WrDatGrossDlyByte delay of - any DIMM minus the DqsRcvEnGrossDelay delay of any other DIMM is - equal to the Critical Gross Delay Difference (CGDD) for TrwtTO. */ - Get_DqsRcvEnGross_Diff(pDCTstat, dev, index_reg); - Get_WrDatGross_Diff(pDCTstat, dct, dev, index_reg); - bytex = pDCTstat->DqsRcvEnGrossL; - byte = pDCTstat->WrDatGrossH; - if (bytex > byte) { - bytex -= byte; - if ((bytex == 1) || (bytex == 2)) - bytex = 3; - else - bytex = 4; - } else { - byte -= bytex; - if ((byte == 0) || (byte == 1)) - bytex = 2; - else - bytex = 1; - } - - pDCTstat->TrwtTO = bytex; -} - - -static void Get_TrwtWB(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - /* TrwtWB ensures read-to-write data-bus turnaround. - This value should be one more than the programmed TrwtTO.*/ - pDCTstat->TrwtWB = pDCTstat->TrwtTO + 1; -} - - -static u8 Check_DqsRcvEn_Diff(struct DCTStatStruc *pDCTstat, - u8 dct, u32 dev, u32 index_reg, - u32 index) -{ - u8 Smallest_0, Largest_0, Smallest_1, Largest_1; - u8 i; - u32 val; - u8 byte; - u8 ecc_reg = 0; - - Smallest_0 = 0xFF; - Smallest_1 = 0xFF; - Largest_0 = 0; - Largest_1 = 0; - - if (index == 0x12) - ecc_reg = 1; - - for (i = 0; i < 8; i+=2) { - if (pDCTstat->DIMMValid & (1 << i)) { - val = Get_NB32_index_wait(dev, index_reg, index); - byte = val & 0xFF; - if (byte < Smallest_0) - Smallest_0 = byte; - if (byte > Largest_0) - Largest_0 = byte; - if (!(ecc_reg)) { - byte = (val >> 16) & 0xFF; - if (byte < Smallest_1) - Smallest_1 = byte; - if (byte > Largest_1) - Largest_1 = byte; - } - } - index += 3; - } /* while ++i */ - - /* check if total DqsRcvEn delay difference between any - two DIMMs is less than half of a MEMCLK */ - if ((Largest_0 - Smallest_0) > 31) - return 1; - if (!(ecc_reg)) - if ((Largest_1 - Smallest_1) > 31) - return 1; - return 0; -} - - -static u8 Get_DqsRcvEnGross_Diff(struct DCTStatStruc *pDCTstat, - u32 dev, u32 index_reg) -{ - u8 Smallest, Largest; - u32 val; - u8 byte, bytex; - - /* The largest DqsRcvEnGrossDelay of any DIMM minus the - DqsRcvEnGrossDelay of any other DIMM is equal to the Critical - Gross Delay Difference (CGDD) */ - /* DqsRcvEn byte 1,0 */ - val = Get_DqsRcvEnGross_MaxMin(pDCTstat, dev, index_reg, 0x10); - Largest = val & 0xFF; - Smallest = (val >> 8) & 0xFF; - - /* DqsRcvEn byte 3,2 */ - val = Get_DqsRcvEnGross_MaxMin(pDCTstat, dev, index_reg, 0x11); - byte = val & 0xFF; - bytex = (val >> 8) & 0xFF; - if (bytex < Smallest) - Smallest = bytex; - if (byte > Largest) - Largest = byte; - - /* DqsRcvEn byte 5,4 */ - val = Get_DqsRcvEnGross_MaxMin(pDCTstat, dev, index_reg, 0x20); - byte = val & 0xFF; - bytex = (val >> 8) & 0xFF; - if (bytex < Smallest) - Smallest = bytex; - if (byte > Largest) - Largest = byte; - - /* DqsRcvEn byte 7,6 */ - val = Get_DqsRcvEnGross_MaxMin(pDCTstat, dev, index_reg, 0x21); - byte = val & 0xFF; - bytex = (val >> 8) & 0xFF; - if (bytex < Smallest) - Smallest = bytex; - if (byte > Largest) - Largest = byte; - - if (pDCTstat->DimmECCPresent> 0) { - /*DqsRcvEn Ecc */ - val = Get_DqsRcvEnGross_MaxMin(pDCTstat, dev, index_reg, 0x12); - byte = val & 0xFF; - bytex = (val >> 8) & 0xFF; - if (bytex < Smallest) - Smallest = bytex; - if (byte > Largest) - Largest = byte; - } - - pDCTstat->DqsRcvEnGrossL = Largest; - return Largest - Smallest; -} - - -static u8 Get_WrDatGross_Diff(struct DCTStatStruc *pDCTstat, - u8 dct, u32 dev, u32 index_reg) -{ - u8 Smallest, Largest; - u32 val; - u8 byte, bytex; - - /* The largest WrDatGrossDlyByte of any DIMM minus the - WrDatGrossDlyByte of any other DIMM is equal to CGDD */ - val = Get_WrDatGross_MaxMin(pDCTstat, dct, dev, index_reg, 0x01); /* WrDatGrossDlyByte byte 0,1,2,3 for DIMM0 */ - Largest = val & 0xFF; - Smallest = (val >> 8) & 0xFF; - val = Get_WrDatGross_MaxMin(pDCTstat, dct, dev, index_reg, 0x101); /* WrDatGrossDlyByte byte 0,1,2,3 for DIMM1 */ - byte = val & 0xFF; - bytex = (val >> 8) & 0xFF; - if (bytex < Smallest) - Smallest = bytex; - if (byte > Largest) - Largest = byte; - - // FIXME: Add Cx support. - - pDCTstat->WrDatGrossH = Largest; - return Largest - Smallest; -} - -static u16 Get_DqsRcvEnGross_MaxMin(struct DCTStatStruc *pDCTstat, - u32 dev, u32 index_reg, - u32 index) -{ - u8 Smallest, Largest; - u8 i; - u8 byte; - u32 val; - u16 word; - u8 ecc_reg = 0; - - Smallest = 7; - Largest = 0; - - if (index == 0x12) - ecc_reg = 1; - - for (i = 0; i < 8; i+=2) { - if (pDCTstat->DIMMValid & (1 << i)) { - val = Get_NB32_index_wait(dev, index_reg, index); - val &= 0x00E000E0; - byte = (val >> 5) & 0xFF; - if (byte < Smallest) - Smallest = byte; - if (byte > Largest) - Largest = byte; - if (!(ecc_reg)) { - byte = (val >> (16 + 5)) & 0xFF; - if (byte < Smallest) - Smallest = byte; - if (byte > Largest) - Largest = byte; - } - } - index += 3; - } /* while ++i */ - - word = Smallest; - word <<= 8; - word |= Largest; - - return word; -} - -static u16 Get_WrDatGross_MaxMin(struct DCTStatStruc *pDCTstat, - u8 dct, u32 dev, u32 index_reg, - u32 index) -{ - u8 Smallest, Largest; - u8 i, j; - u32 val; - u8 byte; - u16 word; - - Smallest = 3; - Largest = 0; - for (i = 0; i < 2; i++) { - val = Get_NB32_index_wait(dev, index_reg, index); - val &= 0x60606060; - val >>= 5; - for (j = 0; j < 4; j++) { - byte = val & 0xFF; - if (byte < Smallest) - Smallest = byte; - if (byte > Largest) - Largest = byte; - val >>= 8; - } /* while ++j */ - index++; - } /*while ++i*/ - - if (pDCTstat->DimmECCPresent > 0) { - index++; - val = Get_NB32_index_wait(dev, index_reg, index); - val &= 0x00000060; - val >>= 5; - byte = val & 0xFF; - if (byte < Smallest) - Smallest = byte; - if (byte > Largest) - Largest = byte; - } - - word = Smallest; - word <<= 8; - word |= Largest; - - return word; -} - - - -static void mct_FinalMCT_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - print_t("\tmct_FinalMCT_D: Clr Cl, Wb\n"); - - - /* ClrClToNB_D postponed until we're done executing from ROM */ - mct_ClrWbEnhWsbDis_D(pMCTstat, pDCTstat); -} - - -static void mct_InitialMCT_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat) -{ - print_t("\tmct_InitialMCT_D: Set Cl, Wb\n"); - mct_SetClToNB_D(pMCTstat, pDCTstat); - mct_SetWbEnhWsbDis_D(pMCTstat, pDCTstat); -} - - -static u32 mct_NodePresent_D(void) -{ - u32 val; - val = 0x12001022; - return val; -} - - -static void mct_init(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u32 lo, hi; - u32 addr; - - pDCTstat->GangedMode = 0; - pDCTstat->DRPresent = 1; - - /* enable extend PCI configuration access */ - addr = NB_CFG_MSR; - _RDMSR(addr, &lo, &hi); - if (hi & (1 << (46-32))) { - pDCTstat->Status |= 1 << SB_ExtConfig; - } else { - hi |= 1 << (46-32); - _WRMSR(addr, lo, hi); - } -} - - -static void clear_legacy_Mode(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u32 reg; - u32 val; - u32 dev = pDCTstat->dev_dct; - - /* Clear Legacy BIOS Mode bit */ - reg = 0x94; - val = Get_NB32(dev, reg); - val &= ~(1<<LegacyBiosMode); - Set_NB32(dev, reg, val); -} - - -static void mct_HTMemMapExt(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - u8 Node; - u32 Drambase, Dramlimit; - u32 val; - u32 reg; - u32 dev; - u32 devx; - u32 dword; - struct DCTStatStruc *pDCTstat; - - pDCTstat = pDCTstatA + 0; - dev = pDCTstat->dev_map; - - /* Copy dram map from F1x40/44,F1x48/4c, - to F1x120/124(Node0),F1x120/124(Node1),...*/ - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - pDCTstat = pDCTstatA + Node; - devx = pDCTstat->dev_map; - - /* get base/limit from Node0 */ - reg = 0x40 + (Node << 3); /* Node0/Dram Base 0 */ - val = Get_NB32(dev, reg); - Drambase = val >> (16 + 3); - - reg = 0x44 + (Node << 3); /* Node0/Dram Base 0 */ - val = Get_NB32(dev, reg); - Dramlimit = val >> (16 + 3); - - /* set base/limit to F1x120/124 per Node */ - if (pDCTstat->NodePresent) { - reg = 0x120; /* F1x120,DramBase[47:27] */ - val = Get_NB32(devx, reg); - val &= 0xFFE00000; - val |= Drambase; - Set_NB32(devx, reg, val); - - reg = 0x124; - val = Get_NB32(devx, reg); - val &= 0xFFE00000; - val |= Dramlimit; - Set_NB32(devx, reg, val); - - if (pMCTstat->GStatus & (1 << GSB_HWHole)) { - reg = 0xF0; - val = Get_NB32(devx, reg); - val |= (1 << DramMemHoistValid); - val &= ~(0xFF << 24); - dword = (pMCTstat->HoleBase >> (24 - 8)) & 0xFF; - dword <<= 24; - val |= dword; - Set_NB32(devx, reg, val); - } - - } - } -} - -static void SetCSTriState(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u32 val; - u32 dev = pDCTstat->dev_dct; - u32 index_reg = 0x98 + 0x100 * dct; - u8 cs; - u32 index; - u16 word; - - /* Tri-state unused chipselects when motherboard - termination is available */ - - // FIXME: skip for Ax - - word = pDCTstat->CSPresent; - if (pDCTstat->Status & (1 << SB_Registered)) { - for (cs = 0; cs < 8; cs++) { - if (word & (1 << cs)) { - if (!(cs & 1)) - word |= 1 << (cs + 1); - } - } - } - word = (~word) & 0xFF; - index = 0x0c; - val = Get_NB32_index_wait(dev, index_reg, index); - val |= word; - Set_NB32_index_wait(dev, index_reg, index, val); -} - - -#ifdef UNUSED_CODE -static void SetCKETriState(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u32 val; - u32 dev; - u32 index_reg = 0x98 + 0x100 * dct; - u8 cs; - u32 index; - u16 word; - - /* Tri-state unused CKEs when motherboard termination is available */ - - // FIXME: skip for Ax - - dev = pDCTstat->dev_dct; - word = 0x101; - for (cs = 0; cs < 8; cs++) { - if (pDCTstat->CSPresent & (1 << cs)) { - if (!(cs & 1)) - word &= 0xFF00; - else - word &= 0x00FF; - } - } - - index = 0x0c; - val = Get_NB32_index_wait(dev, index_reg, index); - if ((word & 0x00FF) == 1) - val |= 1 << 12; - else - val &= ~(1 << 12); - - if ((word >> 8) == 1) - val |= 1 << 13; - else - val &= ~(1 << 13); - - Set_NB32_index_wait(dev, index_reg, index, val); -} -#endif - -static void SetODTTriState(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u32 val; - u32 dev; - u32 index_reg = 0x98 + 0x100 * dct; - u8 cs; - u32 index; - u8 odt; - u8 max_dimms; - - // FIXME: skip for Ax - - dev = pDCTstat->dev_dct; - - /* Tri-state unused ODTs when motherboard termination is available */ - max_dimms = (u8) mctGet_NVbits(NV_MAX_DIMMS); - odt = 0x0F; /* tristate all the pins then clear the used ones. */ - - for (cs = 0; cs < 8; cs += 2) { - if (pDCTstat->CSPresent & (1 << cs)) { - odt &= ~(1 << (cs / 2)); - - /* if quad-rank capable platform clear additional pins */ - if (max_dimms != MAX_CS_SUPPORTED) { - if (pDCTstat->CSPresent & (1 << (cs + 1))) - odt &= ~(4 << (cs / 2)); - } - } - } - - index = 0x0C; - val = Get_NB32_index_wait(dev, index_reg, index); - val |= (odt << 8); - Set_NB32_index_wait(dev, index_reg, index, val); - -} - - -static void InitPhyCompensation(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u8 i; - u32 index_reg = 0x98 + 0x100 * dct; - u32 dev = pDCTstat->dev_dct; - u32 val; - u32 valx = 0; - u32 dword; - const u8 *p; - - val = Get_NB32_index_wait(dev, index_reg, 0x00); - dword = 0; - for (i = 0; i < 6; i++) { - switch (i) { - case 0: - case 4: - p = Table_Comp_Rise_Slew_15x; - valx = p[(val >> 16) & 3]; - break; - case 1: - case 5: - p = Table_Comp_Fall_Slew_15x; - valx = p[(val >> 16) & 3]; - break; - case 2: - p = Table_Comp_Rise_Slew_20x; - valx = p[(val >> 8) & 3]; - break; - case 3: - p = Table_Comp_Fall_Slew_20x; - valx = p[(val >> 8) & 3]; - break; - - } - dword |= valx << (5 * i); - } - - /* Override/Exception */ - if (!pDCTstat->GangedMode) { - i = 0; /* use i for the dct setting required */ - if (pDCTstat->MAdimms[0] < 4) - i = 1; - if (((pDCTstat->Speed == 2) || (pDCTstat->Speed == 3)) && (pDCTstat->MAdimms[i] == 4)) { - dword &= 0xF18FFF18; - index_reg = 0x98; /* force dct = 0 */ - } - } - - Set_NB32_index_wait(dev, index_reg, 0x0a, dword); -} - - -static void WaitRoutine_D(u32 time) -{ - while (time) { - _EXECFENCE; - time--; - } -} - - -static void mct_EarlyArbEn_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u32 reg; - u32 val; - u32 dev = pDCTstat->dev_dct; - - /* GhEnhancement #18429 modified by askar: For low NB CLK : - * Memclk ratio, the DCT may need to arbitrate early to avoid - * unnecessary bubbles. - * bit 19 of F2x[1,0]78 Dram Control Register, set this bit only when - * NB CLK : Memclk ratio is between 3:1 (inclusive) to 4:5 (inclusive) - */ - - reg = 0x78; - val = Get_NB32(dev, reg); - - //FIXME: check for Cx - if (CheckNBCOFEarlyArbEn(pMCTstat, pDCTstat)) - val |= (1 << EarlyArbEn); - - Set_NB32(dev, reg, val); - -} - - -static u8 CheckNBCOFEarlyArbEn(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u32 reg; - u32 val; - u32 tmp; - u32 rem; - u32 dev = pDCTstat->dev_dct; - u32 hi, lo; - u8 NbDid = 0; - - /* Check if NB COF >= 4*Memclk, if it is not, return a fatal error - */ - - /* 3*(Fn2xD4[NBFid]+4)/(2^NbDid)/(3+Fn2x94[MemClkFreq]) */ - _RDMSR(MSR_COFVID_STS, &lo, &hi); - if (lo & (1 << 22)) - NbDid |= 1; - - - reg = 0x94; - val = Get_NB32(dev, reg); - if (!(val & (1 << MemClkFreqVal))) - val = Get_NB32(dev, reg * 0x100); /* get the DCT1 value */ - - val &= 0x07; - val += 3; - if (NbDid) - val <<= 1; - tmp = val; - - dev = pDCTstat->dev_nbmisc; - reg = 0xD4; - val = Get_NB32(dev, reg); - val &= 0x1F; - val += 3; - val *= 3; - val = val / tmp; - rem = val % tmp; - tmp >>= 1; - - // Yes this could be nicer but this was how the asm was.... - if (val < 3) { /* NClk:MemClk < 3:1 */ - return 0; - } else if (val > 4) { /* NClk:MemClk >= 5:1 */ - return 0; - } else if ((val == 4) && (rem > tmp)) { /* NClk:MemClk > 4.5:1 */ - return 0; - } else { - return 1; /* 3:1 <= NClk:MemClk <= 4.5:1*/ - } -} - - -static void mct_ResetDataStruct_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - u8 Node; - struct DCTStatStruc *pDCTstat; - - /* Initialize Data structures by clearing all entries to 0 */ - memset(pMCTstat, 0x00, sizeof(*pMCTstat)); - - for (Node = 0; Node < 8; Node++) { - pDCTstat = pDCTstatA + Node; - - /* Clear all entries except persistentData */ - memset(pDCTstat, 0x00, sizeof(*pDCTstat) - sizeof(pDCTstat->persistentData)); - } -} - - -static void mct_BeforeDramInit_Prod_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u8 i; - u32 reg_off; - u32 dev = pDCTstat->dev_dct; - - // FIXME: skip for Ax - if ((pDCTstat->Speed == 3) || (pDCTstat->Speed == 2)) { // MemClkFreq = 667MHz or 533MHz - for (i = 0; i < 2; i++) { - reg_off = 0x100 * i; - Set_NB32(dev, 0x98 + reg_off, 0x0D000030); - Set_NB32(dev, 0x9C + reg_off, 0x00000806); - Set_NB32(dev, 0x98 + reg_off, 0x4D040F30); - } - } -} - - -void mct_AdjustDelayRange_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 *dqs_pos) -{ - // FIXME: Skip for Ax - if ((pDCTstat->Speed == 3) || (pDCTstat->Speed == 2)) { // MemClkFreq = 667MHz or 533MHz - *dqs_pos = 32; - } -} - -static u32 mct_DisDllShutdownSR(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u32 DramConfigLo, u8 dct) -{ - u32 reg_off = 0x100 * dct; - u32 dev = pDCTstat->dev_dct; - - /* Write 0000_07D0h to register F2x[1, 0]98_x4D0FE006 */ - if (pDCTstat->LogicalCPUID & (AMD_DA_C2 | AMD_RB_C3)) { - Set_NB32(dev, 0x9C + reg_off, 0x7D0); - Set_NB32(dev, 0x98 + reg_off, 0x4D0FE006); - Set_NB32(dev, 0x9C + reg_off, 0x190); - Set_NB32(dev, 0x98 + reg_off, 0x4D0FE007); - } - - return DramConfigLo | /* DisDllShutdownSR */ 1 << 27; -} - -static void mct_EnDllShutdownSR(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u32 reg_off = 0x100 * dct; - u32 dev = pDCTstat->dev_dct, val; - - /* Write 0000_07D0h to register F2x[1, 0]98_x4D0FE006 */ - if (pDCTstat->LogicalCPUID & (AMD_DA_C2 | AMD_RB_C3)) { - Set_NB32(dev, 0x9C + reg_off, 0x1C); - Set_NB32(dev, 0x98 + reg_off, 0x4D0FE006); - Set_NB32(dev, 0x9C + reg_off, 0x13D); - Set_NB32(dev, 0x98 + reg_off, 0x4D0FE007); - - val = Get_NB32(dev, 0x90 + reg_off); - val &= ~(1 << 27/* DisDllShutdownSR */); - Set_NB32(dev, 0x90 + reg_off, val); - } -} - -void mct_SetClToNB_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u32 lo, hi; - u32 msr; - - // FIXME: Maybe check the CPUID? - not for now. - // pDCTstat->LogicalCPUID; - - msr = BU_CFG2_MSR; - _RDMSR(msr, &lo, &hi); - lo |= 1 << ClLinesToNbDis; - _WRMSR(msr, lo, hi); -} - - -void mct_ClrClToNB_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - - u32 lo, hi; - u32 msr; - - // FIXME: Maybe check the CPUID? - not for now. - // pDCTstat->LogicalCPUID; - - msr = BU_CFG2_MSR; - _RDMSR(msr, &lo, &hi); - if (!pDCTstat->ClToNB_flag) - lo &= ~(1 << ClLinesToNbDis); - _WRMSR(msr, lo, hi); - -} - - -void mct_SetWbEnhWsbDis_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u32 lo, hi; - u32 msr; - - // FIXME: Maybe check the CPUID? - not for now. - // pDCTstat->LogicalCPUID; - - msr = BU_CFG_MSR; - _RDMSR(msr, &lo, &hi); - hi |= (1 << WbEnhWsbDis_D); - _WRMSR(msr, lo, hi); -} - - -void mct_ClrWbEnhWsbDis_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u32 lo, hi; - u32 msr; - - // FIXME: Maybe check the CPUID? - not for now. - // pDCTstat->LogicalCPUID; - - msr = BU_CFG_MSR; - _RDMSR(msr, &lo, &hi); - hi &= ~(1 << WbEnhWsbDis_D); - _WRMSR(msr, lo, hi); -} - - -void mct_SetDramConfigHi_D(struct DCTStatStruc *pDCTstat, u32 dct, - u32 DramConfigHi) -{ - /* Bug#15114: Comp. update interrupted by Freq. change can cause - * subsequent update to be invalid during any MemClk frequency change: - * Solution: From the bug report: - * 1. A software-initiated frequency change should be wrapped into the - * following sequence : - * a) Disable Compensation (F2[1, 0]9C_x08[30]) - * b) Reset the Begin Compensation bit (D3CMP->COMP_CONFIG[0]) in - * all the compensation engines - * c) Do frequency change - * d) Enable Compensation (F2[1, 0]9C_x08[30]) - * 2. A software-initiated Disable Compensation should always be - * followed by step b) of the above steps. - * Silicon Status: Fixed In Rev B0 - * - * Errata#177: DRAM Phy Automatic Compensation Updates May Be Invalid - * Solution: BIOS should disable the phy automatic compensation prior - * to initiating a memory clock frequency change as follows: - * 1. Disable PhyAutoComp by writing 1'b1 to F2x[1, 0]9C_x08[30] - * 2. Reset the Begin Compensation bits by writing 32'h0 to - * F2x[1, 0]9C_x4D004F00 - * 3. Perform frequency change - * 4. Enable PhyAutoComp by writing 1'b0 to F2x[1, 0]9C_08[30] - * In addition, any time software disables the automatic phy - * compensation it should reset the begin compensation bit per step 2. - * Silicon Status: Fixed in DR-B0 - */ - - u32 dev = pDCTstat->dev_dct; - u32 index_reg = 0x98 + 0x100 * dct; - u32 index; - - u32 val; - - index = 0x08; - val = Get_NB32_index_wait(dev, index_reg, index); - Set_NB32_index_wait(dev, index_reg, index, val | (1 << DisAutoComp)); - - //FIXME: check for Bx Cx CPU - // if Ax mct_SetDramConfigHi_Samp_D - - /* errata#177 */ - index = 0x4D014F00; /* F2x[1, 0]9C_x[D0FFFFF:D000000] DRAM Phy Debug Registers */ - index |= 1 << DctAccessWrite; - val = 0; - Set_NB32_index_wait(dev, index_reg, index, val); - - Set_NB32(dev, 0x94 + 0x100 * dct, DramConfigHi); - - index = 0x08; - val = Get_NB32_index_wait(dev, index_reg, index); - Set_NB32_index_wait(dev, index_reg, index, val & (~(1 << DisAutoComp))); -} - -static void mct_BeforeDQSTrain_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - u8 Node; - struct DCTStatStruc *pDCTstat; - - /* Errata 178 - * - * Bug#15115: Uncertainty In The Sync Chain Leads To Setup Violations - * In TX FIFO - * Solution: BIOS should program DRAM Control Register[RdPtrInit] = - * 5h, (F2x[1, 0]78[3:0] = 5h). - * Silicon Status: Fixed In Rev B0 - * - * Bug#15880: Determine validity of reset settings for DDR PHY timing. - * Solution: At least, set WrDqs fine delay to be 0 for DDR2 training. - */ - - for (Node = 0; Node < 8; Node++) { - pDCTstat = pDCTstatA + Node; - - if (pDCTstat->NodePresent) { - mct_BeforeDQSTrain_Samp_D(pMCTstat, pDCTstat); - mct_ResetDLL_D(pMCTstat, pDCTstat, 0); - mct_ResetDLL_D(pMCTstat, pDCTstat, 1); - } - } -} - -static void mct_ResetDLL_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u8 Receiver; - u32 dev = pDCTstat->dev_dct; - u32 reg_off = 0x100 * dct; - u32 addr; - u32 lo, hi; - u8 wrap32dis = 0; - u8 valid = 0; - - /* Skip reset DLL for B3 */ - if (pDCTstat->LogicalCPUID & AMD_DR_B3) { - return; - } - - addr = HWCR_MSR; - _RDMSR(addr, &lo, &hi); - if (lo & (1<<17)) { /* save the old value */ - wrap32dis = 1; - } - lo |= (1<<17); /* HWCR.wrap32dis */ - lo &= ~(1<<15); /* SSEDIS */ - /* Setting wrap32dis allows 64-bit memory references in 32bit mode */ - _WRMSR(addr, lo, hi); - - - pDCTstat->Channel = dct; - Receiver = mct_InitReceiver_D(pDCTstat, dct); - /* there are four receiver pairs, loosely associated with chipselects.*/ - for (; Receiver < 8; Receiver += 2) { - if (mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, dct, Receiver)) { - addr = mct_GetRcvrSysAddr_D(pMCTstat, pDCTstat, dct, Receiver, &valid); - if (valid) { - mct_Read1LTestPattern_D(pMCTstat, pDCTstat, addr); /* cache fills */ - - /* Write 0000_8000h to register F2x[1,0]9C_xD080F0C */ - Set_NB32_index_wait(dev, 0x98 + reg_off, 0x4D080F0C, 0x00008000); - mct_Wait(80); /* wait >= 300ns */ - - /* Write 0000_0000h to register F2x[1,0]9C_xD080F0C */ - Set_NB32_index_wait(dev, 0x98 + reg_off, 0x4D080F0C, 0x00000000); - mct_Wait(800); /* wait >= 2us */ - break; - } - } - } - if (!wrap32dis) { - addr = HWCR_MSR; - _RDMSR(addr, &lo, &hi); - lo &= ~(1<<17); /* restore HWCR.wrap32dis */ - _WRMSR(addr, lo, hi); - } -} - - -void mct_EnableDatIntlv_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u32 dev = pDCTstat->dev_dct; - u32 val; - - /* Enable F2x110[DctDatIntlv] */ - // Call back not required mctHookBeforeDatIntlv_D() - // FIXME Skip for Ax - if (!pDCTstat->GangedMode) { - val = Get_NB32(dev, 0x110); - val |= 1 << 5; // DctDatIntlv - Set_NB32(dev, 0x110, val); - - // FIXME Skip for Cx - dev = pDCTstat->dev_nbmisc; - val = Get_NB32(dev, 0x8C); // NB Configuration Hi - val |= 1 << (36-32); // DisDatMask - Set_NB32(dev, 0x8C, val); - } -} - -#ifdef UNUSED_CODE -static void mct_SetupSync_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - /* set F2x78[ChSetupSync] when F2x[1, 0]9C_x04[AddrCmdSetup, CsOdtSetup, - * CkeSetup] setups for one DCT are all 0s and at least one of the setups, - * F2x[1, 0]9C_x04[AddrCmdSetup, CsOdtSetup, CkeSetup], of the other - * controller is 1 - */ - u32 cha, chb; - u32 dev = pDCTstat->dev_dct; - u32 val; - - cha = pDCTstat->CH_ADDR_TMG[0] & 0x0202020; - chb = pDCTstat->CH_ADDR_TMG[1] & 0x0202020; - - if ((cha != chb) && ((cha == 0) || (chb == 0))) { - val = Get_NB32(dev, 0x78); - val |= ChSetupSync; - Set_NB32(dev, 0x78, val); - } -} -#endif - -static void AfterDramInit_D(struct DCTStatStruc *pDCTstat, u8 dct) { - - u32 val; - u32 reg_off = 0x100 * dct; - u32 dev = pDCTstat->dev_dct; - - if (pDCTstat->LogicalCPUID & (AMD_DR_B2 | AMD_DR_B3)) { - mct_Wait(10000); /* Wait 50 us*/ - val = Get_NB32(dev, 0x110); - if (val & (1 << DramEnabled)) { - /* If 50 us expires while DramEnable =0 then do the following */ - val = Get_NB32(dev, 0x90 + reg_off); - val &= ~(1 << Width128); /* Program Width128 = 0 */ - Set_NB32(dev, 0x90 + reg_off, val); - - val = Get_NB32_index_wait(dev, 0x98 + reg_off, 0x05); /* Perform dummy CSR read to F2x09C_x05 */ - - if (pDCTstat->GangedMode) { - val = Get_NB32(dev, 0x90 + reg_off); - val |= 1 << Width128; /* Program Width128 = 0 */ - Set_NB32(dev, 0x90 + reg_off, val); - } - } - } -} - - -/* ========================================================== - * 6-bit Bank Addressing Table - * RR = rows-13 binary - * B = Banks-2 binary - * CCC = Columns-9 binary - * ========================================================== - * DCT CCCBRR Rows Banks Columns 64-bit CS Size - * Encoding - * 0000 000000 13 2 9 128MB - * 0001 001000 13 2 10 256MB - * 0010 001001 14 2 10 512MB - * 0011 010000 13 2 11 512MB - * 0100 001100 13 3 10 512MB - * 0101 001101 14 3 10 1GB - * 0110 010001 14 2 11 1GB - * 0111 001110 15 3 10 2GB - * 1000 010101 14 3 11 2GB - * 1001 010110 15 3 11 4GB - * 1010 001111 16 3 10 4GB - * 1011 010111 16 3 11 8GB - */ diff --git a/src/northbridge/amd/amdmct/mct/mct_d.h b/src/northbridge/amd/amdmct/mct/mct_d.h deleted file mode 100644 index b985137987..0000000000 --- a/src/northbridge/amd/amdmct/mct/mct_d.h +++ /dev/null @@ -1,804 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2015-2017 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * Copyright (C) 2007-2008 Advanced Micro Devices, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -/* - * Description: Include file for all generic DDR 2 MCT files. - */ -#ifndef MCT_D_H -#define MCT_D_H - -#define DQS_TRAIN_DEBUG 0 - -#include <stdint.h> -#include <northbridge/amd/amdfam10/debug.h> -#include <northbridge/amd/amdfam10/raminit.h> - -#include "mct_d_gcc.h" - -extern const u8 Table_DQSRcvEn_Offset[]; -extern const u32 TestPattern0_D[]; -extern const u32 TestPattern1_D[]; -extern const u32 TestPattern2_D[]; - -/*=========================================================================== - CPU - K8/FAM10 -===========================================================================*/ -#define PT_L1 0 /* CPU Package Type */ -#define PT_M2 1 -#define PT_S1 2 -#define PT_GR 3 - -#define J_MIN 0 /* j loop constraint. 1 = CL 2.0 T*/ -#define J_MAX 5 /* j loop constraint. 5 = CL 7.0 T*/ -#define K_MIN 1 /* k loop constraint. 1 = 200 MHz*/ -#define K_MAX 5 /* k loop constraint. 5 = 533 MHz*/ -#define CL_DEF 2 /* Default value for failsafe operation. 2 = CL 4.0 T*/ -#define T_DEF 1 /* Default value for failsafe operation. 1 = 5ns (cycle time)*/ - -#define BSCRate 1 /* reg bit field = rate of dram scrubber for ecc*/ - /* memory initialization (ecc and check-bits).*/ - /* 1 = 40 ns/64 bytes.*/ -#define FirstPass 1 /* First pass through RcvEn training*/ -#define SecondPass 2 /* Second pass through Rcven training*/ - -#define RCVREN_MARGIN 6 /* number of DLL taps to delay beyond first passing position*/ -#define MAXASYNCLATCTL_2 2 /* Max Async Latency Control value*/ -#define MAXASYNCLATCTL_3 3 /* Max Async Latency Control value*/ - -#define DQS_FAIL 1 -#define DQS_PASS 0 -#define DQS_WRITEDIR 1 -#define DQS_READDIR 0 -#define MIN_DQS_WNDW 3 -#define secPassOffset 6 -#define Pass1MemClkDly 0x20 /* Add 1/2 Memlock delay */ -#define MAX_RD_LAT 0x3FF -#define MIN_FENCE 14 -#define MAX_FENCE 20 -#define MIN_DQS_WR_FENCE 14 -#define MAX_DQS_WR_FENCE 20 -#define FenceTrnFinDlySeed 19 -#define EarlyArbEn 19 - -#define PA_HOST(Node) ((((0x18+Node) << 3)+0) << 12) /* Node 0 Host Bus function PCI Address bits [15:0]*/ -#define PA_MAP(Node) ((((0x18+Node) << 3)+1) << 12) /* Node 0 MAP function PCI Address bits [15:0]*/ -#define PA_DCT(Node) ((((0x18+Node) << 3)+2) << 12) /* Node 0 DCT function PCI Address bits [15:0]*/ -//#define PA_EXT_DCT (((00 << 3)+4) << 8) /*Node 0 DCT extended configuration registers*/ -//#define PA_DCTADDL (((00 << 3)+2) << 8) /*Node x DCT function, Additional Registers PCI Address bits [15:0]*/ -//#define PA_EXT_DCTADDL (((00 << 3)+5) << 8) /*Node x DCT function, Additional Registers PCI Address bits [15:0]*/ - -#define PA_NBMISC(Node) ((((0x18+Node) << 3)+3) << 12) /*Node 0 Misc PCI Address bits [15:0]*/ -//#define PA_NBDEVOP (((00 << 3)+3) << 8) /*Node 0 Misc PCI Address bits [15:0]*/ - -#define DCC_EN 1 /* X:2:0x94[19]*/ -#define ILD_Lmt 3 /* X:2:0x94[18:16]*/ - -#define EncodedTSPD 0x00191709 /* encodes which SPD byte to get T from*/ - /* versus CL X, CL X-.5, and CL X-1*/ - -#define Bias_TrpT 3 /* bias to convert bus clocks to bit field value*/ -#define Bias_TrrdT 2 -#define Bias_TrcdT 3 -#define Bias_TrasT 3 -#define Bias_TrcT 11 -#define Bias_TrtpT 2 -#define Bias_TwrT 3 -#define Bias_TwtrT 0 -#define Bias_TfawT 7 - -#define Min_TrpT 3 /* min programmable value in busclocks*/ -#define Max_TrpT 6 /* max programmable value in busclocks*/ -#define Min_TrrdT 2 -#define Max_TrrdT 5 -#define Min_TrcdT 3 -#define Max_TrcdT 6 -#define Min_TrasT 5 -#define Max_TrasT 18 -#define Min_TrcT 11 -#define Max_TrcT 26 -#define Min_TrtpT 2 -#define Max_TrtpT 3 -#define Min_TwrT 3 -#define Max_TwrT 6 -#define Min_TwtrT 1 -#define Max_TwtrT 3 - -/*DDR2-1066 support*/ -#define Bias_TrcdT_1066 5 -#define Bias_TrasT_1066 15 -#define Bias_TrrdT_1066 4 -#define Bias_TwrT_1066 4 -#define Bias_TrpT_1066 5 -#define Bias_TwtrT_1066 4 -#define Bias_TfawT_1066 15 - -#define Min_TrcdT_1066 5 -#define Max_TrcdT_1066 12 -#define Min_TrasT_1066 15 -#define Max_TrasT_1066 30 -#define Min_TrcT_1066 11 -#define Max_TrcT_1066 42 -#define Min_TrrdT_1066 4 -#define Max_TrrdT_1066 7 -#define Min_TwrT_1066 5 -#define Max_TwrT_1066 8 -#define Min_TrpT_1066 5 -#define Max_TrpT_1066 12 -#define Min_TwtrT_1066 4 -#define Max_TwtrT_1066 7 - -/*common register bit names*/ -#define DramHoleValid 0 /* func 1, offset F0h, bit 0*/ -#define DramMemHoistValid 1 /* func 1, offset F0h, bit 1*/ -#define CSEnable 0 /* func 2, offset 40h-5C, bit 0*/ -#define Spare 1 /* func 2, offset 40h-5C, bit 1*/ -#define TestFail 2 /* func 2, offset 40h-5C, bit 2*/ -#define DqsRcvEnTrain 18 /* func 2, offset 78h, bit 18*/ -#define EnDramInit 31 /* func 2, offset 7Ch, bit 31*/ -#define DisAutoRefresh 18 /* func 2, offset 8Ch, bit 18*/ -#define InitDram 0 /* func 2, offset 90h, bit 0*/ -#define BurstLength32 10 /* func 2, offset 90h, bit 10*/ -#define Width128 11 /* func 2, offset 90h, bit 11*/ -#define X4Dimm 12 /* func 2, offset 90h, bit 12*/ -#define UnBuffDimm 16 /* func 2, offset 90h, bit 16*/ -#define DimmEcEn 19 /* func 2, offset 90h, bit 19*/ -#define MemClkFreqVal 3 /* func 2, offset 94h, bit 3*/ -#define RDqsEn 12 /* func 2, offset 94h, bit 12*/ -#define DisDramInterface 14 /* func 2, offset 94h, bit 14*/ -#define DctAccessWrite 30 /* func 2, offset 98h, bit 30*/ -#define DctAccessDone 31 /* func 2, offset 98h, bit 31*/ -#define MemClrStatus 0 /* func 2, offset A0h, bit 0*/ -#define PwrSavingsEn 10 /* func 2, offset A0h, bit 10*/ -#define Mod64BitMux 4 /* func 2, offset A0h, bit 4*/ -#define DisableJitter 1 /* func 2, offset A0h, bit 1*/ -#define MemClrDis 1 /* func 3, offset F8h, FNC 4, bit 1*/ -#define SyncOnUcEccEn 2 /* func 3, offset 44h, bit 2*/ -#define Dr_MemClrStatus 10 /* func 3, offset 110h, bit 10*/ -#define MemClrBusy 9 /* func 3, offset 110h, bit 9*/ -#define DctGangEn 4 /* func 3, offset 110h, bit 4*/ -#define MemClrInit 3 /* func 3, offset 110h, bit 3*/ -#define AssertCke 28 /* func 2, offset 7Ch, bit 28*/ -#define DeassertMemRstX 27 /* func 2, offset 7Ch, bit 27*/ -#define SendMrsCmd 26 /* func 2, offset 7Ch, bit 26*/ -#define SendAutoRefresh 25 /* func 2, offset 7Ch, bit 25*/ -#define SendPchgAll 24 /* func 2, offset 7Ch, bit 24*/ -#define DisDqsBar 6 /* func 2, offset 90h, bit 6*/ -#define DramEnabled 8 /* func 2, offset 110h, bit 8*/ -#define LegacyBiosMode 9 /* func 2, offset 94h, bit 9*/ -#define PrefDramTrainMode 28 /* func 2, offset 11Ch, bit 28*/ -#define FlushWr 30 /* func 2, offset 11Ch, bit 30*/ -#define DisAutoComp 30 /* func 2, offset 9Ch, Index 8, bit 30*/ -#define DqsRcvTrEn 13 /* func 2, offset 9Ch, Index 8, bit 13*/ -#define ForceAutoPchg 23 /* func 2, offset 90h, bit 23*/ -#define ClLinesToNbDis 15 /* Bu_CFG2, bit 15*/ -#define WbEnhWsbDis_D (48-32) -#define PhyFenceTrEn 3 /* func 2, offset 9Ch, Index 8, bit 3 */ -#define ParEn 8 /* func 2, offset 90h, bit 8 */ -#define DcqArbBypassEn 19 /* func 2, offset 94h, bit 19 */ -#define ActiveCmdAtRst 1 /* func 2, offset A8H, bit 1 */ -#define FlushWrOnStpGnt 29 /* func 2, offset 11Ch, bit 29 */ -#define BankSwizzleMode 22 /* func 2, offset 94h, bit 22 */ -#define ChSetupSync 15 /* func 2, offset 78h, bit 15 */ - - - -/*============================================================================= - SW Initialization -============================================================================*/ -#define DLL_Enable 1 -#define OCD_Default 2 -#define OCD_Exit 3 - - - -/*============================================================================= - Jedec DDR II -=============================================================================*/ -#define SPD_TYPE 2 /*SPD byte read location*/ - #define JED_DDRSDRAM 0x07 /*Jedec defined bit field*/ - #define JED_DDR2SDRAM 0x08 /*Jedec defined bit field*/ - -#define SPD_DIMMTYPE 20 -#define SPD_ATTRIB 21 - #define JED_DIFCKMSK 0x20 /*Differential Clock Input*/ - #define JED_REGADCMSK 0x11 /*Registered Address/Control*/ - #define JED_PROBEMSK 0x40 /*Analysis Probe installed*/ -#define SPD_DEVATTRIB 22 -#define SPD_EDCTYPE 11 - #define JED_ECC 0x02 - #define JED_ADRCPAR 0x04 -#define SPD_ROWSZ 3 -#define SPD_COLSZ 4 -#define SPD_LBANKS 17 /*number of [logical] banks on each device*/ -#define SPD_DMBANKS 5 /*number of physical banks on dimm*/ - #define SPDPLBit 4 /* Dram package bit*/ -#define SPD_BANKSZ 31 /*capacity of physical bank*/ -#define SPD_DEVWIDTH 13 -#define SPD_CASLAT 18 -#define SPD_TRP 27 -#define SPD_TRRD 28 -#define SPD_TRCD 29 -#define SPD_TRAS 30 -#define SPD_TWR 36 -#define SPD_TWTR 37 -#define SPD_TRTP 38 -#define SPD_TRCRFC 40 -#define SPD_TRC 41 -#define SPD_TRFC 42 - -#define SPD_MANID_START 64 -#define SPD_PARTN_START 73 -#define SPD_PARTN_LENGTH 18 -#define SPD_REVNO_START 91 - -#define SPD_MANDATEYR 93 /*Module Manufacturing Year (BCD)*/ - -#define SPD_MANDATEWK 94 /*Module Manufacturing Week (BCD)*/ - -#define SPD_SERIAL_START 95 - -/*----------------------------- - Jedec DDR II related equates ------------------------------*/ -#define MYEAR06 6 /* Manufacturing Year BCD encoding of 2006 - 06d*/ -#define MWEEK24 0x24 /* Manufacturing Week BCD encoding of June - 24d*/ - -/*============================================================================= - Macros -=============================================================================*/ - -#define _2GB_RJ8 (2<<(30-8)) -#define _4GB_RJ8 (4<<(30-8)) -#define _4GB_RJ4 (4<<(30-4)) - -#define BigPagex8_RJ8 (1<<(17+3-8)) /*128KB * 8 >> 8 */ - -/*============================================================================= - Global MCT Status Structure -=============================================================================*/ -struct MCTStatStruc { - u32 GStatus; /* Global Status bitfield*/ - u32 HoleBase; /* If not zero, BASE[39:8] (system address) - of sub 4GB dram hole for HW remapping.*/ - u32 Sub4GCacheTop; /* If not zero, the 32-bit top of cacheable memory.*/ - u32 SysLimit; /* LIMIT[39:8] (system address)*/ -} __packed; - -/*============================================================================= - Global MCT Configuration Status Word (GStatus) -=============================================================================*/ -/*These should begin at bit 0 of GStatus[31:0]*/ -#define GSB_MTRRshort 0 /* Ran out of MTRRs while mapping memory*/ -#define GSB_ECCDIMMs 1 /* All banks of all Nodes are ECC capable*/ -#define GSB_DramECCDis 2 /* Dram ECC requested but not enabled.*/ -#define GSB_SoftHole 3 /* A Node Base gap was created*/ -#define GSB_HWHole 4 /* A HW dram remap was created*/ -#define GSB_NodeIntlv 5 /* Node Memory interleaving was enabled*/ -#define GSB_SpIntRemapHole 16 /* Special condition for Node Interleave and HW remapping*/ -#define GSB_EnDIMMSpareNW 17 /* Indicates that DIMM Spare can be used without a warm reset */ - /* NOTE: This is a local bit used by memory code */ - - -/*=============================================================================== - Local DCT Status structure (a structure for each DCT) -===============================================================================*/ - -struct DCTPersistentStatStruc { - u8 CH_D_DIR_B_DQS[2][4][2][9]; /* [A/B] [DIMM1-4] [R/W] [DQS] */ - /* CHA DIMM0 Byte 0 - 7 and Check Write DQS Delay*/ - /* CHA DIMM0 Byte 0 - 7 and Check Read DQS Delay*/ - /* CHA DIMM1 Byte 0 - 7 and Check Write DQS Delay*/ - /* CHA DIMM1 Byte 0 - 7 and Check Read DQS Delay*/ - /* CHB DIMM0 Byte 0 - 7 and Check Write DQS Delay*/ - /* CHB DIMM0 Byte 0 - 7 and Check Read DQS Delay*/ - /* CHB DIMM1 Byte 0 - 7 and Check Write DQS Delay*/ - /* CHB DIMM1 Byte 0 - 7 and Check Read DQS Delay*/ - u8 CH_D_B_RCVRDLY[2][4][8]; /* [A/B] [DIMM0-3] [DQS] */ - /* CHA DIMM 0 Receiver Enable Delay*/ - /* CHA DIMM 1 Receiver Enable Delay*/ - /* CHA DIMM 2 Receiver Enable Delay*/ - /* CHA DIMM 3 Receiver Enable Delay*/ - - /* CHB DIMM 0 Receiver Enable Delay*/ - /* CHB DIMM 1 Receiver Enable Delay*/ - /* CHB DIMM 2 Receiver Enable Delay*/ - /* CHB DIMM 3 Receiver Enable Delay*/ - u8 CH_D_BC_RCVRDLY[2][4]; - /* CHA DIMM 0 - 4 Check Byte Receiver Enable Delay*/ - /* CHB DIMM 0 - 4 Check Byte Receiver Enable Delay*/ - u16 HostBiosSrvc1; /* Word sized general purpose field for use by host BIOS. Scratch space.*/ - u32 HostBiosSrvc2; /* Dword sized general purpose field for use by host BIOS. Scratch space.*/ -} __packed; - - -struct DCTStatStruc { /* A per Node structure*/ -/* DCTStatStruct_F - start */ - u8 Node_ID; /* Node ID of current controller*/ - uint8_t Internal_Node_ID; /* Internal Node ID of the current controller */ - uint8_t Dual_Node_Package; /* 1 = Dual node package (G34) */ - uint8_t stopDCT; /* Set if the DCT will be stopped */ - u8 ErrCode; /* Current error condition of Node - 0= no error - 1= Variance Error, DCT is running but not in an optimal configuration. - 2= Stop Error, DCT is NOT running - 3= Fatal Error, DCT/MCT initialization has been halted.*/ - u32 ErrStatus; /* Error Status bit Field */ - u32 Status; /* Status bit Field*/ - u8 DIMMAddr[8]; /* SPD address of DIMM controlled by MA0_CS_L[0,1]*/ - /* SPD address of..MB0_CS_L[0,1]*/ - /* SPD address of..MA1_CS_L[0,1]*/ - /* SPD address of..MB1_CS_L[0,1]*/ - /* SPD address of..MA2_CS_L[0,1]*/ - /* SPD address of..MB2_CS_L[0,1]*/ - /* SPD address of..MA3_CS_L[0,1]*/ - /* SPD address of..MB3_CS_L[0,1]*/ - u16 DIMMPresent; /*For each bit n 0..7, 1 = DIMM n is present. - DIMM# Select Signal - 0 MA0_CS_L[0,1] - 1 MB0_CS_L[0,1] - 2 MA1_CS_L[0,1] - 3 MB1_CS_L[0,1] - 4 MA2_CS_L[0,1] - 5 MB2_CS_L[0,1] - 6 MA3_CS_L[0,1] - 7 MB3_CS_L[0,1]*/ - u16 DIMMValid; /* For each bit n 0..7, 1 = DIMM n is valid and is/will be configured*/ - u16 DIMMMismatch; /* For each bit n 0..7, 1 = DIMM n is mismatched, channel B is always considered the mismatch */ - u16 DIMMSPDCSE; /* For each bit n 0..7, 1 = DIMM n SPD checksum error*/ - u16 DimmECCPresent; /* For each bit n 0..7, 1 = DIMM n is ECC capable.*/ - u16 DimmPARPresent; /* For each bit n 0..7, 1 = DIMM n is ADR/CMD Parity capable.*/ - u16 Dimmx4Present; /* For each bit n 0..7, 1 = DIMM n contains x4 data devices.*/ - u16 Dimmx8Present; /* For each bit n 0..7, 1 = DIMM n contains x8 data devices.*/ - u16 Dimmx16Present; /* For each bit n 0..7, 1 = DIMM n contains x16 data devices.*/ - u16 DIMM2Kpage; /* For each bit n 0..7, 1 = DIMM n contains 1K page devices.*/ - u8 MAload[2]; /* Number of devices loading MAA bus*/ - /* Number of devices loading MAB bus*/ - u8 MAdimms[2]; /*Number of DIMMs loading CH A*/ - /* Number of DIMMs loading CH B*/ - u8 DATAload[2]; /*Number of ranks loading CH A DATA*/ - /* Number of ranks loading CH B DATA*/ - u8 DIMMAutoSpeed; /*Max valid Mfg. Speed of DIMMs - 1 = 200MHz - 2 = 266MHz - 3 = 333MHz - 4 = 400MHz - 5 = 533MHz*/ - u8 DIMMCASL; /* Min valid Mfg. CL bitfield - 0 = 2.0 - 1 = 3.0 - 2 = 4.0 - 3 = 5.0 - 4 = 6.0 */ - u16 DIMMTrcd; /* Minimax Trcd*40 (ns) of DIMMs*/ - u16 DIMMTrp; /* Minimax Trp*40 (ns) of DIMMs*/ - u16 DIMMTrtp; /* Minimax Trtp*40 (ns) of DIMMs*/ - u16 DIMMTras; /* Minimax Tras*40 (ns) of DIMMs*/ - u16 DIMMTrc; /* Minimax Trc*40 (ns) of DIMMs*/ - u16 DIMMTwr; /* Minimax Twr*40 (ns) of DIMMs*/ - u16 DIMMTrrd; /* Minimax Trrd*40 (ns) of DIMMs*/ - u16 DIMMTwtr; /* Minimax Twtr*40 (ns) of DIMMs*/ - u8 Speed; /* Bus Speed (to set Controller) - 1 = 200MHz - 2 = 266MHz - 3 = 333MHz - 4 = 400MHz */ - u8 CASL; /* CAS latency DCT setting - 0 = 2.0 - 1 = 3.0 - 2 = 4.0 - 3 = 5.0 - 4 = 6.0 */ - u8 Trcd; /* DCT Trcd (busclocks) */ - u8 Trp; /* DCT Trp (busclocks) */ - u8 Trtp; /* DCT Trtp (busclocks) */ - u8 Tras; /* DCT Tras (busclocks) */ - u8 Trc; /* DCT Trc (busclocks) */ - u8 Twr; /* DCT Twr (busclocks) */ - u8 Trrd; /* DCT Trrd (busclocks) */ - u8 Twtr; /* DCT Twtr (busclocks) */ - u8 Trfc[4]; /* DCT Logical DIMM0 Trfc - 0 = 75ns (for 256Mb devs) - 1 = 105ns (for 512Mb devs) - 2 = 127.5ns (for 1Gb devs) - 3 = 195ns (for 2Gb devs) - 4 = 327.5ns (for 4Gb devs) */ - /* DCT Logical DIMM1 Trfc (see Trfc0 for format) */ - /* DCT Logical DIMM2 Trfc (see Trfc0 for format) */ - /* DCT Logical DIMM3 Trfc (see Trfc0 for format) */ - u16 CSPresent; /* For each bit n 0..7, 1 = Chip-select n is present */ - u16 CSTestFail; /* For each bit n 0..7, 1 = Chip-select n is present but disabled */ - u32 DCTSysBase; /* BASE[39:8] (system address) of this Node's DCTs. */ - u32 DCTHoleBase; /* If not zero, BASE[39:8] (system address) of dram hole for HW remapping. Dram hole exists on this Node's DCTs. */ - u32 DCTSysLimit; /* LIMIT[39:8] (system address) of this Node's DCTs */ - u16 PresetmaxFreq; /* Maximum OEM defined DDR frequency - 200 = 200MHz (DDR400) - 266 = 266MHz (DDR533) - 333 = 333MHz (DDR667) - 400 = 400MHz (DDR800) */ - u8 _2Tmode; /* 1T or 2T CMD mode (slow access mode) - 1 = 1T - 2 = 2T */ - u8 TrwtTO; /* DCT TrwtTO (busclocks)*/ - u8 Twrrd; /* DCT Twrrd (busclocks)*/ - u8 Twrwr; /* DCT Twrwr (busclocks)*/ - u8 Trdrd; /* DCT Trdrd (busclocks)*/ - u32 CH_ODC_CTL[2]; /* Output Driver Strength (see BKDG FN2:Offset 9Ch, index 00h*/ - u32 CH_ADDR_TMG[2]; /* Address Bus Timing (see BKDG FN2:Offset 9Ch, index 04h*/ - /* Output Driver Strength (see BKDG FN2:Offset 9Ch, index 20h*/ - /* Address Bus Timing (see BKDG FN2:Offset 9Ch, index 24h*/ - u16 CH_EccDQSLike[2]; /* CHA DQS ECC byte like...*/ - u8 CH_EccDQSScale[2]; /* CHA DQS ECC byte scale*/ - /* CHA DQS ECC byte like...*/ - /* CHA DQS ECC byte scale*/ - u8 MaxAsyncLat; /* Max Asynchronous Latency (ns)*/ - // NOTE: Not used in Barcelona - u8 CH_D_RCVRDLY[2][4]; - /* CHA DIMM 0 - 4 Receiver Enable Delay*/ - /* CHB DIMM 0 - 4 Receiver Enable Delay */ - // NOTE: Not used in Barcelona - u8 CH_D_B_DQS[2][2][8]; - /* CHA Byte 0-7 Write DQS Delay */ - /* CHA Byte 0-7 Read DQS Delay */ - /* CHB Byte 0-7 Write DQS Delay */ - /* CHB Byte 0-7 Read DQS Delay */ - u32 PtrPatternBufA; /* Ptr on stack to aligned DQS testing pattern*/ - u32 PtrPatternBufB; /* Ptr on stack to aligned DQS testing pattern*/ - u8 Channel; /* Current Channel (0= CH A, 1 = CH B)*/ - u8 ByteLane; /* Current Byte Lane (0..7)*/ - u8 Direction; /* Current DQS-DQ training write direction (0 = read, 1 = write)*/ - u8 Pattern; /* Current pattern*/ - u8 DQSDelay; /* Current DQS delay value*/ - u32 TrainErrors; /* Current Training Errors*/ - - u32 AMC_TSC_DeltaLo; /* Time Stamp Counter measurement of AMC, Low dword*/ - u32 AMC_TSC_DeltaHi; /* Time Stamp Counter measurement of AMC, High dword*/ - // NOTE: Not used in Barcelona - u8 CH_D_DIR_MaxMin_B_Dly[2][4][2][2][8]; - /* CH A byte lane 0 - 7 minimum filtered window passing DQS delay value*/ - /* CH A byte lane 0 - 7 maximum filtered window passing DQS delay value*/ - /* CH B byte lane 0 - 7 minimum filtered window passing DQS delay value*/ - /* CH B byte lane 0 - 7 maximum filtered window passing DQS delay value*/ - /* CH A byte lane 0 - 7 minimum filtered window passing DQS delay value*/ - /* CH A byte lane 0 - 7 maximum filtered window passing DQS delay value*/ - /* CH B byte lane 0 - 7 minimum filtered window passing DQS delay value*/ - /* CH B byte lane 0 - 7 maximum filtered window passing DQS delay value*/ - uint64_t LogicalCPUID; /* The logical CPUID of the node*/ - u16 DimmQRPresent; /* QuadRank DIMM present?*/ - u16 DimmTrainFail; /* Bitmap showing which dimms failed training*/ - u16 CSTrainFail; /* Bitmap showing which chipselects failed training*/ - u16 DimmYr06; /* Bitmap indicating which Dimms have a manufactur's year code <= 2006*/ - u16 DimmWk2406; /* Bitmap indicating which Dimms have a manufactur's week code <= 24 of 2006 (June)*/ - u16 DimmDRPresent; /* Bitmap indicating that Dual Rank Dimms are present*/ - u16 DimmPlPresent; /* Bitmap indicating that Planar (1) or Stacked (0) Dimms are present.*/ - u16 ChannelTrainFai; /* Bitmap showing the channel information about failed Chip Selects - 0 in any bit field indicates Channel 0 - 1 in any bit field indicates Channel 1 */ - u16 CSUsrTestFail; /* Chip selects excluded by user */ -/* DCTStatStruct_F - end */ - - u16 CH_MaxRdLat[2]; /* Max Read Latency (ns) for DCT 0*/ - /* Max Read Latency (ns) for DCT 1*/ - u8 DIMMValidDCT[2]; /* DIMM# in DCT0*/ - /* DIMM# in DCT1*/ - u8 MaxDCTs; /* Max number of DCTs in system*/ - // NOTE: removed u8 DCT. Use ->dev_ for pci R/W; /*DCT pointer*/ - u8 GangedMode; /* Ganged mode enabled, 0 = disabled, 1 = enabled*/ - u8 DRPresent; /* Family 10 present flag, 0 = not Fam10, 1 = Fam10*/ - u32 NodeSysLimit; /* BASE[39:8],for DCT0+DCT1 system address*/ - u8 WrDatGrossH; - u8 DqsRcvEnGrossL; - // NOTE: Not used - u8 NodeSpeed /* Bus Speed (to set Controller) - /* 1 = 200MHz */ - /* 2 = 266MHz */ - /* 3 = 333MHz */ - // NOTE: Not used - u8 NodeCASL /* CAS latency DCT setting - /* 0 = 2.0 */ - /* 1 = 3.0 */ - /* 2 = 4.0 */ - /* 3 = 5.0 */ - /* 4 = 6.0 */ - u8 TrwtWB; - u8 CurrRcvrCHADelay; /* for keep current RcvrEnDly of chA*/ - u16 T1000; /* get the T1000 figure (cycle time (ns)*1K)*/ - u8 DqsRcvEn_Pass; /* for TrainRcvrEn byte lane pass flag*/ - u8 DqsRcvEn_Saved; /* for TrainRcvrEn byte lane saved flag*/ - u8 SeedPass1Remainder; /* for Phy assisted DQS receiver enable training*/ - - /* for second pass - Second pass should never run for Fam10*/ - // NOTE: Not used for Barcelona - u8 CH_D_B_RCVRDLY_1[2][4][8]; /* CHA DIMM 0 Receiver Enable Delay*/ - /* CHA DIMM 1 Receiver Enable Delay*/ - /* CHA DIMM 2 Receiver Enable Delay*/ - /* CHA DIMM 3 Receiver Enable Delay*/ - - /* CHB DIMM 0 Receiver Enable Delay*/ - /* CHB DIMM 1 Receiver Enable Delay*/ - /* CHB DIMM 2 Receiver Enable Delay*/ - /* CHB DIMM 3 Receiver Enable Delay*/ - - u8 ClToNB_flag; /* is used to restore ClLinesToNbDis bit after memory */ - u32 NodeSysBase; /* for channel interleave usage */ - -/* New for LB Support */ - u8 NodePresent; - u32 dev_host; - u32 dev_map; - u32 dev_dct; - u32 dev_nbmisc; - - uint8_t DimmRows[MAX_DIMMS_SUPPORTED]; - uint8_t DimmCols[MAX_DIMMS_SUPPORTED]; - uint8_t DimmRanks[MAX_DIMMS_SUPPORTED]; - uint8_t DimmBanks[MAX_DIMMS_SUPPORTED]; - uint8_t DimmWidth[MAX_DIMMS_SUPPORTED]; - uint8_t DimmRegistered[MAX_DIMMS_SUPPORTED]; - - uint64_t DimmManufacturerID[MAX_DIMMS_SUPPORTED]; - char DimmPartNumber[MAX_DIMMS_SUPPORTED][SPD_PARTN_LENGTH+1]; - uint16_t DimmRevisionNumber[MAX_DIMMS_SUPPORTED]; - uint32_t DimmSerialNumber[MAX_DIMMS_SUPPORTED]; - - /* NOTE: This must remain the last entry in this structure */ - struct DCTPersistentStatStruc persistentData; -} __packed; - -/*=============================================================================== - Local Error Status Codes (DCTStatStruc.ErrCode) -===============================================================================*/ -#define SC_RunningOK 0 -#define SC_VarianceErr 1 /* Running non-optimally*/ -#define SC_StopError 2 /* Not Running*/ -#define SC_FatalErr 3 /* Fatal Error, MCTB has exited immediately*/ - -/*=============================================================================== - Local Error Status (DCTStatStruc.ErrStatus[31:0]) -===============================================================================*/ -#define SB_NoDimms 0 -#define SB_DIMMChkSum 1 -#define SB_DimmMismatchM 2 /* dimm module type(buffer) mismatch*/ -#define SB_DimmMismatchT 3 /* dimm CL/T mismatch*/ -#define SB_DimmMismatchO 4 /* dimm organization mismatch (128-bit)*/ -#define SB_NoTrcTrfc 5 /* SPD missing Trc or Trfc info*/ -#define SB_NoCycTime 6 /* SPD missing byte 23 or 25*/ -#define SB_BkIntDis 7 /* Bank interleave requested but not enabled*/ -#define SB_DramECCDis 8 /* Dram ECC requested but not enabled*/ -#define SB_SpareDis 9 /* Online spare requested but not enabled*/ -#define SB_MinimumMode 10 /* Running in Minimum Mode*/ -#define SB_NORCVREN 11 /* No DQS Receiver Enable pass window found*/ -#define SB_CHA2BRCVREN 12 /* DQS Rcvr En pass window CHA to CH B too large*/ -#define SB_SmallRCVR 13 /* DQS Rcvr En pass window too small (far right of dynamic range)*/ -#define SB_NODQSPOS 14 /* No DQS-DQ passing positions*/ -#define SB_SMALLDQS 15 /* DQS-DQ passing window too small*/ -#define SB_DCBKScrubDis 16 /* DCache scrub requested but not enabled */ - -/*=============================================================================== - Local Configuration Status (DCTStatStruc.Status[31:0]) -===============================================================================*/ -#define SB_Registered 0 /* All DIMMs are Registered*/ -#define SB_ECCDIMMs 1 /* All banks ECC capable*/ -#define SB_PARDIMMs 2 /* All banks Addr/CMD Parity capable*/ -#define SB_DiagClks 3 /* Jedec ALL slots clock enable diag mode*/ -#define SB_128bitmode 4 /* DCT in 128-bit mode operation*/ -#define SB_64MuxedMode 5 /* DCT in 64-bit mux'ed mode.*/ -#define SB_2TMode 6 /* 2T CMD timing mode is enabled.*/ -#define SB_SWNodeHole 7 /* Remapping of Node Base on this Node to create a gap.*/ -#define SB_HWHole 8 /* Memory Hole created on this Node using HW remapping.*/ -#define SB_Over400MHz 9 /* DCT freq >= 400MHz flag*/ -#define SB_DQSPos_Pass2 10 /* Using for TrainDQSPos DIMM0/1, when freq >= 400MHz*/ -#define SB_DQSRcvLimit 11 /* Using for DQSRcvEnTrain to know we have reached to upper bound.*/ -#define SB_ExtConfig 12 /* Indicator the default setting for extend PCI configuration support*/ - - - - -/*=============================================================================== - NVRAM/run-time-configurable Items -===============================================================================*/ -/*Platform Configuration*/ -#define NV_PACK_TYPE 0 /* CPU Package Type (2-bits) - 0 = NPT L1 - 1 = NPT M2 - 2 = NPT S1*/ -#define NV_MAX_NODES 1 /* Number of Nodes/Sockets (4-bits)*/ -#define NV_MAX_DIMMS 2 /* Number of DIMM slots for the specified Node ID (4-bits)*/ -#define NV_MAX_MEMCLK 3 /* Maximum platform demonstrated Memclock (10-bits) - 200 = 200MHz (DDR400) - 266 = 266MHz (DDR533) - 333 = 333MHz (DDR667) - 400 = 400MHz (DDR800)*/ -#define NV_MIN_MEMCLK 4 /* Minimum platform demonstrated Memclock (10-bits) */ -#define NV_ECC_CAP 5 /* Bus ECC capable (1-bits) - 0 = Platform not capable - 1 = Platform is capable*/ -#define NV_4RANKType 6 /* Quad Rank DIMM slot type (2-bits) - 0 = Normal - 1 = R4 (4-Rank Registered DIMMs in AMD server configuration) - 2 = S4 (Unbuffered SO-DIMMs)*/ -#define NV_BYPMAX 7 /* Value to set DcqBypassMax field (See Function 2, Offset 94h, [27:24] of BKDG for field definition). - 4 = 4 times bypass (normal for non-UMA systems) - 7 = 7 times bypass (normal for UMA systems)*/ -#define NV_RDWRQBYP 8 /* Value to set RdWrQByp field (See Function 2, Offset A0h, [3:2] of BKDG for field definition). - 2 = 8 times (normal for non-UMA systems) - 3 = 16 times (normal for UMA systems)*/ - - -/*Dram Timing*/ -#define NV_MCTUSRTMGMODE 10 /* User Memclock Mode (2-bits) - 0 = Auto, no user limit - 1 = Auto, user limit provided in NV_MemCkVal - 2 = Manual, user value provided in NV_MemCkVal*/ -#define NV_MemCkVal 11 /* Memory Clock Value (2-bits) - 0 = 200MHz - 1 = 266MHz - 2 = 333MHz - 3 = 400MHz*/ - -/*Dram Configuration*/ -#define NV_BankIntlv 20 /* Dram Bank (chip-select) Interleaving (1-bits) - 0 = disable - 1 = enable*/ -#define NV_AllMemClks 21 /* Turn on All DIMM clocks (1-bits) - 0 = normal - 1 = enable all memclocks*/ -#define NV_SPDCHK_RESTRT 22 /* SPD Check control bitmap (1-bits) - 0 = Exit current node init if any DIMM has SPD checksum error - 1 = Ignore faulty SPD checksums (Note: DIMM cannot be enabled)*/ -#define NV_DQSTrainCTL 23 /* DQS Signal Timing Training Control - 0 = skip DQS training - 1 = perform DQS training*/ -#define NV_NodeIntlv 24 /* Node Memory Interleaving (1-bits) - 0 = disable - 1 = enable*/ -#define NV_BurstLen32 25 /* BurstLength32 for 64-bit mode (1-bits) - 0 = disable (normal) - 1 = enable (4 beat burst when width is 64-bits)*/ - -/*Dram Power*/ -#define NV_CKE_PDEN 30 /* CKE based power down mode (1-bits) - 0 = disable - 1 = enable*/ -#define NV_CKE_CTL 31 /* CKE based power down control (1-bits) - 0 = per Channel control - 1 = per Chip select control*/ -#define NV_CLKHZAltVidC3 32 /* Memclock tri-stating during C3 and Alt VID (1-bits) - 0 = disable - 1 = enable*/ - -/*Memory Map/Mgt.*/ -#define NV_BottomIO 40 /* Bottom of 32-bit IO space (8-bits) - NV_BottomIO[7:0]=Addr[31:24]*/ -#define NV_BottomUMA 41 /* Bottom of shared graphics dram (8-bits) - NV_BottomUMA[7:0]=Addr[31:24]*/ -#define NV_MemHole 42 /* Memory Hole Remapping (1-bits) - 0 = disable - 1 = enable */ - -/*ECC*/ -#define NV_ECC 50 /* Dram ECC enable*/ -#define NV_NBECC 52 /* ECC MCE enable*/ -#define NV_ChipKill 53 /* Chip-Kill ECC Mode enable*/ -#define NV_ECCRedir 54 /* Dram ECC Redirection enable*/ -#define NV_DramBKScrub 55 /* Dram ECC Background Scrubber CTL*/ -#define NV_L2BKScrub 56 /* L2 ECC Background Scrubber CTL*/ -#define NV_L3BKScrub 57 /* L3 ECC Background Scrubber CTL*/ -#define NV_DCBKScrub 58 /* DCache ECC Background Scrubber CTL*/ -#define NV_CS_SpareCTL 59 /* Chip Select Spare Control bit 0: - 0 = disable Spare - 1 = enable Spare */ - /* Chip Select Spare Control bit 1-4: - Reserved, must be zero*/ -#define NV_SyncOnUnEccEn 61 /* SyncOnUnEccEn control - 0 = disable - 1 = enable*/ -#define NV_Unganged 62 - -#define NV_ChannelIntlv 63 /* Channel Interleaving (3-bits) - xx0b = disable - yy1b = enable with DctSelIntLvAddr set to yyb */ - -#define NV_MAX_DIMMS_PER_CH 64 /* Maximum number of DIMMs per channel */ - -#include <northbridge/amd/amdfam10/amdfam10.h> - -/*=============================================================================== - CBMEM storage -===============================================================================*/ -struct amdmct_memory_info { - struct MCTStatStruc mct_stat; - struct DCTStatStruc dct_stat[MAX_NODES_SUPPORTED]; - uint16_t ecc_enabled; - uint16_t ecc_scrub_rate; -} __packed; - -u32 Get_NB32(u32 dev, u32 reg); -void Set_NB32(u32 dev, u32 reg, u32 val); -u32 Get_NB32_index(u32 dev, u32 index_reg, u32 index); -void Set_NB32_index(u32 dev, u32 index_reg, u32 index, u32 data); -u32 Get_NB32_index_wait(u32 dev, u32 index_reg, u32 index); -void Set_NB32_index_wait(u32 dev, u32 index_reg, u32 index, u32 data); -u32 OtherTiming_A_D(struct DCTStatStruc *pDCTstat, u32 val); -void mct_ForceAutoPrecharge_D(struct DCTStatStruc *pDCTstat, u32 dct); -u32 Modify_D3CMP(struct DCTStatStruc *pDCTstat, u32 dct, u32 value); -u8 mct_checkNumberOfDqsRcvEn_1Pass(u8 pass); -u32 SetupDqsPattern_1PassA(u8 Pass); -u32 SetupDqsPattern_1PassB(u8 Pass); -u8 mct_Get_Start_RcvrEnDly_1Pass(u8 Pass); -u8 mct_Average_RcvrEnDly_Pass(struct DCTStatStruc *pDCTstat, u8 RcvrEnDly, u8 RcvrEnDlyLimit, u8 Channel, u8 Receiver, u8 Pass); -void CPUMemTyping_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); -void UMAMemTyping_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); -uint64_t mctGetLogicalCPUID(u32 Node); -u8 ECCInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); -void TrainReceiverEn_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA, u8 Pass); -void mct_TrainDQSPos_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); -void mctSetEccDQSRcvrEn_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); -void TrainMaxReadLatency_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); -void mct_EndDQSTraining_D(struct MCTStatStruc *pMCTstat,struct DCTStatStruc *pDCTstatA); -void mct_SetRcvrEnDly_D(struct DCTStatStruc *pDCTstat, u8 RcvrEnDly, u8 FinalValue, u8 Channel, u8 Receiver, u32 dev, u32 index_reg, u8 Addl_Index, u8 Pass); -void SetEccDQSRcvrEn_D(struct DCTStatStruc *pDCTstat, u8 Channel); -void mctGet_PS_Cfg_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u32 dct); -void InterleaveBanks_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct); -void mct_SetDramConfigHi_D(struct DCTStatStruc *pDCTstat, u32 dct, u32 DramConfigHi); -void mct_DramInit_Hw_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 dct); -void SyncSetting(struct DCTStatStruc *pDCTstat); -void mct_SetClToNB_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat); -void mct_SetWbEnhWsbDis_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat); -void mct_TrainRcvrEn_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 Pass); -void mct_EnableDimmEccEn_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 _DisableDramECC); -u32 procOdtWorkaround(struct DCTStatStruc *pDCTstat, u32 dct, u32 val); -void mct_BeforeDramInit_D(struct DCTStatStruc *pDCTstat, u32 dct); -void InterleaveNodes_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); -void InterleaveChannels_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); -void mct_BeforeDQSTrain_Samp_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat); -void StoreDQSDatStrucVal_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 ChipSel); -void phyAssistedMemFnceTraining(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); -u8 mct_SaveRcvEnDly_D_1Pass(struct DCTStatStruc *pDCTstat, u8 pass); -u32 CheckNBCOFAutoPrechg(struct DCTStatStruc *pDCTstat, u32 dct); -u8 mct_AdjustDQSPosDelay_D(struct DCTStatStruc *pDCTstat, u8 dly); -void mct_AdjustScrub_D(struct DCTStatStruc *pDCTstat, u16 *scrub_request); -u8 mct_InitReceiver_D(struct DCTStatStruc *pDCTstat, u8 dct); -void mct_Wait(u32 cycles); -u8 mct_RcvrRankEnabled_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 Channel, u8 ChipSel); -u32 mct_GetRcvrSysAddr_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u8 channel, u8 receiver, u8 *valid); -void mct_Read1LTestPattern_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u32 addr); -void 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 deleted file mode 100644 index d826fed96d..0000000000 --- a/src/northbridge/amd/amdmct/mct/mct_d_gcc.c +++ /dev/null @@ -1,351 +0,0 @@ -/* - * 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<<i)) { - ret = i; - break; - } - } - - return ret; - -} - - -u32 bsf(u32 x) -{ - u8 i; - u32 ret = 32; - - for (i = 0; i < 32; i++) { - if (x & (1<<i)) { - ret = i; - break; - } - } - - return ret; -} - -#define _MFENCE asm volatile ("mfence") - -#define _SFENCE asm volatile ("sfence") - -/* prevent speculative execution of following instructions */ -#define _EXECFENCE asm volatile ("outb %al, $0xed") - -#include <cpu/x86/cr.h> - -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 deleted file mode 100644 index 993aa21d74..0000000000 --- a/src/northbridge/amd/amdmct/mct/mct_d_gcc.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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. - */ - -#ifndef MCT_D_GCC_H -#define MCT_D_GCC_H - -#include <stdint.h> - -void _WRMSR(u32 addr, u32 lo, u32 hi); -void _RDMSR(u32 addr, u32 *lo, u32 *hi); -void _RDTSC(u32 *lo, u32 *hi); -void _cpu_id(u32 addr, u32 *val); -u32 bsr(u32 x); -u32 bsf(u32 x); - -#define _MFENCE asm volatile ("mfence") -#define _SFENCE asm volatile ("sfence") - -/* prevent speculative execution of following instructions */ -#define _EXECFENCE asm volatile ("outb %al, $0xed") - -u32 SetUpperFSbase(u32 addr_hi); -void proc_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); - -#endif diff --git a/src/northbridge/amd/amdmct/mct/mctardk3.c b/src/northbridge/amd/amdmct/mct/mctardk3.c deleted file mode 100644 index c36ba8ea7a..0000000000 --- a/src/northbridge/amd/amdmct/mct/mctardk3.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * 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 <stdint.h> -#include "mct_d.h" - -static void Get_ChannelPS_Cfg0_D(u8 MAAdimms, u8 Speed, u8 MAAload, - u8 DATAAload, u32 *AddrTmgCTL, u32 *ODC_CTL); - - -void mctGet_PS_Cfg_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u32 dct) -{ - u16 val, valx; - - print_tx("dct: ", dct); - print_tx("Speed: ", pDCTstat->Speed); - - Get_ChannelPS_Cfg0_D(pDCTstat->MAdimms[dct], pDCTstat->Speed, - pDCTstat->MAload[dct], pDCTstat->DATAload[dct], - &(pDCTstat->CH_ADDR_TMG[dct]), &(pDCTstat->CH_ODC_CTL[dct])); - - - if (pDCTstat->MAdimms[dct] == 1) - pDCTstat->CH_ODC_CTL[dct] |= 0x20000000; /* 75ohms */ - else - pDCTstat->CH_ODC_CTL[dct] |= 0x10000000; /* 150ohms */ - - pDCTstat->_2Tmode = 1; - - /* use byte lane 4 delay for ECC lane */ - pDCTstat->CH_EccDQSLike[0] = 0x0504; - pDCTstat->CH_EccDQSScale[0] = 0; /* 100% byte lane 4 */ - pDCTstat->CH_EccDQSLike[1] = 0x0504; - pDCTstat->CH_EccDQSScale[1] = 0; /* 100% byte lane 4 */ - - - /* - Overrides and/or exceptions - */ - - /* 1) QRx4 needs to adjust CS/ODT setup time */ - // FIXME: Add Ax support? - if (mctGet_NVbits(NV_MAX_DIMMS) == 4) { - if (pDCTstat->DimmQRPresent != 0) { - pDCTstat->CH_ADDR_TMG[dct] &= 0xFF00FFFF; - pDCTstat->CH_ADDR_TMG[dct] |= 0x00000000; - if (pDCTstat->MAdimms[dct] == 4) { - pDCTstat->CH_ADDR_TMG[dct] &= 0xFF00FFFF; - pDCTstat->CH_ADDR_TMG[dct] |= 0x002F0000; - if (pDCTstat->Speed == 3 || pDCTstat->Speed == 4) { - pDCTstat->CH_ADDR_TMG[dct] &= 0xFF00FFFF; - pDCTstat->CH_ADDR_TMG[dct] |= 0x00002F00; - if (pDCTstat->MAdimms[dct] == 4) - pDCTstat->CH_ODC_CTL[dct] = 0x00331222; - } - } - } - } - - - /* 2) DRx4 (R/C-J) @ DDR667 needs to adjust CS/ODT setup time */ - if (pDCTstat->Speed == 3 || pDCTstat->Speed == 4) { - val = pDCTstat->Dimmx4Present; - if (dct == 0) { - val &= 0x55; - } else { - val &= 0xAA; - val >>= 1; - } - val &= pDCTstat->DIMMValid; - if (val) { - //FIXME: skip for Ax - valx = pDCTstat->DimmDRPresent; - if (dct == 0) { - valx &= 0x55; - } else { - valx &= 0xAA; - valx >>= 1; - } - val &= valx; - if (val != 0) { - if (mctGet_NVbits(NV_MAX_DIMMS) == 8 || - pDCTstat->Speed == 3) { - pDCTstat->CH_ADDR_TMG[dct] &= 0xFFFF00FF; - pDCTstat->CH_ADDR_TMG[dct] |= 0x00002F00; - } - } - } - } - - - pDCTstat->CH_ODC_CTL[dct] = procOdtWorkaround(pDCTstat, dct, pDCTstat->CH_ODC_CTL[dct]); - - print_tx("CH_ODC_CTL: ", pDCTstat->CH_ODC_CTL[dct]); - print_tx("CH_ADDR_TMG: ", pDCTstat->CH_ADDR_TMG[dct]); - - -} - - -/*=============================================================================== - * Vendor is responsible for correct settings. - * M2/Unbuffered 4 Slot - AMD Design Guideline. - *=============================================================================== - * #1, BYTE, Speed (DCTStatstruc.Speed) (Secondary Key) - * #2, BYTE, number of Address bus loads on the Channel. (Tershery Key) - * These must be listed in ascending order. - * FFh (0xFE) has special meaning of 'any', and must be listed first for each speed grade. - * #3, DWORD, Address Timing Control Register Value - * #4, DWORD, Output Driver Compensation Control Register Value - * #5, BYTE, Number of DIMMs (Primary Key) - */ -static const u8 Table_ATC_ODC_8D_D[] = { - 0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x22, 0x12, 0x11, 0x00, 1, - 0xFE, 0xFF, 0x00, 0x00, 0x37, 0x00, 0x22, 0x12, 0x11, 0x00, 2, - 1, 0xFF, 0x00, 0x00, 0x2F, 0x00, 0x22, 0x12, 0x11, 0x00, 3, - 2, 0xFF, 0x00, 0x00, 0x2F, 0x00, 0x22, 0x12, 0x11, 0x00, 3, - 3, 0xFF, 0x2F, 0x00, 0x2F, 0x00, 0x22, 0x12, 0x11, 0x00, 3, - 4, 0xFF, 0x2F, 0x00, 0x2F, 0x00, 0x22, 0x12, 0x33, 0x00, 3, - 1, 0xFF, 0x00, 0x00, 0x2F, 0x00, 0x22, 0x12, 0x11, 0x00, 4, - 2, 0xFF, 0x00, 0x00, 0x2F, 0x00, 0x22, 0x12, 0x11, 0x00, 4, - 3, 0xFF, 0x2F, 0x00, 0x2F, 0x00, 0x22, 0x12, 0x33, 0x00, 4, - 4, 0xFF, 0x2F, 0x00, 0x2F, 0x00, 0x22, 0x12, 0x33, 0x00, 4, - 0xFF -}; - -static const u8 Table_ATC_ODC_4D_D[] = { - 0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x22, 0x12, 0x11, 0x00, 1, - 0xFE, 0xFF, 0x00, 0x00, 0x37, 0x00, 0x22, 0x12, 0x11, 0x00, 2, - 0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x22, 0x12, 0x11, 0x00, 3, - 0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x22, 0x12, 0x11, 0x00, 4, - 0xFF -}; - - -static void Get_ChannelPS_Cfg0_D(u8 MAAdimms, u8 Speed, u8 MAAload, - u8 DATAAload, u32 *AddrTmgCTL, u32 *ODC_CTL) -{ - const u8 *p; - - *AddrTmgCTL = 0; - *ODC_CTL = 0; - - if (mctGet_NVbits(NV_MAX_DIMMS) == 8) { - /* 8 DIMM Table */ - p = Table_ATC_ODC_8D_D; - //FIXME Add Ax support - } else { - /* 4 DIMM Table*/ - p = Table_ATC_ODC_4D_D; - //FIXME Add Ax support - } - - while (*p != 0xFF) { - if ((MAAdimms == *(p+10)) || (*(p+10) == 0xFE)) { - if ((*p == Speed) || (*p == 0xFE)) { - if (MAAload <= *(p+1)) { - *AddrTmgCTL = stream_to_int((u8*)(p+2)); - *ODC_CTL = stream_to_int((u8*)(p+6)); - break; - } - } - } - p+=11; - } -} diff --git a/src/northbridge/amd/amdmct/mct/mctardk4.c b/src/northbridge/amd/amdmct/mct/mctardk4.c deleted file mode 100644 index c700593740..0000000000 --- a/src/northbridge/amd/amdmct/mct/mctardk4.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * 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 <stdint.h> -#include "mct_d.h" - -static void Get_ChannelPS_Cfg0_D(u8 MAAdimms, u8 Speed, u8 MAAload, - u8 DATAAload, u32 *AddrTmgCTL, u32 *ODC_CTL, - u8 *CMDmode); - - -void mctGet_PS_Cfg_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u32 dct) -{ - print_tx("dct: ", dct); - print_tx("Speed: ", pDCTstat->Speed); - - Get_ChannelPS_Cfg0_D(pDCTstat->MAdimms[dct], pDCTstat->Speed, - pDCTstat->MAload[dct], pDCTstat->DATAload[dct], - &(pDCTstat->CH_ADDR_TMG[dct]), &(pDCTstat->CH_ODC_CTL[dct]), - &pDCTstat->_2Tmode); - - if (pDCTstat->MAdimms[dct] == 1) - pDCTstat->CH_ODC_CTL[dct] |= 0x20000000; /* 75ohms */ - else - pDCTstat->CH_ODC_CTL[dct] |= 0x10000000; /* 150ohms */ - - - /* - * Overrides and/or workarounds - */ - pDCTstat->CH_ODC_CTL[dct] = procOdtWorkaround(pDCTstat, dct, pDCTstat->CH_ODC_CTL[dct]); - - print_tx("4 CH_ODC_CTL: ", pDCTstat->CH_ODC_CTL[dct]); - print_tx("4 CH_ADDR_TMG: ", pDCTstat->CH_ADDR_TMG[dct]); -} - -/*============================================================================= - * Vendor is responsible for correct settings. - * M2/Unbuffered 4 Slot - AMD Design Guideline. - *============================================================================= - * #1, BYTE, Speed (DCTStatstruc.Speed) - * #2, BYTE, number of Address bus loads on the Channel. - * These must be listed in ascending order. - * FFh (-1) has special meaning of 'any', and must be listed first for - * each speed grade. - * #3, DWORD, Address Timing Control Register Value - * #4, DWORD, Output Driver Compensation Control Register Value - */ - -static const u8 Table_ATC_ODC_D_Bx[] = { - 1, 0xFF, 0x00, 0x2F, 0x2F, 0x0, 0x22, 0x13, 0x11, 0x0, - 2, 12, 0x00, 0x2F, 0x2F, 0x0, 0x22, 0x13, 0x11, 0x0, - 2, 16, 0x00, 0x2F, 0x00, 0x0, 0x22, 0x13, 0x11, 0x0, - 2, 20, 0x00, 0x2F, 0x38, 0x0, 0x22, 0x13, 0x11, 0x0, - 2, 24, 0x00, 0x2F, 0x37, 0x0, 0x22, 0x13, 0x11, 0x0, - 2, 32, 0x00, 0x2F, 0x34, 0x0, 0x22, 0x13, 0x11, 0x0, - 3, 12, 0x20, 0x22, 0x20, 0x0, 0x22, 0x13, 0x11, 0x0, - 3, 16, 0x20, 0x22, 0x30, 0x0, 0x22, 0x13, 0x11, 0x0, - 3, 20, 0x20, 0x22, 0x2C, 0x0, 0x22, 0x13, 0x11, 0x0, - 3, 24, 0x20, 0x22, 0x2A, 0x0, 0x22, 0x13, 0x11, 0x0, - 3, 32, 0x20, 0x22, 0x2B, 0x0, 0x22, 0x13, 0x11, 0x0, - 4, 0xFF, 0x20, 0x25, 0x20, 0x0, 0x22, 0x33, 0x11, 0x0, - 5, 0xFF, 0x20, 0x20, 0x2F, 0x0, 0x22, 0x32, 0x11, 0x0, - 0xFF -}; - - -static void Get_ChannelPS_Cfg0_D(u8 MAAdimms, u8 Speed, u8 MAAload, - u8 DATAAload, u32 *AddrTmgCTL, u32 *ODC_CTL, - u8 *CMDmode) -{ - u8 const *p; - - *AddrTmgCTL = 0; - *ODC_CTL = 0; - *CMDmode = 1; - - // FIXME: add Ax support - if (MAAdimms == 0) { - *ODC_CTL = 0x00111222; - if (Speed == 3) - *AddrTmgCTL = 0x00202220; - else if (Speed == 2) - *AddrTmgCTL = 0x002F2F00; - else if (Speed == 1) - *AddrTmgCTL = 0x002F2F00; - else if (Speed == 4) - *AddrTmgCTL = 0x00202520; - else if (Speed == 5) - *AddrTmgCTL = 0x002F2020; - else - *AddrTmgCTL = 0x002F2F2F; - } else if (MAAdimms == 1) { - if (Speed == 4) { - *CMDmode = 2; - *AddrTmgCTL = 0x00202520; - *ODC_CTL = 0x00113222; - } else if (Speed == 5) { - *CMDmode = 2; - *AddrTmgCTL = 0x002F2020; - *ODC_CTL = 0x00113222; - } else { - *CMDmode = 1; - *ODC_CTL = 0x00111222; - if (Speed == 3) { - *AddrTmgCTL = 0x00202220; - } else if (Speed == 2) { - if (MAAload == 4) - *AddrTmgCTL = 0x002B2F00; - else if (MAAload == 16) - *AddrTmgCTL = 0x002B2F00; - else if (MAAload == 8) - *AddrTmgCTL = 0x002F2F00; - else - *AddrTmgCTL = 0x002F2F00; - } else if (Speed == 1) { - *AddrTmgCTL = 0x002F2F00; - } else { - *AddrTmgCTL = 0x002F2F2F; - } - } - } else { - *CMDmode = 2; - p = Table_ATC_ODC_D_Bx; - do { - if (Speed == *p) { - if (MAAload <= *(p+1)) { - *AddrTmgCTL = stream_to_int(p+2); - *ODC_CTL = stream_to_int(p+6); - break; - } - } - p+=10; - } while (*p == 0xff); - } -} diff --git a/src/northbridge/amd/amdmct/mct/mctchi_d.c b/src/northbridge/amd/amdmct/mct/mctchi_d.c deleted file mode 100644 index d2acc15118..0000000000 --- a/src/northbridge/amd/amdmct/mct/mctchi_d.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007-2008 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.h" - -void InterleaveChannels_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - - u8 Node; - u32 DramBase, DctSelBase; - u8 DctSelIntLvAddr, DctSelHi; - u8 HoleValid = 0; - u32 HoleSize, HoleBase = 0; - u32 val, tmp; - u32 dct0_size, dct1_size; - u8 enabled; - struct DCTStatStruc *pDCTstat; - - /* HoleValid - indicates whether the current Node contains hole. - * HoleSize - indicates whether there is IO hole in the whole system - * memory. - */ - - /* call back to wrapper not needed ManualChannelInterleave_D(); */ - /* call back - DctSelIntLvAddr = mctGet_NVbits(NV_ChannelIntlv);*/ /* override interleave */ - // FIXME: Check for Cx - DctSelIntLvAddr = mctGet_NVbits(NV_ChannelIntlv); /* typ = 5: Hash*: exclusive OR of address bits[20:16, 6]. */ - beforeInterleaveChannels_D(pDCTstatA, &enabled); - - if (DctSelIntLvAddr & 1) { - DctSelIntLvAddr >>= 1; - HoleSize = 0; - if ((pMCTstat->GStatus & (1 << GSB_SoftHole)) || - (pMCTstat->GStatus & (1 << GSB_HWHole))) { - if (pMCTstat->HoleBase) { - HoleBase = pMCTstat->HoleBase >> 8; - HoleSize = HoleBase & 0xFFFF0000; - HoleSize |= ((~HoleBase) + 1) & 0xFFFF; - } - } - Node = 0; - while (Node < MAX_NODES_SUPPORTED) { - pDCTstat = pDCTstatA + Node; - val = Get_NB32(pDCTstat->dev_map, 0xF0); - if (val & (1 << DramHoleValid)) - HoleValid = 1; - if (!pDCTstat->GangedMode && pDCTstat->DIMMValidDCT[0] && pDCTstat->DIMMValidDCT[1]) { - DramBase = pDCTstat->NodeSysBase >> 8; - dct1_size = ((pDCTstat->NodeSysLimit) + 2) >> 8; - dct0_size = Get_NB32(pDCTstat->dev_dct, 0x114); - if (dct0_size >= 0x10000) { - dct0_size -= HoleSize; - } - - dct0_size -= DramBase; - dct1_size -= dct0_size; - DctSelHi = 0x05; /* DctSelHiRngEn = 1, DctSelHi = 0 */ - if (dct1_size == dct0_size) { - dct1_size = 0; - DctSelHi = 0x04; /* DctSelHiRngEn = 0 */ - } else if (dct1_size > dct0_size) { - dct1_size = dct0_size; - DctSelHi = 0x07; /* DctSelHiRngEn = 1, DctSelHi = 1 */ - } - dct0_size = dct1_size; - dct0_size += DramBase; - dct0_size += dct1_size; - if (dct0_size >= HoleBase) /* if DctSelBaseAddr > HoleBase */ - dct0_size += HoleSize; - DctSelBase = dct0_size; - - if (dct1_size == 0) - dct0_size = 0; - dct0_size -= dct1_size; /* DctSelBaseOffset = DctSelBaseAddr - Interleaved region */ - Set_NB32(pDCTstat->dev_dct, 0x114, dct0_size); - - if (dct1_size == 0) - dct1_size = DctSelBase; - val = Get_NB32(pDCTstat->dev_dct, 0x110); - val &= 0x7F8; - val |= dct1_size; - val |= DctSelHi; - val |= (DctSelIntLvAddr << 6) & 0xFF; - Set_NB32(pDCTstat->dev_dct, 0x110, val); - print_tx("InterleaveChannels: F2x110 DRAM Controller Select Low Register = ", val); - - if (HoleValid) { - tmp = DramBase; - val = DctSelBase; - if (val < HoleBase) { /* DctSelBaseAddr < DramHoleBase */ - val -= DramBase; - val >>= 1; - tmp += val; - } - tmp += HoleSize; - val = Get_NB32(pDCTstat->dev_map, 0xF0); /* DramHoleOffset */ - val &= 0xFFFF007F; - val |= (tmp & ~0xFFFF007F); - Set_NB32(pDCTstat->dev_map, 0xF0, val); - print_tx("InterleaveChannels: F1xF0 DRAM Hole Address Register = ", val); - - } - } - print_tx("InterleaveChannels_D: Node ", Node); - print_tx("InterleaveChannels_D: Status ", pDCTstat->Status); - print_tx("InterleaveChannels_D: ErrStatus ", pDCTstat->ErrStatus); - print_tx("InterleaveChannels_D: ErrCode ", pDCTstat->ErrCode); - Node++; - } - } - print_t("InterleaveChannels_D: Done\n"); -} diff --git a/src/northbridge/amd/amdmct/mct/mctcsi_d.c b/src/northbridge/amd/amdmct/mct/mctcsi_d.c deleted file mode 100644 index 6a19788ab3..0000000000 --- a/src/northbridge/amd/amdmct/mct/mctcsi_d.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * 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.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 - * ;(2 or 3) to the number of column address bits, plus 3 (the logical - * ;page size), and subtract 8. - */ -static const u8 Tab_int_D[] = { 6,7,7,8,8,8,8,8,9,9,8,9 }; - -void InterleaveBanks_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u8 ChipSel, EnChipSels; - u32 AddrLoMask, AddrHiMask; - u32 AddrLoMaskN, AddrHiMaskN, MemSize = 0; - u8 DoIntlv, _CsIntCap; - u32 BitDelta, BankEncd = 0; - - u32 dev; - u32 reg; - u32 reg_off; - u32 val; - u32 val_lo, val_hi; - - DoIntlv = mctGet_NVbits(NV_BankIntlv); - _CsIntCap = 0; - EnChipSels = 0; - - dev = pDCTstat->dev_dct; - reg_off = 0x100 * dct; - - ChipSel = 0; /* Find out if current configuration is capable */ - while (DoIntlv && (ChipSel < MAX_CS_SUPPORTED)) { - reg = 0x40+(ChipSel << 2) + reg_off; /* Dram CS Base 0 */ - val = Get_NB32(dev, reg); - if (val & (1 << CSEnable)) { - EnChipSels++; - reg = 0x60+((ChipSel >> 1) << 2)+reg_off; /*Dram CS Mask 0 */ - val = Get_NB32(dev, reg); - val >>= 19; - val &= 0x3ff; - val++; - if (EnChipSels == 1) - MemSize = val; - else - /*If mask sizes not same then skip */ - if (val != MemSize) - break; - reg = 0x80 + reg_off; /*Dram Bank Addressing */ - val = Get_NB32(dev, reg); - val >>= (ChipSel >> 1) << 2; - val &= 0x0f; - if (EnChipSels == 1) - BankEncd = val; - else - /*If number of Rows/Columns not equal, skip */ - if (val != BankEncd) - break; - } - ChipSel++; - } - if (ChipSel == MAX_CS_SUPPORTED) { - if ((EnChipSels == 2) || (EnChipSels == 4) || (EnChipSels == 8)) - _CsIntCap = 1; - } - - if (DoIntlv) { - if (!_CsIntCap) { - pDCTstat->ErrStatus |= 1 << SB_BkIntDis; - DoIntlv = 0; - } - } - - if (DoIntlv) { - val = Tab_int_D[BankEncd]; - if (pDCTstat->Status & (1 << SB_128bitmode)) - val++; - - AddrLoMask = (EnChipSels - 1) << val; - AddrLoMaskN = ~AddrLoMask; - - val = bsf(MemSize) + 19; - AddrHiMask = (EnChipSels -1) << val; - AddrHiMaskN = ~AddrHiMask; - - BitDelta = bsf(AddrHiMask) - bsf(AddrLoMask); - - for (ChipSel = 0; ChipSel < MAX_CS_SUPPORTED; ChipSel++) { - reg = 0x40+(ChipSel << 2) + reg_off; /*Dram CS Base 0 */ - val = Get_NB32(dev, reg); - if (val & 3) { - val_lo = val & AddrLoMask; - val_hi = val & AddrHiMask; - val &= AddrLoMaskN; - val &= AddrHiMaskN; - val_lo <<= BitDelta; - val_hi >>= BitDelta; - val |= val_lo; - val |= val_hi; - Set_NB32(dev, reg, val); - - if (ChipSel & 1) - continue; - - reg = 0x60 + ((ChipSel >> 1) << 2) + reg_off; /*Dram CS Mask 0 */ - val = Get_NB32(dev, reg); - val_lo = val & AddrLoMask; - val_hi = val & AddrHiMask; - val &= AddrLoMaskN; - val &= AddrHiMaskN; - val_lo <<= BitDelta; - val_hi >>= BitDelta; - val |= val_lo; - val |= val_hi; - Set_NB32(dev, reg, val); - } - } - print_t("InterleaveBanks_D: Banks Interleaved "); - } /* DoIntlv */ - - print_tx("InterleaveBanks_D: Status ", pDCTstat->Status); - print_tx("InterleaveBanks_D: ErrStatus ", pDCTstat->ErrStatus); - print_tx("InterleaveBanks_D: ErrCode ", pDCTstat->ErrCode); - print_t("InterleaveBanks_D: Done\n"); -} diff --git a/src/northbridge/amd/amdmct/mct/mctdqs_d.c b/src/northbridge/amd/amdmct/mct/mctdqs_d.c deleted file mode 100644 index 2e52a39619..0000000000 --- a/src/northbridge/amd/amdmct/mct/mctdqs_d.c +++ /dev/null @@ -1,1207 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007-2008 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 <console/console.h> -#include <cpu/x86/cr.h> -#include <cpu/amd/msr.h> -#include <cpu/amd/mtrr.h> - -#include "mct_d.h" - -static void CalcEccDQSPos_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u16 like, - u8 scale, u8 ChipSel); -static void GetDQSDatStrucVal_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 ChipSel); -static u8 MiddleDQS_D(u8 min, u8 max); -static void TrainReadDQS_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, - u8 cs_start); -static void TrainWriteDQS_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, - u8 cs_start); -static void WriteDQSTestPattern_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, - u32 TestAddr_lo); -static void WriteL18TestPattern_D(struct DCTStatStruc *pDCTstat, - u32 TestAddr_lo); -static void WriteL9TestPattern_D(struct DCTStatStruc *pDCTstat, - u32 TestAddr_lo); -static u8 CompareDQSTestPattern_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, - u32 addr_lo); -static void FlushDQSTestPattern_D(struct DCTStatStruc *pDCTstat, - u32 addr_lo); -static void ReadDQSTestPattern_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, - u32 TestAddr_lo); -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); -static void SetupDqsPattern_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, - u32 *buffer); - -void print_debug_dqs(const char *str, u32 val, u8 level) -{ -#if DQS_TRAIN_DEBUG > 0 - if (DQS_TRAIN_DEBUG >= level) { - printk(BIOS_DEBUG, "%s%x\n", str, val); - } -#endif -} - -void print_debug_dqs_pair(const char *str, u32 val, const char *str2, u32 val2, u8 level) -{ -#if DQS_TRAIN_DEBUG > 0 - if (DQS_TRAIN_DEBUG >= level) { - printk(BIOS_DEBUG, "%s%08x%s%08x\n", str, val, str2, val2); - } -#endif -} - -/*Warning: These must be located so they do not cross a logical 16-bit segment boundary!*/ -static const u32 TestPatternJD1a_D[] = { - 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF, /* QW0-1, ALL-EVEN */ - 0x00000000,0x00000000,0x00000000,0x00000000, /* QW2-3, ALL-EVEN */ - 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF, /* QW4-5, ALL-EVEN */ - 0x00000000,0x00000000,0x00000000,0x00000000, /* QW6-7, ALL-EVEN */ - 0xFeFeFeFe,0xFeFeFeFe,0x01010101,0x01010101, /* QW0-1, DQ0-ODD */ - 0xFeFeFeFe,0xFeFeFeFe,0x01010101,0x01010101, /* QW2-3, DQ0-ODD */ - 0x01010101,0x01010101,0xFeFeFeFe,0xFeFeFeFe, /* QW4-5, DQ0-ODD */ - 0xFeFeFeFe,0xFeFeFeFe,0x01010101,0x01010101, /* QW6-7, DQ0-ODD */ - 0x02020202,0x02020202,0x02020202,0x02020202, /* QW0-1, DQ1-ODD */ - 0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd, /* QW2-3, DQ1-ODD */ - 0xFdFdFdFd,0xFdFdFdFd,0x02020202,0x02020202, /* QW4-5, DQ1-ODD */ - 0x02020202,0x02020202,0x02020202,0x02020202, /* QW6-7, DQ1-ODD */ - 0x04040404,0x04040404,0xfBfBfBfB,0xfBfBfBfB, /* QW0-1, DQ2-ODD */ - 0x04040404,0x04040404,0x04040404,0x04040404, /* QW2-3, DQ2-ODD */ - 0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, /* QW4-5, DQ2-ODD */ - 0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, /* QW6-7, DQ2-ODD */ - 0x08080808,0x08080808,0xF7F7F7F7,0xF7F7F7F7, /* QW0-1, DQ3-ODD */ - 0x08080808,0x08080808,0x08080808,0x08080808, /* QW2-3, DQ3-ODD */ - 0xF7F7F7F7,0xF7F7F7F7,0x08080808,0x08080808, /* QW4-5, DQ3-ODD */ - 0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7, /* QW6-7, DQ3-ODD */ - 0x10101010,0x10101010,0x10101010,0x10101010, /* QW0-1, DQ4-ODD */ - 0xeFeFeFeF,0xeFeFeFeF,0x10101010,0x10101010, /* QW2-3, DQ4-ODD */ - 0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF, /* QW4-5, DQ4-ODD */ - 0xeFeFeFeF,0xeFeFeFeF,0x10101010,0x10101010, /* QW6-7, DQ4-ODD */ - 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, /* QW0-1, DQ5-ODD */ - 0xdFdFdFdF,0xdFdFdFdF,0x20202020,0x20202020, /* QW2-3, DQ5-ODD */ - 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, /* QW4-5, DQ5-ODD */ - 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, /* QW6-7, DQ5-ODD */ - 0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf, /* QW0-1, DQ6-ODD */ - 0x40404040,0x40404040,0xBfBfBfBf,0xBfBfBfBf, /* QW2-3, DQ6-ODD */ - 0x40404040,0x40404040,0xBfBfBfBf,0xBfBfBfBf, /* QW4-5, DQ6-ODD */ - 0x40404040,0x40404040,0xBfBfBfBf,0xBfBfBfBf, /* QW6-7, DQ6-ODD */ - 0x80808080,0x80808080,0x7F7F7F7F,0x7F7F7F7F, /* QW0-1, DQ7-ODD */ - 0x80808080,0x80808080,0x7F7F7F7F,0x7F7F7F7F, /* QW2-3, DQ7-ODD */ - 0x80808080,0x80808080,0x7F7F7F7F,0x7F7F7F7F, /* QW4-5, DQ7-ODD */ - 0x80808080,0x80808080,0x80808080,0x80808080 /* QW6-7, DQ7-ODD */ -}; -static const u32 TestPatternJD1b_D[] = { - 0x00000000,0x00000000,0x00000000,0x00000000, /* QW0,CHA-B, ALL-EVEN */ - 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, /* QW1,CHA-B, ALL-EVEN */ - 0x00000000,0x00000000,0x00000000,0x00000000, /* QW2,CHA-B, ALL-EVEN */ - 0x00000000,0x00000000,0x00000000,0x00000000, /* QW3,CHA-B, ALL-EVEN */ - 0x00000000,0x00000000,0x00000000,0x00000000, /* QW4,CHA-B, ALL-EVEN */ - 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, /* QW5,CHA-B, ALL-EVEN */ - 0x00000000,0x00000000,0x00000000,0x00000000, /* QW6,CHA-B, ALL-EVEN */ - 0x00000000,0x00000000,0x00000000,0x00000000, /* QW7,CHA-B, ALL-EVEN */ - 0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe, /* QW0,CHA-B, DQ0-ODD */ - 0x01010101,0x01010101,0x01010101,0x01010101, /* QW1,CHA-B, DQ0-ODD */ - 0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe, /* QW2,CHA-B, DQ0-ODD */ - 0x01010101,0x01010101,0x01010101,0x01010101, /* QW3,CHA-B, DQ0-ODD */ - 0x01010101,0x01010101,0x01010101,0x01010101, /* QW4,CHA-B, DQ0-ODD */ - 0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe, /* QW5,CHA-B, DQ0-ODD */ - 0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe,0xFeFeFeFe, /* QW6,CHA-B, DQ0-ODD */ - 0x01010101,0x01010101,0x01010101,0x01010101, /* QW7,CHA-B, DQ0-ODD */ - 0x02020202,0x02020202,0x02020202,0x02020202, /* QW0,CHA-B, DQ1-ODD */ - 0x02020202,0x02020202,0x02020202,0x02020202, /* QW1,CHA-B, DQ1-ODD */ - 0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd, /* QW2,CHA-B, DQ1-ODD */ - 0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd, /* QW3,CHA-B, DQ1-ODD */ - 0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd,0xFdFdFdFd, /* QW4,CHA-B, DQ1-ODD */ - 0x02020202,0x02020202,0x02020202,0x02020202, /* QW5,CHA-B, DQ1-ODD */ - 0x02020202,0x02020202,0x02020202,0x02020202, /* QW6,CHA-B, DQ1-ODD */ - 0x02020202,0x02020202,0x02020202,0x02020202, /* QW7,CHA-B, DQ1-ODD */ - 0x04040404,0x04040404,0x04040404,0x04040404, /* QW0,CHA-B, DQ2-ODD */ - 0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, /* QW1,CHA-B, DQ2-ODD */ - 0x04040404,0x04040404,0x04040404,0x04040404, /* QW2,CHA-B, DQ2-ODD */ - 0x04040404,0x04040404,0x04040404,0x04040404, /* QW3,CHA-B, DQ2-ODD */ - 0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, /* QW4,CHA-B, DQ2-ODD */ - 0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, /* QW5,CHA-B, DQ2-ODD */ - 0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, /* QW6,CHA-B, DQ2-ODD */ - 0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB,0xfBfBfBfB, /* QW7,CHA-B, DQ2-ODD */ - 0x08080808,0x08080808,0x08080808,0x08080808, /* QW0,CHA-B, DQ3-ODD */ - 0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7, /* QW1,CHA-B, DQ3-ODD */ - 0x08080808,0x08080808,0x08080808,0x08080808, /* QW2,CHA-B, DQ3-ODD */ - 0x08080808,0x08080808,0x08080808,0x08080808, /* QW3,CHA-B, DQ3-ODD */ - 0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7, /* QW4,CHA-B, DQ3-ODD */ - 0x08080808,0x08080808,0x08080808,0x08080808, /* QW5,CHA-B, DQ3-ODD */ - 0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7, /* QW6,CHA-B, DQ3-ODD */ - 0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7,0xF7F7F7F7, /* QW7,CHA-B, DQ3-ODD */ - 0x10101010,0x10101010,0x10101010,0x10101010, /* QW0,CHA-B, DQ4-ODD */ - 0x10101010,0x10101010,0x10101010,0x10101010, /* QW1,CHA-B, DQ4-ODD */ - 0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF, /* QW2,CHA-B, DQ4-ODD */ - 0x10101010,0x10101010,0x10101010,0x10101010, /* QW3,CHA-B, DQ4-ODD */ - 0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF, /* QW4,CHA-B, DQ4-ODD */ - 0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF, /* QW5,CHA-B, DQ4-ODD */ - 0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF,0xeFeFeFeF, /* QW6,CHA-B, DQ4-ODD */ - 0x10101010,0x10101010,0x10101010,0x10101010, /* QW7,CHA-B, DQ4-ODD */ - 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, /* QW0,CHA-B, DQ5-ODD */ - 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, /* QW1,CHA-B, DQ5-ODD */ - 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, /* QW2,CHA-B, DQ5-ODD */ - 0x20202020,0x20202020,0x20202020,0x20202020, /* QW3,CHA-B, DQ5-ODD */ - 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, /* QW4,CHA-B, DQ5-ODD */ - 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, /* QW5,CHA-B, DQ5-ODD */ - 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, /* QW6,CHA-B, DQ5-ODD */ - 0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF,0xdFdFdFdF, /* QW7,CHA-B, DQ5-ODD */ - 0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf, /* QW0,CHA-B, DQ6-ODD */ - 0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf, /* QW1,CHA-B, DQ6-ODD */ - 0x40404040,0x40404040,0x40404040,0x40404040, /* QW2,CHA-B, DQ6-ODD */ - 0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf, /* QW3,CHA-B, DQ6-ODD */ - 0x40404040,0x40404040,0x40404040,0x40404040, /* QW4,CHA-B, DQ6-ODD */ - 0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf, /* QW5,CHA-B, DQ6-ODD */ - 0x40404040,0x40404040,0x40404040,0x40404040, /* QW6,CHA-B, DQ6-ODD */ - 0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf,0xBfBfBfBf, /* QW7,CHA-B, DQ6-ODD */ - 0x80808080,0x80808080,0x80808080,0x80808080, /* QW0,CHA-B, DQ7-ODD */ - 0x7F7F7F7F,0x7F7F7F7F,0x7F7F7F7F,0x7F7F7F7F, /* QW1,CHA-B, DQ7-ODD */ - 0x80808080,0x80808080,0x80808080,0x80808080, /* QW2,CHA-B, DQ7-ODD */ - 0x7F7F7F7F,0x7F7F7F7F,0x7F7F7F7F,0x7F7F7F7F, /* QW3,CHA-B, DQ7-ODD */ - 0x80808080,0x80808080,0x80808080,0x80808080, /* QW4,CHA-B, DQ7-ODD */ - 0x7F7F7F7F,0x7F7F7F7F,0x7F7F7F7F,0x7F7F7F7F, /* QW5,CHA-B, DQ7-ODD */ - 0x80808080,0x80808080,0x80808080,0x80808080, /* QW6,CHA-B, DQ7-ODD */ - 0x80808080,0x80808080,0x80808080,0x80808080 /* QW7,CHA-B, DQ7-ODD */ -}; - -void TrainReceiverEn_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA, u8 Pass) -{ - u8 Node; - struct DCTStatStruc *pDCTstat; - - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - pDCTstat = pDCTstatA + Node; - -/*FIXME: needed? if (!pDCTstat->NodePresent) - break; -*/ - if (pDCTstat->DCTSysLimit) { - mct_TrainRcvrEn_D(pMCTstat, pDCTstat, Pass); - } - } -} - - -static void SetEccDQSRdWrPos_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 ChipSel) -{ - u8 channel; - u8 direction; - - for (channel = 0; channel < 2; channel++) { - for (direction = 0; direction < 2; direction++) { - pDCTstat->Channel = channel; /* Channel A or B */ - pDCTstat->Direction = direction; /* Read or write */ - CalcEccDQSPos_D(pMCTstat, pDCTstat, pDCTstat->CH_EccDQSLike[channel], pDCTstat->CH_EccDQSScale[channel], ChipSel); - print_debug_dqs_pair("\t\tSetEccDQSRdWrPos: channel ", channel, direction == DQS_READDIR? " R dqs_delay":" W dqs_delay", pDCTstat->DQSDelay, 2); - pDCTstat->ByteLane = 8; - StoreDQSDatStrucVal_D(pMCTstat, pDCTstat, ChipSel); - mct_SetDQSDelayCSR_D(pMCTstat, pDCTstat, ChipSel); - } - } -} - - - -static void CalcEccDQSPos_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, - u16 like, u8 scale, u8 ChipSel) -{ - u8 DQSDelay0, DQSDelay1; - u16 DQSDelay; - - pDCTstat->ByteLane = like & 0xff; - GetDQSDatStrucVal_D(pMCTstat, pDCTstat, ChipSel); - DQSDelay0 = pDCTstat->DQSDelay; - - pDCTstat->ByteLane = (like >> 8) & 0xff; - GetDQSDatStrucVal_D(pMCTstat, pDCTstat, ChipSel); - DQSDelay1 = pDCTstat->DQSDelay; - - if (DQSDelay0 > DQSDelay1) { - DQSDelay = DQSDelay0 - DQSDelay1; - } else { - DQSDelay = DQSDelay1 - DQSDelay0; - } - - DQSDelay = DQSDelay * (~scale); - - DQSDelay += 0x80; // round it - - DQSDelay >>= 8; // /256 - - if (DQSDelay0 > DQSDelay1) { - DQSDelay = DQSDelay1 - DQSDelay; - } else { - DQSDelay += DQSDelay1; - } - - pDCTstat->DQSDelay = (u8)DQSDelay; -} - - -static void TrainDQSRdWrPos_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, - u8 cs_start) -{ - u32 Errors; - u8 Channel, DQSWrDelay; - u8 _DisableDramECC = 0; - u32 PatternBuffer[292]; - u8 _Wrap32Dis = 0, _SSE2 = 0; - u8 dqsWrDelay_end; - - u32 addr; - CRx_TYPE cr4; - u32 lo, hi; - - print_debug_dqs("\nTrainDQSRdWrPos: Node_ID ", pDCTstat->Node_ID, 0); - cr4 = read_cr4(); - if (cr4 & (1<<9)) { - _SSE2 = 1; - } - cr4 |= (1<<9); /* OSFXSR enable SSE2 */ - write_cr4(cr4); - - addr = HWCR_MSR; - _RDMSR(addr, &lo, &hi); - if (lo & (1<<17)) { - _Wrap32Dis = 1; - } - lo |= (1<<17); /* HWCR.wrap32dis */ - _WRMSR(addr, lo, hi); /* allow 64-bit memory references in real mode */ - - /* Disable ECC correction of reads on the dram bus. */ - _DisableDramECC = mct_DisableDimmEccEn_D(pMCTstat, pDCTstat); - - SetupDqsPattern_D(pMCTstat, pDCTstat, PatternBuffer); - - /* mct_BeforeTrainDQSRdWrPos_D */ - dqsWrDelay_end = 0x20; - - Errors = 0; - for (Channel = 0; Channel < 2; Channel++) { - print_debug_dqs("\tTrainDQSRdWrPos: 1 Channel ",Channel, 1); - pDCTstat->Channel = Channel; - - if (pDCTstat->DIMMValidDCT[Channel] == 0) /* mct_BeforeTrainDQSRdWrPos_D */ - continue; - - for (DQSWrDelay = 0; DQSWrDelay < dqsWrDelay_end; DQSWrDelay++) { - pDCTstat->DQSDelay = DQSWrDelay; - pDCTstat->Direction = DQS_WRITEDIR; - mct_SetDQSDelayAllCSR_D(pMCTstat, pDCTstat, cs_start); - - print_debug_dqs("\t\tTrainDQSRdWrPos: 21 DQSWrDelay ", DQSWrDelay, 2); - TrainReadDQS_D(pMCTstat, pDCTstat, cs_start); - - print_debug_dqs("\t\tTrainDQSRdWrPos: 22 TrainErrors ",pDCTstat->TrainErrors, 2); - if (pDCTstat->TrainErrors == 0) { - break; - } - Errors |= pDCTstat->TrainErrors; - } - if (DQSWrDelay < dqsWrDelay_end) { - Errors = 0; - - print_debug_dqs("\tTrainDQSRdWrPos: 231 DQSWrDelay ", DQSWrDelay, 1); - TrainWriteDQS_D(pMCTstat, pDCTstat, cs_start); - } - print_debug_dqs("\tTrainDQSRdWrPos: 232 Errors ", Errors, 1); - pDCTstat->ErrStatus |= Errors; - } - -#if DQS_TRAIN_DEBUG > 0 - { - u8 val; - u8 i; - u8 Channel, Receiver, Dir; - u8 *p; - - for (Dir = 0; Dir < 2; Dir++) { - if (Dir == 0) { - printk(BIOS_DEBUG, "TrainDQSRdWrPos: CH_D_DIR_B_DQS WR:\n"); - } else { - printk(BIOS_DEBUG, "TrainDQSRdWrPos: CH_D_DIR_B_DQS RD:\n"); - } - for (Channel = 0; Channel < 2; Channel++) { - printk(BIOS_DEBUG, "Channel: %02x\n", Channel); - for (Receiver = cs_start; Receiver < (cs_start + 2); Receiver += 2) { - printk(BIOS_DEBUG, "\t\tReceiver: %02x: ", Receiver); - p = pDCTstat->persistentData.CH_D_DIR_B_DQS[Channel][Receiver >> 1][Dir]; - for (i = 0; i < 8; i++) { - val = p[i]; - printk(BIOS_DEBUG, "%02x ", val); - } - printk(BIOS_DEBUG, "\n"); - } - } - } - - } -#endif - - if (_DisableDramECC) { - mct_EnableDimmEccEn_D(pMCTstat, pDCTstat, _DisableDramECC); - } - if (!_Wrap32Dis) { - addr = HWCR_MSR; - _RDMSR(addr, &lo, &hi); - lo &= ~(1<<17); /* restore HWCR.wrap32dis */ - _WRMSR(addr, lo, hi); - } - if (!_SSE2) { - cr4 = read_cr4(); - cr4 &= ~(1<<9); /* restore cr4.OSFXSR */ - write_cr4(cr4); - } - - print_tx("TrainDQSRdWrPos: Status ", pDCTstat->Status); - print_tx("TrainDQSRdWrPos: TrainErrors ", pDCTstat->TrainErrors); - print_tx("TrainDQSRdWrPos: ErrStatus ", pDCTstat->ErrStatus); - print_tx("TrainDQSRdWrPos: ErrCode ", pDCTstat->ErrCode); - print_t("TrainDQSRdWrPos: Done\n"); -} - - -static void SetupDqsPattern_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u32 *buffer) -{ - /* 1. Set the Pattern type (0 or 1) in DCTStatstruc.Pattern - * 2. Copy the pattern from ROM to Cache, aligning on 16 byte boundary - * 3. Set the ptr to Cacheable copy in DCTStatstruc.PtrPatternBufA - */ - - u32 *buf; - u16 i; - - buf = (u32 *)(((u32)buffer + 0x10) & (0xfffffff0)); - if (pDCTstat->Status & (1 << SB_128bitmode)) { - pDCTstat->Pattern = 1; /* 18 cache lines, alternating qwords */ - for (i = 0; i < 16*18; i++) - buf[i] = TestPatternJD1b_D[i]; - } else { - pDCTstat->Pattern = 0; /* 9 cache lines, sequential qwords */ - for (i = 0; i < 16*9; i++) - buf[i] = TestPatternJD1a_D[i]; - } - pDCTstat->PtrPatternBufA = (u32)buf; -} - - -static void TrainDQSPos_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, - u8 cs_start) -{ - u32 Errors; - u8 ChipSel, DQSDelay; - u8 RnkDlySeqPassMin,RnkDlySeqPassMax, RnkDlyFilterMin, RnkDlyFilterMax; - u8 LastTest; - u32 TestAddr; - u8 ByteLane; - u8 MutualCSPassW[64]; - u8 BanksPresent; - u8 dqsDelay_end; - u8 tmp, valid; - - - /* MutualCSPassW: each byte represents a bitmap of pass/fail per - * ByteLane. The indext within MutualCSPassW is the delay value - * given the results. - */ - - - print_debug_dqs("\t\t\tTrainDQSPos begin ", 0, 3); - - Errors = 0; - BanksPresent = 0; - - if (pDCTstat->Direction == DQS_READDIR) { - dqsDelay_end = 64; - mct_AdjustDelayRange_D(pMCTstat, pDCTstat, &dqsDelay_end); - } else { - dqsDelay_end = 32; - } - - /* Bitmapped status per delay setting, 0xff = All positions - * passing (1= PASS). Set the entire array. - */ - for (DQSDelay = 0; DQSDelay < 64; DQSDelay++) { - MutualCSPassW[DQSDelay] = 0xFF; - } - - for (ChipSel = cs_start; ChipSel < (cs_start + 2); ChipSel++) { /* logical register chipselects 0..7 */ - print_debug_dqs("\t\t\t\tTrainDQSPos: 11 ChipSel ", ChipSel, 4); - - if (!mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, pDCTstat->Channel, ChipSel)) { - print_debug_dqs("\t\t\t\tmct_RcvrRankEnabled_D CS not enabled ", ChipSel, 4); - continue; - } - - BanksPresent = 1; /* flag for at least one bank is present */ - TestAddr = mct_GetMCTSysAddr_D(pMCTstat, pDCTstat, pDCTstat->Channel, ChipSel, &valid); - if (!valid) { - print_debug_dqs("\t\t\t\tAddress not supported on current CS ", TestAddr, 4); - continue; - } - - print_debug_dqs("\t\t\t\tTrainDQSPos: 12 TestAddr ", TestAddr, 4); - SetUpperFSbase(TestAddr); /* fs:eax = far ptr to target */ - - if (pDCTstat->Direction == DQS_READDIR) { - print_debug_dqs("\t\t\t\tTrainDQSPos: 13 for read ", 0, 4); - WriteDQSTestPattern_D(pMCTstat, pDCTstat, TestAddr << 8); - } - - for (DQSDelay = 0; DQSDelay < dqsDelay_end; DQSDelay++) { - print_debug_dqs("\t\t\t\t\tTrainDQSPos: 141 DQSDelay ", DQSDelay, 5); - if (MutualCSPassW[DQSDelay] == 0) - continue; //skip current delay value if other chipselects have failed all 8 bytelanes - pDCTstat->DQSDelay = DQSDelay; - mct_SetDQSDelayAllCSR_D(pMCTstat, pDCTstat, cs_start); - print_debug_dqs("\t\t\t\t\tTrainDQSPos: 142 MutualCSPassW ", MutualCSPassW[DQSDelay], 5); - - if (pDCTstat->Direction == DQS_WRITEDIR) { - print_debug_dqs("\t\t\t\t\tTrainDQSPos: 143 for write", 0, 5); - WriteDQSTestPattern_D(pMCTstat, pDCTstat, TestAddr << 8); - } - - print_debug_dqs("\t\t\t\t\tTrainDQSPos: 144 Pattern ", pDCTstat->Pattern, 5); - ReadDQSTestPattern_D(pMCTstat, pDCTstat, TestAddr << 8); - /* print_debug_dqs("\t\t\t\t\tTrainDQSPos: 145 MutualCSPassW ", MutualCSPassW[DQSDelay], 5); */ - tmp = CompareDQSTestPattern_D(pMCTstat, pDCTstat, TestAddr << 8); /* 0 = fail, 1 = pass */ - - if (mct_checkFenceHoleAdjust_D(pMCTstat, pDCTstat, DQSDelay, ChipSel, &tmp)) { - goto skipLocMiddle; - } - - MutualCSPassW[DQSDelay] &= tmp; - print_debug_dqs("\t\t\t\t\tTrainDQSPos: 146\tMutualCSPassW ", MutualCSPassW[DQSDelay], 5); - - SetTargetWTIO_D(TestAddr); - FlushDQSTestPattern_D(pDCTstat, TestAddr << 8); - ResetTargetWTIO_D(); - } - - } - - if (BanksPresent) { - for (ByteLane = 0; ByteLane < 8; ByteLane++) { - print_debug_dqs("\t\t\t\tTrainDQSPos: 31 ByteLane ",ByteLane, 4); - pDCTstat->ByteLane = ByteLane; - LastTest = DQS_FAIL; /* Analyze the results */ - RnkDlySeqPassMin = 0; - RnkDlySeqPassMax = 0; - RnkDlyFilterMax = 0; - RnkDlyFilterMin = 0; - for (DQSDelay = 0; DQSDelay < dqsDelay_end; DQSDelay++) { - if (MutualCSPassW[DQSDelay] & (1 << ByteLane)) { - print_debug_dqs("\t\t\t\t\tTrainDQSPos: 321 DQSDelay ", DQSDelay, 5); - print_debug_dqs("\t\t\t\t\tTrainDQSPos: 322 MutualCSPassW ", MutualCSPassW[DQSDelay], 5); - - RnkDlySeqPassMax = DQSDelay; - if (LastTest == DQS_FAIL) { - RnkDlySeqPassMin = DQSDelay; //start sequential run - } - if ((RnkDlySeqPassMax - RnkDlySeqPassMin)>(RnkDlyFilterMax-RnkDlyFilterMin)) { - RnkDlyFilterMin = RnkDlySeqPassMin; - RnkDlyFilterMax = RnkDlySeqPassMax; - } - LastTest = DQS_PASS; - } else { - LastTest = DQS_FAIL; - } - } - print_debug_dqs("\t\t\t\tTrainDQSPos: 33 RnkDlySeqPassMax ", RnkDlySeqPassMax, 4); - if (RnkDlySeqPassMax == 0) { - Errors |= 1 << SB_NODQSPOS; /* no passing window */ - } else { - print_debug_dqs_pair("\t\t\t\tTrainDQSPos: 34 RnkDlyFilter: ", RnkDlyFilterMin, " ", RnkDlyFilterMax, 4); - if (((RnkDlyFilterMax - RnkDlyFilterMin) < MIN_DQS_WNDW)) { - Errors |= 1 << SB_SMALLDQS; - } else { - u8 middle_dqs; - /* mctEngDQSwindow_Save_D Not required for arrays */ - middle_dqs = MiddleDQS_D(RnkDlyFilterMin, RnkDlyFilterMax); - pDCTstat->DQSDelay = middle_dqs; - mct_SetDQSDelayCSR_D(pMCTstat, pDCTstat, cs_start); /* load the register with the value */ - StoreDQSDatStrucVal_D(pMCTstat, pDCTstat, cs_start); /* store the value into the data structure */ - print_debug_dqs("\t\t\t\tTrainDQSPos: 42 middle_dqs : ",middle_dqs, 4); - } - } - } - } -skipLocMiddle: - pDCTstat->TrainErrors = Errors; - - print_debug_dqs("\t\t\tTrainDQSPos: Errors ", Errors, 3); - -} - - -void StoreDQSDatStrucVal_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 ChipSel) -{ - /* Store the DQSDelay value, found during a training sweep, into the DCT - * status structure for this node - */ - - - /* When 400, 533, 667, it will support dimm0/1/2/3, - * and set conf for dimm0, hw will copy to dimm1/2/3 - * set for dimm1, hw will copy to dimm3 - * Rev A/B only support DIMM0/1 when 800MHz and above + 0x100 to next dimm - * Rev C support DIMM0/1/2/3 when 800MHz and above + 0x100 to next dimm - */ - - /* FindDQSDatDimmVal_D is not required since we use an array */ - u8 dn = 0; - - if (pDCTstat->Status & (1 << SB_Over400MHz)) - dn = ChipSel>>1; /* if odd or even logical DIMM */ - - pDCTstat->persistentData.CH_D_DIR_B_DQS[pDCTstat->Channel][dn][pDCTstat->Direction][pDCTstat->ByteLane] = - pDCTstat->DQSDelay; -} - - -static void GetDQSDatStrucVal_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 ChipSel) -{ - u8 dn = 0; - - - /* When 400, 533, 667, it will support dimm0/1/2/3, - * and set conf for dimm0, hw will copy to dimm1/2/3 - * set for dimm1, hw will copy to dimm3 - * Rev A/B only support DIMM0/1 when 800MHz and above + 0x100 to next dimm - * Rev C support DIMM0/1/2/3 when 800MHz and above + 0x100 to next dimm - */ - - /* FindDQSDatDimmVal_D is not required since we use an array */ - if (pDCTstat->Status & (1<<SB_Over400MHz)) - dn = ChipSel >> 1; /*if odd or even logical DIMM */ - - pDCTstat->DQSDelay = - pDCTstat->persistentData.CH_D_DIR_B_DQS[pDCTstat->Channel][dn][pDCTstat->Direction][pDCTstat->ByteLane]; -} - - -/* FindDQSDatDimmVal_D is not required since we use an array */ - - -static u8 MiddleDQS_D(u8 min, u8 max) -{ - u8 size; - size = max-min; - if (size % 2) - size++; // round up if the size isn't even. - return (min + (size >> 1)); -} - - -static void TrainReadDQS_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, - u8 cs_start) -{ - print_debug_dqs("\t\tTrainReadPos ", 0, 2); - pDCTstat->Direction = DQS_READDIR; - TrainDQSPos_D(pMCTstat, pDCTstat, cs_start); -} - - -static void TrainWriteDQS_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, - u8 cs_start) -{ - pDCTstat->Direction = DQS_WRITEDIR; - print_debug_dqs("\t\tTrainWritePos", 0, 2); - TrainDQSPos_D(pMCTstat, pDCTstat, cs_start); -} - - -void proc_IOCLFLUSH_D(u32 addr_hi) -{ - SetTargetWTIO_D(addr_hi); - proc_CLFLUSH(addr_hi); - ResetTargetWTIO_D(); -} - - -static u8 ChipSelPresent_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, - u8 Channel, u8 ChipSel) -{ - u32 val; - u32 reg; - u32 dev = pDCTstat->dev_dct; - u32 reg_off; - u8 ret = 0; - - if (!pDCTstat->GangedMode) { - reg_off = 0x100 * Channel; - } else { - reg_off = 0; - } - - if (ChipSel < MAX_CS_SUPPORTED) { - reg = 0x40 + (ChipSel << 2) + reg_off; - val = Get_NB32(dev, reg); - if (val & (1 << 0)) - ret = 1; - } - - return ret; -} - - -/* proc_CLFLUSH_D located in mct_gcc.h */ - - -static void WriteDQSTestPattern_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, - u32 TestAddr_lo) -{ - /* Write a pattern of 72 bit times (per DQ), to test dram functionality. - * The pattern is a stress pattern which exercises both ISI and - * crosstalk. The number of cache lines to fill is dependent on DCT - * width mode and burstlength. - * Mode BL Lines Pattern no. - * ----+---+------------------- - * 64 4 9 0 - * 64 8 9 0 - * 64M 4 9 0 - * 64M 8 9 0 - * 128 4 18 1 - * 128 8 N/A - - */ - - if (pDCTstat->Pattern == 0) - WriteL9TestPattern_D(pDCTstat, TestAddr_lo); - else - WriteL18TestPattern_D(pDCTstat, TestAddr_lo); -} - - -static void WriteL18TestPattern_D(struct DCTStatStruc *pDCTstat, - u32 TestAddr_lo) -{ - u8 *buf; - - buf = (u8 *)pDCTstat->PtrPatternBufA; - WriteLNTestPattern(TestAddr_lo, buf, 18); - -} - - -static void WriteL9TestPattern_D(struct DCTStatStruc *pDCTstat, - u32 TestAddr_lo) -{ - u8 *buf; - - buf = (u8 *)pDCTstat->PtrPatternBufA; - WriteLNTestPattern(TestAddr_lo, buf, 9); -} - - - -static u8 CompareDQSTestPattern_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u32 addr_lo) -{ - /* Compare a pattern of 72 bit times (per DQ), to test dram functionality. - * The pattern is a stress pattern which exercises both ISI and - * crosstalk. The number of cache lines to fill is dependent on DCT - * width mode and burstlength. - * Mode BL Lines Pattern no. - * ----+---+------------------- - * 64 4 9 0 - * 64 8 9 0 - * 64M 4 9 0 - * 64M 8 9 0 - * 128 4 18 1 - * 128 8 N/A - - */ - - u32 *test_buf; - u8 bitmap; - u8 bytelane; - u8 i; - u32 value; - u8 j; - u32 value_test; - u8 pattern, channel; - - pattern = pDCTstat->Pattern; - channel = pDCTstat->Channel; - test_buf = (u32 *)pDCTstat->PtrPatternBufA; - - if (pattern && channel) { - addr_lo += 8; //second channel - test_buf += 2; - } - - bytelane = 0; /* bytelane counter */ - bitmap = 0xFF; /* bytelane test bitmap, 1 = pass */ - for (i = 0; i < (9 * 64 / 4); i++) { /* sizeof testpattern. /4 due to next loop */ - value = read32_fs(addr_lo); - value_test = *test_buf; - - print_debug_dqs_pair("\t\t\t\t\t\ttest_buf = ", (u32)test_buf, " value = ", value_test, 7); - print_debug_dqs_pair("\t\t\t\t\t\ttaddr_lo = ", addr_lo, " value = ", value, 7); - - for (j = 0; j < (4 * 8); j += 8) { /* go through a 32bit data, on 1 byte step. */ - if (((value >> j) & 0xff) != ((value_test >> j) & 0xff)) { - bitmap &= ~(1 << bytelane); - } - - bytelane++; - bytelane &= 0x7; - } - - print_debug_dqs("\t\t\t\t\t\tbitmap = ", bitmap, 7); - - if (!bitmap) - break; - - if (bytelane == 0) { - if (pattern == 1) { //dual channel - addr_lo += 8; //skip over other channel's data - test_buf += 2; - } - } - addr_lo += 4; - test_buf += 1; - } - - return bitmap; -} - - -static void FlushDQSTestPattern_D(struct DCTStatStruc *pDCTstat, - u32 addr_lo) -{ - /* Flush functions in mct_gcc.h */ - if (pDCTstat->Pattern == 0) { - FlushDQSTestPattern_L9(addr_lo); - } else { - FlushDQSTestPattern_L18(addr_lo); - } -} - -void SetTargetWTIO_D(u32 TestAddr) -{ - u32 lo, hi; - hi = TestAddr >> 24; - lo = TestAddr << 8; - _WRMSR(MTRR_IORR0_BASE, lo, hi); /* IORR0 Base */ - hi = 0xFF; - lo = 0xFC000800; /* 64MB Mask */ - _WRMSR(MTRR_IORR0_MASK, lo, hi); /* IORR0 Mask */ -} - - -void ResetTargetWTIO_D(void) -{ - u32 lo, hi; - - hi = 0; - lo = 0; - _WRMSR(MTRR_IORR0_MASK, lo, hi); // IORR0 Mask -} - - -static void ReadDQSTestPattern_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, - u32 TestAddr_lo) -{ - /* Read a pattern of 72 bit times (per DQ), to test dram functionality. - * The pattern is a stress pattern which exercises both ISI and - * crosstalk. The number of cache lines to fill is dependent on DCT - * width mode and burstlength. - * Mode BL Lines Pattern no. - * ----+---+------------------- - * 64 4 9 0 - * 64 8 9 0 - * 64M 4 9 0 - * 64M 8 9 0 - * 128 4 18 1 - * 128 8 N/A - - */ - if (pDCTstat->Pattern == 0) - ReadL9TestPattern(TestAddr_lo); - else - ReadL18TestPattern(TestAddr_lo); - _MFENCE; -} - - -u32 SetUpperFSbase(u32 addr_hi) -{ - /* Set the upper 32-bits of the Base address, 4GB aligned) for the - * FS selector. - */ - - u32 lo, hi; - u32 addr; - lo = 0; - hi = addr_hi>>24; - addr = FS_Base; - _WRMSR(addr, lo, hi); - return addr_hi << 8; -} - - -void ResetDCTWrPtr_D(u32 dev, u32 index_reg, u32 index) -{ - u32 val; - - val = Get_NB32_index_wait(dev, index_reg, index); - Set_NB32_index_wait(dev, index_reg, index, val); -} - - -/* mctEngDQSwindow_Save_D not required with arrays */ - - -void mct_TrainDQSPos_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - u8 Node; - u8 ChipSel; - struct DCTStatStruc *pDCTstat; - - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - pDCTstat = pDCTstatA + Node; - if (pDCTstat->DCTSysLimit) { - /* when DCT speed >= 400MHz, we only support 2 DIMMs - * and we have two sets registers for DIMM0 and DIMM1 so - * here we must traning DQSRd/WrPos for DIMM0 and DIMM1 - */ - if (pDCTstat->Speed >= 4) { - pDCTstat->Status |= (1 << SB_Over400MHz); - } - for (ChipSel = 0; ChipSel < MAX_CS_SUPPORTED; ChipSel += 2) { - TrainDQSRdWrPos_D(pMCTstat, pDCTstat, ChipSel); - SetEccDQSRdWrPos_D(pMCTstat, pDCTstat, ChipSel); - } - } - } -} - - -/* mct_BeforeTrainDQSRdWrPos_D - * Function is inline. - */ - -u8 mct_DisableDimmEccEn_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u8 _DisableDramECC = 0; - u32 val; - u32 reg; - u32 dev; - - /*Disable ECC correction of reads on the dram bus. */ - - dev = pDCTstat->dev_dct; - reg = 0x90; - val = Get_NB32(dev, reg); - if (val & (1<<DimmEcEn)) { - _DisableDramECC |= 0x01; - val &= ~(1<<DimmEcEn); - Set_NB32(dev, reg, val); - } - if (!pDCTstat->GangedMode) { - reg = 0x190; - val = Get_NB32(dev, reg); - if (val & (1<<DimmEcEn)) { - _DisableDramECC |= 0x02; - val &= ~(1<<DimmEcEn); - Set_NB32(dev, reg, val); - } - } - return _DisableDramECC; -} - - - -void mct_EnableDimmEccEn_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 _DisableDramECC) -{ - - u32 val; - u32 reg; - u32 dev; - - /* Enable ECC correction if it was previously disabled */ - - dev = pDCTstat->dev_dct; - - if ((_DisableDramECC & 0x01) == 0x01) { - reg = 0x90; - val = Get_NB32(dev, reg); - val |= (1<<DimmEcEn); - Set_NB32(dev, reg, val); - } - if ((_DisableDramECC & 0x02) == 0x02) { - reg = 0x190; - val = Get_NB32(dev, reg); - val |= (1<<DimmEcEn); - Set_NB32(dev, reg, val); - } -} - - -static void mct_SetDQSDelayCSR_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 ChipSel) -{ - u8 ByteLane; - u32 val; - u32 index_reg = 0x98 + 0x100 * pDCTstat->Channel; - u8 shift; - u32 dqs_delay = (u32)pDCTstat->DQSDelay; - u32 dev = pDCTstat->dev_dct; - u32 index; - - ByteLane = pDCTstat->ByteLane; - - /* Channel is offset */ - if (ByteLane < 4) { - index = 1; - } else if (ByteLane <8) { - index = 2; - } else { - index = 3; - } - - if (pDCTstat->Direction == DQS_READDIR) { - index += 4; - } - - /* get the proper register index */ - shift = ByteLane % 4; - shift <<= 3; /* get bit position of bytelane, 8 bit */ - - if (pDCTstat->Status & (1 << SB_Over400MHz)) { - index += (ChipSel >> 1) * 0x100; /* if logical DIMM1/DIMM3 */ - } - - val = Get_NB32_index_wait(dev, index_reg, index); - val &= ~(0x7f << shift); - val |= (dqs_delay << shift); - Set_NB32_index_wait(dev, index_reg, index, val); -} - - -static void mct_SetDQSDelayAllCSR_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, - u8 cs_start) -{ - u8 ByteLane; - u8 ChipSel = cs_start; - - - for (ChipSel = cs_start; ChipSel < (cs_start + 2); ChipSel++) { - if (mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, pDCTstat->Channel, ChipSel)) { - for (ByteLane = 0; ByteLane < 8; ByteLane++) { - pDCTstat->ByteLane = ByteLane; - mct_SetDQSDelayCSR_D(pMCTstat, pDCTstat, ChipSel); - } - } - } -} - - -u8 mct_RcvrRankEnabled_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, - u8 Channel, u8 ChipSel) -{ - u8 ret; - - ret = ChipSelPresent_D(pMCTstat, pDCTstat, Channel, ChipSel); - return ret; -} - - -u32 mct_GetRcvrSysAddr_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, - u8 channel, u8 receiver, u8 *valid) -{ - return mct_GetMCTSysAddr_D(pMCTstat, pDCTstat, channel, receiver, valid); -} - - -u32 mct_GetMCTSysAddr_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, - u8 Channel, u8 receiver, u8 *valid) -{ - u32 val; - u32 reg_off = 0; - u32 reg; - u32 dword; - u32 dev = pDCTstat->dev_dct; - - *valid = 0; - - - if (!pDCTstat->GangedMode) { - reg_off = 0x100 * Channel; - } - - /* get the local base addr of the chipselect */ - reg = 0x40 + (receiver << 2) + reg_off; - val = Get_NB32(dev, reg); - - val &= ~0x0F; - - /* unganged mode DCT0+DCT1, sys addr of DCT1 = node - * base+DctSelBaseAddr+local ca base*/ - if ((Channel) && (pDCTstat->GangedMode == 0) && (pDCTstat->DIMMValidDCT[0] > 0)) { - reg = 0x110; - dword = Get_NB32(dev, reg); - dword &= 0xfffff800; - dword <<= 8; /* scale [47:27] of F2x110[31:11] to [39:8]*/ - val += dword; - - /* if DCTSelBaseAddr < Hole, and eax > HoleBase, then add Hole size to test address */ - if ((val >= pDCTstat->DCTHoleBase) && (pDCTstat->DCTHoleBase > dword)) { - dword = (~(pDCTstat->DCTHoleBase >> (24 - 8)) + 1) & 0xFF; - dword <<= (24 - 8); - val += dword; - } - } else { - /* sys addr = node base+local cs base */ - val += pDCTstat->DCTSysBase; - - /* New stuff */ - if (pDCTstat->DCTHoleBase && (val >= pDCTstat->DCTHoleBase)) { - val -= pDCTstat->DCTSysBase; - dword = Get_NB32(pDCTstat->dev_map, 0xF0); /* get Hole Offset */ - val += (dword & 0x0000ff00) << (24-8-8); - } - } - - /* New stuff */ - val += ((1 << 21) >> 8); /* Add 2MB offset to avoid compat area */ - if (val >= MCT_TRNG_KEEPOUT_START) { - while (val < MCT_TRNG_KEEPOUT_END) - val += (1 << (15-8)); /* add 32K */ - } - - /* Add a node seed */ - val += (((1 * pDCTstat->Node_ID) << 20) >> 8); /* Add 1MB per node to avoid aliases */ - - /* HW remap disabled? */ - if (!(pDCTstat->Status & (1 << SB_HWHole))) { - if (!(pDCTstat->Status & (1 << SB_SWNodeHole))) { - /* SW memhole disabled */ - u32 lo, hi; - _RDMSR(TOP_MEM, &lo, &hi); - lo >>= 8; - if ((val >= lo) && (val < _4GB_RJ8)) { - val = 0; - *valid = 0; - goto exitGetAddr; - } else { - *valid = 1; - goto exitGetAddrWNoError; - } - } else { - *valid = 1; - goto exitGetAddrWNoError; - } - } else { - *valid = 1; - goto exitGetAddrWNoError; - } - -exitGetAddrWNoError: - - /* Skip if Address is in UMA region */ - dword = pMCTstat->Sub4GCacheTop; - dword >>= 8; - if (dword != 0) { - if ((val >= dword) && (val < _4GB_RJ8)) { - val = 0; - *valid = 0; - } else { - *valid = 1; - } - } - print_debug_dqs("mct_GetMCTSysAddr_D: receiver ", receiver, 2); - print_debug_dqs("mct_GetMCTSysAddr_D: Channel ", Channel, 2); - print_debug_dqs("mct_GetMCTSysAddr_D: base_addr ", val, 2); - print_debug_dqs("mct_GetMCTSysAddr_D: valid ", *valid, 2); - print_debug_dqs("mct_GetMCTSysAddr_D: status ", pDCTstat->Status, 2); - print_debug_dqs("mct_GetMCTSysAddr_D: HoleBase ", pDCTstat->DCTHoleBase, 2); - print_debug_dqs("mct_GetMCTSysAddr_D: Cachetop ", pMCTstat->Sub4GCacheTop, 2); - -exitGetAddr: - return val; -} - - -void mct_Write1LTestPattern_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, - u32 TestAddr, u8 pattern) -{ - - u8 *buf; - - /* Issue the stream of writes. When F2x11C[MctWrLimit] is reached - * (or when F2x11C[FlushWr] is set again), all the writes are written - * to DRAM. - */ - - SetUpperFSbase(TestAddr); - - if (pattern) - buf = (u8 *)pDCTstat->PtrPatternBufB; - else - buf = (u8 *)pDCTstat->PtrPatternBufA; - - WriteLNTestPattern(TestAddr << 8, buf, 1); -} - - -void mct_Read1LTestPattern_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u32 addr) -{ - /* BIOS issues the remaining (Ntrain - 2) reads after checking that - * F2x11C[PrefDramTrainMode] is cleared. These reads must be to - * consecutive cache lines (i.e., 64 bytes apart) and must not cross - * a naturally aligned 4KB boundary. These reads hit the prefetches and - * read the data from the prefetch buffer. - */ - - /* get data from DIMM */ - SetUpperFSbase(addr); - - /* 1st move causes read fill (to exclusive or shared)*/ - read32_fs(addr << 8); -} diff --git a/src/northbridge/amd/amdmct/mct/mctecc_d.c b/src/northbridge/amd/amdmct/mct/mctecc_d.c deleted file mode 100644 index 8eb7bf54b7..0000000000 --- a/src/northbridge/amd/amdmct/mct/mctecc_d.c +++ /dev/null @@ -1,314 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007-2008 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.h" - -static void setSyncOnUnEccEn_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA); -#ifdef UNUSED_CODE -static u32 GetScrubAddr_D(u32 Node); -#endif -static u8 isDramECCEn_D(struct DCTStatStruc *pDCTstat); - - -/* Initialize ECC modes of Integrated Dram+Memory Controllers of a network of - * Hammer processors. Use Dram background scrubber to fast initialize ECC bits - * of all dram. - * - * Notes: - * - * Order that items are set: - * 1. eccen bit in NB - * 2. Scrub Base - * 3. Temp Node Base - * 4. Temp Node Limit - * 5. Redir bit in NB - * 6. Scrub CTL - * - * Conditions for setting background scrubber. - * 1. node is present - * 2. node has dram functioning (WE = RE = 1) - * 3. all eccdimms (or bit 17 of offset 90,fn 2) - * 4. no chip-select gap exists - * - * The dram background scrubber is used under very controlled circumstances to - * initialize all the ECC bits on the DIMMs of the entire dram address map - * (including hidden or lost dram and dram above 4GB). We will turn the scrub - * rate up to maximum, which should clear 4GB of dram in about 2.7 seconds. - * We will activate the scrubbers of all nodes with ecc dram and let them run in - * parallel, thereby reducing even further the time required to condition dram. - * Finally, we will go through each node and either disable background scrubber, - * or set the scrub rate to the user setup specified rate. - * - * To allow the NB to scrub, we need to wait a time period long enough to - * guarantee that the NB scrubs the entire dram on its node. Do do this, we - * simply sample the scrub ADDR once, for an initial value, then we sample and poll until the polled value of scrub ADDR - * has wrapped around at least once: Scrub ADDRi+1 < Scrub ADDRi. Since we let all - * Nodes run in parallel, we need to guarantee that all nodes have wrapped. To do - * this efficiently, we need only to sample one of the nodes, the node with the - * largest ammount of dram populated is the one which will take the longest amount - * of time (the scrub rate is set to max, the same rate, on all nodes). So, - * during setup of scrub Base, we determine how much memory and which node has - * the largest memory installed. - * - * Scrubbing should not ordinarily be enabled on a Node with a chip-select gap - * (aka SW memhole, cs hoisting, etc..).To init ECC memory on this node, the - * scrubber is used in two steps. First, the Dram Limit for the node is adjusted - * down to the bottom of the gap, and that ECC dram is initialized. Second, the - * original Limit is restored, the Scrub base is set to 4GB, and scrubber is - * allowed to run until the Scrub Addr wraps around to zero. - */ -u8 ECCInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA) -{ - u8 Node; - u8 AllECC; - u16 OB_NBECC; - u32 curBase; - u16 OB_ECCRedir; - u32 LDramECC; - u32 OF_ScrubCTL; - u8 MemClrECC; - - u32 dev; - u32 reg; - u32 val; - u16 nvbits; - - mctHookBeforeECC(); - - /* Construct these booleans, based on setup options, for easy handling - later in this procedure */ - OB_NBECC = mctGet_NVbits(NV_NBECC); /* MCA ECC (MCE) enable bit */ - - OB_ECCRedir = mctGet_NVbits(NV_ECCRedir); /* ECC Redirection */ - - mctGet_NVbits(NV_ChipKill); /* ECC Chip-kill mode */ - - OF_ScrubCTL = 0; /* Scrub CTL for Dcache, L2, and dram */ - nvbits = mctGet_NVbits(NV_DCBKScrub); - mct_AdjustScrub_D(pDCTstatA, &nvbits); - OF_ScrubCTL |= (u32) nvbits << 16; - - nvbits = mctGet_NVbits(NV_L2BKScrub); - OF_ScrubCTL |= (u32) nvbits << 8; - - nvbits = mctGet_NVbits(NV_DramBKScrub); - OF_ScrubCTL |= nvbits; - - AllECC = 1; - MemClrECC = 0; - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - LDramECC = 0; - if (NodePresent_D(Node)) { /*If Node is present */ - dev = pDCTstat->dev_map; - reg = 0x40+(Node << 3); /* Dram Base Node 0 + index */ - val = Get_NB32(dev, reg); - - /* WE/RE is checked */ - if ((val & 3) == 3) { /* Node has dram populated */ - /* Negate 'all nodes/dimms ECC' flag if non ecc - memory populated */ - if (pDCTstat->Status & (1 << SB_ECCDIMMs)) { - LDramECC = isDramECCEn_D(pDCTstat); - if (pDCTstat->ErrCode != SC_RunningOK) { - pDCTstat->Status &= ~(1 << SB_ECCDIMMs); - if (!OB_NBECC) { - pDCTstat->ErrStatus |= (1 << SB_DramECCDis); - } - AllECC = 0; - LDramECC =0; - } - } else { - AllECC = 0; - } - if (LDramECC) { /* if ECC is enabled on this dram */ - if (OB_NBECC) { - mct_EnableDatIntlv_D(pMCTstat, pDCTstat); - dev = pDCTstat->dev_nbmisc; - reg =0x44; /* MCA NB Configuration */ - val = Get_NB32(dev, reg); - val |= 1 << 22; /* EccEn */ - Set_NB32(dev, reg, val); - DCTMemClr_Init_D(pMCTstat, pDCTstat); - MemClrECC = 1; - print_tx(" ECC enabled on node: ", Node); - } - } /* this node has ECC enabled dram */ - } else { - LDramECC = 0; - } /* Node has Dram */ - - if (MemClrECC) { - MCTMemClrSync_D(pMCTstat, pDCTstatA); - } - } /* if Node present */ - } - - if (AllECC) - pMCTstat->GStatus |= 1 << GSB_ECCDIMMs; - else - pMCTstat->GStatus &= ~(1 << GSB_ECCDIMMs); - - /* Program the Dram BKScrub CTL to the proper (user selected) value.*/ - /* Reset MC4_STS. */ - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - LDramECC = 0; - if (NodePresent_D(Node)) { /* If Node is present */ - reg = 0x40+(Node << 3); /* Dram Base Node 0 + index */ - val = Get_NB32(pDCTstat->dev_map, reg); - curBase = val & 0xffff0000; - /*WE/RE is checked because memory config may have been */ - if ((val & 3) == 3) { /* Node has dram populated */ - if (isDramECCEn_D(pDCTstat)) { /* if ECC is enabled on this dram */ - dev = pDCTstat->dev_nbmisc; - val = curBase << 8; - if (OB_ECCRedir) { - val |= (1<<0); /* enable redirection */ - } - Set_NB32(dev, 0x5C, val); /* Dram Scrub Addr Low */ - val = curBase >> 24; - Set_NB32(dev, 0x60, val); /* Dram Scrub Addr High */ - Set_NB32(dev, 0x58, OF_ScrubCTL); /*Scrub Control */ - - /* Divisor should not be set deeper than - * divide by 16 when Dcache scrubber or - * L2 scrubber is enabled. - */ - if ((OF_ScrubCTL & (0x1F << 16)) || (OF_ScrubCTL & (0x1F << 8))) { - val = Get_NB32(dev, 0x84); - if ((val & 0xE0000000) > 0x80000000) { /* Get F3x84h[31:29]ClkDivisor for C1 */ - val &= 0x1FFFFFFF; /* If ClkDivisor is deeper than divide-by-16 */ - val |= 0x80000000; /* set it to divide-by-16 */ - Set_NB32(dev, 0x84, val); - } - } - } /* this node has ECC enabled dram */ - } /*Node has Dram */ - } /*if Node present */ - } - - if (mctGet_NVbits(NV_SyncOnUnEccEn)) - setSyncOnUnEccEn_D(pMCTstat, pDCTstatA); - - mctHookAfterECC(); - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - if (NodePresent_D(Node)) { - print_tx("ECCInit: Node ", Node); - print_tx("ECCInit: Status ", pDCTstat->Status); - print_tx("ECCInit: ErrStatus ", pDCTstat->ErrStatus); - print_tx("ECCInit: ErrCode ", pDCTstat->ErrCode); - print_t("ECCInit: Done\n"); - } - } - return MemClrECC; -} - - -static void setSyncOnUnEccEn_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - u32 Node; - u32 reg; - u32 dev; - u32 val; - - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - if (NodePresent_D(Node)) { /* If Node is present*/ - reg = 0x40+(Node << 3); /* Dram Base Node 0 + index*/ - val = Get_NB32(pDCTstat->dev_map, reg); - /*WE/RE is checked because memory config may have been*/ - if ((val & 3) == 3) { /* Node has dram populated*/ - if (isDramECCEn_D(pDCTstat)) { - /*if ECC is enabled on this dram*/ - dev = pDCTstat->dev_nbmisc; - reg = 0x44; /* MCA NB Configuration*/ - val = Get_NB32(dev, reg); - val |= (1 << SyncOnUcEccEn); - Set_NB32(dev, reg, val); - } - } /* Node has Dram*/ - } /* if Node present*/ - } -} - -#ifdef UNUSED_CODE -static u32 GetScrubAddr_D(u32 Node) -{ - /* Get the current 40-bit Scrub ADDR address, scaled to 32-bits, - * of the specified Node. - */ - - u32 reg; - u32 regx; - u32 lo, hi; - u32 val; - u32 dev = PA_NBMISC(Node); - - - reg = 0x60; /* Scrub Addr High */ - hi = Get_NB32(dev, reg); - - regx = 0x5C; /* Scrub Addr Low */ - lo = Get_NB32(dev, regx); - /* Scrub Addr High again, detect 32-bit wrap */ - val = Get_NB32(dev, reg); - if (val != hi) { - hi = val; /* Scrub Addr Low again, if wrap occurred */ - lo = Get_NB32(dev, regx); - } - - val = hi << 24; - val |= lo >> 8; - - return val; /* ScrubAddr[39:8] */ -} -#endif - -static u8 isDramECCEn_D(struct DCTStatStruc *pDCTstat) -{ - u32 reg; - u32 val; - u8 i; - u32 dev = pDCTstat->dev_dct; - u8 ch_end; - u8 isDimmECCEn = 0; - - if (pDCTstat->GangedMode) { - ch_end = 1; - } else { - ch_end = 2; - } - for (i = 0; i < ch_end; i++) { - if (pDCTstat->DIMMValidDCT[i] > 0) { - reg = 0x90 + i * 0x100; /* Dram Config Low */ - val = Get_NB32(dev, reg); - if (val & (1 << DimmEcEn)) { - /* set local flag 'dram ecc capable' */ - isDimmECCEn = 1; - break; - } - } - } - return isDimmECCEn; -} diff --git a/src/northbridge/amd/amdmct/mct/mctgr.c b/src/northbridge/amd/amdmct/mct/mctgr.c deleted file mode 100644 index 41a479b21e..0000000000 --- a/src/northbridge/amd/amdmct/mct/mctgr.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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. - */ - - -static const u8 Tab_GRCLKDis[] = { 8,0,8,8,0,0,8,0 }; - - -u32 mct_AdjustMemClkDis_GR(struct DCTStatStruc *pDCTstat, u32 dct, - u32 DramTimingLo) -{ - /* Greayhound format -> Griffin format */ - u32 NewDramTimingLo; - u32 dev = pDCTstat->dev_dct; - u32 reg; - u32 reg_off = 0x100 * dct; - u32 val; - int i; - - DramTimingLo = val; - /* Dram Timing Low (owns Clock Enable bits) */ - NewDramTimingLo = Get_NB32(dev, 0x88 + reg_off); - if (mctGet_NVbits(NV_AllMemClks) == 0) { - /*Special Jedec SPD diagnostic bit - "enable all clocks"*/ - if (!(pDCTstat->Status & (1<<SB_DiagClks))) { - for (i = 0; i < MAX_DIMMS_SUPPORTED; i++) { - val = Tab_GRCLKDis[i]; - if (val < 8) { - if (!(pDCTstat->DIMMValidDCT[dct] & (1<<val))) { - /* disable memclk */ - NewDramTimingLo |= (1<<(i+1)); - } - } - } - } - } - DramTimingLo &= ~(0xff<<24); - DramTimingLo |= NewDramTimingLo & (0xff<<24); - DramTimingLo &= (0x4d<<24); /* FIXME - enable all MemClks for now */ - - return DramTimingLo; -} - - -u32 mct_AdjustDramConfigLo_GR(struct DCTStatStruc *pDCTstat, u32 dct, u32 val) -{ - /* Greayhound format -> Griffin format */ - /*FIXME - BurstLength32 must be 0 when F3x44[DramEccEn]=1. */ -/* - ; mov cx,PA_NBMISC+44h ;MCA NB Configuration - ; call Get_NB32n_D - ; bt eax,22 ;EccEn - ; .if (CARRY?) - ; btr eax,BurstLength32 - ; .endif -*/ - return val; -} - - -void mct_AdjustMemHoist_GR(struct DCTStatStruc *pDCTstat, u32 base, u32 HoleSize) -{ - u32 val; - if (base >= pDCTstat->DCTHoleBase) { - u32 dev = pDCTstat->dev_dct; - base += HoleSize; - base >>= 27 - 8; - val = Get_NB32(dev, 0x110); - val &= ~(0xfff<<11); - val |= (base & 0xfff)<<11; - Set_NB32(dev, 0x110, val); - } -} diff --git a/src/northbridge/amd/amdmct/mct/mcthdi.c b/src/northbridge/amd/amdmct/mct/mcthdi.c deleted file mode 100644 index b67282ef60..0000000000 --- a/src/northbridge/amd/amdmct/mct/mcthdi.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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.h" - -void mct_DramInit_Hw_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u32 val; - u32 reg; - u32 dev = pDCTstat->dev_dct; - - /*flag for selecting HW/SW DRAM Init HW DRAM Init */ - reg = 0x90 + 0x100 * dct; /*DRAM Configuration Low */ - val = Get_NB32(dev, reg); - val |= (1<<InitDram); - Set_NB32(dev, reg, val); -} diff --git a/src/northbridge/amd/amdmct/mct/mctmtr_d.c b/src/northbridge/amd/amdmct/mct/mctmtr_d.c deleted file mode 100644 index 883ab651cc..0000000000 --- a/src/northbridge/amd/amdmct/mct/mctmtr_d.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007-2008 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.h" -#include <cpu/amd/mtrr.h> -#include <cpu/x86/mtrr.h> - -static void SetMTRRrangeWB_D(u32 Base, u32 *pLimit, u32 *pMtrrAddr); -static void SetMTRRrange_D(u32 Base, u32 *pLimit, u32 *pMtrrAddr, u16 MtrrType); - -void CPUMemTyping_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - /* BSP only. Set the fixed MTRRs for common legacy ranges. - * Set TOP_MEM and TOM2. - * Set some variable MTRRs with WB Uncacheable type. - */ - - u32 Bottom32bIO, Bottom40bIO, Cache32bTOP; - u32 val; - u32 addr; - u32 lo, hi; - - /* Set temporary top of memory from Node structure data. - * Adjust temp top of memory down to accommodate 32-bit IO space. - * Bottom40bIO = top of memory, right justified 8 bits - * (defines dram versus IO space type) - * Bottom32bIO = sub 4GB top of memory, right justified 8 bits - * (defines dram versus IO space type) - * Cache32bTOP = sub 4GB top of WB cacheable memory, - * right justified 8 bits - */ - - val = mctGet_NVbits(NV_BottomIO); - if (val == 0) - val++; - - Bottom32bIO = val << (24-8); - - val = pMCTstat->SysLimit + 1; - if (val <= _4GB_RJ8) { - Bottom40bIO = 0; - if (Bottom32bIO >= val) - Bottom32bIO = val; - } else { - Bottom40bIO = val; - } - - Cache32bTOP = Bottom32bIO; - - /*====================================================================== - Set default values for CPU registers - ======================================================================*/ - - /* NOTE : For coreboot, we don't need to set mtrr enables here because - they are still enable from cache_as_ram.inc */ - - addr = MTRR_FIX_64K_00000; - lo = 0x1E1E1E1E; - hi = lo; - _WRMSR(addr, lo, hi); /* 0 - 512K = WB Mem */ - addr = MTRR_FIX_16K_80000; - _WRMSR(addr, lo, hi); /* 512K - 640K = WB Mem */ - - /*====================================================================== - Set variable MTRR values - ======================================================================*/ - /* NOTE: for coreboot change from 0x200 to 0x204: coreboot is using - 0x200, 0x201 for [1M, CONFIG_TOP_MEM) - 0x202, 0x203 for ROM Caching - */ - addr = MTRR_PHYS_BASE(2); /* MTRR phys base 2*/ - /* use TOP_MEM as limit*/ - /* Limit = TOP_MEM|TOM2*/ - /* Base = 0*/ - print_tx("\t CPUMemTyping: Cache32bTOP:", Cache32bTOP); - SetMTRRrangeWB_D(0, &Cache32bTOP, &addr); - /* Base */ - /* Limit */ - /* MtrrAddr */ - if (addr == -1) /* ran out of MTRRs?*/ - pMCTstat->GStatus |= 1<<GSB_MTRRshort; - - pMCTstat->Sub4GCacheTop = Cache32bTOP<<8; - - /*====================================================================== - Set TOP_MEM and TOM2 CPU registers - ======================================================================*/ - addr = TOP_MEM; - lo = Bottom32bIO<<8; - hi = Bottom32bIO>>24; - _WRMSR(addr, lo, hi); - print_tx("\t CPUMemTyping: Bottom32bIO:", Bottom32bIO); - print_tx("\t CPUMemTyping: Bottom40bIO:", Bottom40bIO); - if (Bottom40bIO) { - hi = Bottom40bIO >> 24; - lo = Bottom40bIO << 8; - if (mctSetNodeBoundary_D()) - lo &= 0xC0000000; - addr += 3; /* TOM2 */ - _WRMSR(addr, lo, hi); - } - addr = SYSCFG_MSR; /* SYS_CFG */ - _RDMSR(addr, &lo, &hi); - if (Bottom40bIO) { - lo |= SYSCFG_MSR_TOM2En; /* MtrrTom2En = 1 */ - lo |= SYSCFG_MSR_TOM2WB; /* Tom2ForceMemTypeWB */ - } else { - lo &= ~SYSCFG_MSR_TOM2En; /* MtrrTom2En = 0 */ - lo &= ~SYSCFG_MSR_TOM2WB; /* Tom2ForceMemTypeWB */ - } - _WRMSR(addr, lo, hi); -} - - -static void SetMTRRrangeWB_D(u32 Base, u32 *pLimit, u32 *pMtrrAddr) -{ - /*set WB type*/ - SetMTRRrange_D(Base, pLimit, pMtrrAddr, 6); -} - - -static void SetMTRRrange_D(u32 Base, u32 *pLimit, u32 *pMtrrAddr, u16 MtrrType) -{ - /* Program MTRRs to describe given range as given cache type. - * Use MTRR pairs starting with the given MTRRphys Base address, - * and use as many as is required up to (excluding) MSR 020C, which - * is reserved for OS. - * - * "Limit" in the context of this procedure is not the numerically - * correct limit, but rather the Last address+1, for purposes of coding - * efficiency and readability. Size of a region is then Limit-Base. - * - * 1. Size of each range must be a power of two - * 2. Each range must be naturally aligned (Base is same as size) - * - * There are two code paths: the ascending path and descending path - * (analogous to bsf and bsr), where the next limit is a function of the - * next set bit in a forward or backward sequence of bits (as a function - * of the Limit). We start with the ascending path, to ensure that - * regions are naturally aligned, then we switch to the descending path - * to maximize MTRR usage efficiency. Base = 0 is a special case where we - * start with the descending path. Correct Mask for region is - * 2comp(Size-1)-1, which is 2comp(Limit-Base-1)-1 - */ - - u32 curBase, curLimit, curSize; - u32 val, valx; - u32 addr; - - val = curBase = Base; - curLimit = *pLimit; - addr = *pMtrrAddr; - while ((addr >= 0x200) && (addr < 0x20C) && (val < *pLimit)) { - /* start with "ascending" code path */ - /* alignment (largest block size)*/ - valx = 1 << bsf(curBase); - curSize = valx; - - /* largest legal limit, given current non-zero range Base*/ - valx += curBase; - if ((curBase == 0) || (*pLimit < valx)) { - /* flop direction to "descending" code path*/ - valx = 1<<bsr(*pLimit - curBase); - curSize = valx; - valx += curBase; - } - curLimit = valx; /*eax = curBase, edx = curLimit*/ - valx = val>>24; - val <<= 8; - - /* now program the MTRR */ - val |= MtrrType; /* set cache type (UC or WB)*/ - _WRMSR(addr, val, valx); /* prog. MTRR with current region Base*/ - val = ((~(curSize - 1))+1) - 1; /* Size-1*/ /*Mask = 2comp(Size-1)-1*/ - valx = (val >> 24) | (0xff00); /* GH have 48 bits addr */ - val <<= 8; - val |= (1 << 11); /* set MTRR valid*/ - addr++; - _WRMSR(addr, val, valx); /* prog. MTRR with current region Mask*/ - val = curLimit; - curBase = val; /* next Base = current Limit (loop exit)*/ - addr++; /* next MTRR pair addr */ - } - if (val < *pLimit) { - *pLimit = val; - addr = -1; - } - *pMtrrAddr = addr; -} - -void UMAMemTyping_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA) -{ -/* UMA memory size may need splitting the MTRR configuration into two - Before training use NB_BottomIO or the physical memory size to set the MTRRs. - After training, add UMAMemTyping function to reconfigure the MTRRs based on - NV_BottomUMA (for UMA systems only). - This two-step process allows all memory to be cached for training -*/ - u32 Bottom32bIO, Cache32bTOP; - u32 val; - u32 addr; - u32 lo, hi; - - /*====================================================================== - * Adjust temp top of memory down to accommodate UMA memory start - *======================================================================*/ - /* Bottom32bIO = sub 4GB top of memory, right justified 8 bits - * (defines dram versus IO space type) - * Cache32bTOP = sub 4GB top of WB cacheable memory, right justified 8 bits */ - - Bottom32bIO = pMCTstat->Sub4GCacheTop >> 8; - - val = mctGet_NVbits(NV_BottomUMA); - if (val == 0) - val++; - - val <<= (24-8); - if (val < Bottom32bIO) { - Cache32bTOP = val; - pMCTstat->Sub4GCacheTop = val; - - /*====================================================================== - * Clear variable MTRR values - *======================================================================*/ - addr = MTRR_PHYS_BASE(0); - lo = 0; - hi = lo; - while (addr < MTRR_PHYS_BASE(6)) { - _WRMSR(addr, lo, hi); /* prog. MTRR with current region Mask */ - addr++; /* next MTRR pair addr */ - } - - /*====================================================================== - * Set variable MTRR values - *======================================================================*/ - print_tx("\t UMAMemTyping_D: Cache32bTOP:", Cache32bTOP); - SetMTRRrangeWB_D(0, &Cache32bTOP, &addr); - if (addr == -1) /* ran out of MTRRs?*/ - pMCTstat->GStatus |= 1<<GSB_MTRRshort; - } -} diff --git a/src/northbridge/amd/amdmct/mct/mctndi_d.c b/src/northbridge/amd/amdmct/mct/mctndi_d.c deleted file mode 100644 index 3f09f4a472..0000000000 --- a/src/northbridge/amd/amdmct/mct/mctndi_d.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * 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.h" - -void InterleaveNodes_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - - /* Applies Node memory interleaving if enabled and if all criteria are met. */ - u8 Node; - u32 Base; - u32 MemSize, MemSize0 = 0; - u32 Dct0MemSize = 0, DctSelBase, DctSelBaseOffset = 0; - u8 Nodes; - u8 NodesWmem; - u8 DoIntlv; - u8 _NdIntCap; - u8 _SWHole; - u32 HWHoleSz; - u32 DramHoleAddrReg; - u32 HoleBase; - u32 dev0; - u32 reg0; - u32 val; - u8 i; - struct DCTStatStruc *pDCTstat; - - DoIntlv = mctGet_NVbits(NV_NodeIntlv); - - _NdIntCap = 0; - HWHoleSz = 0; /*For HW remapping, NOT Node hoisting. */ - - pDCTstat = pDCTstatA + 0; - dev0 = pDCTstat->dev_host; - Nodes = ((Get_NB32(dev0, 0x60) >> 4) & 0x7) + 1; - - - dev0 = pDCTstat->dev_map; - reg0 = 0x40; - - NodesWmem = 0; - Node = 0; - - while (DoIntlv && (Node < Nodes)) { - pDCTstat = pDCTstatA + Node; - if (pMCTstat->GStatus & (1 << GSB_SpIntRemapHole)) { - pMCTstat->GStatus |= 1 << GSB_HWHole; - _SWHole = 0; - } else if (pDCTstat->Status & (1 << SB_SWNodeHole)) { - _SWHole = 1; - } else { - _SWHole = 0; - } - - if (!_SWHole) { - Base = Get_NB32(dev0, reg0); - if (Base & 1) { - NodesWmem++; - Base &= 0xFFFF0000; /* Base[39:8] */ - - if (pDCTstat->Status & (1 << SB_HWHole)) { - - /* to get true amount of dram, - * subtract out memory hole if HW dram remapping */ - DramHoleAddrReg = Get_NB32(pDCTstat->dev_map, 0xF0); - HWHoleSz = DramHoleAddrReg >> 16; - HWHoleSz = (((~HWHoleSz) + 1) & 0xFF); - HWHoleSz <<= 24-8; - } - /* check to see if the amount of memory on each channel - * are the same on all nodes */ - - DctSelBase = Get_NB32(pDCTstat->dev_dct, 0x114); - if (DctSelBase) { - DctSelBase <<= 8; - if (pDCTstat->Status & (1 << SB_HWHole)) { - if (DctSelBase >= 0x1000000) { - DctSelBase -= HWHoleSz; - } - } - DctSelBaseOffset -= Base; - if (Node == 0) { - Dct0MemSize = DctSelBase; - } else if (DctSelBase != Dct0MemSize) { - break; - } - } - - MemSize = Get_NB32(dev0, reg0 + 4); - MemSize &= 0xFFFF0000; - MemSize += 0x00010000; - MemSize -= Base; - if (pDCTstat->Status & (1 << SB_HWHole)) { - MemSize -= HWHoleSz; - } - if (Node == 0) { - MemSize0 = MemSize; - } else if (MemSize0 != MemSize) { - break; - } - } else { - break; - } - } else { - break; - } - Node++; - reg0 += 8; - } - - if (Node == Nodes) { - /* if all nodes have memory and no Node had SW memhole */ - if (Nodes == 2 || Nodes == 4 || Nodes == 8) - _NdIntCap = 1; - } - - if (!_NdIntCap) - DoIntlv = 0; - - - if (pMCTstat->GStatus & 1 << (GSB_SpIntRemapHole)) { - HWHoleSz = pMCTstat->HoleBase; - if (HWHoleSz == 0) { - HWHoleSz = mctGet_NVbits(NV_BottomIO) & 0xFF; - HWHoleSz <<= 24-8; - } - HWHoleSz = ((~HWHoleSz) + 1) & 0x00FF0000; - } - - if (DoIntlv) { - MCTMemClr_D(pMCTstat,pDCTstatA); - /* Program Interleaving enabled on Node 0 map only.*/ - MemSize0 <<= bsf(Nodes); /* MemSize = MemSize*2 (or 4, or 8) */ - Dct0MemSize <<= bsf(Nodes); - MemSize0 += HWHoleSz; - Base = ((Nodes - 1) << 8) | 3; - reg0 = 0x40; - Node = 0; - while (Node < Nodes) { - Set_NB32(dev0, reg0, Base); - MemSize = MemSize0; - MemSize--; - MemSize &= 0xFFFF0000; - MemSize |= Node << 8; /* set IntlvSel[2:0] field */ - MemSize |= Node; /* set DstNode[2:0] field */ - Set_NB32(dev0, reg0 + 4, MemSize0); - reg0 += 8; - Node++; - } - - /* set base/limit to F1x120/124 per Node */ - Node = 0; - while (Node < Nodes) { - pDCTstat = pDCTstatA + Node; - pDCTstat->NodeSysBase = 0; - MemSize = MemSize0; - MemSize -= HWHoleSz; - MemSize--; - pDCTstat->NodeSysLimit = MemSize; - Set_NB32(pDCTstat->dev_map, 0x120, Node << 21); - MemSize = MemSize0; - MemSize--; - MemSize >>= 19; - val = Base; - val &= 0x700; - val <<= 13; - val |= MemSize; - Set_NB32(pDCTstat->dev_map, 0x124, val); - - if (pMCTstat->GStatus & (1 << GSB_HWHole)) { - HoleBase = pMCTstat->HoleBase; - if (Dct0MemSize >= HoleBase) { - val = HWHoleSz; - if (Node == 0) { - val += Dct0MemSize; - } - } else { - val = HWHoleSz + Dct0MemSize; - } - - val >>= 8; /* DramHoleOffset */ - HoleBase <<= 8; /* DramHoleBase */ - val |= HoleBase; - val |= 1 << DramMemHoistValid; - val |= 1 << DramHoleValid; - Set_NB32(pDCTstat->dev_map, 0xF0, val); - } - - - Set_NB32(pDCTstat->dev_dct, 0x114, Dct0MemSize >> 8); /* DctSelBaseOffset */ - val = Get_NB32(pDCTstat->dev_dct, 0x110); - val &= 0x7FF; - val |= Dct0MemSize >> 8; - Set_NB32(pDCTstat->dev_dct, 0x110, val); /* DctSelBaseAddr */ - print_tx("InterleaveNodes: DRAM Controller Select Low Register = ", val); - Node++; - } - - - /* Copy Node 0 into other Nodes' CSRs */ - Node = 1; - while (Node < Nodes) { - pDCTstat = pDCTstatA + Node; - - for (i = 0x40; i <= 0x80; i++) { - val = Get_NB32(dev0, i); - Set_NB32(pDCTstat->dev_map, i, val); - } - - val = Get_NB32(dev0, 0xF0); - Set_NB32(pDCTstat->dev_map, 0xF0, val); - Node++; - } - pMCTstat->GStatus = (1 << GSB_NodeIntlv); - } - print_tx("InterleaveNodes_D: Status ", pDCTstat->Status); - print_tx("InterleaveNodes_D: ErrStatus ", pDCTstat->ErrStatus); - print_tx("InterleaveNodes_D: ErrCode ", pDCTstat->ErrCode); - print_t("InterleaveNodes_D: Done\n"); -} diff --git a/src/northbridge/amd/amdmct/mct/mctpro_d.c b/src/northbridge/amd/amdmct/mct/mctpro_d.c deleted file mode 100644 index 83937330f8..0000000000 --- a/src/northbridge/amd/amdmct/mct/mctpro_d.c +++ /dev/null @@ -1,396 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Advanced Micro Devices, Inc. - * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "mct_d.h" - -void EarlySampleSupport_D(void) -{ -} - -u32 procOdtWorkaround(struct DCTStatStruc *pDCTstat, u32 dct, u32 val) -{ - uint64_t tmp; - tmp = pDCTstat->LogicalCPUID; - if ((tmp == AMD_DR_A0A) || (tmp == AMD_DR_A1B) || (tmp == AMD_DR_A2)) { - val &= 0x0FFFFFFF; - if (pDCTstat->MAdimms[dct] > 1) - val |= 0x10000000; - } - - return val; -} - - -u32 OtherTiming_A_D(struct DCTStatStruc *pDCTstat, u32 val) -{ - /* Bug#10695:One MEMCLK Bubble Writes Don't Do X4 X8 Switching Correctly - * Solution: BIOS should set DRAM Timing High[Twrwr] > 00b - * (F2x[1, 0]8C[1:0] > 00b). Silicon Status: Fixed in Rev B - * FIXME: check if this is still required. - */ - uint64_t tmp; - tmp = pDCTstat->LogicalCPUID; - if ((tmp == AMD_DR_A0A) || (tmp == AMD_DR_A1B) || (tmp == AMD_DR_A2)) { - if (!(val & (3<<12))) - val |= 1<<12; - } - return val; -} - - -void mct_ForceAutoPrecharge_D(struct DCTStatStruc *pDCTstat, u32 dct) -{ - uint64_t tmp; - u32 reg; - u32 reg_off; - u32 dev; - u32 val; - - tmp = pDCTstat->LogicalCPUID; - if ((tmp == AMD_DR_A0A) || (tmp == AMD_DR_A1B) || (tmp == AMD_DR_A2)) { - if (CheckNBCOFAutoPrechg(pDCTstat, dct)) { - dev = pDCTstat->dev_dct; - reg_off = 0x100 * dct; - reg = 0x90 + reg_off; /* Dram Configuration Lo */ - val = Get_NB32(dev, reg); - val |= 1<<ForceAutoPchg; - if (!pDCTstat->GangedMode) - val |= 1<<BurstLength32; - Set_NB32(dev, reg, val); - - reg = 0x88 + reg_off; /* cx = Dram Timing Lo */ - val = Get_NB32(dev, reg); - val |= 0x000F0000; /* Trc = 0Fh */ - Set_NB32(dev, reg, val); - } - } -} - - -void mct_EndDQSTraining_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - /* Bug#13341: Prefetch is getting killed when the limit is reached in - * PrefDramTrainMode - * Solution: Explicitly clear the PrefDramTrainMode bit after training - * sequence in order to ensure resumption of normal HW prefetch - * behavior. - * NOTE -- this has been documented with a note at the end of this - * section in the BKDG (although, admittedly, the note does not really - * stand out). - * Silicon Status: Fixed in Rev B (confirm) - * FIXME: check this. - */ - - uint64_t tmp; - u32 dev; - u32 reg; - u32 val; - u32 Node; - - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - - if (!pDCTstat->NodePresent) break; - - tmp = pDCTstat->LogicalCPUID; - if ((tmp == AMD_DR_A0A) || (tmp == AMD_DR_A1B) || (tmp == AMD_DR_A2)) { - dev = pDCTstat->dev_dct; - reg = 0x11c; - val = Get_NB32(dev, reg); - val &= ~(1<<PrefDramTrainMode); - Set_NB32(dev, reg, val); - } - } -} - - - - -void mct_BeforeDQSTrain_Samp_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - /* Bug#15115: Uncertainty In The Sync Chain Leads To Setup Violations - * In TX FIFO - * Solution: BIOS should program DRAM Control Register[RdPtrInit] = 5h, - * (F2x[1, 0]78[3:0] = 5h). - * Silicon Status: Fixed In Rev B0 - */ - - /* Bug#15880: Determine validity of reset settings for DDR PHY timing - * regi.. - * Solution: At least, set WrDqs fine delay to be 0 for DDR2 training. - */ - - u32 dev; - u32 reg_off; - u32 index_reg; - u32 index; - u32 reg; - u32 val; - uint64_t tmp; - u32 Channel; - - tmp = pDCTstat->LogicalCPUID; - if ((tmp == AMD_DR_A0A) || (tmp == AMD_DR_A1B) || (tmp == AMD_DR_A2)) { - - dev = pDCTstat->dev_dct; - index = 0; - - for (Channel = 0; Channel < 2; Channel++) { - index_reg = 0x98 + 0x100 * Channel; - val = Get_NB32_index_wait(dev, index_reg, 0x0d004007); - val |= 0x3ff; - Set_NB32_index_wait(dev, index_reg, 0x0d0f4f07, val); - } - - for (Channel = 0; Channel < 2; Channel++) { - if (pDCTstat->GangedMode && Channel) - break; - reg_off = 0x100 * Channel; - reg = 0x78 + reg_off; - val = Get_NB32(dev, reg); - val &= ~(0x07); - val |= 5; - Set_NB32(dev, reg, val); - } - - for (Channel = 0; Channel < 2; Channel++) { - reg_off = 0x100 * Channel; - val = 0; - index_reg = 0x98 + reg_off; - for (index = 0x30; index < (0x45 + 1); index++) { - Set_NB32_index_wait(dev, index_reg, index, val); - } - } - - } -} - - -u32 Modify_D3CMP(struct DCTStatStruc *pDCTstat, u32 dct, u32 value) -{ - /* Errata#189: Reads To Phy Driver Calibration Register and Phy - * Predriver Calibration Register Do Not Return Bit 27. - * Solution: See #41322 for details. - * BIOS can modify bit 27 of the Phy Driver Calibration register - * as follows: - * 1. Read F2x[1, 0]9C_x09 - * 2. Read F2x[1, 0]9C_x0D004201 - * 3. Set F2x[1, 0]9C_x09[27] = F2x[1, 0]9C_x0D004201[10] - * BIOS can modify bit 27 of the Phy Predriver Calibration register - * as follows: - * 1. Read F2x[1, 0]9C_x0A - * 2. Read F2x[1, 0]9C_x0D004209 - * 3. Set F2x[1, 0]9C_x0A[27] = F2x[1, 0]9C_x0D004209[10] - * Silicon Status: Fixed planned for DR-B0 - */ - - u32 dev; - u32 index_reg; - u32 index; - u32 val; - uint64_t tmp; - - tmp = pDCTstat->LogicalCPUID; - if ((tmp == AMD_DR_A0A) || (tmp == AMD_DR_A1B) || (tmp == AMD_DR_A2)) { - dev = pDCTstat->dev_dct; - index_reg = 0x98 + 0x100 * dct; - index = 0x0D004201; - val = Get_NB32_index_wait(dev, index_reg, index); - value &= ~(1<<27); - value |= ((val >> 10) & 1) << 27; - } - return value; -} - - -void SyncSetting(struct DCTStatStruc *pDCTstat) -{ - /* Errata#198: AddrCmdSetup, CsOdtSetup, and CkeSetup Require Identical - * Programming For Both Channels in Ganged Mode - * Solution: The BIOS must program the following DRAM timing parameters - * the same for both channels: - * 1. F2x[1, 0]9C_x04[21] (AddrCmdSetup) - * 2. F2x[1, 0]9C_x04[15] (CsOdtSetup) - * 3. F2x[1, 0]9C_x04[5]) (CkeSetup) - * That is, if the AddrCmdSetup, CsOdtSetup, or CkeSetup is - * set to 1'b1 for one of the controllers, then the corresponding - * AddrCmdSetup, CsOdtSetup, or CkeSetup must be set to 1'b1 for the - * other controller. - * Silicon Status: Fix TBD - */ - - uint64_t tmp; - tmp = pDCTstat->LogicalCPUID; - if ((tmp == AMD_DR_A0A) || (tmp == AMD_DR_A1B) || (tmp == AMD_DR_A2)) { - pDCTstat->CH_ODC_CTL[1] = pDCTstat->CH_ODC_CTL[0]; - pDCTstat->CH_ADDR_TMG[1] = pDCTstat->CH_ADDR_TMG[0]; - } -} - - -u32 CheckNBCOFAutoPrechg(struct DCTStatStruc *pDCTstat, u32 dct) -{ - u32 ret = 0; - u32 lo, hi; - u32 msr; - u32 val; - u32 valx, valy; - u32 NbDid; - - /* 3 * (Fn2xD4[NBFid]+4)/(2^NbDid)/(3+Fn2x94[MemClkFreq]) */ - msr = 0xC0010071; - _RDMSR(msr, &lo, &hi); - NbDid = (lo >> 22) & 1; - - val = Get_NB32(pDCTstat->dev_dct, 0x94 + 0x100 * dct); - valx = ((val & 0x07) + 3) << NbDid; - print_tx("MemClk:", valx >> NbDid); - - val = Get_NB32(pDCTstat->dev_nbmisc, 0xd4); - valy = ((val & 0x1f) + 4) * 3; - print_tx("NB COF:", valy >> NbDid); - - val = valy/valx; - if ((val == 3) && (valy % valx)) /* 3 < NClk/MemClk < 4 */ - ret = 1; - - return ret; -} - - -void mct_BeforeDramInit_D(struct DCTStatStruc *pDCTstat, u32 dct) -{ - uint64_t tmp; - u32 Speed; - u32 ch, ch_start, ch_end; - u32 index_reg; - u32 dev; - u32 val; - - tmp = pDCTstat->LogicalCPUID; - if ((tmp == AMD_DR_A0A) || (tmp == AMD_DR_A1B) || (tmp == AMD_DR_A2)) { - Speed = pDCTstat->Speed; - /* MemClkFreq = 333MHz or 533MHz */ - if ((Speed == 3) || (Speed == 2)) { - if (pDCTstat->GangedMode) { - ch_start = 0; - ch_end = 2; - } else { - ch_start = dct; - ch_end = dct+1; - } - dev = pDCTstat->dev_dct; - - for (ch = ch_start; ch < ch_end; ch++) { - index_reg = 0x98 + 0x100 * ch; - val = Get_NB32_index(dev, index_reg, 0x0D00E001); - val &= ~(0xf0); - val |= 0x80; - Set_NB32_index(dev, index_reg, 0x0D01E001, val); - } - } - - } -} - -#ifdef UNUSED_CODE -/* Callback not required */ -static u8 mct_AdjustDelay_D(struct DCTStatStruc *pDCTstat, u8 dly) -{ - u8 skip = 0; - dly &= 0x1f; - if ((dly >= MIN_FENCE) && (dly <= MAX_FENCE)) - skip = 1; - - return skip; -} -#endif - -u8 mct_checkFenceHoleAdjust_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 DQSDelay, - u8 ChipSel, u8 *result) -{ - u8 ByteLane; - uint64_t tmp; - - tmp = pDCTstat->LogicalCPUID; - if ((tmp == AMD_DR_A0A) || (tmp == AMD_DR_A1B) || (tmp == AMD_DR_A2)) { - if (pDCTstat->Direction == DQS_WRITEDIR) { - if ((pDCTstat->Speed == 2) || (pDCTstat->Speed == 3)) { - if (DQSDelay == 13) { - if (*result == 0xFF) { - for (ByteLane = 0; ByteLane < 8; ByteLane++) { - pDCTstat->DQSDelay = 13; - pDCTstat->ByteLane = ByteLane; - /* store the value into the data structure */ - StoreDQSDatStrucVal_D(pMCTstat, pDCTstat, ChipSel); - } - return 1; - } - } - } - if (mct_AdjustDQSPosDelay_D(pDCTstat, DQSDelay)) { - *result = 0; - } - } - } - return 0; -} - - -u8 mct_AdjustDQSPosDelay_D(struct DCTStatStruc *pDCTstat, u8 dly) -{ - u8 skip = 0; - - dly &= 0x1f; - if ((dly >= MIN_DQS_WR_FENCE) && (dly <= MAX_DQS_WR_FENCE)) - skip = 1; - - return skip; - -} - -#ifdef UNUSED_CODE -static u8 mctDoAxRdPtrInit_D(struct DCTStatStruc *pDCTstat, u8 *Rdtr) -{ - u32 tmp; - - tmp = pDCTstat->LogicalCPUID; - if ((tmp == AMD_DR_A0A) || (tmp == AMD_DR_A1B) || (tmp == AMD_DR_A2)) { - *Rdtr = 5; - return 1; - } - return 0; -} -#endif - -void mct_AdjustScrub_D(struct DCTStatStruc *pDCTstat, u16 *scrub_request) { - - /* Erratum #202: disable DCache scrubber for Ax parts */ - - if (pDCTstat->LogicalCPUID & (AMD_DR_Ax)) { - *scrub_request = 0; - 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 deleted file mode 100644 index 406547e0f8..0000000000 --- a/src/northbridge/amd/amdmct/mct/mctsrc.c +++ /dev/null @@ -1,1090 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007-2008 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include <console/console.h> -#include <cpu/x86/cr.h> -#include <cpu/amd/msr.h> - -#include "mct_d.h" - -/****************************************************************************** - Description: Receiver En and DQS Timing Training feature for DDR 2 MCT -******************************************************************************/ - -static void dqsTrainRcvrEn_SW(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 Pass); -static u8 mct_SavePassRcvEnDly_D(struct DCTStatStruc *pDCTstat, - u8 rcvrEnDly, u8 Channel, - u8 receiver, u8 Pass); -static u8 mct_CompareTestPatternQW0_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, - u32 addr, u8 channel, - u8 pattern, u8 Pass); -static void mct_InitDQSPos4RcvrEn_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -static void InitDQSPos4RcvrEn_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 Channel); -static void CalcEccDQSRcvrEn_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 Channel); -static void mct_SetFinalRcvrEnDly_D(struct DCTStatStruc *pDCTstat, - u8 RcvrEnDly, u8 where, - u8 Channel, u8 Receiver, - u32 dev, u32 index_reg, - u8 Addl_Index, u8 Pass); -static void mct_SetMaxLatency_D(struct DCTStatStruc *pDCTstat, u8 Channel, u8 DQSRcvEnDly); -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! */ -const u32 TestPattern0_D[] = { - 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, - 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, - 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, - 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, -}; -const u32 TestPattern1_D[] = { - 0x55555555, 0x55555555, 0x55555555, 0x55555555, - 0x55555555, 0x55555555, 0x55555555, 0x55555555, - 0x55555555, 0x55555555, 0x55555555, 0x55555555, - 0x55555555, 0x55555555, 0x55555555, 0x55555555, -}; -const u32 TestPattern2_D[] = { - 0x12345678, 0x87654321, 0x23456789, 0x98765432, - 0x59385824, 0x30496724, 0x24490795, 0x99938733, - 0x40385642, 0x38465245, 0x29432163, 0x05067894, - 0x12349045, 0x98723467, 0x12387634, 0x34587623, -}; - -static void SetupRcvrPattern(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u32 *buffer, u8 pass) -{ - /* - * 1. Copy the alpha and Beta patterns from ROM to Cache, - * aligning on 16 byte boundary - * 2. Set the ptr to DCTStatstruc.PtrPatternBufA for Alpha - * 3. Set the ptr to DCTStatstruc.PtrPatternBufB for Beta - */ - - u32 *buf_a; - u32 *buf_b; - u32 *p_A; - u32 *p_B; - u8 i; - - buf_a = (u32 *)(((u32)buffer + 0x10) & (0xfffffff0)); - buf_b = buf_a + 32; //?? - p_A = (u32 *)SetupDqsPattern_1PassB(pass); - p_B = (u32 *)SetupDqsPattern_1PassA(pass); - - for (i = 0; i < 16; i++) { - buf_a[i] = p_A[i]; - buf_b[i] = p_B[i]; - } - - pDCTstat->PtrPatternBufA = (u32)buf_a; - pDCTstat->PtrPatternBufB = (u32)buf_b; -} - - -void mct_TrainRcvrEn_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 Pass) -{ - if (mct_checkNumberOfDqsRcvEn_1Pass(Pass)) - dqsTrainRcvrEn_SW(pMCTstat, pDCTstat, Pass); -} - - -static void dqsTrainRcvrEn_SW(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 Pass) -{ - u8 Channel, RcvrEnDly, RcvrEnDlyRmin; - u8 Test0, Test1, CurrTest, CurrTestSide0, CurrTestSide1; - u8 CTLRMaxDelay, _2Ranks, PatternA, PatternB; - u8 Addl_Index = 0; - u8 Receiver; - u8 _DisableDramECC = 0, _Wrap32Dis = 0, _SSE2 = 0; - u8 RcvrEnDlyLimit, Final_Value, MaxDelay_CH[2]; - u32 TestAddr0, TestAddr1, TestAddr0B, TestAddr1B; - u32 PatternBuffer[64+4]; /* FIXME: need increase 8? */ - u32 Errors; - - u32 val; - u32 reg; - u32 dev; - u32 index_reg; - u32 ch_start, ch_end, ch; - u32 msr; - CRx_TYPE cr4; - u32 lo, hi; - - u8 valid; - u32 tmp; - u8 LastTest; - - print_debug_dqs("\nTrainRcvEn: Node", pDCTstat->Node_ID, 0); - print_debug_dqs("TrainRcvEn: Pass", Pass, 0); - - - dev = pDCTstat->dev_dct; - ch_start = 0; - if (!pDCTstat->GangedMode) { - ch_end = 2; - } else { - ch_end = 1; - } - - for (ch = ch_start; ch < ch_end; ch++) { - reg = 0x78 + (0x100 * ch); - val = Get_NB32(dev, reg); - val &= ~(0x3ff << 22); - val |= (0x0c8 << 22); /* Max Rd Lat */ - Set_NB32(dev, reg, val); - } - - Final_Value = 1; - if (Pass == FirstPass) { - mct_InitDQSPos4RcvrEn_D(pMCTstat, pDCTstat); - } else { - pDCTstat->DimmTrainFail = 0; - pDCTstat->CSTrainFail = ~pDCTstat->CSPresent; - } - print_t("TrainRcvrEn: 1\n"); - - cr4 = read_cr4(); - if (cr4 & (1 << 9)) { /* save the old value */ - _SSE2 = 1; - } - cr4 |= (1 << 9); /* OSFXSR enable SSE2 */ - write_cr4(cr4); - print_t("TrainRcvrEn: 2\n"); - - msr = HWCR_MSR; - _RDMSR(msr, &lo, &hi); - //FIXME: Why use SSEDIS - if (lo & (1 << 17)) { /* save the old value */ - _Wrap32Dis = 1; - } - lo |= (1 << 17); /* HWCR.wrap32dis */ - lo &= ~(1 << 15); /* SSEDIS */ - _WRMSR(msr, lo, hi); /* Setting wrap32dis allows 64-bit memory references in real mode */ - print_t("TrainRcvrEn: 3\n"); - - _DisableDramECC = mct_DisableDimmEccEn_D(pMCTstat, pDCTstat); - - - if (pDCTstat->Speed == 1) { - pDCTstat->T1000 = 5000; /* get the T1000 figure (cycle time (ns)*1K */ - } else if (pDCTstat->Speed == 2) { - pDCTstat->T1000 = 3759; - } else if (pDCTstat->Speed == 3) { - pDCTstat->T1000 = 3003; - } else if (pDCTstat->Speed == 4) { - pDCTstat->T1000 = 2500; - } else if (pDCTstat->Speed == 5) { - pDCTstat->T1000 = 1876; - } else { - pDCTstat->T1000 = 0; - } - - SetupRcvrPattern(pMCTstat, pDCTstat, PatternBuffer, Pass); - print_t("TrainRcvrEn: 4\n"); - - Errors = 0; - dev = pDCTstat->dev_dct; - CTLRMaxDelay = 0; - - for (Channel = 0; Channel < 2; Channel++) { - print_debug_dqs("\tTrainRcvEn51: Node ", pDCTstat->Node_ID, 1); - print_debug_dqs("\tTrainRcvEn51: Channel ", Channel, 1); - pDCTstat->Channel = Channel; - - MaxDelay_CH[Channel] = 0; - index_reg = 0x98 + 0x100 * Channel; - - Receiver = mct_InitReceiver_D(pDCTstat, Channel); - /* There are four receiver pairs, loosely associated with chipselects. */ - for (; Receiver < 8; Receiver += 2) { - Addl_Index = (Receiver >> 1) * 3 + 0x10; - LastTest = DQS_FAIL; - - /* mct_ModifyIndex_D */ - RcvrEnDlyRmin = RcvrEnDlyLimit = 0xff; - - print_debug_dqs("\t\tTrainRcvEnd52: index ", Addl_Index, 2); - - if (!mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, Channel, Receiver)) { - print_t("\t\t\tRank not enabled_D\n"); - continue; - } - - TestAddr0 = mct_GetRcvrSysAddr_D(pMCTstat, pDCTstat, Channel, Receiver, &valid); - if (!valid) { /* Address not supported on current CS */ - print_t("\t\t\tAddress not supported on current CS\n"); - continue; - } - - TestAddr0B = TestAddr0 + (BigPagex8_RJ8 << 3); - - if (mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, Channel, Receiver+1)) { - TestAddr1 = mct_GetRcvrSysAddr_D(pMCTstat, pDCTstat, Channel, Receiver+1, &valid); - if (!valid) { /* Address not supported on current CS */ - print_t("\t\t\tAddress not supported on current CS+1\n"); - continue; - } - TestAddr1B = TestAddr1 + (BigPagex8_RJ8 << 3); - _2Ranks = 1; - } else { - _2Ranks = TestAddr1 = TestAddr1B = 0; - } - - print_debug_dqs("\t\tTrainRcvEn53: TestAddr0 ", TestAddr0, 2); - print_debug_dqs("\t\tTrainRcvEn53: TestAddr0B ", TestAddr0B, 2); - print_debug_dqs("\t\tTrainRcvEn53: TestAddr1 ", TestAddr1, 2); - print_debug_dqs("\t\tTrainRcvEn53: TestAddr1B ", TestAddr1B, 2); - - /* - * Get starting RcvrEnDly value - */ - RcvrEnDly = mct_Get_Start_RcvrEnDly_1Pass(Pass); - - /* mct_GetInitFlag_D*/ - if (Pass == FirstPass) { - pDCTstat->DqsRcvEn_Pass = 0; - } else { - pDCTstat->DqsRcvEn_Pass = 0xFF; - } - pDCTstat->DqsRcvEn_Saved = 0; - - - while (RcvrEnDly < RcvrEnDlyLimit) { /* sweep Delay value here */ - print_debug_dqs("\t\t\tTrainRcvEn541: RcvrEnDly ", RcvrEnDly, 3); - - /* callback not required - if (mct_AdjustDelay_D(pDCTstat, RcvrEnDly)) - goto skipDly; - */ - - /* Odd steps get another pattern such that even - and odd steps alternate. The pointers to the - patterns will be swaped at the end of the loop - so that they correspond. */ - if (RcvrEnDly & 1) { - PatternA = 1; - PatternB = 0; - } else { - /* Even step */ - PatternA = 0; - PatternB = 1; - } - - mct_Write1LTestPattern_D(pMCTstat, pDCTstat, TestAddr0, PatternA); /* rank 0 of DIMM, testpattern 0 */ - mct_Write1LTestPattern_D(pMCTstat, pDCTstat, TestAddr0B, PatternB); /* rank 0 of DIMM, testpattern 1 */ - if (_2Ranks) { - mct_Write1LTestPattern_D(pMCTstat, pDCTstat, TestAddr1, PatternA); /*rank 1 of DIMM, testpattern 0 */ - mct_Write1LTestPattern_D(pMCTstat, pDCTstat, TestAddr1B, PatternB); /*rank 1 of DIMM, testpattern 1 */ - } - - mct_SetRcvrEnDly_D(pDCTstat, RcvrEnDly, 0, Channel, Receiver, dev, index_reg, Addl_Index, Pass); - - CurrTest = DQS_FAIL; - CurrTestSide0 = DQS_FAIL; - CurrTestSide1 = DQS_FAIL; - - mct_Read1LTestPattern_D(pMCTstat, pDCTstat, TestAddr0); /*cache fills */ - Test0 = mct_CompareTestPatternQW0_D(pMCTstat, pDCTstat, TestAddr0, Channel, PatternA, Pass);/* ROM vs cache compare */ - proc_IOCLFLUSH_D(TestAddr0); - ResetDCTWrPtr_D(dev, index_reg, Addl_Index); - - print_debug_dqs("\t\t\tTrainRcvEn542: Test0 result ", Test0, 3); - - // != 0x00 mean pass - - if (Test0 == DQS_PASS) { - mct_Read1LTestPattern_D(pMCTstat, pDCTstat, TestAddr0B); /*cache fills */ - /* ROM vs cache compare */ - Test1 = mct_CompareTestPatternQW0_D(pMCTstat, pDCTstat, TestAddr0B, Channel, PatternB, Pass); - proc_IOCLFLUSH_D(TestAddr0B); - ResetDCTWrPtr_D(dev, index_reg, Addl_Index); - - print_debug_dqs("\t\t\tTrainRcvEn543: Test1 result ", Test1, 3); - - if (Test1 == DQS_PASS) { - CurrTestSide0 = DQS_PASS; - } - } - if (_2Ranks) { - mct_Read1LTestPattern_D(pMCTstat, pDCTstat, TestAddr1); /*cache fills */ - /* ROM vs cache compare */ - Test0 = mct_CompareTestPatternQW0_D(pMCTstat, pDCTstat, TestAddr1, Channel, PatternA, Pass); - proc_IOCLFLUSH_D(TestAddr1); - ResetDCTWrPtr_D(dev, index_reg, Addl_Index); - - print_debug_dqs("\t\t\tTrainRcvEn544: Test0 result ", Test0, 3); - - if (Test0 == DQS_PASS) { - mct_Read1LTestPattern_D(pMCTstat, pDCTstat, TestAddr1B); /*cache fills */ - /* ROM vs cache compare */ - Test1 = mct_CompareTestPatternQW0_D(pMCTstat, pDCTstat, TestAddr1B, Channel, PatternB, Pass); - proc_IOCLFLUSH_D(TestAddr1B); - ResetDCTWrPtr_D(dev, index_reg, Addl_Index); - - print_debug_dqs("\t\t\tTrainRcvEn545: Test1 result ", Test1, 3); - if (Test1 == DQS_PASS) { - CurrTestSide1 = DQS_PASS; - } - } - } - - if (_2Ranks) { - if ((CurrTestSide0 == DQS_PASS) && (CurrTestSide1 == DQS_PASS)) { - CurrTest = DQS_PASS; - } - } else if (CurrTestSide0 == DQS_PASS) { - CurrTest = DQS_PASS; - } - - - /* record first pass DqsRcvEn to stack */ - valid = mct_SavePassRcvEnDly_D(pDCTstat, RcvrEnDly, Channel, Receiver, Pass); - - /* Break(1:RevF,2:DR) or not(0) FIXME: This comment deosn't make sense */ - if (valid == 2 || (LastTest == DQS_FAIL && valid == 1)) { - RcvrEnDlyRmin = RcvrEnDly; - break; - } - - LastTest = CurrTest; - - /* swap the rank 0 pointers */ - tmp = TestAddr0; - TestAddr0 = TestAddr0B; - TestAddr0B = tmp; - - /* swap the rank 1 pointers */ - tmp = TestAddr1; - TestAddr1 = TestAddr1B; - TestAddr1B = tmp; - - print_debug_dqs("\t\t\tTrainRcvEn56: RcvrEnDly ", RcvrEnDly, 3); - - RcvrEnDly++; - - } /* while RcvrEnDly */ - - print_debug_dqs("\t\tTrainRcvEn61: RcvrEnDly ", RcvrEnDly, 2); - print_debug_dqs("\t\tTrainRcvEn61: RcvrEnDlyRmin ", RcvrEnDlyRmin, 3); - print_debug_dqs("\t\tTrainRcvEn61: RcvrEnDlyLimit ", RcvrEnDlyLimit, 3); - if (RcvrEnDlyRmin == RcvrEnDlyLimit) { - /* no passing window */ - pDCTstat->ErrStatus |= 1 << SB_NORCVREN; - Errors |= 1 << SB_NORCVREN; - pDCTstat->ErrCode = SC_FatalErr; - } - - if (RcvrEnDly > (RcvrEnDlyLimit - 1)) { - /* passing window too narrow, too far delayed*/ - pDCTstat->ErrStatus |= 1 << SB_SmallRCVR; - Errors |= 1 << SB_SmallRCVR; - pDCTstat->ErrCode = SC_FatalErr; - RcvrEnDly = RcvrEnDlyLimit - 1; - pDCTstat->CSTrainFail |= 1 << Receiver; - pDCTstat->DimmTrainFail |= 1 << (Receiver + Channel); - } - - // CHB_D0_B0_RCVRDLY set in mct_Average_RcvrEnDly_Pass - mct_Average_RcvrEnDly_Pass(pDCTstat, RcvrEnDly, RcvrEnDlyLimit, Channel, Receiver, Pass); - - mct_SetFinalRcvrEnDly_D(pDCTstat, RcvrEnDly, Final_Value, Channel, Receiver, dev, index_reg, Addl_Index, Pass); - - if (pDCTstat->ErrStatus & (1 << SB_SmallRCVR)) { - Errors |= 1 << SB_SmallRCVR; - } - - RcvrEnDly += Pass1MemClkDly; - if (RcvrEnDly > CTLRMaxDelay) { - CTLRMaxDelay = RcvrEnDly; - } - - } /* while Receiver */ - - MaxDelay_CH[Channel] = CTLRMaxDelay; - } /* for Channel */ - - CTLRMaxDelay = MaxDelay_CH[0]; - if (MaxDelay_CH[1] > CTLRMaxDelay) - CTLRMaxDelay = MaxDelay_CH[1]; - - for (Channel = 0; Channel < 2; Channel++) { - mct_SetMaxLatency_D(pDCTstat, Channel, CTLRMaxDelay); /* program Ch A/B MaxAsyncLat to correspond with max delay */ - } - - ResetDCTWrPtr_D(dev, index_reg, Addl_Index); - - if (_DisableDramECC) { - mct_EnableDimmEccEn_D(pMCTstat, pDCTstat, _DisableDramECC); - } - - if (Pass == FirstPass) { - /*Disable DQSRcvrEn training mode */ - print_t("TrainRcvrEn: mct_DisableDQSRcvEn_D\n"); - mct_DisableDQSRcvEn_D(pDCTstat); - } - - if (!_Wrap32Dis) { - msr = HWCR_MSR; - _RDMSR(msr, &lo, &hi); - lo &= ~(1<<17); /* restore HWCR.wrap32dis */ - _WRMSR(msr, lo, hi); - } - if (!_SSE2) { - cr4 = read_cr4(); - cr4 &= ~(1<<9); /* restore cr4.OSFXSR */ - write_cr4(cr4); - } - -#if DQS_TRAIN_DEBUG > 0 - { - u8 Channel; - printk(BIOS_DEBUG, "TrainRcvrEn: CH_MaxRdLat:\n"); - for (Channel = 0; Channel < 2; Channel++) { - printk(BIOS_DEBUG, "Channel: %02x: %02x\n", Channel, pDCTstat->CH_MaxRdLat[Channel]); - } - } -#endif - -#if DQS_TRAIN_DEBUG > 0 - { - u8 val; - u8 Channel, Receiver; - u8 i; - u8 *p; - - printk(BIOS_DEBUG, "TrainRcvrEn: CH_D_B_RCVRDLY:\n"); - for (Channel = 0; Channel < 2; Channel++) { - printk(BIOS_DEBUG, "Channel: %02x\n", Channel); - for (Receiver = 0; Receiver < 8; Receiver+=2) { - printk(BIOS_DEBUG, "\t\tReceiver: %02x: ", Receiver); - p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][Receiver>>1]; - for (i = 0; i < 8; i++) { - val = p[i]; - printk(BIOS_DEBUG, "%02x ", val); - } - printk(BIOS_DEBUG, "\n"); - } - } - } -#endif - - print_tx("TrainRcvrEn: Status ", pDCTstat->Status); - print_tx("TrainRcvrEn: ErrStatus ", pDCTstat->ErrStatus); - print_tx("TrainRcvrEn: ErrCode ", pDCTstat->ErrCode); - print_t("TrainRcvrEn: Done\n"); -} - - -u8 mct_InitReceiver_D(struct DCTStatStruc *pDCTstat, u8 dct) -{ - if (pDCTstat->DIMMValidDCT[dct] == 0) { - return 8; - } else { - return 0; - } -} - - -static void mct_SetFinalRcvrEnDly_D(struct DCTStatStruc *pDCTstat, u8 RcvrEnDly, u8 where, u8 Channel, u8 Receiver, u32 dev, u32 index_reg, u8 Addl_Index, u8 Pass/*, u8 *p*/) -{ - /* - * Program final DqsRcvEnDly to additional index for DQS receiver - * enabled delay - */ - mct_SetRcvrEnDly_D(pDCTstat, RcvrEnDly, where, Channel, Receiver, dev, index_reg, Addl_Index, Pass); -} - - -static void mct_DisableDQSRcvEn_D(struct DCTStatStruc *pDCTstat) -{ - u8 ch_end, ch; - u32 reg; - u32 dev; - u32 val; - - dev = pDCTstat->dev_dct; - if (pDCTstat->GangedMode) { - ch_end = 1; - } else { - ch_end = 2; - } - - for (ch = 0; ch < ch_end; ch++) { - reg = 0x78 + 0x100 * ch; - val = Get_NB32(dev, reg); - val &= ~(1 << DqsRcvEnTrain); - Set_NB32(dev, reg, val); - } -} - - -/* mct_ModifyIndex_D - * Function only used once so it was inlined. - */ - - -/* mct_GetInitFlag_D - * Function only used once so it was inlined. - */ - - -void mct_SetRcvrEnDly_D(struct DCTStatStruc *pDCTstat, u8 RcvrEnDly, - u8 FinalValue, u8 Channel, u8 Receiver, u32 dev, - u32 index_reg, u8 Addl_Index, u8 Pass) -{ - u32 index; - u8 i; - u8 *p; - u32 val; - - if (RcvrEnDly == 0xFE) { - /*set the boudary flag */ - pDCTstat->Status |= 1 << SB_DQSRcvLimit; - } - - /* DimmOffset not needed for CH_D_B_RCVRDLY array */ - - - for (i = 0; i < 8; i++) { - if (FinalValue) { - /*calculate dimm offset */ - p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][Receiver >> 1]; - RcvrEnDly = p[i]; - } - - /* if flag = 0, set DqsRcvEn value to reg. */ - /* get the register index from table */ - index = Table_DQSRcvEn_Offset[i >> 1]; - index += Addl_Index; /* DIMMx DqsRcvEn byte0 */ - val = Get_NB32_index_wait(dev, index_reg, index); - if (i & 1) { - /* odd byte lane */ - val &= ~(0xFF << 16); - val |= (RcvrEnDly << 16); - } else { - /* even byte lane */ - val &= ~0xFF; - val |= RcvrEnDly; - } - Set_NB32_index_wait(dev, index_reg, index, val); - } - -} - -static void mct_SetMaxLatency_D(struct DCTStatStruc *pDCTstat, u8 Channel, u8 DQSRcvEnDly) -{ - u32 dev; - u32 reg; - u16 SubTotal; - u32 index_reg; - u32 reg_off; - u32 val; - u32 valx; - - if (pDCTstat->GangedMode) - Channel = 0; - - dev = pDCTstat->dev_dct; - reg_off = 0x100 * Channel; - index_reg = 0x98 + reg_off; - - /* Multiply the CAS Latency by two to get a number of 1/2 MEMCLKs units.*/ - val = Get_NB32(dev, 0x88 + reg_off); - SubTotal = ((val & 0x0f) + 1) << 1; /* SubTotal is 1/2 Memclk unit */ - - /* If registered DIMMs are being used then - * add 1 MEMCLK to the sub-total. - */ - val = Get_NB32(dev, 0x90 + reg_off); - if (!(val & (1 << UnBuffDimm))) - SubTotal += 2; - - /* If the address prelaunch is setup for 1/2 MEMCLKs then - * add 1, else add 2 to the sub-total. - * if (AddrCmdSetup || CsOdtSetup || CkeSetup) then K := K + 2; - */ - val = Get_NB32_index_wait(dev, index_reg, 0x04); - if (!(val & 0x00202020)) - SubTotal += 1; - else - SubTotal += 2; - - /* If the F2x[1, 0]78[RdPtrInit] field is 4, 5, 6 or 7 MEMCLKs, - * then add 4, 3, 2, or 1 MEMCLKs, respectively to the sub-total. */ - val = Get_NB32(dev, 0x78 + reg_off); - SubTotal += 8 - (val & 0x0f); - - /* Convert bits 7-5 (also referred to as the course delay) of - * the current (or worst case) DQS receiver enable delay to - * 1/2 MEMCLKs units, rounding up, and add this to the sub-total. - */ - SubTotal += DQSRcvEnDly >> 5; /*BOZO-no rounding up */ - - /* Add 5.5 to the sub-total. 5.5 represents part of the - * processor specific constant delay value in the DRAM - * clock domain. - */ - SubTotal <<= 1; /*scale 1/2 MemClk to 1/4 MemClk */ - SubTotal += 11; /*add 5.5 1/2MemClk */ - - /* Convert the sub-total (in 1/2 MEMCLKs) to northbridge - * clocks (NCLKs) as follows (assuming DDR400 and assuming - * that no P-state or link speed changes have occurred). - */ - - /* New formula: - * SubTotal *= 3*(Fn2xD4[NBFid]+4)/(3+Fn2x94[MemClkFreq])/2 */ - val = Get_NB32(dev, 0x94 + reg_off); - - /* SubTotal div 4 to scale 1/4 MemClk back to MemClk */ - val &= 7; - if (val == 4) { - val++; /* adjust for DDR2-1066 */ - } - valx = (val + 3) << 2; - - val = Get_NB32(pDCTstat->dev_nbmisc, 0xD4); - SubTotal *= ((val & 0x1f) + 4) * 3; - - SubTotal /= valx; - if (SubTotal % valx) { /* round up */ - SubTotal++; - } - - /* Add 5 NCLKs to the sub-total. 5 represents part of the - * processor specific constant value in the northbridge - * clock domain. - */ - SubTotal += 5; - - pDCTstat->CH_MaxRdLat[Channel] = SubTotal; - if (pDCTstat->GangedMode) { - pDCTstat->CH_MaxRdLat[1] = SubTotal; - } - - /* Program the F2x[1, 0]78[MaxRdLatency] register with - * the total delay value (in NCLKs). - */ - - reg = 0x78 + reg_off; - val = Get_NB32(dev, reg); - val &= ~(0x3ff << 22); - val |= (SubTotal & 0x3ff) << 22; - - /* program MaxRdLatency to correspond with current delay */ - Set_NB32(dev, reg, val); -} - - -static u8 mct_SavePassRcvEnDly_D(struct DCTStatStruc *pDCTstat, - u8 rcvrEnDly, u8 Channel, - u8 receiver, u8 Pass) -{ - u8 i; - u8 mask_Saved, mask_Pass; - u8 *p; - - /* calculate dimm offset - * not needed for CH_D_B_RCVRDLY array - */ - - /* cmp if there has new DqsRcvEnDly to be recorded */ - mask_Pass = pDCTstat->DqsRcvEn_Pass; - - if (Pass == SecondPass) { - mask_Pass = ~mask_Pass; - } - - mask_Saved = pDCTstat->DqsRcvEn_Saved; - if (mask_Pass != mask_Saved) { - - /* find desired stack offset according to channel/dimm/byte */ - if (Pass == SecondPass) { - // FIXME: SecondPass is never used for Barcelona p = pDCTstat->persistentData.CH_D_B_RCVRDLY_1[Channel][receiver>>1]; - p = 0; // Keep the compiler happy. - } else { - mask_Saved &= mask_Pass; - p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][receiver>>1]; - } - for (i = 0; i < 8; i++) { - /* cmp per byte lane */ - if (mask_Pass & (1 << i)) { - if (!(mask_Saved & (1 << i))) { - /* save RcvEnDly to stack, according to - the related Dimm/byte lane */ - p[i] = (u8)rcvrEnDly; - mask_Saved |= 1 << i; - } - } - } - pDCTstat->DqsRcvEn_Saved = mask_Saved; - } - return mct_SaveRcvEnDly_D_1Pass(pDCTstat, Pass); -} - - -static u8 mct_CompareTestPatternQW0_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, - u32 addr, u8 channel, - u8 pattern, u8 Pass) -{ - /* Compare only the first beat of data. Since target addrs are cache - * line aligned, the Channel parameter is used to determine which - * cache QW to compare. - */ - - u8 *test_buf; - u8 i; - u8 result; - u8 value; - - - if (Pass == FirstPass) { - if (pattern == 1) { - test_buf = (u8 *)TestPattern1_D; - } else { - test_buf = (u8 *)TestPattern0_D; - } - } else { // Second Pass - test_buf = (u8 *)TestPattern2_D; - } - - SetUpperFSbase(addr); - addr <<= 8; - - if ((pDCTstat->Status & (1<<SB_128bitmode)) && channel) { - addr += 8; /* second channel */ - test_buf += 8; - } - - print_debug_dqs_pair("\t\t\t\t\t\t test_buf = ", (u32)test_buf, " | addr_lo = ", addr, 4); - for (i = 0; i < 8; i++) { - value = read32_fs(addr); - print_debug_dqs_pair("\t\t\t\t\t\t\t\t ", test_buf[i], " | ", value, 4); - - if (value == test_buf[i]) { - pDCTstat->DqsRcvEn_Pass |= (1<<i); - } else { - pDCTstat->DqsRcvEn_Pass &= ~(1<<i); - } - } - - result = DQS_FAIL; - - if (Pass == FirstPass) { - /* if first pass, at least one byte lane pass - * ,then DQS_PASS = 1 and will set to related reg. - */ - if (pDCTstat->DqsRcvEn_Pass != 0) { - result = DQS_PASS; - } else { - result = DQS_FAIL; - } - - } else { - /* if second pass, at least one byte lane fail - * ,then DQS_FAIL = 1 and will set to related reg. - */ - if (pDCTstat->DqsRcvEn_Pass != 0xFF) { - result = DQS_FAIL; - } else { - result = DQS_PASS; - } - } - - /* if second pass, we can't find the fail until FFh, - * then let it fail to save the final delay - */ - if ((Pass == SecondPass) && (pDCTstat->Status & (1 << SB_DQSRcvLimit))) { - result = DQS_FAIL; - pDCTstat->DqsRcvEn_Pass = 0; - } - - /* second pass needs to be inverted - * FIXME? this could be inverted in the above code to start with... - */ - if (Pass == SecondPass) { - if (result == DQS_PASS) { - result = DQS_FAIL; - } else if (result == DQS_FAIL) { /* FIXME: doesn't need to be else if */ - result = DQS_PASS; - } - } - - - return result; -} - - - -static void mct_InitDQSPos4RcvrEn_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - /* Initialize the DQS Positions in preparation for - * Receiver Enable Training. - * Write Position is 1/2 Memclock Delay - * Read Position is 1/2 Memclock Delay - */ - u8 i; - for (i = 0; i < 2; i++) { - InitDQSPos4RcvrEn_D(pMCTstat, pDCTstat, i); - } -} - - -static void InitDQSPos4RcvrEn_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 Channel) -{ - /* Initialize the DQS Positions in preparation for - * Receiver Enable Training. - * Write Position is no Delay - * Read Position is 1/2 Memclock Delay - */ - - u8 i, j; - u32 dword; - u8 dn = 2; // TODO: Rev C could be 4 - u32 dev = pDCTstat->dev_dct; - u32 index_reg = 0x98 + 0x100 * Channel; - - - // FIXME: add Cx support - dword = 0x00000000; - for (i = 1; i <= 3; i++) { - for (j = 0; j < dn; j++) - /* DIMM0 Write Data Timing Low */ - /* DIMM0 Write ECC Timing */ - Set_NB32_index_wait(dev, index_reg, i + 0x100 * j, dword); - } - - /* errata #180 */ - dword = 0x2f2f2f2f; - for (i = 5; i <= 6; i++) { - for (j = 0; j < dn; j++) - /* DIMM0 Read DQS Timing Control Low */ - Set_NB32_index_wait(dev, index_reg, i + 0x100 * j, dword); - } - - dword = 0x0000002f; - for (j = 0; j < dn; j++) - /* DIMM0 Read DQS ECC Timing Control */ - Set_NB32_index_wait(dev, index_reg, 7 + 0x100 * j, dword); -} - - -void SetEccDQSRcvrEn_D(struct DCTStatStruc *pDCTstat, u8 Channel) -{ - u32 dev; - u32 index_reg; - u32 index; - u8 ChipSel; - u8 *p; - u32 val; - - dev = pDCTstat->dev_dct; - index_reg = 0x98 + Channel * 0x100; - index = 0x12; - p = pDCTstat->persistentData.CH_D_BC_RCVRDLY[Channel]; - print_debug_dqs("\t\tSetEccDQSRcvrPos: Channel ", Channel, 2); - for (ChipSel = 0; ChipSel < MAX_CS_SUPPORTED; ChipSel += 2) { - val = p[ChipSel>>1]; - Set_NB32_index_wait(dev, index_reg, index, val); - print_debug_dqs_pair("\t\tSetEccDQSRcvrPos: ChipSel ", - ChipSel, " rcvr_delay ", val, 2); - index += 3; - } -} - - -static void CalcEccDQSRcvrEn_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 Channel) -{ - u8 ChipSel; - u16 EccDQSLike; - u8 EccDQSScale; - u32 val, val0, val1; - - EccDQSLike = pDCTstat->CH_EccDQSLike[Channel]; - EccDQSScale = pDCTstat->CH_EccDQSScale[Channel]; - - for (ChipSel = 0; ChipSel < MAX_CS_SUPPORTED; ChipSel += 2) { - if (mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, Channel, ChipSel)) { - u8 *p; - p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][ChipSel>>1]; - - /* DQS Delay Value of Data Bytelane - * most like ECC byte lane */ - val0 = p[EccDQSLike & 0x07]; - /* DQS Delay Value of Data Bytelane - * 2nd most like ECC byte lane */ - val1 = p[(EccDQSLike>>8) & 0x07]; - - if (val0 > val1) { - val = val0 - val1; - } else { - val = val1 - val0; - } - - val *= ~EccDQSScale; - val >>= 8; // /256 - - if (val0 > val1) { - val -= val1; - } else { - val += val0; - } - - pDCTstat->persistentData.CH_D_BC_RCVRDLY[Channel][ChipSel>>1] = val; - } - } - SetEccDQSRcvrEn_D(pDCTstat, Channel); -} - -void mctSetEccDQSRcvrEn_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - u8 Node; - u8 i; - - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - if (!pDCTstat->NodePresent) - break; - if (pDCTstat->DCTSysLimit) { - for (i = 0; i < 2; i++) - CalcEccDQSRcvrEn_D(pMCTstat, pDCTstat, i); - } - } -} - - -void phyAssistedMemFnceTraining(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - - u8 Node = 0; - struct DCTStatStruc *pDCTstat; - - // FIXME: skip for Ax - while (Node < MAX_NODES_SUPPORTED) { - pDCTstat = pDCTstatA + Node; - - if (pDCTstat->DCTSysLimit) { - fenceDynTraining_D(pMCTstat, pDCTstat, 0); - fenceDynTraining_D(pMCTstat, pDCTstat, 1); - } - Node++; - } -} - - -static void fenceDynTraining_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 dct) -{ - u16 avRecValue; - u32 val; - u32 dev; - u32 index_reg = 0x98 + 0x100 * dct; - u32 index; - - /* BIOS first programs a seed value to the phase recovery engine - * (recommended 19) registers. - * Dram Phase Recovery Control Register (F2x[1,0]9C_x[51:50] and - * F2x[1,0]9C_x52.) . - */ - - dev = pDCTstat->dev_dct; - for (index = 0x50; index <= 0x52; index ++) { - val = (FenceTrnFinDlySeed & 0x1F); - if (index != 0x52) { - val |= val << 8 | val << 16 | val << 24; - } - Set_NB32_index_wait(dev, index_reg, index, val); - } - - - /* Set F2x[1,0]9C_x08[PhyFenceTrEn]=1. */ - val = Get_NB32_index_wait(dev, index_reg, 0x08); - val |= 1 << PhyFenceTrEn; - Set_NB32_index_wait(dev, index_reg, 0x08, val); - - /* Wait 200 MEMCLKs. */ - mct_Wait(50000); /* wait 200us */ - - /* Clear F2x[1,0]9C_x08[PhyFenceTrEn]=0. */ - val = Get_NB32_index_wait(dev, index_reg, 0x08); - val &= ~(1 << PhyFenceTrEn); - Set_NB32_index_wait(dev, index_reg, 0x08, val); - - /* BIOS reads the phase recovery engine registers - * F2x[1,0]9C_x[51:50] and F2x[1,0]9C_x52. */ - avRecValue = 0; - for (index = 0x50; index <= 0x52; index ++) { - val = Get_NB32_index_wait(dev, index_reg, index); - avRecValue += val & 0x7F; - if (index != 0x52) { - avRecValue += (val >> 8) & 0x7F; - avRecValue += (val >> 16) & 0x7F; - avRecValue += (val >> 24) & 0x7F; - } - } - - val = avRecValue / 9; - if (avRecValue % 9) - val++; - avRecValue = val; - - /* Write the (averaged value -8) to F2x[1,0]9C_x0C[PhyFence]. */ - avRecValue -= 8; - val = Get_NB32_index_wait(dev, index_reg, 0x0C); - val &= ~(0x1F << 16); - val |= (avRecValue & 0x1F) << 16; - Set_NB32_index_wait(dev, index_reg, 0x0C, val); - - /* Rewrite F2x[1,0]9C_x04-DRAM Address/Command Timing Control Register - * delays (both channels). */ - val = Get_NB32_index_wait(dev, index_reg, 0x04); - Set_NB32_index_wait(dev, index_reg, 0x04, val); -} - - -void mct_Wait(u32 cycles) -{ - u32 saved; - u32 hi, lo, msr; - - /* Wait # of 50ns cycles - This seems like a hack to me... */ - - cycles <<= 3; /* x8 (number of 1.25ns ticks) */ - - msr = 0x10; /* TSC */ - _RDMSR(msr, &lo, &hi); - saved = lo; - do { - _RDMSR(msr, &lo, &hi); - } while (lo - saved < cycles); -} diff --git a/src/northbridge/amd/amdmct/mct/mctsrc1p.c b/src/northbridge/amd/amdmct/mct/mctsrc1p.c deleted file mode 100644 index 8ae60253ab..0000000000 --- a/src/northbridge/amd/amdmct/mct/mctsrc1p.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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.h" - -u8 mct_checkNumberOfDqsRcvEn_1Pass(u8 pass) -{ - u8 ret = 1; - if (pass == SecondPass) - ret = 0; - - return ret; -} - - -u32 SetupDqsPattern_1PassA(u8 pass) -{ - return (u32) TestPattern1_D; -} - - -u32 SetupDqsPattern_1PassB(u8 pass) -{ - return (u32) TestPattern0_D; -} - -u8 mct_Get_Start_RcvrEnDly_1Pass(u8 pass) -{ - return 0; -} - -static u8 mct_Average_RcvrEnDly_1Pass(struct DCTStatStruc *pDCTstat, u8 Channel, u8 Receiver, - u8 Pass) -{ - u8 i, MaxValue; - u8 *p; - u8 val; - - MaxValue = 0; - p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][Receiver >> 1]; - - for (i = 0; i < 8; i++) { - /* get left value from DCTStatStruc.CHA_D0_B0_RCVRDLY*/ - val = p[i]; - /* get right value from DCTStatStruc.CHA_D0_B0_RCVRDLY_1*/ - val += Pass1MemClkDly; - /* write back the value to stack */ - if (val > MaxValue) - MaxValue = val; - - p[i] = val; - } - - return MaxValue; -} - -#ifdef UNUSED_CODE -static u8 mct_AdjustFinalDQSRcvValue_1Pass(u8 val_1p, u8 val_2p) -{ - return (val_1p & 0xff) + ((val_2p & 0xff)<<8); -} -#endif - -u8 mct_SaveRcvEnDly_D_1Pass(struct DCTStatStruc *pDCTstat, u8 pass) -{ - u8 ret; - ret = 0; - if ((pDCTstat->DqsRcvEn_Pass == 0xff) && (pass== FirstPass)) - ret = 2; - return ret; -} - -u8 mct_Average_RcvrEnDly_Pass(struct DCTStatStruc *pDCTstat, - u8 RcvrEnDly, u8 RcvrEnDlyLimit, - u8 Channel, u8 Receiver, u8 Pass) - -{ - return mct_Average_RcvrEnDly_1Pass(pDCTstat, Channel, Receiver, Pass); -} diff --git a/src/northbridge/amd/amdmct/mct/mctsrc2p.c b/src/northbridge/amd/amdmct/mct/mctsrc2p.c deleted file mode 100644 index ab278e9199..0000000000 --- a/src/northbridge/amd/amdmct/mct/mctsrc2p.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - - -u8 mct_checkNumberOfDqsRcvEn_Pass(u8 pass) -{ - return 1; -} - - -u32 SetupDqsPattern_PassA(u8 Pass) -{ - u32 ret; - if (Pass == FirstPass) - ret = (u32) TestPattern1_D; - else - ret = (u32) TestPattern2_D; - - return ret; -} - - -u32 SetupDqsPattern_PassB(u8 Pass) -{ - u32 ret; - if (Pass == FirstPass) - ret = (u32) TestPattern0_D; - else - ret = (u32) TestPattern2_D; - - return ret; -} - - -u8 mct_Get_Start_RcvrEnDly_Pass(struct DCTStatStruc *pDCTstat, - u8 Channel, u8 Receiver, - u8 Pass) -{ - u8 RcvrEnDly; - - if (Pass == FirstPass) - RcvrEnDly = 0; - else { - u8 max = 0; - u8 val; - u8 i; - u8 *p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][Receiver>>1]; - u8 bn; - bn = 8; - - for (i = 0; i < bn; i++) { - val = p[i]; - if (val > max) { - max = val; - } - } - RcvrEnDly = max; -// while (1) {; } -// RcvrEnDly += secPassOffset; //FIXME Why - } - - return RcvrEnDly; -} - - - -u8 mct_Average_RcvrEnDly_Pass(struct DCTStatStruc *pDCTstat, - u8 RcvrEnDly, u8 RcvrEnDlyLimit, - u8 Channel, u8 Receiver, u8 Pass) -{ - u8 i; - u8 *p; - u8 *p_1; - u8 val; - u8 val_1; - u8 valid = 1; - u8 bn; - - bn = 8; - - p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][Receiver>>1]; - - if (Pass == SecondPass) { /* second pass must average values */ - //FIXME: which byte? - p_1 = pDCTstat->B_RCVRDLY_1; -// p_1 = pDCTstat->persistentData.CH_D_B_RCVRDLY_1[Channel][Receiver>>1]; - for (i = 0; i < bn; i++) { - val = p[i]; - /* left edge */ - if (val != (RcvrEnDlyLimit - 1)) { - val -= Pass1MemClkDly; - val_1 = p_1[i]; - val += val_1; - val >>= 1; - p[i] = val; - } else { - valid = 0; - break; - } - } - if (!valid) { - pDCTstat->ErrStatus |= 1<<SB_NORCVREN; - } else { - pDCTstat->DimmTrainFail &= ~(1<<(Receiver + Channel)); - } - } else { - for (i = 0; i < bn; i++) { - val = p[i]; - /* Add 1/2 Memlock delay */ - val += 0x5; // NOTE: middle value with DQSRCVEN_SAVED_GOOD_TIMES - p[i] = val; - pDCTstat->DimmTrainFail &= ~(1<<(Receiver + Channel)); - } - } - - return RcvrEnDly; -} diff --git a/src/northbridge/amd/amdmct/mct/mcttmrl.c b/src/northbridge/amd/amdmct/mct/mcttmrl.c deleted file mode 100644 index 6ec4d648d8..0000000000 --- a/src/northbridge/amd/amdmct/mct/mcttmrl.c +++ /dev/null @@ -1,409 +0,0 @@ -/* - * 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 <console/console.h> -#include <cpu/x86/cr.h> -#include <cpu/amd/msr.h> - -#include "mct_d.h" - -/* - * Description: Max Read Latency Training feature for DDR 2 MCT - */ - -static u8 CompareMaxRdLatTestPattern_D(u32 pattern_buf, u32 addr); -static u32 GetMaxRdLatTestAddr_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 Channel, - u8 *MaxRcvrEnDly, u8 *valid); -u8 mct_GetStartMaxRdLat_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, u8 Channel, - u8 DQSRcvEnDly, u32 *Margin); -static void maxRdLatencyTrain_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat); -static void mct_setMaxRdLatTrnVal_D(struct DCTStatStruc *pDCTstat, u8 Channel, - u16 MaxRdLatVal); - -/*Warning: These must be located so they do not cross a logical 16-bit - segment boundary!*/ -static const u32 TestMaxRdLAtPattern_D[] = { - 0x6E0E3FAC, 0x0C3CFF52, - 0x4A688181, 0x49C5B613, - 0x7C780BA6, 0x5C1650E3, - 0x0C4F9D76, 0x0C6753E6, - 0x205535A5, 0xBABFB6CA, - 0x610E6E5F, 0x0C5F1C87, - 0x488493CE, 0x14C9C383, - 0xF5B9A5CD, 0x9CE8F615, - - 0xAAD714B5, 0xC38F1B4C, - 0x72ED647C, 0x669F7562, - 0x5233F802, 0x4A898B30, - 0x10A40617, 0x3326B465, - 0x55386E04, 0xC807E3D3, - 0xAB49E193, 0x14B4E63A, - 0x67DF2495, 0xEA517C45, - 0x7624CE51, 0xF8140C51, - - 0x4824BD23, 0xB61DD0C9, - 0x072BCFBE, 0xE8F3807D, - 0x919EA373, 0x25E30C47, - 0xFEB12958, 0x4DA80A5A, - 0xE9A0DDF8, 0x792B0076, - 0xE81C73DC, 0xF025B496, - 0x1DB7E627, 0x808594FE, - 0x82668268, 0x655C7783, -}; - - -static u32 SetupMaxRdPattern(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, - u32 *buffer) -{ - /* 1. Copy the alpha and Beta patterns from ROM to Cache, - * aligning on 16 byte boundary - * 2. Set the ptr to Cacheable copy in DCTStatstruc.PtrPatternBufA - * for Alpha - * 3. Set the ptr to Cacheable copy in DCTStatstruc.PtrPatternBufB - * for Beta - */ - - u32 *buf; - u8 i; - - buf = (u32 *)(((u32)buffer + 0x10) & (0xfffffff0)); - - for (i = 0; i < (16 * 3); i++) { - buf[i] = TestMaxRdLAtPattern_D[i]; - } - - return (u32)buf; - -} - - -void TrainMaxReadLatency_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstatA) -{ - u8 Node; - - for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { - struct DCTStatStruc *pDCTstat; - pDCTstat = pDCTstatA + Node; - - if (!pDCTstat->NodePresent) - break; - - if (pDCTstat->DCTSysLimit) - maxRdLatencyTrain_D(pMCTstat, pDCTstat); - } -} - - -static void maxRdLatencyTrain_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat) -{ - u8 Channel; - u32 TestAddr0; - u8 _DisableDramECC = 0, _Wrap32Dis = 0, _SSE2 = 0; - u16 MaxRdLatDly; - u8 RcvrEnDly = 0; - u32 PatternBuffer[60]; // FIXME: why not 48 + 4 - u32 Margin; - u32 addr; - CRx_TYPE cr4; - u32 lo, hi; - - u8 valid; - u32 pattern_buf; - - cr4 = read_cr4(); - if (cr4 & (1<<9)) { /* save the old value */ - _SSE2 = 1; - } - cr4 |= (1<<9); /* OSFXSR enable SSE2 */ - write_cr4(cr4); - - addr = HWCR_MSR; - _RDMSR(addr, &lo, &hi); - if (lo & (1<<17)) { /* save the old value */ - _Wrap32Dis = 1; - } - lo |= (1<<17); /* HWCR.wrap32dis */ - lo &= ~(1<<15); /* SSEDIS */ - /* Setting wrap32dis allows 64-bit memory references in - real mode */ - _WRMSR(addr, lo, hi); - - _DisableDramECC = mct_DisableDimmEccEn_D(pMCTstat, pDCTstat); - - pattern_buf = SetupMaxRdPattern(pMCTstat, pDCTstat, PatternBuffer); - - for (Channel = 0; Channel < 2; Channel++) { - print_debug_dqs("\tMaxRdLatencyTrain51: Channel ",Channel, 1); - pDCTstat->Channel = Channel; - - if ((pDCTstat->Status & (1 << SB_128bitmode)) && Channel) - break; /*if ganged mode, skip DCT 1 */ - - TestAddr0 = GetMaxRdLatTestAddr_D(pMCTstat, pDCTstat, Channel, &RcvrEnDly, &valid); - if (!valid) /* Address not supported on current CS */ - continue; - /* rank 1 of DIMM, testpattern 0 */ - WriteMaxRdLat1CLTestPattern_D(pattern_buf, TestAddr0); - - MaxRdLatDly = mct_GetStartMaxRdLat_D(pMCTstat, pDCTstat, Channel, RcvrEnDly, &Margin); - print_debug_dqs("\tMaxRdLatencyTrain52: MaxRdLatDly start ", MaxRdLatDly, 2); - print_debug_dqs("\tMaxRdLatencyTrain52: MaxRdLatDly Margin ", Margin, 2); - while (MaxRdLatDly < MAX_RD_LAT) { /* sweep Delay value here */ - mct_setMaxRdLatTrnVal_D(pDCTstat, Channel, MaxRdLatDly); - ReadMaxRdLat1CLTestPattern_D(TestAddr0); - if (CompareMaxRdLatTestPattern_D(pattern_buf, TestAddr0) == DQS_PASS) - break; - SetTargetWTIO_D(TestAddr0); - FlushMaxRdLatTestPattern_D(TestAddr0); - ResetTargetWTIO_D(); - MaxRdLatDly++; - } - print_debug_dqs("\tMaxRdLatencyTrain53: MaxRdLatDly end ", MaxRdLatDly, 2); - mct_setMaxRdLatTrnVal_D(pDCTstat, Channel, MaxRdLatDly + Margin); - } - - if (_DisableDramECC) { - mct_EnableDimmEccEn_D(pMCTstat, pDCTstat, _DisableDramECC); - } - - if (!_Wrap32Dis) { - addr = HWCR_MSR; - _RDMSR(addr, &lo, &hi); - lo &= ~(1<<17); /* restore HWCR.wrap32dis */ - _WRMSR(addr, lo, hi); - } - if (!_SSE2) { - cr4 = read_cr4(); - cr4 &= ~(1<<9); /* restore cr4.OSFXSR */ - write_cr4(cr4); - } - -#if DQS_TRAIN_DEBUG > 0 - { - u8 Channel; - printk(BIOS_DEBUG, "maxRdLatencyTrain: CH_MaxRdLat:\n"); - for (Channel = 0; Channel < 2; Channel++) { - printk(BIOS_DEBUG, "Channel: %02x: %02x\n", Channel, pDCTstat->CH_MaxRdLat[Channel]); - } - } -#endif - -} - -static void mct_setMaxRdLatTrnVal_D(struct DCTStatStruc *pDCTstat, - u8 Channel, u16 MaxRdLatVal) -{ - u8 i; - u32 reg; - u32 dev; - u32 val; - - if (pDCTstat->GangedMode) { - Channel = 0; // for safe - for (i = 0; i < 2; i++) - pDCTstat->CH_MaxRdLat[i] = MaxRdLatVal; - } else { - pDCTstat->CH_MaxRdLat[Channel] = MaxRdLatVal; - } - - dev = pDCTstat->dev_dct; - reg = 0x78 + Channel * 0x100; - val = Get_NB32(dev, reg); - val &= ~(0x3ff<<22); - val |= MaxRdLatVal << 22; - /* program MaxRdLatency to correspond with current delay */ - Set_NB32(dev, reg, val); - -} - - -static u8 CompareMaxRdLatTestPattern_D(u32 pattern_buf, u32 addr) -{ - /* Compare only the first beat of data. Since target addrs are cache - * line aligned, the Channel parameter is used to determine which cache - * QW to compare. - */ - - u32 *test_buf = (u32 *)pattern_buf; - u32 addr_lo; - u32 val, val_test; - int i; - u8 ret = DQS_PASS; - - SetUpperFSbase(addr); - addr_lo = addr << 8; - - _EXECFENCE; - for (i = 0; i < (16*3); i++) { - val = read32_fs(addr_lo); - val_test = test_buf[i]; - - print_debug_dqs_pair("\t\t\t\t\t\ttest_buf = ", (u32)test_buf, " value = ", val_test, 5); - print_debug_dqs_pair("\t\t\t\t\t\ttaddr_lo = ", addr_lo, " value = ", val, 5); - if (val != val_test) { - ret = DQS_FAIL; - break; - } - addr_lo += 4; - } - - return ret; -} - -static u32 GetMaxRdLatTestAddr_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, - u8 Channel, u8 *MaxRcvrEnDly, - u8 *valid) -{ - u8 Max = 0; - - u8 Channel_Max = 0; - u8 d; - u8 d_Max = 0; - - u8 Byte; - u32 TestAddr0 = 0; - u8 ch, ch_start, ch_end; - u8 bn; - - bn = 8; - - if (pDCTstat->Status & (1 << SB_128bitmode)) { - ch_start = 0; - ch_end = 2; - } else { - ch_start = Channel; - ch_end = Channel + 1; - } - - *valid = 0; - - for (ch = ch_start; ch < ch_end; ch++) { - for (d = 0; d < 4; d++) { - for (Byte = 0; Byte < bn; Byte++) { - u8 tmp; - tmp = pDCTstat->persistentData.CH_D_B_RCVRDLY[ch][d][Byte]; - if (tmp > Max) { - Max = tmp; - Channel_Max = Channel; - d_Max = d; - } - } - } - } - - if (mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, Channel_Max, d_Max << 1)) { - TestAddr0 = mct_GetMCTSysAddr_D(pMCTstat, pDCTstat, Channel_Max, d_Max << 1, valid); - } - - if (*valid) - *MaxRcvrEnDly = Max; - - return TestAddr0; - -} - -u8 mct_GetStartMaxRdLat_D(struct MCTStatStruc *pMCTstat, - struct DCTStatStruc *pDCTstat, - u8 Channel, u8 DQSRcvEnDly, u32 *Margin) -{ - u32 SubTotal; - u32 val; - u32 valx; - u32 valxx; - u32 index_reg; - u32 reg_off; - u32 dev; - - if (pDCTstat->GangedMode) - Channel = 0; - - index_reg = 0x98 + 0x100 * Channel; - - reg_off = 0x100 * Channel; - dev = pDCTstat->dev_dct; - - /* Multiply the CAS Latency by two to get a number of 1/2 MEMCLKs units.*/ - val = Get_NB32(dev, 0x88 + reg_off); - SubTotal = ((val & 0x0f) + 1) << 1; /* SubTotal is 1/2 Memclk unit */ - - /* If registered DIMMs are being used then add 1 MEMCLK to the sub-total*/ - val = Get_NB32(dev, 0x90 + reg_off); - if (!(val & (1 << UnBuffDimm))) - SubTotal += 2; - - /*If the address prelaunch is setup for 1/2 MEMCLKs then add 1, - * else add 2 to the sub-total. if (AddrCmdSetup || CsOdtSetup - * || CkeSetup) then K := K + 2; */ - val = Get_NB32_index_wait(dev, index_reg, 0x04); - if (!(val & 0x00202020)) - SubTotal += 1; - else - SubTotal += 2; - - /* If the F2x[1, 0]78[RdPtrInit] field is 4, 5, 6 or 7 MEMCLKs, - * then add 4, 3, 2, or 1 MEMCLKs, respectively to the sub-total. */ - val = Get_NB32(dev, 0x78 + reg_off); - SubTotal += 8 - (val & 0x0f); - - /* Convert bits 7-5 (also referred to as the course delay) of the current - * (or worst case) DQS receiver enable delay to 1/2 MEMCLKs units, - * rounding up, and add this to the sub-total. */ - SubTotal += DQSRcvEnDly >> 5; /*BOZO-no rounding up */ - - SubTotal <<= 1; /*scale 1/2 MemClk to 1/4 MemClk */ - - /* Convert the sub-total (in 1/2 MEMCLKs) to northbridge clocks (NCLKs) - * as follows (assuming DDR400 and assuming that no P-state or link speed - * changes have occurred). */ - - /*New formula: - SubTotal *= 3*(Fn2xD4[NBFid]+4)/(3+Fn2x94[MemClkFreq])/2 */ - val = Get_NB32(dev, 0x94 + reg_off); - /* SubTotal div 4 to scale 1/4 MemClk back to MemClk */ - val &= 7; - if (val == 4) { - val++; /* adjust for DDR2-1066 */ - } - valx = (val + 3) << 2; /* SubTotal div 4 to scale 1/4 MemClk back to MemClk */ - - - val = Get_NB32(pDCTstat->dev_nbmisc, 0xD4); - val = ((val & 0x1f) + 4) * 3; - - /* Calculate 1 MemClk + 1 NCLK delay in NCLKs for margin */ - valxx = val << 2; - valxx /= valx; - if (valxx % valx) - valxx++; /* round up */ - valxx++; /* add 1NCLK */ - *Margin = valxx; /* one MemClk delay in NCLKs and one additional NCLK */ - - val *= SubTotal; - - val /= valx; - if (val % valx) - val++; /* round up */ - - - - return val; -} |