Since some people disapprove of white space cleanups mixed in regular commits
[coreboot.git] / src / northbridge / amd / gx2 / pll_reset.c
index ea54c49277f60da98c8c319e2f8c3875e79b79d9..c1b22a28a0428f074dcbd4c36a9c3bea37362962 100644 (file)
@@ -110,6 +110,143 @@ static unsigned int get_memory_speed(void)
 }
 #endif
 
+#define USE_GOODRICH_VERSION 1
+
+#if USE_GOODRICH_VERSION
+///////////////////////////////////////////////////////////////////////////////
+// Goodrich Version of pll_reset
+
+// 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  22      // 366/244 ; 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;
@@ -125,17 +262,24 @@ static void pll_reset(void)
        msr = rdmsr(GLCP_SYS_RSTPLL);
        if (msr.lo & (1 << GLCP_SYS_RSTPLL_BYPASS)) {
 #if 0
+               print_debug("MSR ");
+               print_debug_hex32(GLCP_SYS_RSTPLL);
+               print_debug("is ");
+               print_debug_hex32(msr.hi);
+               print_debug(":");
+               print_debug_hex32(msr.lo);
+
                msr.hi = PLLMSRhi;
                msr.lo = PLLMSRlo;
                wrmsr(GLCP_SYS_RSTPLL, msr);
                msr.lo |= PLLMSRlo1;
                wrmsr(GLCP_SYS_RSTPLL, msr);
 
-               print_debug("Reset PLL\n\r");
+               print_debug("Reset PLL\n");
 
                msr.lo |= PLLMSRlo2;
                wrmsr(GLCP_SYS_RSTPLL,msr);
-               print_debug("should not be here\n\r");
+               print_debug("should not be here\n");
 #endif
                print_err("shit");
                while (1)
@@ -144,7 +288,7 @@ static void pll_reset(void)
 
        if (msr.lo & GLCP_SYS_RSTPLL_SWFLAGS_MASK) {
                /* PLL is already set and we are reboot from PLL reset */
-               print_debug("reboot from BIOS reset\n\r");
+               print_debug("reboot from BIOS reset\n");
                return;
        }
 
@@ -165,10 +309,11 @@ static void pll_reset(void)
        msr.lo |= ((0xde << 16) | (1 << 26) | (1 << 24));
        wrmsr(0x4c000014, msr);
 
-       print_debug("Reset PLL\n\r");
+       print_debug("Reset PLL\n");
 
        msr.lo |= ((1<<14) |(1<<13) | (1<<0));
        wrmsr(0x4c000014,msr);
 
-       print_debug("should not be here\n\r");
+       print_debug("should not be here\n");
 }
+#endif // #if USE_GOODRICH_VERSION