lots of ifxmips fixes and features
[openwrt/openwrt.git] / target / linux / ifxmips / files / arch / mips / ifxmips / clock.c
index c86b70cc04704beb0345f7fee6ba9f9558623af6..fc3658b71fbf5bbe918d3dd0d1cfeecd33b2a058 100644 (file)
 #include <linux/errno.h>
 #include <asm/ifxmips/ifxmips.h>
 
-#define FIX_FOR_36M_CRYSTAL             1
 #define BASIC_INPUT_CLOCK_FREQUENCY_1   35328000
 #define BASIC_INPUT_CLOCK_FREQUENCY_2   36000000
 
 #define BASIS_INPUT_CRYSTAL_USB         12000000
 
 #define GET_BITS(x, msb, lsb)           (((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb))
-#define SET_BITS(x, msb, lsb, value)    (((x) & ~(((1 << ((msb) + 1)) - 1) ^ ((1 << (lsb)) - 1))) | (((value) & ((1 << (1 + (msb) - (lsb))) - 1)) << (lsb)))
 
-#define CGU_PLL0_PHASE_DIVIDER_ENABLE   (*IFXMIPS_CGU_PLL0_CFG & (1 << 31))
-#define CGU_PLL0_BYPASS                 (*IFXMIPS_CGU_PLL0_CFG & (1 << 30))
-#define CGU_PLL0_SRC                    (*IFXMIPS_CGU_PLL0_CFG & (1 << 29))
-#define CGU_PLL0_CFG_DSMSEL             (*IFXMIPS_CGU_PLL0_CFG & (1 << 28))
-#define CGU_PLL0_CFG_FRAC_EN            (*IFXMIPS_CGU_PLL0_CFG & (1 << 27))
+
+#define CGU_PLL0_PHASE_DIVIDER_ENABLE   (ifxmips_r32(IFXMIPS_CGU_PLL0_CFG) & (1 << 31))
+#define CGU_PLL0_BYPASS                 (ifxmips_r32(IFXMIPS_CGU_PLL0_CFG) & (1 << 30))
+#define CGU_PLL0_CFG_DSMSEL             (ifxmips_r32(IFXMIPS_CGU_PLL0_CFG) & (1 << 28))
+#define CGU_PLL0_CFG_FRAC_EN            (ifxmips_r32(IFXMIPS_CGU_PLL0_CFG) & (1 << 27))
+#define CGU_PLL1_SRC                    (ifxmips_r32(IFXMIPS_CGU_PLL1_CFG) & (1 << 31))
+#define CGU_PLL1_BYPASS                 (ifxmips_r32(IFXMIPS_CGU_PLL1_CFG) & (1 << 30))
+#define CGU_PLL1_CFG_DSMSEL             (ifxmips_r32(IFXMIPS_CGU_PLL1_CFG) & (1 << 28))
+#define CGU_PLL1_CFG_FRAC_EN            (ifxmips_r32(IFXMIPS_CGU_PLL1_CFG) & (1 << 27))
+#define CGU_PLL2_PHASE_DIVIDER_ENABLE   (ifxmips_r32(IFXMIPS_CGU_PLL2_CFG) & (1 << 20))
+#define CGU_PLL2_BYPASS                 (ifxmips_r32(IFXMIPS_CGU_PLL2_CFG) & (1 << 19))
+#define CGU_SYS_FPI_SEL                 (1 << 6)
+#define CGU_SYS_DDR_SEL                 0x3
+#define CGU_PLL0_SRC                    (1 << 29)
+
 #define CGU_PLL0_CFG_PLLK               GET_BITS(*IFXMIPS_CGU_PLL0_CFG, 26, 17)
 #define CGU_PLL0_CFG_PLLN               GET_BITS(*IFXMIPS_CGU_PLL0_CFG, 12, 6)
 #define CGU_PLL0_CFG_PLLM               GET_BITS(*IFXMIPS_CGU_PLL0_CFG, 5, 2)
-#define CGU_PLL1_SRC                    (*IFXMIPS_CGU_PLL1_CFG & (1 << 31))
-#define CGU_PLL1_BYPASS                 (*IFXMIPS_CGU_PLL1_CFG & (1 << 30))
-#define CGU_PLL1_CFG_DSMSEL             (*IFXMIPS_CGU_PLL1_CFG & (1 << 28))
-#define CGU_PLL1_CFG_FRAC_EN            (*IFXMIPS_CGU_PLL1_CFG & (1 << 27))
 #define CGU_PLL1_CFG_PLLK               GET_BITS(*IFXMIPS_CGU_PLL1_CFG, 26, 17)
 #define CGU_PLL1_CFG_PLLN               GET_BITS(*IFXMIPS_CGU_PLL1_CFG, 12, 6)
 #define CGU_PLL1_CFG_PLLM               GET_BITS(*IFXMIPS_CGU_PLL1_CFG, 5, 2)
-#define CGU_PLL2_PHASE_DIVIDER_ENABLE   (*IFXMIPS_CGU_PLL2_CFG & (1 << 20))
-#define CGU_PLL2_BYPASS                 (*IFXMIPS_CGU_PLL2_CFG & (1 << 19))
 #define CGU_PLL2_SRC                    GET_BITS(*IFXMIPS_CGU_PLL2_CFG, 18, 17)
 #define CGU_PLL2_CFG_INPUT_DIV          GET_BITS(*IFXMIPS_CGU_PLL2_CFG, 16, 13)
 #define CGU_PLL2_CFG_PLLN               GET_BITS(*IFXMIPS_CGU_PLL2_CFG, 12, 6)
 #define CGU_PLL2_CFG_PLLM               GET_BITS(*IFXMIPS_CGU_PLL2_CFG, 5, 2)
-#define CGU_SYS_PPESEL                  GET_BITS(*IFXMIPS_CGU_SYS, 8, 7)
-#define CGU_SYS_FPI_SEL                 (*IFXMIPS_CGU_SYS & (1 << 6))
-#define CGU_SYS_CPU1SEL                 GET_BITS(*IFXMIPS_CGU_SYS, 5, 4)
-#define CGU_SYS_CPU0SEL                 GET_BITS(*IFXMIPS_CGU_SYS, 3, 2)
-#define CGU_SYS_DDR_SEL                 GET_BITS(*IFXMIPS_CGU_SYS, 1, 0)
 #define CGU_IF_CLK_PCI_CLK              GET_BITS(*IFXMIPS_CGU_IF_CLK, 23, 20)
-#define CGU_IF_CLK_USBSEL               GET_BITS(*IFXMIPS_CGU_IF_CLK, 5, 4)
-#define CGU_IF_CLK_MIISEL               GET_BITS(*IFXMIPS_CGU_IF_CLK, 1, 0)
 
 static unsigned int cgu_get_pll0_fdiv(void);
+unsigned int ifxmips_clocks[] = {CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M };
+
+#define DDR_HZ ifxmips_clocks[ifxmips_r32(IFXMIPS_CGU_SYS) & 0x3]
+
 
 static inline unsigned int
 get_input_clock(int pll)
@@ -78,7 +77,7 @@ get_input_clock(int pll)
        switch(pll)
        {
        case 0:
-               if(CGU_PLL0_SRC)
+               if(ifxmips_r32(IFXMIPS_CGU_PLL0_CFG) & CGU_PLL0_SRC)
                        return BASIS_INPUT_CRYSTAL_USB;
                else if(CGU_PLL0_PHASE_DIVIDER_ENABLE)
                        return BASIC_INPUT_CLOCK_FREQUENCY_1;
@@ -169,134 +168,18 @@ cgu_get_pll0_fosc(void)
                                CGU_PLL0_CFG_DSMSEL, CGU_PLL0_PHASE_DIVIDER_ENABLE);
 }
 
-static inline unsigned int
-cgu_get_pll0_fps(int phase)
-{
-       register unsigned int fps = cgu_get_pll0_fosc();
-
-       switch(phase)
-       {
-       case 1:
-               /*  1.25    */
-               fps = ((fps << 2) + 2) / 5;
-               break;
-       case 2:
-               /*  1.5     */
-               fps = ((fps << 1) + 1) / 3;
-               break;
-       }
-       return fps;
-}
-
 static unsigned int
 cgu_get_pll0_fdiv(void)
 {
        register unsigned int div = CGU_PLL2_CFG_INPUT_DIV + 1;
-
        return (cgu_get_pll0_fosc() + (div >> 1)) / div;
 }
 
-static inline unsigned int
-cgu_get_pll1_fosc(void)
-{
-       if(CGU_PLL1_BYPASS)
-               return get_input_clock(1);
-       else
-               return !CGU_PLL1_CFG_FRAC_EN
-                       ? dsm(1, CGU_PLL1_CFG_PLLM, CGU_PLL1_CFG_PLLN, 0, CGU_PLL1_CFG_DSMSEL, 0)
-                       : dsm(1, CGU_PLL1_CFG_PLLM, CGU_PLL1_CFG_PLLN, CGU_PLL1_CFG_PLLK, CGU_PLL1_CFG_DSMSEL, 0);
-}
-
-static inline unsigned int
-cgu_get_pll1_fps(void)
-{
-       register unsigned int fps = cgu_get_pll1_fosc();
-
-       return ((fps << 1) + 1) / 3;
-}
-
-static inline unsigned int
-cgu_get_pll1_fdiv(void)
-{
-       return cgu_get_pll1_fosc();
-}
-
-static inline unsigned int
-cgu_get_pll2_fosc(void)
-{
-       u64 res, clock = get_input_clock(2);
-
-       if ( CGU_PLL2_BYPASS )
-               return get_input_clock(2);
-
-       res = (CGU_PLL2_CFG_PLLN + 1) * clock;
-       do_div(res, CGU_PLL2_CFG_PLLM + 1);
-
-       return res;
-}
-
-static inline unsigned int
-cgu_get_pll2_fps(int phase)
-{
-       register unsigned int fps = cgu_get_pll2_fosc();
-
-       switch ( phase )
-       {
-       case 1:
-               /*  1.125   */
-               fps = ((fps << 2) + 2) / 5; break;
-       case 2:
-               /*  1.25    */
-               fps = ((fps << 3) + 4) / 9;
-       }
-
-       return fps;
-}
-
-static inline unsigned int
-cgu_get_pll2_fdiv(void)
-{
-       register unsigned int div = CGU_IF_CLK_PCI_CLK + 1;
-       return (cgu_get_pll2_fosc() + (div >> 1)) / div;
-}
-
-unsigned int
-cgu_get_mips_clock(int cpu)
-{
-       register unsigned int ret = cgu_get_pll0_fosc();
-       register unsigned int cpusel = cpu == 0 ? CGU_SYS_CPU0SEL : CGU_SYS_CPU1SEL;
-
-       if(cpusel == 0)
-               return ret;
-       else if(cpusel == 2)
-               ret <<= 1;
-
-       switch(CGU_SYS_DDR_SEL)
-       {
-       default:
-       case 0:
-               return (ret + 1) / 2;
-       case 1:
-               return (ret * 2 + 2) / 5;
-       case 2:
-               return (ret + 1) / 3;
-       case 3:
-               return (ret + 2) / 4;
-       }
-}
-
-unsigned int
-cgu_get_cpu_clock(void)
-{
-       return cgu_get_mips_clock(0);
-}
-
 unsigned int
 cgu_get_io_region_clock(void)
 {
        register unsigned int ret = cgu_get_pll0_fosc();
-
-       switch(CGU_SYS_DDR_SEL)
+       switch(ifxmips_r32(IFXMIPS_CGU_PLL2_CFG) & CGU_SYS_DDR_SEL)
        {
        default:
        case 0:
@@ -314,112 +197,16 @@ unsigned int
 cgu_get_fpi_bus_clock(int fpi)
 {
        register unsigned int ret = cgu_get_io_region_clock();
-
-       if((fpi == 2) && (CGU_SYS_FPI_SEL))
+       if((fpi == 2) && (ifxmips_r32(IFXMIPS_CGU_SYS) & CGU_SYS_FPI_SEL))
                ret >>= 1;
-
        return ret;
 }
 
-unsigned int
-cgu_get_pp32_clock(void)
-{
-       switch(CGU_SYS_PPESEL)
-       {
-       default:
-       case 0:
-               return cgu_get_pll2_fps(1);
-       case 1:
-               return cgu_get_pll2_fps(2);
-       case 2:
-               return (cgu_get_pll2_fps(1) + 1) >> 1;
-       case 3:
-               return (cgu_get_pll2_fps(2) + 1) >> 1;
-       }
-}
-
-unsigned int
-cgu_get_ethernet_clock(int mii)
-{
-       switch(CGU_IF_CLK_MIISEL)
-       {
-       case 0:
-               return (cgu_get_pll2_fosc() + 3) / 12;
-       case 1:
-               return (cgu_get_pll2_fosc() + 3) / 6;
-       case 2:
-               return 50000000;
-       case 3:
-               return 25000000;
-       }
-       return 0;
-}
-
-unsigned int
-cgu_get_usb_clock(void)
-{
-       switch(CGU_IF_CLK_USBSEL)
-       {
-       case 0:
-               return (cgu_get_pll2_fosc() + 12) / 25;
-       case 1:
-               return 12000000;
-       case 2:
-               return 12000000 / 4;
-       case 3:
-               return 12000000;
-       }
-       return 0;
-}
-
-unsigned int
-cgu_get_clockout(int clkout)
-{
-       unsigned int fosc1 = cgu_get_pll1_fosc();
-       unsigned int fosc2 = cgu_get_pll2_fosc();
-
-       if(clkout > 3 || clkout < 0)
-               return 0;
-
-       switch(((unsigned int)clkout << 2) | GET_BITS(*IFXMIPS_CGU_IF_CLK, 15 - clkout * 2, 14 - clkout * 2))
-       {
-       case 0: /*  32.768KHz   */
-       case 15:
-               return (fosc1 + 6000) / 12000;
-       case 1: /*  1.536MHz    */
-               return (fosc1 + 128) / 256;
-       case 2: /*  2.5MHz      */
-               return (fosc2 + 60) / 120;
-       case 3: /*  12MHz       */
-       case 5:
-       case 12:
-               return (fosc2 + 12) / 25;
-       case 4: /*  40MHz       */
-               return (cgu_get_pll2_fps(2) + 3) / 6;
-       case 6: /*  24MHz       */
-               return (cgu_get_pll2_fps(2) + 5) / 10;
-       case 7: /*  48MHz       */
-               return (cgu_get_pll2_fps(2) + 2) / 5;
-       case 8: /*  25MHz       */
-       case 14:
-               return (fosc2 + 6) / 12;
-       case 9: /*  50MHz       */
-       case 13:
-               return (fosc2 + 3) / 6;
-       case 10:/*  30MHz       */
-               return (fosc2 + 5) / 10;
-       case 11:/*  60MHz       */
-               return (fosc2 + 2) / 5;
-       }
-       return 0;
-}
-
 void cgu_setup_pci_clk(int external_clock)
 {
        //set clock to 33Mhz 
        ifxmips_w32(ifxmips_r32(IFXMIPS_CGU_IFCCR) & ~0xf00000, IFXMIPS_CGU_IFCCR);
        ifxmips_w32(ifxmips_r32(IFXMIPS_CGU_IFCCR) | 0x800000, IFXMIPS_CGU_IFCCR);
-       // internal or external clock
        if(external_clock)
        {
                ifxmips_w32(ifxmips_r32(IFXMIPS_CGU_IFCCR) & ~ (1 << 16), IFXMIPS_CGU_IFCCR);
@@ -430,26 +217,10 @@ void cgu_setup_pci_clk(int external_clock)
        }
 }
 
-unsigned int
-ifxmips_get_ddr_hz(void)
-{
-       switch(ifxmips_r32(IFXMIPS_CGU_SYS) & 0x3)
-       {
-       case 0:
-               return CLOCK_167M;
-       case 1:
-               return CLOCK_133M;
-       case 2:
-               return CLOCK_111M;
-       }
-       return CLOCK_83M;
-}
-EXPORT_SYMBOL(ifxmips_get_ddr_hz);
-
 unsigned int
 ifxmips_get_cpu_hz(void)
 {
-       unsigned int ddr_clock = ifxmips_get_ddr_hz();
+       unsigned int ddr_clock = DDR_HZ;
        switch(ifxmips_r32(IFXMIPS_CGU_SYS) & 0xc)
        {
        case 0:
@@ -464,11 +235,9 @@ EXPORT_SYMBOL(ifxmips_get_cpu_hz);
 unsigned int
 ifxmips_get_fpi_hz(void)
 {
-       unsigned int ddr_clock = ifxmips_get_ddr_hz();
+       unsigned int ddr_clock = DDR_HZ;
        if(ifxmips_r32(IFXMIPS_CGU_SYS) & 0x40)
                return ddr_clock >> 1;
        return ddr_clock;
 }
 EXPORT_SYMBOL(ifxmips_get_fpi_hz);
-
-