summaryrefslogtreecommitdiff
path: root/src/northbridge/amd
diff options
context:
space:
mode:
Diffstat (limited to 'src/northbridge/amd')
-rw-r--r--src/northbridge/amd/amdht/AsPsDefs.h3
-rw-r--r--src/northbridge/amd/amdmct/wrappers/mcti_d.c37
2 files changed, 38 insertions, 2 deletions
diff --git a/src/northbridge/amd/amdht/AsPsDefs.h b/src/northbridge/amd/amdht/AsPsDefs.h
index b961ac5aa7..6f03be886d 100644
--- a/src/northbridge/amd/amdht/AsPsDefs.h
+++ b/src/northbridge/amd/amdht/AsPsDefs.h
@@ -291,7 +291,10 @@
#define TSC_MSR 0x10
#define CUR_PSTATE_MSR 0xc0010063
+#define TSC_FREQ_SEL_SHIFT 24
+#define TSC_FREQ_SEL_MASK (1 << TSC_FREQ_SEL_SHIFT)
+
#define WAIT_PSTATE_TIMEOUT 80000000 /* 0.1 s , unit : 1.25 ns */
#endif
diff --git a/src/northbridge/amd/amdmct/wrappers/mcti_d.c b/src/northbridge/amd/amdmct/wrappers/mcti_d.c
index 584a220864..569d61c7b0 100644
--- a/src/northbridge/amd/amdmct/wrappers/mcti_d.c
+++ b/src/northbridge/amd/amdmct/wrappers/mcti_d.c
@@ -340,6 +340,39 @@ 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)
{
@@ -385,7 +418,7 @@ static void vErrata350(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTs
print_t("vErrata350: step 3\n");
/* 3. Wait at least 300 nanoseconds. */
- coreDelay();
+ coreDelay(1);
print_t("vErrata350: step 4\n");
/* 4. Write 0000_0000h to register F2x[1, 0]9C_xD080F0C. */
@@ -398,7 +431,7 @@ static void vErrata350(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTs
print_t("vErrata350: step 5\n");
/* 5. Wait at least 2 microseconds. */
- coreDelay();
+ coreDelay(2);
}