Add the AMD Family10 Agesa code
[coreboot.git] / src / vendorcode / amd / agesa / f10 / Proc / Mem / Tech / DDR3 / mtrci3.c
diff --git a/src/vendorcode/amd/agesa/f10/Proc/Mem/Tech/DDR3/mtrci3.c b/src/vendorcode/amd/agesa/f10/Proc/Mem/Tech/DDR3/mtrci3.c
new file mode 100755 (executable)
index 0000000..77ddfb4
--- /dev/null
@@ -0,0 +1,307 @@
+/**
+ * @file
+ *
+ * mtrci3.c
+ *
+ * Technology Control word initialization for DDR3
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/Tech/DDR3)
+ * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "Ids.h"
+#include "mm.h"
+#include "mn.h"
+#include "mu.h"
+#include "mt.h"
+#include "mt3.h"
+#include "mtrci3.h"
+#include "merrhdl.h"
+#include "Filecode.h"
+#define FILECODE PROC_MEM_TECH_DDR3_MTRCI3_FILECODE
+/*----------------------------------------------------------------------------
+ *                          DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ *                           TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ *                        PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+VOID
+STATIC
+MemTSendCtlWord3 (
+  IN OUT   MEM_TECH_BLOCK *TechPtr,
+  IN       UINT8 CmdNum,
+  IN       UINT8 Value
+  );
+
+/*----------------------------------------------------------------------------
+ *                            EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ *   This function sends control words
+ *
+ *     @param[in,out]   *TechPtr   - Pointer to the MEM_TECH_BLOCK
+ *
+ */
+
+VOID
+MemTDramControlRegInit3 (
+  IN OUT   MEM_TECH_BLOCK *TechPtr
+  )
+{
+  UINT8 ChipSel;
+  UINT8 i;
+  UINT8 RawCard;
+  UINT8 Data;
+  UINT16 CsPresent;
+
+  MEM_DATA_STRUCT *MemPtr;
+  MEM_NB_BLOCK  *NBPtr;
+
+  NBPtr = TechPtr->NBPtr;
+  MemPtr = NBPtr->MemPtr;
+  CsPresent = NBPtr->DCTPtr->Timings.CsPresent;
+
+  MemUWait10ns (800, MemPtr);   // wait 8us TACT must be changed to optimize to 8 MEM CLKs
+
+  // Set EnDramInit to start DRAM initialization
+
+  MemUWait10ns (600, MemPtr);   // wait 6us for PLL LOCK
+
+  for (ChipSel = 0; ChipSel < MAX_CS_PER_CHANNEL; ChipSel += 2) {
+    //
+    // If chip select present
+    //
+    if ((CsPresent & ((UINT16)3 << ChipSel)) != 0) {
+      NBPtr->SetBitField (NBPtr, BFMrsChipSel, ChipSel);
+
+      // 2. Program F2x[1, 0]A8[CtrlWordCS]=bit mask for target chip selects.
+      NBPtr->SetBitField (NBPtr, BFCtrlWordCS, 3 << (ChipSel & 0xFE));
+
+      RawCard = NBPtr->ChannelPtr->RefRawCard[ChipSel >> 1];
+
+      for (i = 0; i <= 15; i++) {
+        // wait 8us for TMRD, must be changed to optimize to 8 MEM CLKs
+        MemUWait10ns (800, MemPtr);
+        if ((i != 6) && (i != 7)) {
+          Data = MemTGetCtlWord3 (TechPtr, i, RawCard, ChipSel);
+          MemTSendCtlWord3 (TechPtr, i, Data);
+        }
+      }
+    }
+  }
+  MemUWait10ns (600, MemPtr);   // wait 6us for TSTAB
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ *   This function calculates the ControlRC value
+ *
+ *     @param[in,out]   *TechPtr   - Pointer to the MEM_TECH_BLOCK
+ *     @param[in]     CtrlWordNum  -  control Word number.
+ *     @param[in]     RawCard  -  Raw Card
+ *     @param[in]     ChipSel  - Target Chip Select
+ *     @return  Control Word value
+ */
+
+UINT8
+MemTGetCtlWord3 (
+  IN OUT   MEM_TECH_BLOCK *TechPtr,
+  IN       UINT8 CtrlWordNum,
+  IN       UINT8 RawCard,
+  IN       UINT8 ChipSel
+  )
+{
+  UINT8  Data;
+  DCT_STRUCT *DCTPtr;
+  CH_DEF_STRUCT *ChannelPtr;
+
+  DCTPtr = TechPtr->NBPtr->DCTPtr;
+  ChannelPtr = TechPtr->NBPtr->ChannelPtr;
+
+  Data = 0;  //Default value for all control words is 0
+  switch (CtrlWordNum) {
+  case 0:
+    Data = 0x02;  // DA4=1
+    break;
+  case 1:
+    if (DCTPtr->Timings.DimmSRPresent & ((UINT16) 1 << (ChipSel >> 1))) {
+      Data = 0x0C;  // if single rank, set DBA1 and DBA0
+    }
+    break;
+  case 2:
+    Data = ChannelPtr->CtrlWrd02[ChipSel >> 1];
+    break;
+  case 3:
+    Data = ChannelPtr->CtrlWrd03[ChipSel >> 1];
+    break;
+  case 4:
+    Data = ChannelPtr->CtrlWrd04[ChipSel >> 1];
+    break;
+  case 5:
+    Data = ChannelPtr->CtrlWrd05[ChipSel >> 1];
+    break;
+  case 8:
+    Data = ChannelPtr->CtrlWrd08[ChipSel >> 1];
+    break;
+  case 9:
+    Data = 0x0D;
+    break;
+  default:;
+  }
+
+  return (Data & 0x0F);
+}
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ *   This function sends control word command
+ *
+ *     @param[in,out]   *TechPtr   - Pointer to the MEM_TECH_BLOCK
+ *     @param[in]     CmdNum  -  control number.
+ *     @param[in]     Value  -  value to send
+ *
+ */
+
+VOID
+STATIC
+MemTSendCtlWord3 (
+  IN OUT   MEM_TECH_BLOCK *TechPtr,
+  IN       UINT8 CmdNum,
+  IN       UINT8 Value
+  )
+{
+  MEM_NB_BLOCK  *NBPtr;
+
+  NBPtr = TechPtr->NBPtr;
+
+  // 1. Program MrsBank and MrsAddress.
+  //    n = [BA2, A2, A1, A0].
+  //    data = [BA1, BA0, A4, A3].
+  //    Set all other bits in MrsAddress to zero.
+  //
+  NBPtr->SetBitField (NBPtr, BFMrsBank, ((CmdNum & 8) >> 1) | (Value >> 2));
+  NBPtr->SetBitField (NBPtr, BFMrsAddress, ((Value & 3) << 3) | (CmdNum & 7));
+  IDS_HDT_CONSOLE ("\t\tCS%lx RC%02lx %04lx\n",
+              (NBPtr->GetBitField (NBPtr, BFDramInitRegReg) >> 20) & 0xF,
+              ((NBPtr->GetBitField (NBPtr, BFDramInitRegReg) >> 15) & 8) |
+              (NBPtr->GetBitField (NBPtr, BFDramInitRegReg) & 7),
+              ((NBPtr->GetBitField (NBPtr, BFDramInitRegReg) >> 14) & 0xC) |
+              ((NBPtr->GetBitField (NBPtr, BFDramInitRegReg) >> 3) & 3));
+
+  // 2.Set SendCtrlWord=1
+  NBPtr->SetBitField (NBPtr, BFSendCtrlWord, 1);
+  // 3.Wait for BFSendCtrlWord=0
+  NBPtr->PollBitField (NBPtr, BFSendCtrlWord, 0, PCI_ACCESS_TIMEOUT, FALSE);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ *   This function sends specific control words commands before frequency change for certain DRAM buffers.
+ *
+ *     @param[in,out]   *TechPtr   - Pointer to the MEM_TECH_BLOCK
+ *
+ */
+
+VOID
+FreqChgCtrlWrd3 (
+  IN OUT   MEM_TECH_BLOCK *TechPtr
+  )
+{
+  UINT8 ChipSel;
+  UINT16 Speed;
+  UINT16 CsPresent;
+
+  MEM_DATA_STRUCT *MemPtr;
+  MEM_NB_BLOCK  *NBPtr;
+
+  NBPtr = TechPtr->NBPtr;
+  MemPtr = NBPtr->MemPtr;
+  Speed = NBPtr->DCTPtr->Timings.Speed;
+  CsPresent = NBPtr->DCTPtr->Timings.CsPresent;
+
+
+  for (ChipSel = 0; ChipSel < MAX_CS_PER_CHANNEL; ChipSel += 2) {
+    //
+    // If chip select present.
+    //
+    if ((CsPresent & ((UINT16)3 << ChipSel)) != 0) {
+
+      NBPtr->SetBitField (NBPtr, BFMrsChipSel, ChipSel);
+      // program F2x[1, 0]A8[CtrlWordCS]=bit mask for target chip selects.
+      NBPtr->SetBitField (NBPtr, BFCtrlWordCS, 3 << (ChipSel & 0xFE));
+
+      //wait 8us for TMRD, must be changed to optimize to 8 MEM CLKs
+      MemUWait10ns (800, MemPtr);
+      if (Speed == DDR1066_FREQUENCY) {
+        MemTSendCtlWord3 (TechPtr, 0x0A, 1);
+      } else if (Speed == DDR1333_FREQUENCY) {
+        MemTSendCtlWord3 (TechPtr, 0x0A, 2);
+      } else if (Speed == DDR1600_FREQUENCY) {
+        MemTSendCtlWord3 (TechPtr, 0x0A, 3);
+      }
+    }
+  }
+}
+