diff options
Diffstat (limited to 'src/northbridge')
-rw-r--r-- | src/northbridge/amd/gx2/northbridgeinit.c | 4 | ||||
-rw-r--r-- | src/northbridge/amd/gx2/pll_reset.c | 139 |
2 files changed, 141 insertions, 2 deletions
diff --git a/src/northbridge/amd/gx2/northbridgeinit.c b/src/northbridge/amd/gx2/northbridgeinit.c index c89e4cb845..724b4de4c4 100644 --- a/src/northbridge/amd/gx2/northbridgeinit.c +++ b/src/northbridge/amd/gx2/northbridgeinit.c @@ -102,8 +102,8 @@ struct msrinit GeodeLinkPriorityTable [] = { {0x0FFFFFFFF, {0x0FFFFFFFF, 0x0FFFFFFFF}}, /* END*/ }; -/* do we have dmi or not? assume yes */ -int havedmi = 1; +/* do we have dmi or not? assume NO per AMD */ +int havedmi = 0; static void writeglmsr(struct gliutable *gl){ diff --git a/src/northbridge/amd/gx2/pll_reset.c b/src/northbridge/amd/gx2/pll_reset.c index 504658576d..2437647c59 100644 --- a/src/northbridge/amd/gx2/pll_reset.c +++ b/src/northbridge/amd/gx2/pll_reset.c @@ -110,6 +110,144 @@ static unsigned int get_memory_speed(void) } #endif +#define USE_GOODRICH_VERSION 1 + +#if USE_GOODRICH_VERSION +/////////////////////////////////////////////////////////////////////////////// +// Goodrich Version of pll_reset +#define POST_CODE(x) outb(0x80, x) + +// PLLCHECK_COMPLETED is the "we've already done this" flag +#define PLLCHECK_COMPLETED (1 << RSTPLL_LOWER_SWFLAGS_SHIFT) + +#ifndef RSTPPL_LOWER_BYPASS_SET +#define RSTPPL_LOWER_BYPASS_SET (1 << GLCP_SYS_RSTPLL_BYPASS) +#endif // RSTPPL_LOWER_BYPASS_SET + +#define DEFAULT_MDIV 3 +#define DEFAULT_VDIV 2 +#define DEFAULT_FBDIV 24 // 400/266 018 ;300/200 + +static void pll_reset(void) +{ + msr_t msrGlcpSysRstpll; + unsigned MDIV_VDIV_FBDIV; + unsigned SyncBits; // store the sync bits in up ebx + + // clear the Bypass bit + + // If the straps say we are in bypass and the syspll is not AND there are no software + // bits set then FS2 or something set up the PLL and we should not change it. + + msrGlcpSysRstpll = rdmsr(GLCP_SYS_RSTPLL); + msrGlcpSysRstpll.lo &= ~RSTPPL_LOWER_BYPASS_SET; + wrmsr(GLCP_SYS_RSTPLL, msrGlcpSysRstpll); + + // If the "we've already been here" flag is set, don't reconfigure the pll + if ( !(msrGlcpSysRstpll.lo & PLLCHECK_COMPLETED ) ) + { // we haven't configured the PLL; do it now + + // Store PCI33(0)/66(1), SDR(0)/DDR(1), and CRT(0)/TFT(1) in upper esi to get to the + // correct Strap Table. + POST_CODE(POST_PLL_INIT); + + // configure for DDR + msrGlcpSysRstpll.lo &= ~(1 << RSTPPL_LOWER_SDRMODE_SHIFT); + wrmsr(GLCP_SYS_RSTPLL, msrGlcpSysRstpll); + + // Use Manual settings + // UseManual: + POST_CODE(POST_PLL_MANUAL); + + // DIV settings manually entered. + // ax = VDIV, upper eax = MDIV, upper ecx = FbDIV + // use gs and fs since we don't need them. + + // ProgramClocks: + // ax = VDIV, upper eax = MDIV, upper ecx = FbDIV + // move everything into ebx + // VDIV + MDIV_VDIV_FBDIV = ((DEFAULT_VDIV - 2) << RSTPLL_UPPER_VDIV_SHIFT); + + // MDIV + MDIV_VDIV_FBDIV |= ((DEFAULT_MDIV - 2) << RSTPLL_UPPER_MDIV_SHIFT); + + // FbDIV + MDIV_VDIV_FBDIV |= (plldiv2fbdiv[DEFAULT_FBDIV] << RSTPLL_UPPER_FBDIV_SHIFT); + + // write GLCP_SYS_RSTPPL (GLCP reg 0x14) with clock values + msrGlcpSysRstpll.lo &= ~(1 << RSTPPL_LOWER_SDRMODE_SHIFT); + wrmsr(GLCP_SYS_RSTPLL, msrGlcpSysRstpll); + + msrGlcpSysRstpll.hi = MDIV_VDIV_FBDIV; + wrmsr(GLCP_SYS_RSTPLL, msrGlcpSysRstpll); + + // Set Reset, LockWait, and SW flag + // DoReset: + + // CheckSemiSync proc + // Check for Semi-Sync in GeodeLink and CPU. + // We need to do this here since the strap settings don't account for these bits. + SyncBits = 0; // store the sync bits in up ebx + + // Check for Bypass mode. + if (msrGlcpSysRstpll.lo & RSTPPL_LOWER_BYPASS_SET) + { + // If we are in BYPASS PCI may or may not be sync'd but CPU and GeodeLink will. + SyncBits |= RSTPPL_LOWER_CPU_SEMI_SYNC_SET; + } + else + { + // CheckPCIsync: + // If FBdiv/Mdiv is evenly divisible then set the PCI semi-sync. FB is always greater + // look up the real divider... if we get a 0 we have serious problems + if ( !(fbdiv2plldiv[((msrGlcpSysRstpll.hi >> RSTPLL_UPPER_FBDIV_SHIFT) & 0x3f)] % + (((msrGlcpSysRstpll.hi >> RSTPLL_UPPER_MDIV_SHIFT) & 0x0F) + 2)) ) + { + SyncBits |= RSTPPL_LOWER_PCI_SEMI_SYNC_SET; + } + + // CheckCPUSync: + // If Vdiv/Mdiv is evenly divisible then set the CPU semi-sync. + // CPU is always greater or equal. + if (!((((msrGlcpSysRstpll.hi >> RSTPLL_UPPER_MDIV_SHIFT) & 0x07) + 2) % + (((msrGlcpSysRstpll.hi >> RSTPLL_UPPER_VDIV_SHIFT) & 0x0F) + 2))) + { + SyncBits |= RSTPPL_LOWER_CPU_SEMI_SYNC_SET; + } + } + + + // SetSync: + msrGlcpSysRstpll.lo &= ~(RSTPPL_LOWER_PCI_SEMI_SYNC_SET | RSTPPL_LOWER_CPU_SEMI_SYNC_SET); + msrGlcpSysRstpll.lo |= SyncBits; + wrmsr(GLCP_SYS_RSTPLL, msrGlcpSysRstpll); + // CheckSemiSync endp + + // now we do the reset + // Set hold count to 99 (063h) + msrGlcpSysRstpll.lo &= ~(0x0FF << RSTPPL_LOWER_HOLD_COUNT_SHIFT); + msrGlcpSysRstpll.lo |= (0x0DE << RSTPPL_LOWER_HOLD_COUNT_SHIFT); + msrGlcpSysRstpll.lo |= PLLCHECK_COMPLETED; // Say we are done + wrmsr(GLCP_SYS_RSTPLL, msrGlcpSysRstpll); + + // Don't want to use LOCKWAIT + msrGlcpSysRstpll.lo |= (RSTPPL_LOWER_PLL_RESET_SET + RSTPPL_LOWER_PD_SET); + msrGlcpSysRstpll.lo |= RSTPPL_LOWER_CHIP_RESET_SET; + wrmsr(GLCP_SYS_RSTPLL, msrGlcpSysRstpll); + + // You should never get here..... The chip has reset. + POST_CODE(POST_PLL_RESET_FAIL); + while (1); + + } // we haven't configured the PLL; do it now + +} +// End of Goodrich version of pll_reset +/////////////////////////////////////////////////////////////////////////////// + +#else // #if USE_GOODRICH_VERSION + static void pll_reset(void) { msr_t msr; @@ -179,3 +317,4 @@ static void pll_reset(void) print_debug("should not be here\n\r"); } +#endif // #if USE_GOODRICH_VERSION |