49, 40, 19, 59, 32, 54, 35, 0, 41, 60, 55, 0, 61, 0, 0, 0
};
-#if 1
-static void get_memory_speed(void)
+static const unsigned char pci33_ddr_crt [] = {
+ /* FbDIV, VDIV, MDIV CPU/GeodeLink */
+ 12, 2, 3, // 200/133
+ 16, 2, 3, // 266/177
+ 18, 2, 3, // 300/200
+ 20, 2, 3, // 333/222
+ 22, 2, 3, // 366/244
+ 24, 2, 3, // 400/266
+ 26, 2, 3 // 433/289
+};
+
+#if 0
+static unsigned int get_memory_speed(void)
{
- unsigned char val;
-
- val = do_smbus_read_byte(0x6000, 0xA0, 0);
- print_debug("SPD byte ");
- print_debug_hex8(0);
- print_debug(" = ");
- print_debug_hex8(val);
- print_debug("\r\n");
-
- val = do_smbus_read_byte(0x6000, 0xA0, 1);
- print_debug("SPD byte ");
- print_debug_hex8(1);
- print_debug(" = ");
- print_debug_hex8(val);
- print_debug("\r\n");
-
- val = do_smbus_read_byte(0x6000, 0xA0, 2);
- print_debug("SPD byte ");
- print_debug_hex8(2);
- print_debug(" = ");
- print_debug_hex8(val);
- print_debug("\r\n");
+ unsigned char val, hi, lo;
+
+ val = spd_read_byte(0xA0, 9);
+ hi = (val >> 4) & 0x0f;
+ lo = val & 0x0f;
+
+ return 20000/(hi*10 + lo);
}
#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;
print_debug("Cpu core is ");
print_debug_hex32(cpu_core);
print_debug("\n");
- //get_memory_speed();
- //msr = rdmsr(GLCP_SYS_RSTPLL);
- msr = rdmsr(0x4c000014);
- print_debug("4c000014 is ");
- print_debug_hex32(msr.hi); print_debug(":"); print_debug_hex32(msr.lo); print_debug("\n");
- if (msr.lo & (1 << GLCP_SYS_RSTPLL_BYPASS)) {
- print_debug("disable PLL bypass\n\r");
- msr.hi = 0x00001490;
- msr.lo = 0x02000030;
+ 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 |= ((0xde << 16) | (1 << 26) | (1 << 24));
+ msr.lo |= PLLMSRlo1;
wrmsr(GLCP_SYS_RSTPLL, msr);
- print_debug("Reset PLL\n\r");
+ print_debug("Reset PLL\n");
- msr.lo |= ((1<<14) |(1<<13) | (1<<0));
+ 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)
+ ;
}
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;
}
- print_debug("prgramming PLL\n\r");
-
+ /* get the sysref clock rate */
vdiv = (msr.hi >> GLCP_SYS_RSTPLL_VDIV_SHIFT) & 0x07;
vdiv += 2;
fbdiv = (msr.hi >> GLCP_SYS_RSTPLL_FBDIV_SHIFT) & 0x3f;
fbdiv = fbdiv2plldiv[fbdiv];
-
spll_raw = cpu_core * vdiv;
sysref = spll_raw / fbdiv;
- print_debug("SYSREF/PCI Clock ");
- print_debug_hex32(sysref);
- print_debug("\n\r");
-
+ /* get target memory rate by SPD */
//gliu = get_memory_speed();
- //get_memory_speed();
- //print_debug("Target Memory Clock ");
- //print_debug_hex32(gliu);
- //print_debug("\n\r");
msr.hi = 0x00000019;
msr.lo = 0x06de0378;
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