Patch by Jon Loeliger, 16 Jul 2004:
[oweals/u-boot.git] / cpu / ppc4xx / speed.c
index fdefbb6877a73bccdde167bdab000857b8554ccb..be0de0c32a08433a50379a8bc6eee6b8c7183322 100644 (file)
@@ -206,6 +206,7 @@ ulong get_PCI_freq (void)
 
 
 #elif defined(CONFIG_440)
+#if !defined(CONFIG_440_GX)
 void get_sys_info (sys_info_t * sysInfo)
 {
        unsigned long strp0;
@@ -232,11 +233,64 @@ void get_sys_info (sys_info_t * sysInfo)
        sysInfo->freqProcessor = sysInfo->freqVCOMhz/sysInfo->pllFwdDivA;
        sysInfo->freqPLB = sysInfo->freqVCOMhz/sysInfo->pllFwdDivB;
     if( get_pvr() == PVR_440GP_RB ) /* Rev B divs an extra 2 -- geez! */
-        sysInfo->freqPLB >>= 1;
+       sysInfo->freqPLB >>= 1;
        sysInfo->freqOPB = sysInfo->freqPLB/sysInfo->pllOpbDiv;
        sysInfo->freqEPB = sysInfo->freqOPB/sysInfo->pllExtBusDiv;
 
 }
+#else
+void get_sys_info (sys_info_t * sysInfo)
+{
+       unsigned long strp0;
+       unsigned long strp1;
+       unsigned long temp;
+       unsigned long temp1;
+       unsigned long lfdiv;
+       unsigned long m;
+       unsigned long prbdv0;
+
+       /* Extract configured divisors */
+       mfsdr( sdr_sdstp0,strp0 );
+       mfsdr( sdr_sdstp1,strp1 );
+
+       temp = ((strp0 & PLLSYS0_FWD_DIV_A_MASK) >> 8);
+       sysInfo->pllFwdDivA = temp ? temp : 16 ;
+       temp = ((strp0 & PLLSYS0_FWD_DIV_B_MASK) >> 5);
+       sysInfo->pllFwdDivB = temp ? temp: 8 ;
+       temp = (strp0 & PLLSYS0_FB_DIV_MASK) >> 12;
+       sysInfo->pllFbkDiv = temp ? temp : 32;
+       temp = (strp0 & PLLSYS0_OPB_DIV_MASK);
+       sysInfo->pllOpbDiv = temp ? temp : 4;
+       temp = (strp1 & PLLSYS1_PERCLK_DIV_MASK) >> 24;
+       sysInfo->pllExtBusDiv = temp ? temp : 4;
+       prbdv0 = (strp0 >> 2) & 0x7;
+
+       /* Calculate 'M' based on feedback source */
+       temp = (strp0 & PLLSYS0_SEL_MASK) >> 27;
+       temp1 = (strp1 & PLLSYS1_LF_DIV_MASK) >> 26;
+       lfdiv = temp1 ? temp1 : 64;
+       if (temp == 0) { /* PLL output */
+               /* Figure which pll to use */
+               temp = (strp0 & PLLSYS0_SRC_MASK) >> 30;
+               if (!temp)
+                       m = sysInfo->pllFbkDiv * lfdiv * sysInfo->pllFwdDivA;
+               else
+                       m = sysInfo->pllFbkDiv * lfdiv * sysInfo->pllFwdDivB;
+       }
+       else if (temp == 1) /* CPU output */
+               m = sysInfo->pllFbkDiv * sysInfo->pllFwdDivA;
+       else /* PerClk */
+               m = sysInfo->pllExtBusDiv * sysInfo->pllOpbDiv * sysInfo->pllFwdDivB;
+
+       /* Now calculate the individual clocks */
+       sysInfo->freqVCOMhz = (m * CONFIG_SYS_CLK_FREQ) + (m>>1);
+       sysInfo->freqProcessor = sysInfo->freqVCOMhz/sysInfo->pllFwdDivA;
+       sysInfo->freqPLB = sysInfo->freqVCOMhz/sysInfo->pllFwdDivB/prbdv0;
+       sysInfo->freqOPB = sysInfo->freqPLB/sysInfo->pllOpbDiv;
+       sysInfo->freqEPB = sysInfo->freqOPB/sysInfo->pllExtBusDiv;
+
+}
+#endif
 
 ulong get_OPB_freq (void)
 {
@@ -246,6 +300,10 @@ ulong get_OPB_freq (void)
        return sys_info.freqOPB;
 }
 
+#elif defined(CONFIG_XILINX_ML300)
+extern void get_sys_info (sys_info_t * sysInfo);
+extern ulong get_PCI_freq (void);
+
 #elif defined(CONFIG_405)
 
 void get_sys_info (sys_info_t * sysInfo) {
@@ -325,8 +383,13 @@ void get_sys_info (PPC405_SYS_INFO * sysInfo)
         */
        pllmr0_ccdv = ((pllmr0 & PLLMR0_CPU_DIV_MASK) >> 20) + 1;
        if (pllmr1 & PLLMR1_SSCS_MASK) {
-               sysInfo->freqProcessor = (CONFIG_SYS_CLK_FREQ * sysInfo->pllFbkDiv)
-                       / pllmr0_ccdv;
+               /*
+                * This is true if FWDVA == FWDVB:
+                * sysInfo->freqProcessor = (CONFIG_SYS_CLK_FREQ * sysInfo->pllFbkDiv)
+                *      / pllmr0_ccdv;
+                */
+               sysInfo->freqProcessor = (CONFIG_SYS_CLK_FREQ * sysInfo->pllFbkDiv * sysInfo->pllFwdDivB)
+                       / sysInfo->pllFwdDiv / pllmr0_ccdv;
        } else {
                sysInfo->freqProcessor = CONFIG_SYS_CLK_FREQ / pllmr0_ccdv;
        }