amd/mct/ddr2|ddr3: Refactor persistent members of DCTStatStruc
Several members of DCTStatStruc are designed to persist across resets of all other members. Move the persistent members into a substructure in order to simplify the reset logic and avoid compiler warnings / UB. Change-Id: I1139b7b3b167d33d99619338d42fcd26e2581a5d Signed-off-by: Timothy Pearson <tpearson@raptorengineering.com> Reviewed-on: https://review.coreboot.org/18058 Tested-by: build bot (Jenkins) Tested-by: Raptor Engineering Automated Test Stand <noreply@raptorengineeringinc.com> Reviewed-by: Nico Huber <nico.h@gmx.de>
This commit is contained in:
parent
8c42424ec1
commit
a4dcdca7ba
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the coreboot project.
|
* This file is part of the coreboot project.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
|
* Copyright (C) 2015-2017 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
|
||||||
* Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
|
* Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -35,6 +35,8 @@
|
||||||
|
|
||||||
#include "mct_d.h"
|
#include "mct_d.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
static u8 ReconfigureDIMMspare_D(struct MCTStatStruc *pMCTstat,
|
static u8 ReconfigureDIMMspare_D(struct MCTStatStruc *pMCTstat,
|
||||||
struct DCTStatStruc *pDCTstatA);
|
struct DCTStatStruc *pDCTstatA);
|
||||||
static void DQSTiming_D(struct MCTStatStruc *pMCTstat,
|
static void DQSTiming_D(struct MCTStatStruc *pMCTstat,
|
||||||
|
@ -459,7 +461,7 @@ static void LoadDQSSigTmgRegs_D(struct MCTStatStruc *pMCTstat,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Dir = 0; Dir < 2; Dir++) {//RD/WR
|
for (Dir = 0; Dir < 2; Dir++) {//RD/WR
|
||||||
p = pDCTstat->CH_D_DIR_B_DQS[Channel][DIMM][Dir];
|
p = pDCTstat->persistentData.CH_D_DIR_B_DQS[Channel][DIMM][Dir];
|
||||||
val = stream_to_int(p); /* CHA Read Data Timing High */
|
val = stream_to_int(p); /* CHA Read Data Timing High */
|
||||||
Set_NB32_index_wait(dev, index_reg, index+1, val);
|
Set_NB32_index_wait(dev, index_reg, index+1, val);
|
||||||
val = stream_to_int(p+4); /* CHA Write Data Timing High */
|
val = stream_to_int(p+4); /* CHA Write Data Timing High */
|
||||||
|
@ -3598,37 +3600,16 @@ static void mct_ResetDataStruct_D(struct MCTStatStruc *pMCTstat,
|
||||||
struct DCTStatStruc *pDCTstatA)
|
struct DCTStatStruc *pDCTstatA)
|
||||||
{
|
{
|
||||||
u8 Node;
|
u8 Node;
|
||||||
u32 i;
|
|
||||||
struct DCTStatStruc *pDCTstat;
|
struct DCTStatStruc *pDCTstat;
|
||||||
u32 start, stop;
|
|
||||||
u8 *p;
|
|
||||||
u16 host_serv1, host_serv2;
|
|
||||||
|
|
||||||
/* Initialize Data structures by clearing all entries to 0 */
|
/* Initialize Data structures by clearing all entries to 0 */
|
||||||
p = (u8 *) pMCTstat;
|
memset(pMCTstat, 0x00, sizeof(*pMCTstat));
|
||||||
for (i = 0; i < sizeof(struct MCTStatStruc); i++) {
|
|
||||||
p[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Node = 0; Node < 8; Node++) {
|
for (Node = 0; Node < 8; Node++) {
|
||||||
pDCTstat = pDCTstatA + Node;
|
pDCTstat = pDCTstatA + Node;
|
||||||
host_serv1 = pDCTstat->HostBiosSrvc1;
|
|
||||||
host_serv2 = pDCTstat->HostBiosSrvc2;
|
|
||||||
|
|
||||||
p = (u8 *) pDCTstat;
|
/* Clear all entries except persistentData */
|
||||||
start = 0;
|
memset(pDCTstat, 0x00, sizeof(*pDCTstat) - sizeof(pDCTstat->persistentData));
|
||||||
stop = (u32)(&((struct DCTStatStruc *)0)->CH_MaxRdLat[2]);
|
|
||||||
for (i = start; i < stop; i++) {
|
|
||||||
p[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
start = (u32)(&((struct DCTStatStruc *)0)->CH_D_BC_RCVRDLY[2][4]);
|
|
||||||
stop = sizeof(struct DCTStatStruc);
|
|
||||||
for (i = start; i < stop; i++) {
|
|
||||||
p[i] = 0;
|
|
||||||
}
|
|
||||||
pDCTstat->HostBiosSrvc1 = host_serv1;
|
|
||||||
pDCTstat->HostBiosSrvc2 = host_serv2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the coreboot project.
|
* This file is part of the coreboot project.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
|
* Copyright (C) 2015-2017 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
|
||||||
* Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
|
* Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -296,6 +296,34 @@ struct MCTStatStruc {
|
||||||
Local DCT Status structure (a structure for each DCT)
|
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.*/
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
|
||||||
struct DCTStatStruc { /* A per Node structure*/
|
struct DCTStatStruc { /* A per Node structure*/
|
||||||
/* DCTStatStruct_F - start */
|
/* DCTStatStruct_F - start */
|
||||||
u8 Node_ID; /* Node ID of current controller*/
|
u8 Node_ID; /* Node ID of current controller*/
|
||||||
|
@ -445,8 +473,6 @@ struct DCTStatStruc { /* A per Node structure*/
|
||||||
/* CH B byte lane 0 - 7 minimum 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 B byte lane 0 - 7 maximum filtered window passing DQS delay value*/
|
||||||
uint64_t LogicalCPUID; /* The logical CPUID of the node*/
|
uint64_t 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 DimmQRPresent; /* QuadRank DIMM present?*/
|
||||||
u16 DimmTrainFail; /* Bitmap showing which dimms failed training*/
|
u16 DimmTrainFail; /* Bitmap showing which dimms failed training*/
|
||||||
u16 CSTrainFail; /* Bitmap showing which chipselects failed training*/
|
u16 CSTrainFail; /* Bitmap showing which chipselects failed training*/
|
||||||
|
@ -462,28 +488,6 @@ struct DCTStatStruc { /* A per Node structure*/
|
||||||
|
|
||||||
u16 CH_MaxRdLat[2]; /* Max Read Latency (ns) for DCT 0*/
|
u16 CH_MaxRdLat[2]; /* Max Read Latency (ns) for DCT 0*/
|
||||||
/* Max Read Latency (ns) for DCT 1*/
|
/* Max Read Latency (ns) for DCT 1*/
|
||||||
u8 CH_D_DIR_B_DQS[2][4][2][9]; /* [A/B] [DIMM1-4] [R/W] [DQS] */
|
|
||||||
/* CHA DIMM0 Byte 0 - 7 and Check Write DQS Delay*/
|
|
||||||
/* CHA DIMM0 Byte 0 - 7 and Check Read DQS Delay*/
|
|
||||||
/* CHA DIMM1 Byte 0 - 7 and Check Write DQS Delay*/
|
|
||||||
/* CHA DIMM1 Byte 0 - 7 and Check Read DQS Delay*/
|
|
||||||
/* CHB DIMM0 Byte 0 - 7 and Check Write DQS Delay*/
|
|
||||||
/* CHB DIMM0 Byte 0 - 7 and Check Read DQS Delay*/
|
|
||||||
/* CHB DIMM1 Byte 0 - 7 and Check Write DQS Delay*/
|
|
||||||
/* CHB DIMM1 Byte 0 - 7 and Check Read DQS Delay*/
|
|
||||||
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*/
|
|
||||||
u8 DIMMValidDCT[2]; /* DIMM# in DCT0*/
|
u8 DIMMValidDCT[2]; /* DIMM# in DCT0*/
|
||||||
/* DIMM# in DCT1*/
|
/* DIMM# in DCT1*/
|
||||||
u8 MaxDCTs; /* Max number of DCTs in system*/
|
u8 MaxDCTs; /* Max number of DCTs in system*/
|
||||||
|
@ -542,6 +546,9 @@ struct DCTStatStruc { /* A per Node structure*/
|
||||||
char DimmPartNumber[MAX_DIMMS_SUPPORTED][SPD_PARTN_LENGTH+1];
|
char DimmPartNumber[MAX_DIMMS_SUPPORTED][SPD_PARTN_LENGTH+1];
|
||||||
uint16_t DimmRevisionNumber[MAX_DIMMS_SUPPORTED];
|
uint16_t DimmRevisionNumber[MAX_DIMMS_SUPPORTED];
|
||||||
uint32_t DimmSerialNumber[MAX_DIMMS_SUPPORTED];
|
uint32_t DimmSerialNumber[MAX_DIMMS_SUPPORTED];
|
||||||
|
|
||||||
|
/* NOTE: This must remain the last entry in this structure */
|
||||||
|
struct DCTPersistentStatStruc persistentData;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
/*===============================================================================
|
/*===============================================================================
|
||||||
|
|
|
@ -351,7 +351,7 @@ static void TrainDQSRdWrPos_D(struct MCTStatStruc *pMCTstat,
|
||||||
printk(BIOS_DEBUG, "Channel: %02x\n", Channel);
|
printk(BIOS_DEBUG, "Channel: %02x\n", Channel);
|
||||||
for (Receiver = cs_start; Receiver < (cs_start + 2); Receiver += 2) {
|
for (Receiver = cs_start; Receiver < (cs_start + 2); Receiver += 2) {
|
||||||
printk(BIOS_DEBUG, "\t\tReceiver: %02x: ", Receiver);
|
printk(BIOS_DEBUG, "\t\tReceiver: %02x: ", Receiver);
|
||||||
p = pDCTstat->CH_D_DIR_B_DQS[Channel][Receiver >> 1][Dir];
|
p = pDCTstat->persistentData.CH_D_DIR_B_DQS[Channel][Receiver >> 1][Dir];
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
val = p[i];
|
val = p[i];
|
||||||
printk(BIOS_DEBUG, "%02x ", val);
|
printk(BIOS_DEBUG, "%02x ", val);
|
||||||
|
@ -583,7 +583,7 @@ void StoreDQSDatStrucVal_D(struct MCTStatStruc *pMCTstat,
|
||||||
if (pDCTstat->Status & (1 << SB_Over400MHz))
|
if (pDCTstat->Status & (1 << SB_Over400MHz))
|
||||||
dn = ChipSel>>1; /* if odd or even logical DIMM */
|
dn = ChipSel>>1; /* if odd or even logical DIMM */
|
||||||
|
|
||||||
pDCTstat->CH_D_DIR_B_DQS[pDCTstat->Channel][dn][pDCTstat->Direction][pDCTstat->ByteLane] =
|
pDCTstat->persistentData.CH_D_DIR_B_DQS[pDCTstat->Channel][dn][pDCTstat->Direction][pDCTstat->ByteLane] =
|
||||||
pDCTstat->DQSDelay;
|
pDCTstat->DQSDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,7 +606,7 @@ static void GetDQSDatStrucVal_D(struct MCTStatStruc *pMCTstat,
|
||||||
dn = ChipSel >> 1; /*if odd or even logical DIMM */
|
dn = ChipSel >> 1; /*if odd or even logical DIMM */
|
||||||
|
|
||||||
pDCTstat->DQSDelay =
|
pDCTstat->DQSDelay =
|
||||||
pDCTstat->CH_D_DIR_B_DQS[pDCTstat->Channel][dn][pDCTstat->Direction][pDCTstat->ByteLane];
|
pDCTstat->persistentData.CH_D_DIR_B_DQS[pDCTstat->Channel][dn][pDCTstat->Direction][pDCTstat->ByteLane];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -476,7 +476,7 @@ static void dqsTrainRcvrEn_SW(struct MCTStatStruc *pMCTstat,
|
||||||
printk(BIOS_DEBUG, "Channel: %02x\n", Channel);
|
printk(BIOS_DEBUG, "Channel: %02x\n", Channel);
|
||||||
for (Receiver = 0; Receiver < 8; Receiver+=2) {
|
for (Receiver = 0; Receiver < 8; Receiver+=2) {
|
||||||
printk(BIOS_DEBUG, "\t\tReceiver: %02x: ", Receiver);
|
printk(BIOS_DEBUG, "\t\tReceiver: %02x: ", Receiver);
|
||||||
p = pDCTstat->CH_D_B_RCVRDLY[Channel][Receiver>>1];
|
p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][Receiver>>1];
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
val = p[i];
|
val = p[i];
|
||||||
printk(BIOS_DEBUG, "%02x ", val);
|
printk(BIOS_DEBUG, "%02x ", val);
|
||||||
|
@ -567,7 +567,7 @@ void mct_SetRcvrEnDly_D(struct DCTStatStruc *pDCTstat, u8 RcvrEnDly,
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
if (FinalValue) {
|
if (FinalValue) {
|
||||||
/*calculate dimm offset */
|
/*calculate dimm offset */
|
||||||
p = pDCTstat->CH_D_B_RCVRDLY[Channel][Receiver >> 1];
|
p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][Receiver >> 1];
|
||||||
RcvrEnDly = p[i];
|
RcvrEnDly = p[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -719,11 +719,11 @@ static u8 mct_SavePassRcvEnDly_D(struct DCTStatStruc *pDCTstat,
|
||||||
|
|
||||||
/* find desired stack offset according to channel/dimm/byte */
|
/* find desired stack offset according to channel/dimm/byte */
|
||||||
if (Pass == SecondPass) {
|
if (Pass == SecondPass) {
|
||||||
// FIXME: SecondPass is never used for Barcelona p = pDCTstat->CH_D_B_RCVRDLY_1[Channel][receiver>>1];
|
// FIXME: SecondPass is never used for Barcelona p = pDCTstat->persistentData.CH_D_B_RCVRDLY_1[Channel][receiver>>1];
|
||||||
p = 0; // Keep the compiler happy.
|
p = 0; // Keep the compiler happy.
|
||||||
} else {
|
} else {
|
||||||
mask_Saved &= mask_Pass;
|
mask_Saved &= mask_Pass;
|
||||||
p = pDCTstat->CH_D_B_RCVRDLY[Channel][receiver>>1];
|
p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][receiver>>1];
|
||||||
}
|
}
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
/* cmp per byte lane */
|
/* cmp per byte lane */
|
||||||
|
@ -903,7 +903,7 @@ void SetEccDQSRcvrEn_D(struct DCTStatStruc *pDCTstat, u8 Channel)
|
||||||
dev = pDCTstat->dev_dct;
|
dev = pDCTstat->dev_dct;
|
||||||
index_reg = 0x98 + Channel * 0x100;
|
index_reg = 0x98 + Channel * 0x100;
|
||||||
index = 0x12;
|
index = 0x12;
|
||||||
p = pDCTstat->CH_D_BC_RCVRDLY[Channel];
|
p = pDCTstat->persistentData.CH_D_BC_RCVRDLY[Channel];
|
||||||
print_debug_dqs("\t\tSetEccDQSRcvrPos: Channel ", Channel, 2);
|
print_debug_dqs("\t\tSetEccDQSRcvrPos: Channel ", Channel, 2);
|
||||||
for (ChipSel = 0; ChipSel < MAX_CS_SUPPORTED; ChipSel += 2) {
|
for (ChipSel = 0; ChipSel < MAX_CS_SUPPORTED; ChipSel += 2) {
|
||||||
val = p[ChipSel>>1];
|
val = p[ChipSel>>1];
|
||||||
|
@ -929,7 +929,7 @@ static void CalcEccDQSRcvrEn_D(struct MCTStatStruc *pMCTstat,
|
||||||
for (ChipSel = 0; ChipSel < MAX_CS_SUPPORTED; ChipSel += 2) {
|
for (ChipSel = 0; ChipSel < MAX_CS_SUPPORTED; ChipSel += 2) {
|
||||||
if (mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, Channel, ChipSel)) {
|
if (mct_RcvrRankEnabled_D(pMCTstat, pDCTstat, Channel, ChipSel)) {
|
||||||
u8 *p;
|
u8 *p;
|
||||||
p = pDCTstat->CH_D_B_RCVRDLY[Channel][ChipSel>>1];
|
p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][ChipSel>>1];
|
||||||
|
|
||||||
/* DQS Delay Value of Data Bytelane
|
/* DQS Delay Value of Data Bytelane
|
||||||
* most like ECC byte lane */
|
* most like ECC byte lane */
|
||||||
|
@ -953,7 +953,7 @@ static void CalcEccDQSRcvrEn_D(struct MCTStatStruc *pMCTstat,
|
||||||
val += val0;
|
val += val0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pDCTstat->CH_D_BC_RCVRDLY[Channel][ChipSel>>1] = val;
|
pDCTstat->persistentData.CH_D_BC_RCVRDLY[Channel][ChipSel>>1] = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SetEccDQSRcvrEn_D(pDCTstat, Channel);
|
SetEccDQSRcvrEn_D(pDCTstat, Channel);
|
||||||
|
|
|
@ -49,7 +49,7 @@ static u8 mct_Average_RcvrEnDly_1Pass(struct DCTStatStruc *pDCTstat, u8 Channel,
|
||||||
u8 val;
|
u8 val;
|
||||||
|
|
||||||
MaxValue = 0;
|
MaxValue = 0;
|
||||||
p = pDCTstat->CH_D_B_RCVRDLY[Channel][Receiver >> 1];
|
p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][Receiver >> 1];
|
||||||
|
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
/* get left value from DCTStatStruc.CHA_D0_B0_RCVRDLY*/
|
/* get left value from DCTStatStruc.CHA_D0_B0_RCVRDLY*/
|
||||||
|
|
|
@ -57,7 +57,7 @@ u8 mct_Get_Start_RcvrEnDly_Pass(struct DCTStatStruc *pDCTstat,
|
||||||
u8 max = 0;
|
u8 max = 0;
|
||||||
u8 val;
|
u8 val;
|
||||||
u8 i;
|
u8 i;
|
||||||
u8 *p = pDCTstat->CH_D_B_RCVRDLY[Channel][Receiver>>1];
|
u8 *p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][Receiver>>1];
|
||||||
u8 bn;
|
u8 bn;
|
||||||
bn = 8;
|
bn = 8;
|
||||||
|
|
||||||
|
@ -91,12 +91,12 @@ u8 mct_Average_RcvrEnDly_Pass(struct DCTStatStruc *pDCTstat,
|
||||||
|
|
||||||
bn = 8;
|
bn = 8;
|
||||||
|
|
||||||
p = pDCTstat->CH_D_B_RCVRDLY[Channel][Receiver>>1];
|
p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][Receiver>>1];
|
||||||
|
|
||||||
if (Pass == SecondPass) { /* second pass must average values */
|
if (Pass == SecondPass) { /* second pass must average values */
|
||||||
//FIXME: which byte?
|
//FIXME: which byte?
|
||||||
p_1 = pDCTstat->B_RCVRDLY_1;
|
p_1 = pDCTstat->B_RCVRDLY_1;
|
||||||
// p_1 = pDCTstat->CH_D_B_RCVRDLY_1[Channel][Receiver>>1];
|
// p_1 = pDCTstat->persistentData.CH_D_B_RCVRDLY_1[Channel][Receiver>>1];
|
||||||
for (i = 0; i < bn; i++) {
|
for (i = 0; i < bn; i++) {
|
||||||
val = p[i];
|
val = p[i];
|
||||||
/* left edge */
|
/* left edge */
|
||||||
|
|
|
@ -297,7 +297,7 @@ static u32 GetMaxRdLatTestAddr_D(struct MCTStatStruc *pMCTstat,
|
||||||
for (d = 0; d < 4; d++) {
|
for (d = 0; d < 4; d++) {
|
||||||
for (Byte = 0; Byte < bn; Byte++) {
|
for (Byte = 0; Byte < bn; Byte++) {
|
||||||
u8 tmp;
|
u8 tmp;
|
||||||
tmp = pDCTstat->CH_D_B_RCVRDLY[ch][d][Byte];
|
tmp = pDCTstat->persistentData.CH_D_B_RCVRDLY[ch][d][Byte];
|
||||||
if (tmp > Max) {
|
if (tmp > Max) {
|
||||||
Max = tmp;
|
Max = tmp;
|
||||||
Channel_Max = Channel;
|
Channel_Max = Channel;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the coreboot project.
|
* This file is part of the coreboot project.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015-2016 Raptor Engineering, LLC
|
* Copyright (C) 2015-2017 Raptor Engineering, LLC
|
||||||
* Copyright (C) 2010 Advanced Micro Devices, Inc.
|
* Copyright (C) 2010 Advanced Micro Devices, Inc.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -3732,7 +3732,7 @@ static void LoadDQSSigTmgRegs_D(struct MCTStatStruc *pMCTstat,
|
||||||
2); /* Pass Second Pass ? */
|
2); /* Pass Second Pass ? */
|
||||||
/* Restore Write levelization training data */
|
/* Restore Write levelization training data */
|
||||||
for (ByteLane = 0; ByteLane < 9; ByteLane ++) {
|
for (ByteLane = 0; ByteLane < 9; ByteLane ++) {
|
||||||
txdqs = pDCTstat->CH_D_B_TxDqs[Channel][Receiver >> 1][ByteLane];
|
txdqs = pDCTstat->persistentData.CH_D_B_TxDqs[Channel][Receiver >> 1][ByteLane];
|
||||||
index = Table_DQSRcvEn_Offset[ByteLane >> 1];
|
index = Table_DQSRcvEn_Offset[ByteLane >> 1];
|
||||||
index += (Receiver >> 1) * 3 + 0x10 + 0x20; /* Addl_Index */
|
index += (Receiver >> 1) * 3 + 0x10 + 0x20; /* Addl_Index */
|
||||||
val = Get_NB32_index_wait_DCT(dev, Channel, 0x98, index);
|
val = Get_NB32_index_wait_DCT(dev, Channel, 0x98, index);
|
||||||
|
@ -7373,23 +7373,13 @@ static void mct_ResetDataStruct_D(struct MCTStatStruc *pMCTstat,
|
||||||
{
|
{
|
||||||
uint8_t Node;
|
uint8_t Node;
|
||||||
struct DCTStatStruc *pDCTstat;
|
struct DCTStatStruc *pDCTstat;
|
||||||
uint16_t host_serv1, host_serv2;
|
|
||||||
uint8_t CH_D_B_TxDqs_bkp[2][4][9];
|
|
||||||
|
|
||||||
/* Initialize Data structures by clearing all entries to 0 */
|
/* Initialize Data structures by clearing all entries to 0 */
|
||||||
memset(pMCTstat, 0, sizeof(struct MCTStatStruc));
|
memset(pMCTstat, 0, sizeof(*pMCTstat));
|
||||||
|
|
||||||
for (Node = 0; Node < 8; Node++) {
|
for (Node = 0; Node < 8; Node++) {
|
||||||
pDCTstat = pDCTstatA + Node;
|
pDCTstat = pDCTstatA + Node;
|
||||||
host_serv1 = pDCTstat->HostBiosSrvc1;
|
memset(pDCTstat, 0, sizeof(*pDCTstat) - sizeof(pDCTstat->persistentData));
|
||||||
host_serv2 = pDCTstat->HostBiosSrvc2;
|
|
||||||
memcpy(CH_D_B_TxDqs_bkp, pDCTstat->CH_D_B_TxDqs, sizeof(CH_D_B_TxDqs_bkp));
|
|
||||||
|
|
||||||
memset(pDCTstat, 0, sizeof(struct DCTStatStruc));
|
|
||||||
|
|
||||||
pDCTstat->HostBiosSrvc1 = host_serv1;
|
|
||||||
pDCTstat->HostBiosSrvc2 = host_serv2;
|
|
||||||
memcpy(pDCTstat->CH_D_B_TxDqs, CH_D_B_TxDqs_bkp, sizeof(pDCTstat->CH_D_B_TxDqs));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the coreboot project.
|
* This file is part of the coreboot project.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015-2016 Raptor Engineering, LLC
|
* Copyright (C) 2015-2017 Raptor Engineering, LLC
|
||||||
* Copyright (C) 2010 Advanced Micro Devices, Inc.
|
* Copyright (C) 2010 Advanced Micro Devices, Inc.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -335,6 +335,20 @@ struct amd_spd_node_data {
|
||||||
uint8_t nvram_memclk[2]; /* [channel] */
|
uint8_t nvram_memclk[2]; /* [channel] */
|
||||||
} __attribute__((packed, aligned(4)));
|
} __attribute__((packed, aligned(4)));
|
||||||
|
|
||||||
|
struct DCTPersistentStatStruc {
|
||||||
|
u8 CH_D_B_TxDqs[2][4][9]; /* [A/B] [DIMM1-4] [DQS] */
|
||||||
|
/* CHA DIMM0 Byte 0 - 7 TxDqs */
|
||||||
|
/* CHA DIMM0 Byte 0 - 7 TxDqs */
|
||||||
|
/* CHA DIMM1 Byte 0 - 7 TxDqs */
|
||||||
|
/* CHA DIMM1 Byte 0 - 7 TxDqs */
|
||||||
|
/* CHB DIMM0 Byte 0 - 7 TxDqs */
|
||||||
|
/* CHB DIMM0 Byte 0 - 7 TxDqs */
|
||||||
|
/* CHB DIMM1 Byte 0 - 7 TxDqs */
|
||||||
|
/* CHB DIMM1 Byte 0 - 7 TxDqs */
|
||||||
|
u16 HostBiosSrvc1; /* Word sized general purpose field for use by host BIOS. Scratch space.*/
|
||||||
|
u32 HostBiosSrvc2; /* Dword sized general purpose field for use by host BIOS. Scratch space.*/
|
||||||
|
} __attribute__((packed, aligned(4)));
|
||||||
|
|
||||||
struct DCTStatStruc { /* A per Node structure*/
|
struct DCTStatStruc { /* A per Node structure*/
|
||||||
/* DCTStatStruct_F - start */
|
/* DCTStatStruct_F - start */
|
||||||
u8 Node_ID; /* Node ID of current controller */
|
u8 Node_ID; /* Node ID of current controller */
|
||||||
|
@ -485,8 +499,6 @@ struct DCTStatStruc { /* A per Node structure*/
|
||||||
/* CH B byte lane 0 - 7 minimum 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 B byte lane 0 - 7 maximum filtered window passing DQS delay value*/
|
||||||
uint64_t LogicalCPUID; /* The logical CPUID of the node*/
|
uint64_t 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 DimmQRPresent; /* QuadRank DIMM present?*/
|
||||||
u16 DimmTrainFail; /* Bitmap showing which dimms failed training*/
|
u16 DimmTrainFail; /* Bitmap showing which dimms failed training*/
|
||||||
u16 CSTrainFail; /* Bitmap showing which chipselects failed training*/
|
u16 CSTrainFail; /* Bitmap showing which chipselects failed training*/
|
||||||
|
@ -513,15 +525,6 @@ struct DCTStatStruc { /* A per Node structure*/
|
||||||
/* CHB DIMM0 Byte 0 - 7 and Check Read 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 Write DQS Delay*/
|
||||||
/* CHB DIMM1 Byte 0 - 7 and Check Read DQS Delay*/
|
/* CHB DIMM1 Byte 0 - 7 and Check Read DQS Delay*/
|
||||||
u8 CH_D_B_TxDqs[2][4][9]; /* [A/B] [DIMM1-4] [DQS] */
|
|
||||||
/* CHA DIMM0 Byte 0 - 7 TxDqs */
|
|
||||||
/* CHA DIMM0 Byte 0 - 7 TxDqs */
|
|
||||||
/* CHA DIMM1 Byte 0 - 7 TxDqs */
|
|
||||||
/* CHA DIMM1 Byte 0 - 7 TxDqs */
|
|
||||||
/* CHB DIMM0 Byte 0 - 7 TxDqs */
|
|
||||||
/* CHB DIMM0 Byte 0 - 7 TxDqs */
|
|
||||||
/* CHB DIMM1 Byte 0 - 7 TxDqs */
|
|
||||||
/* CHB DIMM1 Byte 0 - 7 TxDqs */
|
|
||||||
u16 CH_D_B_RCVRDLY[2][4][8]; /* [A/B] [DIMM0-3] [DQS] */
|
u16 CH_D_B_RCVRDLY[2][4][8]; /* [A/B] [DIMM0-3] [DQS] */
|
||||||
/* CHA DIMM 0 Receiver Enable Delay*/
|
/* CHA DIMM 0 Receiver Enable Delay*/
|
||||||
/* CHA DIMM 1 Receiver Enable Delay*/
|
/* CHA DIMM 1 Receiver Enable Delay*/
|
||||||
|
@ -635,6 +638,9 @@ struct DCTStatStruc { /* A per Node structure*/
|
||||||
uint32_t DimmSerialNumber[MAX_DIMMS_SUPPORTED];
|
uint32_t DimmSerialNumber[MAX_DIMMS_SUPPORTED];
|
||||||
|
|
||||||
struct amd_spd_node_data spd_data;
|
struct amd_spd_node_data spd_data;
|
||||||
|
|
||||||
|
/* NOTE: This must remain the last entry in this structure */
|
||||||
|
struct DCTPersistentStatStruc persistentData;
|
||||||
} __attribute__((packed, aligned(4)));
|
} __attribute__((packed, aligned(4)));
|
||||||
|
|
||||||
struct amd_s3_persistent_mct_channel_data {
|
struct amd_s3_persistent_mct_channel_data {
|
||||||
|
|
|
@ -2301,7 +2301,7 @@ static void mct_SetDQSDelayCSR_D(struct MCTStatStruc *pMCTstat,
|
||||||
val = Get_NB32_index_wait_DCT(dev, pDCTstat->Channel, index_reg, index);
|
val = Get_NB32_index_wait_DCT(dev, pDCTstat->Channel, index_reg, index);
|
||||||
if (ByteLane < 8) {
|
if (ByteLane < 8) {
|
||||||
if (pDCTstat->Direction == DQS_WRITEDIR) {
|
if (pDCTstat->Direction == DQS_WRITEDIR) {
|
||||||
dqs_delay += pDCTstat->CH_D_B_TxDqs[pDCTstat->Channel][ChipSel>>1][ByteLane];
|
dqs_delay += pDCTstat->persistentData.CH_D_B_TxDqs[pDCTstat->Channel][ChipSel>>1][ByteLane];
|
||||||
} else {
|
} else {
|
||||||
dqs_delay <<= 1;
|
dqs_delay <<= 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ static void SetEccWrDQS_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pD
|
||||||
if (OddByte)
|
if (OddByte)
|
||||||
val >>= 16;
|
val >>= 16;
|
||||||
/* Save WrDqs to stack for later usage */
|
/* Save WrDqs to stack for later usage */
|
||||||
pDCTstat->CH_D_B_TxDqs[Channel][DimmNum][ByteLane] = val & 0xFF;
|
pDCTstat->persistentData.CH_D_B_TxDqs[Channel][DimmNum][ByteLane] = val & 0xFF;
|
||||||
EccDQSScale = pDCTstat->CH_EccDQSScale[Channel];
|
EccDQSScale = pDCTstat->CH_EccDQSScale[Channel];
|
||||||
word = pDCTstat->CH_EccDQSLike[Channel];
|
word = pDCTstat->CH_EccDQSLike[Channel];
|
||||||
if ((word & 0xFF) == ByteLane) EccRef1 = val & 0xFF;
|
if ((word & 0xFF) == ByteLane) EccRef1 = val & 0xFF;
|
||||||
|
|
|
@ -54,7 +54,7 @@ u8 mct_Get_Start_RcvrEnDly_Pass(struct DCTStatStruc *pDCTstat,
|
||||||
u8 max = 0;
|
u8 max = 0;
|
||||||
u8 val;
|
u8 val;
|
||||||
u8 i;
|
u8 i;
|
||||||
u8 *p = pDCTstat->CH_D_B_RCVRDLY[Channel][Receiver>>1];
|
u8 *p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][Receiver>>1];
|
||||||
u8 bn;
|
u8 bn;
|
||||||
bn = 8;
|
bn = 8;
|
||||||
|
|
||||||
|
@ -85,12 +85,12 @@ u16 mct_Average_RcvrEnDly_Pass(struct DCTStatStruc *pDCTstat,
|
||||||
|
|
||||||
bn = 8;
|
bn = 8;
|
||||||
|
|
||||||
p = pDCTstat->CH_D_B_RCVRDLY[Channel][Receiver>>1];
|
p = pDCTstat->persistentData.CH_D_B_RCVRDLY[Channel][Receiver>>1];
|
||||||
|
|
||||||
if (Pass == SecondPass) { /* second pass must average values */
|
if (Pass == SecondPass) { /* second pass must average values */
|
||||||
/* FIXME: which byte? */
|
/* FIXME: which byte? */
|
||||||
p_1 = pDCTstat->B_RCVRDLY_1;
|
p_1 = pDCTstat->B_RCVRDLY_1;
|
||||||
/* p_1 = pDCTstat->CH_D_B_RCVRDLY_1[Channel][Receiver>>1]; */
|
/* p_1 = pDCTstat->persistentData.CH_D_B_RCVRDLY_1[Channel][Receiver>>1]; */
|
||||||
for (i = 0; i < bn; i++) {
|
for (i = 0; i < bn; i++) {
|
||||||
val = p[i];
|
val = p[i];
|
||||||
/* left edge */
|
/* left edge */
|
||||||
|
|
Loading…
Reference in New Issue