aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/amd/amdmct/wrappers
diff options
context:
space:
mode:
authorTimothy Pearson <tpearson@raptorengineeringinc.com>2015-09-05 17:55:58 -0500
committerMartin Roth <martinroth@google.com>2015-10-26 23:52:54 +0100
commitb8a355dcdf319671b97f8688209ad5d471fc0905 (patch)
tree6cd55b06343af460642431bb8dd3d782d0ccc45e /src/northbridge/amd/amdmct/wrappers
parent7a5413a81c2fecc443999b006d641cd903327346 (diff)
northbridge/amd/amdmct: Fix broken AMD K10 DDR3 memory initalization
The native AMD DDR3 memory initialization code was riddled with numerous errors and was missing critical configuration code segments; this made it so that DDR3 memory did not function on most AMD boards. This patch corrects enough of the DDR3 initialization such that UDIMMs can be used on most channels of G34 Opteron boards. Further work is needed to fix the broken RDIMM code and remaining UDIMM issues. Change-Id: Iab690db769e820600693ad1170085623b177b94e Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> Reviewed-on: http://review.coreboot.org/11941 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@chromium.org> Tested-by: Raptor Engineering Automated Test Stand <noreply@raptorengineeringinc.com>
Diffstat (limited to 'src/northbridge/amd/amdmct/wrappers')
-rw-r--r--src/northbridge/amd/amdmct/wrappers/mcti_d.c102
1 files changed, 5 insertions, 97 deletions
diff --git a/src/northbridge/amd/amdmct/wrappers/mcti_d.c b/src/northbridge/amd/amdmct/wrappers/mcti_d.c
index ea328935b2..f9a9921e6e 100644
--- a/src/northbridge/amd/amdmct/wrappers/mcti_d.c
+++ b/src/northbridge/amd/amdmct/wrappers/mcti_d.c
@@ -59,6 +59,10 @@ static u16 mctGet_NVbits(u8 index)
val = 1;
#elif CONFIG_CPU_SOCKET_TYPE == 0x13 /* ASB2 */
val = 4;
+#elif CONFIG_CPU_SOCKET_TYPE == 0x14 /* C32 */
+ val = 5;
+#elif CONFIG_CPU_SOCKET_TYPE == 0x15 /* G34 */
+ val = 3;
//#elif SYSTEM_TYPE == MOBILE
// val = 2;
#endif
@@ -413,101 +417,6 @@ static void mctHookAfterDramInit(void)
}
#if (CONFIG_DIMM_SUPPORT & 0x000F)==0x0005 /* AMD_FAM10_DDR3 */
-static void coreDelay(u32 microseconds)
-{
- msr_t now;
- msr_t end;
- u32 cycles;
-
- /* delay ~40us
- This seems like a hack to me...
- It would be nice to have a central delay function. */
-
- cycles = (microseconds * 100) << 3; /* x8 (number of 1.25ns ticks) */
-
- if (!(rdmsr(HWCR).lo & TSC_FREQ_SEL_MASK)) {
- msr_t pstate_msr = rdmsr(CUR_PSTATE_MSR);
- if (!(rdmsr(0xC0010064+pstate_msr.lo).lo & NB_DID_M_ON)) {
- cycles = cycles <<1; // half freq, double cycles
- }
- } // else should we keep p0 freq at the time of setting TSC_FREQ_SEL_MASK somewhere and check it here ?
-
- now = rdmsr(TSC_MSR);
- // avoid overflow when called near 2^32 ticks ~ 5.3 s boundaries
- if (0xffffffff - cycles >= now.lo ) {
- end.hi = now.hi;
- end.lo = now.lo + cycles;
- } else {
- end.hi = now.hi +1; //
- end.lo = cycles - (1+(0xffffffff - now.lo));
- }
- do {
- now = rdmsr(TSC_MSR);
- } while ((now.hi < end.hi) || ((now.hi == end.hi) && (now.lo < end.lo)));
-}
-
-/* Erratum 350 */
-static void vErrata350(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat)
-{
- u8 u8Channel;
- u8 u8Receiver;
- u32 u32Addr;
- u8 u8Valid;
- u32 u32DctDev;
-
- // 1. dummy read for each installed DIMM */
- for (u8Channel = 0; u8Channel < 2; u8Channel++) {
- // This will be 0 for vaild DIMMS, eles 8
- u8Receiver = mct_InitReceiver_D(pDCTstat, u8Channel);
-
- for (; u8Receiver < 8; u8Receiver += 2) {
- u32Addr = mct_GetRcvrSysAddr_D(pMCTstat, pDCTstat, u8Channel, u8Receiver, &u8Valid);
-
- if(!u8Valid) { /* Address not supported on current CS */
- print_t("vErrata350: Address not supported on current CS\n");
- continue;
- }
- print_t("vErrata350: dummy read \n");
- read32_fs(u32Addr);
- }
- }
-
- print_t("vErrata350: step 2a\n");
-
- /* 2. Write 0000_8000h to register F2x[1, 0]9C_xD080F0C. */
- u32DctDev = pDCTstat->dev_dct;
- Set_NB32_index_wait(u32DctDev, 0x098, 0xD080F0C, 0x00008000);
- /* ^--- value
- ^---F2x[1, 0]9C_x0D080F0C, No description in BKDG.
- ^----F2x[1, 0]98 DRAM Controller Additional Data Offset Register */
-
- if(!pDCTstat->GangedMode) {
- print_t("vErrata350: step 2b\n");
- Set_NB32_index_wait(u32DctDev, 0x198, 0xD080F0C, 0x00008000);
- /* ^--- value
- ^---F2x[1, 0]9C_x0D080F0C, No description in BKDG
- ^----F2x[1, 0]98 DRAM Controller Additional Data Offset Register */
- }
-
- print_t("vErrata350: step 3\n");
- /* 3. Wait at least 300 nanoseconds. */
- coreDelay(1);
-
- print_t("vErrata350: step 4\n");
- /* 4. Write 0000_0000h to register F2x[1, 0]9C_xD080F0C. */
- Set_NB32_index_wait(u32DctDev, 0x098, 0xD080F0C, 0x00000000);
-
- if(!pDCTstat->GangedMode) {
- print_t("vErrata350: step 4b\n");
- Set_NB32_index_wait(u32DctDev, 0x198, 0xD080F0C, 0x00000000);
- }
-
- print_t("vErrata350: step 5\n");
- /* 5. Wait at least 2 microseconds. */
- coreDelay(2);
-
-}
-
static void vErratum372(struct DCTStatStruc *pDCTstat)
{
msr_t msr = rdmsr(NB_CFG_MSR);
@@ -546,8 +455,7 @@ static void mctHookBeforeAnyTraining(struct MCTStatStruc *pMCTstat, struct DCTSt
{
#if (CONFIG_DIMM_SUPPORT & 0x000F)==0x0005 /* AMD_FAM10_DDR3 */
/* FIXME : as of 25.6.2010 errata 350 and 372 should apply to ((RB|BL|DA)-C[23])|(HY-D[01])|(PH-E0) but I don't find constants for all of them */
- if (pDCTstatA->LogicalCPUID & AMD_DRBH_Cx) {
- vErrata350(pMCTstat, pDCTstatA);
+ if (pDCTstatA->LogicalCPUID & (AMD_DRBH_Cx | AMD_DR_Dx)) {
vErratum372(pDCTstatA);
vErratum414(pDCTstatA);
}