From c3132105bdd35ba174cd0938847ebf292e2eda26 Mon Sep 17 00:00:00 2001 From: Xavi Drudis Ferran Date: Mon, 28 Feb 2011 03:49:28 +0000 Subject: Improving BKDG implementation of P-states, CPU and northbridge frequency and voltage handling for Fam 10 in SVI mode. In fact I changed coreDelay before deleting the code in fidvid that called it. But there're still a couple of calls from src/northbridge/amd/amdmct/wrappers/mcti_d.c Since the comment encouraged fixing something, I parametrized it with the delay time in microseconds and paranoically tried to avoid an overflow at pathological moments. Signed-off-by: Xavi Drudis Ferran Acked-by: Marc Jones git-svn-id: svn://svn.coreboot.org/coreboot/trunk@6408 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- src/northbridge/amd/amdmct/wrappers/mcti_d.c | 37 ++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) (limited to 'src/northbridge/amd/amdmct/wrappers') 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); } -- cgit v1.2.3