From patchwork Thu Feb 17 06:45:01 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: Fam10 FIDVID in SVI 21/25 Date: Thu, 17 Feb 2011 06:45:01 -0000 From: xdrudis X-Patchwork-Id: 2668 Message-Id: <20110217064501.GY8966@ideafix.casa.ct> To: coreboot@coreboot.org see patch Acked-by: Marc Jones 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 --- src/cpu/amd/model_10xxx/fidvid.c 2011-02-15 23:44:58.000000000 +0100 +++ src/cpu/amd/model_10xxx/fidvid.c 2011-02-16 00:51:36.000000000 +0100 @@ -689,24 +689,38 @@ } -static void coreDelay(void) + +static void coreDelay(u32 microseconds) { - u32 saved; - u32 hi, lo, msr; + 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 = 8000 << 3; /* x8 (number of 1.25ns ticks) */ + cycles = (microseconds * 100) << 3; /* x8 (number of 1.25ns ticks) */ - msr = 0x10; /* TSC */ - _RDMSR(msr, &lo, &hi); - saved = lo; + 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 { - _RDMSR(msr, &lo, &hi); - } while (lo - saved < cycles); + now = rdmsr(TSC_MSR); + } while ((now.hi < end.hi) || ((now.hi == end.hi) && (now.lo < end.lo))); } static u32 needs_NB_COF_VID_update(void) --- src/northbridge/amd/amdht/AsPsDefs.h 2011-02-15 23:44:58.000000000 +0100 +++ src/northbridge/amd/amdht/AsPsDefs.h 2011-02-16 00:51:37.000000000 +0100 @@ -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 --- src/northbridge/amd/amdmct/wrappers/mcti_d.c 2011-02-15 23:44:58.000000000 +0100 +++ src/northbridge/amd/amdmct/wrappers/mcti_d.c 2011-02-16 00:51:37.000000000 +0100 @@ -339,7 +339,7 @@ { } -static void coreDelay (void); +static void coreDelay (u32 microseconds); #if (CONFIG_DIMM_SUPPORT & 0x000F)==0x0005 /* AMD_FAM10_DDR3 */ @@ -388,7 +388,7 @@ 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. */ @@ -401,7 +401,7 @@ print_t("vErrata350: step 5\n"); /* 5. Wait at least 2 microseconds. */ - coreDelay(); + coreDelay(2); }