/* $NoKeywords:$ */
/**
 * @file
 *
 * mtspd2.c
 *
 * Technology SPD supporting functions for DDR2
 *
 * @xrefitem bom "File Content Label" "Release Content"
 * @e project: AGESA
 * @e sub-project: (Mem/Tech/DDR2)
 * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
 *
 **/
/*
 *****************************************************************************
 *
 * Copyright (c) 2011, Advanced Micro Devices, Inc.
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Advanced Micro Devices, Inc. nor the names of 
 *       its contributors may be used to endorse or promote products derived 
 *       from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * ***************************************************************************
 *
 */

/*
 *----------------------------------------------------------------------------
 *                                MODULES USED
 *
 *----------------------------------------------------------------------------
 */



#include "AGESA.h"
#include "AdvancedApi.h"
#include "amdlib.h"
#include "Ids.h"
#include "mport.h"
#include "mm.h"
#include "mn.h"
#include "mt.h"
#include "mu.h"
#include "mt2.h"
#include "mtspd2.h"
#include "mftds.h"
#include "GeneralServices.h"
#include "Filecode.h"
CODE_GROUP (G1_PEICC)
RDATA_GROUP (G1_PEICC)

#define FILECODE PROC_MEM_TECH_DDR2_MTSPD2_FILECODE

/*----------------------------------------------------------------------------
 *                          DEFINITIONS AND MACROS
 *
 *----------------------------------------------------------------------------
 */

/*----------------------------------------------------------------------------
 *                           TYPEDEFS AND STRUCTURES
 *
 *----------------------------------------------------------------------------
 */

/*----------------------------------------------------------------------------
 *                        PROTOTYPES OF LOCAL FUNCTIONS
 *
 *----------------------------------------------------------------------------
 */

UINT8
STATIC
MemTSPDGetTCL2 (
  IN OUT   MEM_TECH_BLOCK *TechPtr
  );

BOOLEAN
STATIC
MemTSysCapability2 (
  IN OUT   MEM_TECH_BLOCK *TechPtr,
  IN       UINT8 k,
  IN       UINT16 j
  );

BOOLEAN
STATIC
MemTDimmSupports2 (
  IN OUT   MEM_TECH_BLOCK *TechPtr,
  IN       UINT8 k,
  IN       UINT8 j,
  IN       UINT8 i
  );

UINT8
STATIC
MemTGetTk2 (
  IN       UINT8 k
  );

UINT8
STATIC
MemTGetBankAddr2 (
  IN       UINT8 k
  );

/*----------------------------------------------------------------------------
 *                            EXPORTED FUNCTIONS
 *
 *----------------------------------------------------------------------------
 */

extern BUILD_OPT_CFG UserOptions;

/* -----------------------------------------------------------------------------*/
/**
 *
 *   This function sets the DRAM mode
 *
 *     @param[in,out]   *TechPtr   - Pointer to the MEM_TECH_BLOCK
 *
 *     @return  TRUE - indicates that the DRAM mode is set to DDR2
 */

BOOLEAN
MemTSetDramMode2 (
  IN OUT   MEM_TECH_BLOCK *TechPtr
  )
{
  TechPtr->NBPtr->SetBitField (TechPtr->NBPtr, BFLegacyBiosMode, 0);
  return TRUE;
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *   This function determines if DIMMs are present. It checks checksum and interrogates the SPDs
 *
 *     @param[in,out]   *TechPtr   - Pointer to the MEM_TECH_BLOCK
 *
 *     @return  TRUE - indicates that a FATAL error has not occurred
 *     @return  FALSE - indicates that a FATAL error has occurred
 */

BOOLEAN
MemTDIMMPresence2 (
  IN OUT   MEM_TECH_BLOCK *TechPtr
  )
{
  UINT8 *SpdBufferPtr;
  MEM_PARAMETER_STRUCT *RefPtr;
  DIE_STRUCT *MCTPtr;
  DCT_STRUCT *DCTPtr;
  CH_DEF_STRUCT *ChannelPtr;
  MEM_NB_BLOCK *NBPtr;
  UINT16 Checksum;
  UINT16 Value16;
  UINT8 Dct;
  UINT8 Channel;
  UINT8 i;
  UINT8 ByteNum;
  UINT8 Devwidth;
  UINT8 Value8;
  UINT8 MaxDimms;
  UINT8 DimmSlots;
  UINT16 DimmMask;
  BOOLEAN SPDCtrl;

  NBPtr = TechPtr->NBPtr;
  RefPtr = NBPtr->RefPtr;
  MCTPtr = NBPtr->MCTPtr;

  SPDCtrl = UserOptions.CfgIgnoreSpdChecksum;

  for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
    NBPtr->SwitchDCT (NBPtr, Dct);
    DCTPtr = NBPtr->DCTPtr;
    for (Channel = 0; Channel < NBPtr->ChannelCount; Channel++) {
      NBPtr->SwitchChannel (NBPtr, Channel);
      ChannelPtr = NBPtr->ChannelPtr;
      ChannelPtr->DimmQrPresent = 0;

      //  Get the maximum number of DIMMs
      DimmSlots = GetMaxDimmsPerChannel (RefPtr->PlatformMemoryConfiguration,
                                         MCTPtr->SocketId,
                                         NBPtr->GetSocketRelativeChannel (NBPtr, Dct, Channel)
                                        );
      MaxDimms = MAX_DIMMS_PER_CHANNEL;
      for (i = 0; i < MaxDimms; i++) {
        //  Bitmask representing dimm #i.
        DimmMask = (UINT16)1 << i;

        if ((ChannelPtr->DimmQrPresent & DimmMask) || (i < DimmSlots)) {
          if (MemTGetDimmSpdBuffer2 (TechPtr, &SpdBufferPtr, i)) {
            MCTPtr->DimmPresent |= DimmMask;

            //  Start by computing checksum for this SPD
            Checksum = 0;
            for (ByteNum = 0; ByteNum < SPD_CHECKSUM; ByteNum++) {
              Checksum = Checksum + (UINT16) SpdBufferPtr[ByteNum];
            }
            //  Check for valid checksum value
            AGESA_TESTPOINT (TpProcMemSPDChecking, &(NBPtr->MemPtr->StdHeader));

            if (SpdBufferPtr[SPD_TYPE] == JED_DDR2_SDRAM) {
              ChannelPtr->ChDimmValid |= DimmMask;
              MCTPtr->DimmValid |= DimmMask;
            } else {
              // Current socket is set up to only support DDR2 dimms.
              IDS_ERROR_TRAP;
            }
            if ((SpdBufferPtr[SPD_CHECKSUM] != (UINT8)Checksum) && !SPDCtrl) {
              //
              // if NV_SPDCHK_RESTRT is set to 0,
              // cannot ignore faulty SPD checksum
              //
              //  Indicate checksum error
              ChannelPtr->DimmSpdCse |= DimmMask;
              PutEventLog (AGESA_ERROR, MEM_ERROR_CHECKSUM_NV_SPDCHK_RESTRT_ERROR, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader);
              SetMemError (AGESA_ERROR, MCTPtr);
            }

            //  Check module type information.
            if (SpdBufferPtr[SPD_DIMM_TYPE] & JED_REG_ADC_MSK) {
              ChannelPtr->RegDimmPresent |= DimmMask;
              MCTPtr->RegDimmPresent |= DimmMask;
            }

            if (SpdBufferPtr[SPD_DIMM_TYPE] & JED_SODIMM) {
              ChannelPtr->SODimmPresent |= DimmMask;
            }

            //  Check error correction type
            if (SpdBufferPtr[SPD_EDC_TYPE] & JED_ECC) {
              MCTPtr->DimmEccPresent |= DimmMask;  //  Dimm has ECC
            }
            if (SpdBufferPtr[SPD_EDC_TYPE] & JED_ADRC_PAR) {
              MCTPtr->DimmParPresent |= DimmMask;  //  Dimm has parity
            }

            //  Get the Dimm width data
            Devwidth = SpdBufferPtr[SPD_DEV_WIDTH] & 0xFE;
            if (Devwidth == 4) {
              ChannelPtr->Dimmx4Present |= DimmMask;   //  Dimm has parity
            } else if (Devwidth == 8) {
              ChannelPtr->Dimmx8Present |= DimmMask;   //  Dimm has parity
            } else if (Devwidth == 16) {
              ChannelPtr->Dimmx16Present |= DimmMask;  //  Dimm has parity
            }

            //  Determine the page size.
            //       page_size = 2^COLBITS * Devwidth/8
            //
            Value16 = (((UINT16)1 << SpdBufferPtr[SPD_COL_SZ]) * Devwidth) / 8;
            if (!(Value16 >> 11)) {
              DCTPtr->Timings.DIMM1KPage |= DimmMask;
            }

            //  Check for 'analysis probe installed'
            if (SpdBufferPtr[SPD_ATTRIB] & JED_PROBE_MSK) {
              MCTPtr->Status[SbDiagClks] = TRUE;
            }

            //  Determine the geometry of the DIMM module
            if (SpdBufferPtr[SPD_DM_BANKS] & SP_DPL_BIT) {
              ChannelPtr->DimmPlPresent |= DimmMask;   //  Dimm is planar
            }

            //  specify the number of ranks
            Value8 = (SpdBufferPtr[SPD_DM_BANKS] & 0x07) + 1;
            if (Value8 > 2) {
              if (ChannelPtr->DimmQrPresent == 0) {
                // if any DIMMs are QR,
                // we have to make two passes through DIMMs
                //
                MaxDimms = MaxDimms << 1;
              }

              if (i < DimmSlots) {
                ChannelPtr->DimmQrPresent |= DimmMask;
                ChannelPtr->DimmQrPresent |= (DimmMask << 2);
              }
              Value8 = 2;
            } else if (Value8 == 2) {
              ChannelPtr->DimmDrPresent |= DimmMask;   //  Dual rank dimms
            }

            //  Calculate bus loading per Channel
            if (Devwidth == 16) {
              Devwidth = 4;
            } else if (Devwidth == 4) {
              Devwidth = 16;
            }
            //  double Addr bus load value for dual rank DIMMs
            if (Value8 == 2) {
              Devwidth = Devwidth << 1;
            }

            ChannelPtr->Ranks = ChannelPtr->Ranks + Value8;
            ChannelPtr->Loads = ChannelPtr->Loads + Devwidth;
            ChannelPtr->Dimms++;

            //  Now examine the dimm packaging dates
            Value8 = SpdBufferPtr[SPD_MAN_DATE_YR];
            if (Value8 < M_YEAR_06) {
              ChannelPtr->DimmYr06 |= DimmMask;    //  Built before end of 2006
              ChannelPtr->DimmWk2406 |= DimmMask;  //  Built before end of week 24,2006
            } else if (Value8 == M_YEAR_06) {
              ChannelPtr->DimmYr06 |= DimmMask;    //  Built before end of 2006
              if (SpdBufferPtr[SPD_MAN_DATE_WK] <= M_WEEK_24) {
                ChannelPtr->DimmWk2406 |= DimmMask;  //  Built before end of week 24,2006
              }
            }
          } // if DIMM present
        } // Quadrank
      } // Dimm loop

      if (Channel == 0) {
        DCTPtr->Timings.DctDimmValid = ChannelPtr->ChDimmValid;
        DCTPtr->Timings.DimmSpdCse = ChannelPtr->DimmSpdCse;
        DCTPtr->Timings.DimmQrPresent = ChannelPtr->DimmQrPresent;
        DCTPtr->Timings.DimmDrPresent = ChannelPtr->DimmDrPresent;
        DCTPtr->Timings.Dimmx4Present = ChannelPtr->Dimmx4Present;
        DCTPtr->Timings.Dimmx8Present = ChannelPtr->Dimmx8Present;
        DCTPtr->Timings.Dimmx16Present = ChannelPtr->Dimmx16Present;
      }
      if ((Channel != 1) || (Dct != 1)) {
        MCTPtr->DimmPresent <<= 8;
        MCTPtr->DimmValid <<= 8;
        MCTPtr->RegDimmPresent <<= 8;
        MCTPtr->DimmEccPresent <<= 8;
        MCTPtr->DimmParPresent <<= 8;
      }
    } // Channel loop
  } // DCT loop


  //  If we have DIMMs, some further general characteristics checking
  if (MCTPtr->DimmValid) {
    //  If there are registered dimms, all the dimms must be registered
    if (MCTPtr->RegDimmPresent == MCTPtr->DimmValid) {
      //  All dimms registered
      MCTPtr->Status[SbRegistered] = TRUE;
    } else if (MCTPtr->RegDimmPresent) {
      //  We have an illegal DIMM mismatch
      PutEventLog (AGESA_FATAL, MEM_ERROR_MODULE_TYPE_MISMATCH_DIMM, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader);
      SetMemError (AGESA_FATAL, MCTPtr);
    }

    //  check the ECC capability of the DIMMs
    if (MCTPtr->DimmEccPresent == MCTPtr->DimmValid) {
      MCTPtr->Status[SbEccDimms] = TRUE;  //  All dimms ECC capable
    }

    //  check the parity capability of the DIMMs
    if (MCTPtr->DimmParPresent == MCTPtr->DimmValid) {
      MCTPtr->Status[SbParDimms] = TRUE;  //  All dimms parity capable
    }
  } else {
  }

  NBPtr->SwitchDCT (NBPtr, 0);
  NBPtr->SwitchChannel (NBPtr, 0);
  return (BOOLEAN) (MCTPtr->ErrCode < AGESA_FATAL);
}


/* -----------------------------------------------------------------------------*/
/**
 *
 *   This function finds the best T and CL primary timing parameter pair, per Mfg.,for the given
 *   set of DIMMs, and store into DIE_STRUCT(.Speed and .Casl).
 *   See "Global relationship between index values and item values" for definition of
 *   CAS latency index (j) and Frequency index (k).
 *
 *     @param[in,out]   *TechPtr   - Pointer to the MEM_TECH_BLOCK
 *
 *     @return  TRUE - indicates that a FATAL error has not occurred
 *     @return  FALSE - indicates that a FATAL error has occurred
 */

BOOLEAN
MemTSPDGetTargetSpeed2 (
  IN OUT   MEM_TECH_BLOCK *TechPtr
  )
{
  CONST UINT16 SpeedCvt[] = {
    DDR400_FREQUENCY,
    DDR533_FREQUENCY,
    DDR667_FREQUENCY,
    DDR800_FREQUENCY,
    DDR1066_FREQUENCY
  };
  INT8 i;
  INT8 j;
  INT8 k;
  INT8 Dct;
  INT8 Channel;
  UINT8 T1min;
  UINT8 CL1min;
  BOOLEAN IsSupported;
  MEM_NB_BLOCK *NBPtr;
  DIE_STRUCT *MCTPtr;
  DCT_STRUCT *DCTPtr;
  CH_DEF_STRUCT *ChannelPtr;

  NBPtr = TechPtr->NBPtr;
  MCTPtr = TechPtr->NBPtr->MCTPtr;

  CL1min = 0xFF;
  T1min = 0xFF;

  // For DDR2, run SyncTargetSpeed first to get frequency limit into DCTPtr->Timings.Speed
  for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
    NBPtr->SwitchDCT (NBPtr, Dct);
    NBPtr->DCTPtr->Timings.TargetSpeed = 16;  // initialized with big number
  }
  NBPtr->SyncTargetSpeed (NBPtr);

  // Find target frequency and Tcl
  for (k = K_MAX; k >= K_MIN; k--) {
    for (j = J_MIN; j <= J_MAX; j++) {
      if (MemTSysCapability2 (TechPtr, k, j)) {
        IsSupported = TRUE;
        for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
          NBPtr->SwitchDCT (NBPtr, Dct);
          for (Channel = 0; Channel < NBPtr->ChannelCount; Channel++) {
            NBPtr->SwitchChannel (NBPtr, Channel);
            ChannelPtr = NBPtr->ChannelPtr;
            for (i = 0; i < MAX_DIMMS_PER_CHANNEL; i++) {
              if (ChannelPtr->ChDimmValid & ((UINT8)1 << i)) {
                if (!MemTDimmSupports2 (TechPtr, k, j, i)) {
                  IsSupported = FALSE;
                  Dct = NBPtr->DctCount;
                  Channel = NBPtr->ChannelCount;
                  break;
                }
              }
            }
          }
        }

        if (IsSupported) {
          T1min = k;
          CL1min = j;
          //  Kill the loops...
          k = K_MIN - 1;
          j = J_MAX + 1;
        }
      }
    }
  }

  if (T1min == 0xFF) {
    //  Failsafe values, running in minimum mode
    PutEventLog (AGESA_FATAL, MEM_ERROR_MISMATCH_DIMM_CLOCKS, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader);
    PutEventLog (AGESA_FATAL, MEM_ERROR_MINIMUM_MODE, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader);
    SetMemError (AGESA_ERROR, MCTPtr);

    T1min = T_DEF;
    CL1min = CL_DEF;
  }

  for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
    NBPtr->SwitchDCT (NBPtr, Dct);
    DCTPtr = NBPtr->DCTPtr;
    DCTPtr->Timings.TargetSpeed = SpeedCvt[T1min - 1];
  }

  // Ensure the target speed can be applied to all channels of the current node
  NBPtr->SyncTargetSpeed (NBPtr);

  // Set the start-up frequency
  for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
    NBPtr->SwitchDCT (NBPtr, Dct);
    DCTPtr = NBPtr->DCTPtr;
    DCTPtr->Timings.Speed = DCTPtr->Timings.TargetSpeed;
    DCTPtr->Timings.CasL = CL1min + 2;  // Convert to clocks
  }

  return (BOOLEAN) (MCTPtr->ErrCode < AGESA_FATAL);
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *   This function 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.
 *
 *     @param[in,out]   *TechPtr   - Pointer to the MEM_TECH_BLOCK
 *
 *     @return  TRUE - indicates that a FATAL error has not occurred
 *     @return  FALSE - indicates that a FATAL error has occurred
 */

BOOLEAN
MemTSPDCalcWidth2 (
  IN OUT   MEM_TECH_BLOCK *TechPtr
  )
{
  UINT8 *SpdBufferAPtr;
  UINT8 *SpdBufferBPtr;
  MEM_NB_BLOCK *NBPtr;
  DIE_STRUCT *MCTPtr;
  DCT_STRUCT *DCTPtr;
  UINT8 i;
  UINT16 DimmMask;
  UINT8 UngangMode;

  NBPtr = TechPtr->NBPtr;
  MCTPtr = NBPtr->MCTPtr;
  DCTPtr = NBPtr->DCTPtr;

  UngangMode = UserOptions.CfgMemoryModeUnganged;
  IDS_OPTION_HOOK (IDS_GANGING_MODE, &UngangMode, &(NBPtr->MemPtr->StdHeader));

  //  Check symmetry of channel A and channel B dimms for 128-bit mode
  //  capability.
  //
  AGESA_TESTPOINT (TpProcMemModeChecking, &(NBPtr->MemPtr->StdHeader));
  i = 0;
  if (MCTPtr->DctData[0].Timings.DctDimmValid == MCTPtr->DctData[1].Timings.DctDimmValid) {
    for (; i < MAX_DIMMS_PER_CHANNEL; i++) {
      DimmMask = (UINT16)1 << i;
      if (DCTPtr->Timings.DctDimmValid & DimmMask) {
        NBPtr->SwitchDCT (NBPtr, 0);
        MemTGetDimmSpdBuffer2 (TechPtr, &SpdBufferAPtr, i);
        NBPtr->SwitchDCT (NBPtr, 1);
        MemTGetDimmSpdBuffer2 (TechPtr, &SpdBufferBPtr, i);

        if ((SpdBufferAPtr[SPD_ROW_SZ]&0x1F) != (SpdBufferBPtr[SPD_ROW_SZ]&0x1F)) {
          break;
        }

        if ((SpdBufferAPtr[SPD_COL_SZ]&0x1F) != (SpdBufferBPtr[SPD_COL_SZ]&0x1F)) {
          break;
        }

        if (SpdBufferAPtr[SPD_BANK_SZ] != SpdBufferBPtr[SPD_BANK_SZ]) {
          break;
        }

        if ((SpdBufferAPtr[SPD_DEV_WIDTH]&0x7F) != (SpdBufferBPtr[SPD_DEV_WIDTH]&0x7F)) {
          break;
        }

        if ((SpdBufferAPtr[SPD_DM_BANKS]&0x07) != (SpdBufferBPtr[SPD_DM_BANKS]&0x07)) {
          break;
        }
      }
    }
  }
  if (i < MAX_DIMMS_PER_CHANNEL) {
    PutEventLog (AGESA_ALERT, MEM_ALERT_ORG_MISMATCH_DIMM, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader);
    SetMemError (AGESA_ALERT, MCTPtr);
  } else if (!UngangMode) {
    NBPtr->Ganged = TRUE;
    MCTPtr->GangedMode = TRUE;
    MCTPtr->Status[Sb128bitmode] = TRUE;
    NBPtr->SetBitField (NBPtr, BFDctGangEn, 1);
  }

  return (BOOLEAN) (MCTPtr->ErrCode < AGESA_FATAL);
}


/* -----------------------------------------------------------------------------*/
/**
 *
 *       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.
 *
 *   Note:
 *   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 only applies when user timing mode is 'Auto'.

 *
 *     @param[in,out]   *TechPtr   - Pointer to the MEM_TECH_BLOCK
 *
 *     @return  TRUE - indicates that a FATAL error has not occurred
 *     @return  FALSE - indicates that a FATAL error has occurred
 */

BOOLEAN
MemTAutoCycTiming2 (
  IN OUT   MEM_TECH_BLOCK *TechPtr
  )
{
  CONST UINT8 SpdIndexes[] = {
    SPD_TRCD,
    SPD_TRP,
    SPD_TRTP,
    SPD_TRAS,
    SPD_TRC,
    SPD_TWR,
    SPD_TRRD,
    SPD_TWTR
  };
  CONST UINT8 Multiples[] = {10, 10, 10, 40, 40, 10, 10, 10};

  CONST UINT8 Tab1KTfawTK[] = {8, 10, 13, 14, 0, 20};
  CONST UINT8 Tab2KTfawTK[] = {10, 14, 17, 18, 0, 24};
  CONST UINT8 TabDefTrcK[]  = {0x41, 0x3C, 0x3C, 0x3A, 0, 0x3A};

  UINT8 MiniMaxTmg[GET_SIZE_OF (SpdIndexes)];
  UINT8 MiniMaxTrfc[4];

  DIE_STRUCT *MCTPtr;
  DCT_STRUCT *DCTPtr;
  MEM_NB_BLOCK *NBPtr;
  UINT16 DimmMask;
  UINT16 Value16;
  UINT16 Tk40;
  UINT8 i;
  UINT8 j;
  UINT8 Value8;
  UINT8 Temp8;
  UINT8  *StatTmgPtr;
  UINT16 *StatDimmTmgPtr;
  BOOLEAN   Is1066;
  UINT8 *SpdBufferPtr;

  NBPtr = TechPtr->NBPtr;
  MCTPtr = NBPtr->MCTPtr;
  DCTPtr = NBPtr->DCTPtr;

  // initialize mini-max arrays
  for (j = 0; j < GET_SIZE_OF (MiniMaxTmg); j++) {
    MiniMaxTmg[j] = 0;
  }
  for (j = 0; j < GET_SIZE_OF (MiniMaxTrfc); j++) {
    MiniMaxTrfc[j] = 0;
  }

  // ======================================================================
  //  Get primary timing (CAS Latency and Cycle Time)
  // ======================================================================
  //  Get OEM specific load variant max
  //

  //======================================================================
  // Gather all DIMM mini-max values for cycle timing data
  //======================================================================
  //
  DimmMask = 1;
  for (i = 0; i < (MAX_CS_PER_CHANNEL / 2); i++) {
    if (DCTPtr->Timings.DctDimmValid & DimmMask) {
      MemTGetDimmSpdBuffer2 (TechPtr, &SpdBufferPtr, i);
      for (j = 0; j < GET_SIZE_OF (SpdIndexes); j++) {
        Value8 = SpdBufferPtr[SpdIndexes[j]];
        if (SpdIndexes[j] == SPD_TRC) {
          if (Value8 == 0 || Value8 == 0xFF) {
            PutEventLog (AGESA_WARNING, MEM_WARNING_NO_SPDTRC_FOUND, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, i, &NBPtr->MemPtr->StdHeader);
            SetMemError (AGESA_WARNING, MCTPtr);
            Value8 = TabDefTrcK[(DCTPtr->Timings.Speed / 66) - 3];
          }
        }
        if (MiniMaxTmg[j] < Value8) {
          MiniMaxTmg[j] = Value8;
        }
      }

      //  get Trfc0 - Trfc3 values
      Value8 = SpdBufferPtr[SPD_BANK_SZ];
      Temp8 = (Value8 << 3) | (Value8 >> 5);
      Value8 = SpdBufferPtr[SPD_DEV_WIDTH];
      ASSERT (LibAmdBitScanReverse ((UINT32)Value8) <= 4);
      Temp8 >>= 4 - LibAmdBitScanReverse ((UINT32)Value8);
      Value8 = LibAmdBitScanReverse ((UINT32)Temp8);
      if (MiniMaxTrfc[i] < Value8) {
        MiniMaxTrfc[i] = Value8;
      }
    }
    DimmMask <<= 1;
  }

  // ======================================================================
  //  Convert  DRAM CycleTiming values and store into DCT structure
  // ======================================================================
  //
  Tk40 = 40000 / DCTPtr->Timings.Speed;
  if (DCTPtr->Timings.Speed == DDR1066_FREQUENCY) {
    Is1066 = TRUE;
  } else {
    Is1066 = FALSE;
  }
  //   Notes:
  //   1. All secondary time values given in SPDs are in binary with UINTs 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).
  //
  StatDimmTmgPtr = &DCTPtr->Timings.DIMMTrcd;
  StatTmgPtr = &DCTPtr->Timings.Trcd;
  for (j = 0; j < GET_SIZE_OF (SpdIndexes); j++) {
    Value16 = (UINT16)MiniMaxTmg[j] * Multiples[j];
    StatDimmTmgPtr[j] = Value16;

    MiniMaxTmg[j] = (UINT8) ((Value16 + Tk40 - 1) / Tk40);
    if (SpdIndexes[j] == SPD_TRTP) {
      MiniMaxTmg[j] = (DCTPtr->Timings.Speed <= DDR533_FREQUENCY) ? 2 : 3;   // based on BL of 32 bytes
    }

    StatTmgPtr[j] = MiniMaxTmg[j];
  }
  DCTPtr->Timings.Trfc0 = MiniMaxTrfc[0];
  DCTPtr->Timings.Trfc1 = MiniMaxTrfc[1];
  DCTPtr->Timings.Trfc2 = MiniMaxTrfc[2];
  DCTPtr->Timings.Trfc3 = MiniMaxTrfc[3];

  DCTPtr->Timings.CasL = MemTSPDGetTCL2 (TechPtr);

  if (DCTPtr->Timings.DIMM1KPage) {
    DCTPtr->Timings.Tfaw = Tab1KTfawTK[(DCTPtr->Timings.Speed / 66) - 3];
  } else {
    DCTPtr->Timings.Tfaw = Tab2KTfawTK[(DCTPtr->Timings.Speed / 66) - 3];
  }
  if (Is1066) {
    DCTPtr->Timings.Tfaw >>= 1;
  }

  //======================================================================
  // Program DRAM Timing values
  //======================================================================
  //
  NBPtr->ProgramCycTimings (NBPtr);

  MemFInitTableDrive (NBPtr, MTAfterAutoCycTiming);

  return (BOOLEAN) (MCTPtr->ErrCode < AGESA_FATAL);
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *   This function sets the bank addressing, program Mask values and build a chip-select population map.
 *   This routine programs PCI 0:24N:2x80 config register.
 *   This routine programs PCI 0:24N:2x60,64,68,6C config registers (CS Mask 0-3)
 *
 *     @param[in,out]   *TechPtr   - Pointer to the MEM_TECH_BLOCK
 *
 *     @return  TRUE - indicates that a FATAL error has not occurred
 *     @return  FALSE - indicates that a FATAL error has occurred
 */

BOOLEAN
MemTSPDSetBanks2 (
  IN OUT   MEM_TECH_BLOCK *TechPtr
  )
{
  UINT8 *SpdBufferPtr;
  UINT8 i;
  UINT8 ChipSel;
  UINT8 DimmID;
  UINT8 Value8;
  UINT8 Rows;
  UINT8 Cols;
  UINT8 Ranks;
  UINT8 Banks;
  UINT32 BankAddrReg;
  UINT32 CsMask;
  UINT16 CSSpdCSE;
  UINT16 CSExclude;
  UINT16 DimmQRDR;
  DIE_STRUCT *MCTPtr;
  DCT_STRUCT *DCTPtr;
  MEM_NB_BLOCK *NBPtr;

  NBPtr = TechPtr->NBPtr;
  MCTPtr = NBPtr->MCTPtr;
  DCTPtr = NBPtr->DCTPtr;

  BankAddrReg = 0;
  CSSpdCSE = 0;
  CSExclude = 0;
  for (ChipSel = 0; ChipSel < MAX_CS_PER_CHANNEL; ChipSel += 2) {
    DimmID = ChipSel >> 1;

    DimmQRDR = (DCTPtr->Timings.DimmQrPresent) | (DCTPtr->Timings.DimmDrPresent);
    if (DCTPtr->Timings.DimmSpdCse & (UINT16) 1 << DimmID) {
      CSSpdCSE |= (UINT16) ((DimmQRDR & (UINT16) 1 << DimmID) ? 3 : 1) << ChipSel;
    }
    if ((DCTPtr->Timings.DimmExclude & ((UINT16) 1 << DimmID)) != 0) {
      CSExclude |= (UINT16) ((DimmQRDR & (UINT16) 1 << DimmID) ? 3: 1) << ChipSel;
    }

    if (DCTPtr->Timings.DctDimmValid & ((UINT16)1 << DimmID)) {
      MemTGetDimmSpdBuffer2 (TechPtr, &SpdBufferPtr, DimmID);

      //  Get the basic data
      Rows = SpdBufferPtr[SPD_ROW_SZ] & 0x1F;
      Cols = SpdBufferPtr[SPD_COL_SZ] & 0x1F;
      Banks = SpdBufferPtr[SPD_L_BANKS];
      Ranks = (SpdBufferPtr[SPD_DM_BANKS] & 0x07) + 1;

      //  Configure the bank encoding
      Value8 = (Cols - 9) << 3;
      Value8 |= (Banks == 8) ? 4 : 0;
      Value8 |= (Rows - 13);

      for (i = 0; i < 12; i++) {
        if (Value8 == MemTGetBankAddr2 (i)) {
          break;
        }
      }

      if (i < 12) {
        BankAddrReg |= ((UINT32)i << (ChipSel << 1));

        // Mask value=(2pow(rows+cols+banks+3)-1)>>8,
        // or 2pow(rows+cols+banks-5)-1
        //
        Value8 = Rows + Cols;
        Value8 -= (Banks == 8) ? 2:3;
        if (MCTPtr->Status[Sb128bitmode]) {
          Value8++;
        }
        CsMask = ((UINT32)1 << Value8) - 1;
        DCTPtr->Timings.CsPresent |= (UINT16)1 << ChipSel;

        if (Ranks >= 2) {
          DCTPtr->Timings.CsPresent |= (UINT16)1 << (ChipSel + 1);
        }

        //  Update the DRAM CS Mask for this chipselect
        NBPtr->SetBitField (NBPtr, BFCSMask0Reg + (ChipSel >> 1), (CsMask & 0x1FF83FE0));
      }
    }
  }
  // For ranks that need to be excluded, the loading of this rank should be considered
  // in timing, so need to set CsPresent before setting CsTestFail
  if ((CSSpdCSE != 0) || (CSExclude != 0)) {
    NBPtr->MemPtr->ErrorHandling (MCTPtr, NBPtr->Dct, (CSSpdCSE | CSExclude), &NBPtr->MemPtr->StdHeader);
  }

  //  If there are no chip selects, we have an error situation.
  if (DCTPtr->Timings.CsPresent == 0) {
    PutEventLog (AGESA_ERROR, MEM_ERROR_NO_CHIPSELECT, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader);
    SetMemError (AGESA_ERROR, MCTPtr);
  }

  NBPtr->SetBitField (NBPtr, BFDramBankAddrReg, BankAddrReg);

  return (BOOLEAN) (MCTPtr->ErrCode < AGESA_FATAL);
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *      This function returns the low bit that will be swapped to enable CS interleaving
 *
 *     @param[in]   BankEnc - AddrMap Bank encoding from F2x80
 *     @param[in]   *LowBit - pointer to low bit
 *     @param[in]   *HiBit  - pointer hight bit
 *
 */

VOID
MemTGetCSIntLvAddr2 (
  IN       UINT8 BankEnc,
     OUT   UINT8 *LowBit,
     OUT   UINT8 *HiBit
  )
{
  CONST UINT8 ArrCodesLo[] = {6, 7, 7, 8, 8, 8, 8, 8, 9, 9, 8, 9};
  CONST UINT8 ArrCodesHi[] = {19, 20, 21, 21, 21, 22, 22, 23, 23, 24, 24, 25};
  ASSERT (BankEnc < GET_SIZE_OF (ArrCodesLo));
  ASSERT (BankEnc < GET_SIZE_OF (ArrCodesHi));
  //  return ArrCodes[BankEnc];
  *LowBit = ArrCodesLo[BankEnc];
  *HiBit = ArrCodesHi[BankEnc];
}

/*----------------------------------------------------------------------------
 *                              LOCAL FUNCTIONS
 *
 *----------------------------------------------------------------------------
 */
/* -----------------------------------------------------------------------------*/
/**
 *
 *   This function returns the CAS latency of the current frequency.
 *
 *     @param[in,out]   *TechPtr   - Pointer to the MEM_TECH_BLOCK
 *
 *     @return  CAS Latency
 */
UINT8
STATIC
MemTSPDGetTCL2 (
  IN OUT   MEM_TECH_BLOCK *TechPtr
  )
{
  return TechPtr->NBPtr->DCTPtr->Timings.CasL;
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *               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 DIE_STRUCT.PresetmaxFreq.
 *
 *     @param[in,out]   *TechPtr   - Pointer to the MEM_TECH_BLOCK
 *     @param[in]   k -  Frequency index
 *     @param[in]   j - CAS Latency index
 *
 *     @return  TRUE  - (k << 8) | j
 *     @return  FALSE - 0
 */

BOOLEAN
STATIC
MemTSysCapability2 (
  IN OUT   MEM_TECH_BLOCK *TechPtr,
  IN       UINT8 k,
  IN       UINT16 j
  )
{
  if ((k > TechPtr->NBPtr->DCTPtr->Timings.TargetSpeed) || (j > J_MAX)) {
    return FALSE;
  }

  return TRUE;    //(k << 8) | j;
}


/* -----------------------------------------------------------------------------*/
/**
 *
 *      Determine whether dimm(b,i) supports CL(j) and F(k)
 *
 *     @param[in,out]   *TechPtr   - Pointer to the MEM_TECH_BLOCK
 *     @param[in]   k -  Frequency index
 *     @param[in]   j - CAS Latency index
 *     @param[in]   i - DIMM number
 *
 *     @return  TRUE  - DIMM supports
 *     @return  FALSE - DIMM does not support
 */

BOOLEAN
STATIC
MemTDimmSupports2 (
  IN OUT   MEM_TECH_BLOCK *TechPtr,
  IN       UINT8 k,
  IN       UINT8 j,
  IN       UINT8 i
  )
{
  CONST UINT8 SpdBytesForCL[3] = { 9, 23, 25};   // SPD bytes for CL X, CL X-.5, and CL X-1
  UINT8 CLj;
  UINT8 CLi;
  UINT8 T1;
  UINT8 T2;
  UINT8 Tk;
  UINT8 *SpdBufferPtr;
  MEM_NB_BLOCK *NBPtr;

  NBPtr = TechPtr->NBPtr;

  MemTGetDimmSpdBuffer2 (TechPtr, &SpdBufferPtr, i);
  CLj = (UINT8) 1 << (j + 2);
  CLi = SpdBufferPtr[SPD_CAS_LAT];

  if (CLj & CLi) {
    //  If this dimm supports the desired CAS latency...
    //  Determine the SPD location of the dimm speed UINT8 appropriate
    //  to the CAS latency indicated by Table_CL2_j.
    //
    T1 = LibAmdBitScanReverse ((UINT32)CLj);
    T2 = LibAmdBitScanReverse ((UINT32)CLi);
    ASSERT ((T2 - T1) < 3);
    CLi = SpdBufferPtr[SpdBytesForCL[(T2 - T1)]];
    Tk = MemTGetTk2 (k);
    if (CLi == 0) {
      PutEventLog (AGESA_FATAL, MEM_ERROR_NO_CYC_TIME, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader);
      SetMemError (AGESA_WARNING, NBPtr->MCTPtr);
    } else if (Tk >= CLi) {
      return TRUE;
    }
  }
  return FALSE;
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *      This function returns the cycle time
 *
 *     @param[in]   k - CAS Latency index
 *
 *     @return      Tk as specified by JEDEC SPD byte 9.
 */

UINT8
STATIC
MemTGetTk2 (
  IN       UINT8 k
  )
{
  CONST UINT8 TableTK[] = {0x00, 0x50, 0x3D, 0x30, 0x25, 0x18};
  ASSERT (k < GET_SIZE_OF (TableTK));
  return TableTK[k];
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *       This function returns the encoded value of bank address.
 *
 *     @param[in]  k  value
 *
 *     @return      RRRBCC, where CC is the number of Columns minus 9,
 *                  RRR is the number of Rows minus 12, and B is the number of banks
 *                  minus 3.
 */

UINT8
STATIC
MemTGetBankAddr2 (
  IN       UINT8 k
  )
{
  CONST UINT8 TabBankAddr[] = {
    0x00, 0x08, 0x09, 0x10, 0x0C, 0x0D,
    0x11, 0x0E, 0x15, 0x16, 0x0F, 0x17
  };
  ASSERT (k < GET_SIZE_OF (TabBankAddr));
  return TabBankAddr[k];
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *       This function returns a pointer to the SPD Buffer of a specific dimm on
 *    the current channel.
 *
 *     @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK
 *     @param[in,out] **SpdBuffer - Pointer to a pointer to a UINT8 Buffer
 *     @param[in] Dimm - Dimm number
 *
 *
 *     @return BOOLEAN - Value of DimmPresent
 *                       TRUE = Dimm is present, pointer is valid
 *                       FALSE = Dimm is not present, pointer has not been modified.
 */

BOOLEAN
MemTGetDimmSpdBuffer2 (
  IN OUT   MEM_TECH_BLOCK *TechPtr,
  IN OUT   UINT8 **SpdBuffer,
  IN       UINT8 Dimm
  )
{
  CH_DEF_STRUCT *ChannelPtr;
  SPD_DEF_STRUCT *SPDPtr;
  BOOLEAN DimmPresent;

  DimmPresent = FALSE;
  ChannelPtr = TechPtr->NBPtr->ChannelPtr;
  ASSERT (Dimm < (sizeof (ChannelPtr->DimmSpdPtr) / sizeof (ChannelPtr->DimmSpdPtr[0])))
  SPDPtr = ChannelPtr->DimmSpdPtr[Dimm];


  if (SPDPtr != NULL) {
    DimmPresent = SPDPtr->DimmPresent;
    if (DimmPresent) {
      *SpdBuffer = SPDPtr->Data;
    }
  }
  return DimmPresent;
}
