MIPS: Netlogic: PIC freq calculation for XLP 9XX/2XX
authorGanesan Ramalingam <ganesanr@broadcom.com>
Tue, 29 Apr 2014 14:37:51 +0000 (20:07 +0530)
committerRalf Baechle <ralf@linux-mips.org>
Fri, 30 May 2014 14:49:41 +0000 (16:49 +0200)
Update PIC frequency calculation for XLP9XX and 2XX processors using
the correct PLL registers. This should work for all possible board
configurations.

Signed-off-by: Ganesan Ramalingam <ganesanr@broadcom.com>
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/6876/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/include/asm/netlogic/xlp-hal/iomap.h
arch/mips/include/asm/netlogic/xlp-hal/sys.h
arch/mips/netlogic/common/time.c
arch/mips/netlogic/xlp/nlm_hal.c

index 14b2f5142c6e740bc03f80cbad8c6996ade14444..805bfd21f33e7dbd5bbf151c5a99fb1c4b083842 100644 (file)
 #define XLP9XX_IO_UART_OFFSET(node)    XLP9XX_HDR_OFFSET(node, 2, 2)
 #define XLP9XX_IO_SYS_OFFSET(node)     XLP9XX_HDR_OFFSET(node, 6, 0)
 #define XLP9XX_IO_FUSE_OFFSET(node)    XLP9XX_HDR_OFFSET(node, 6, 1)
+#define XLP9XX_IO_CLOCK_OFFSET(node)   XLP9XX_HDR_OFFSET(node, 6, 2)
+#define XLP9XX_IO_POWER_OFFSET(node)   XLP9XX_HDR_OFFSET(node, 6, 3)
 #define XLP9XX_IO_JTAG_OFFSET(node)    XLP9XX_HDR_OFFSET(node, 6, 4)
 
 #define XLP9XX_IO_PCIE_OFFSET(node, i) XLP9XX_HDR_OFFSET(node, 1, i)
index d9b107ffca933ca525235321200f63f872a1d8c3..bcb136d224e65801ffa36ffa259751aac9ff9783 100644 (file)
 #define SYS_SYS_PLL_MEM_REQ                    0x2a3
 #define SYS_PLL_MEM_STAT                       0x2a4
 
+/* PLL registers XLP9XX */
+#define SYS_9XX_DMC_PLL_CTRL0                  0x140
+#define SYS_9XX_DMC_PLL_CTRL1                  0x141
+#define SYS_9XX_DMC_PLL_CTRL2                  0x142
+#define SYS_9XX_DMC_PLL_CTRL3                  0x143
+#define SYS_9XX_PLL_CTRL0                      0x144
+#define SYS_9XX_PLL_CTRL1                      0x145
+#define SYS_9XX_PLL_CTRL2                      0x146
+#define SYS_9XX_PLL_CTRL3                      0x147
+
+#define SYS_9XX_PLL_CTRL0_DEVX(x)              (0x148 + (x) * 4)
+#define SYS_9XX_PLL_CTRL1_DEVX(x)              (0x149 + (x) * 4)
+#define SYS_9XX_PLL_CTRL2_DEVX(x)              (0x14a + (x) * 4)
+#define SYS_9XX_PLL_CTRL3_DEVX(x)              (0x14b + (x) * 4)
+
+#define SYS_9XX_CPU_PLL_CHG_CTRL               0x188
+#define SYS_9XX_PLL_CHG_CTRL                   0x189
+#define SYS_9XX_CLK_DEV_DIS                    0x18a
+#define SYS_9XX_CLK_DEV_SEL                    0x18b
+#define SYS_9XX_CLK_DEV_DIV                    0x18d
+#define SYS_9XX_CLK_DEV_CHG                    0x18f
+
 /* Registers changed on 9XX */
 #define SYS_9XX_POWER_ON_RESET_CFG             0x00
 #define SYS_9XX_CHIP_RESET                     0x01
 #define nlm_get_fuse_regbase(node)     \
                        (nlm_get_fuse_pcibase(node) + XLP_IO_PCI_HDRSZ)
 
+#define nlm_get_clock_pcibase(node)    \
+                       nlm_pcicfg_base(XLP9XX_IO_CLOCK_OFFSET(node))
+#define nlm_get_clock_regbase(node)    \
+                       (nlm_get_clock_pcibase(node) + XLP_IO_PCI_HDRSZ)
+
 unsigned int nlm_get_pic_frequency(int node);
 #endif
 #endif
index 13391b8a60317337ac212751edb25d1f9868d8e8..0c0a1a606f73820dc92d8894ff29c0f56bf892d6 100644 (file)
@@ -82,6 +82,7 @@ static struct clocksource csrc_pic = {
 static void nlm_init_pic_timer(void)
 {
        uint64_t picbase = nlm_get_node(0)->picbase;
+       u32 picfreq;
 
        nlm_pic_set_timer(picbase, PIC_CLOCK_TIMER, ~0ULL, 0, 0);
        if (current_cpu_data.cputype == CPU_XLR) {
@@ -92,7 +93,9 @@ static void nlm_init_pic_timer(void)
                csrc_pic.read   = nlm_get_pic_timer;
        }
        csrc_pic.rating = 1000;
-       clocksource_register_hz(&csrc_pic, pic_timer_freq());
+       picfreq = pic_timer_freq();
+       clocksource_register_hz(&csrc_pic, picfreq);
+       pr_info("PIC clock source added, frequency %d\n", picfreq);
 }
 
 void __init plat_time_init(void)
index 9f9814d646a942be2a240bb9632a8e6b81736921..59f1303b69d758c9d3de72f2633ac831167a6404 100644 (file)
@@ -234,21 +234,28 @@ unsigned int nlm_get_core_frequency(int node, int core)
        return (unsigned int)num;
 }
 
-/* Calculate Frequency to the PIC from PLL.
- * freq_out = ( ref_freq/2 * (6 + ctrl2[7:0]) + ctrl2[20:8]/2^13 ) /
- * ((2^ctrl0[7:5]) * Table(ctrl0[26:24]))
+/*
+ * Calculate PIC frequency from PLL registers.
+ * freq_out = (ref_freq/2 * (6 + ctrl2[7:0]) + ctrl2[20:8]/2^13) /
+ *             ((2^ctrl0[7:5]) * Table(ctrl0[26:24]))
  */
-static unsigned int nlm_2xx_get_pic_frequency(int node)
+static unsigned int nlm_xlp2_get_pic_frequency(int node)
 {
-       u32 ctrl_val0, ctrl_val2, vco_post_div, pll_post_div;
+       u32 ctrl_val0, ctrl_val2, vco_post_div, pll_post_div, cpu_xlp9xx;
        u32 mdiv, fdiv, pll_out_freq_den, reg_select, ref_div, pic_div;
-       u64 ref_clk, sysbase, pll_out_freq_num, ref_clk_select;
+       u64 sysbase, pll_out_freq_num, ref_clk_select, clockbase, ref_clk;
 
        sysbase = nlm_get_node(node)->sysbase;
+       clockbase = nlm_get_clock_regbase(node);
+       cpu_xlp9xx = cpu_is_xlp9xx();
 
        /* Find ref_clk_base */
-       ref_clk_select =
-               (nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG) >> 18) & 0x3;
+       if (cpu_xlp9xx)
+               ref_clk_select = (nlm_read_sys_reg(sysbase,
+                               SYS_9XX_POWER_ON_RESET_CFG) >> 18) & 0x3;
+       else
+               ref_clk_select = (nlm_read_sys_reg(sysbase,
+                                       SYS_POWER_ON_RESET_CFG) >> 18) & 0x3;
        switch (ref_clk_select) {
        case 0:
                ref_clk = 200000000ULL;
@@ -269,30 +276,70 @@ static unsigned int nlm_2xx_get_pic_frequency(int node)
        }
 
        /* Find the clock source PLL device for PIC */
-       reg_select = (nlm_read_sys_reg(sysbase, SYS_CLK_DEV_SEL) >> 22) & 0x3;
-       switch (reg_select) {
-       case 0:
-               ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0);
-               ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2);
-               break;
-       case 1:
-               ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(0));
-               ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(0));
-               break;
-       case 2:
-               ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(1));
-               ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(1));
-               break;
-       case 3:
-               ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(2));
-               ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(2));
-               break;
+       if (cpu_xlp9xx) {
+               reg_select = nlm_read_sys_reg(clockbase,
+                               SYS_9XX_CLK_DEV_SEL) & 0x3;
+               switch (reg_select) {
+               case 0:
+                       ctrl_val0 = nlm_read_sys_reg(clockbase,
+                                       SYS_9XX_PLL_CTRL0);
+                       ctrl_val2 = nlm_read_sys_reg(clockbase,
+                                       SYS_9XX_PLL_CTRL2);
+                       break;
+               case 1:
+                       ctrl_val0 = nlm_read_sys_reg(clockbase,
+                                       SYS_9XX_PLL_CTRL0_DEVX(0));
+                       ctrl_val2 = nlm_read_sys_reg(clockbase,
+                                       SYS_9XX_PLL_CTRL2_DEVX(0));
+                       break;
+               case 2:
+                       ctrl_val0 = nlm_read_sys_reg(clockbase,
+                                       SYS_9XX_PLL_CTRL0_DEVX(1));
+                       ctrl_val2 = nlm_read_sys_reg(clockbase,
+                                       SYS_9XX_PLL_CTRL2_DEVX(1));
+                       break;
+               case 3:
+                       ctrl_val0 = nlm_read_sys_reg(clockbase,
+                                       SYS_9XX_PLL_CTRL0_DEVX(2));
+                       ctrl_val2 = nlm_read_sys_reg(clockbase,
+                                       SYS_9XX_PLL_CTRL2_DEVX(2));
+                       break;
+               }
+       } else {
+               reg_select = (nlm_read_sys_reg(sysbase,
+                                       SYS_CLK_DEV_SEL) >> 22) & 0x3;
+               switch (reg_select) {
+               case 0:
+                       ctrl_val0 = nlm_read_sys_reg(sysbase,
+                                       SYS_PLL_CTRL0);
+                       ctrl_val2 = nlm_read_sys_reg(sysbase,
+                                       SYS_PLL_CTRL2);
+                       break;
+               case 1:
+                       ctrl_val0 = nlm_read_sys_reg(sysbase,
+                                       SYS_PLL_CTRL0_DEVX(0));
+                       ctrl_val2 = nlm_read_sys_reg(sysbase,
+                                       SYS_PLL_CTRL2_DEVX(0));
+                       break;
+               case 2:
+                       ctrl_val0 = nlm_read_sys_reg(sysbase,
+                                       SYS_PLL_CTRL0_DEVX(1));
+                       ctrl_val2 = nlm_read_sys_reg(sysbase,
+                                       SYS_PLL_CTRL2_DEVX(1));
+                       break;
+               case 3:
+                       ctrl_val0 = nlm_read_sys_reg(sysbase,
+                                       SYS_PLL_CTRL0_DEVX(2));
+                       ctrl_val2 = nlm_read_sys_reg(sysbase,
+                                       SYS_PLL_CTRL2_DEVX(2));
+                       break;
+               }
        }
 
        vco_post_div = (ctrl_val0 >> 5) & 0x7;
        pll_post_div = (ctrl_val0 >> 24) & 0x7;
        mdiv = ctrl_val2 & 0xff;
-       fdiv = (ctrl_val2 >> 8) & 0xfff;
+       fdiv = (ctrl_val2 >> 8) & 0x1fff;
 
        /* Find PLL post divider value */
        switch (pll_post_div) {
@@ -322,7 +369,12 @@ static unsigned int nlm_2xx_get_pic_frequency(int node)
                do_div(pll_out_freq_num, pll_out_freq_den);
 
        /* PIC post divider, which happens after PLL */
-       pic_div = (nlm_read_sys_reg(sysbase, SYS_CLK_DEV_DIV) >> 22) & 0x3;
+       if (cpu_xlp9xx)
+               pic_div = nlm_read_sys_reg(clockbase,
+                               SYS_9XX_CLK_DEV_DIV) & 0x3;
+       else
+               pic_div = (nlm_read_sys_reg(sysbase,
+                                       SYS_CLK_DEV_DIV) >> 22) & 0x3;
        do_div(pll_out_freq_num, 1 << pic_div);
 
        return pll_out_freq_num;
@@ -330,12 +382,8 @@ static unsigned int nlm_2xx_get_pic_frequency(int node)
 
 unsigned int nlm_get_pic_frequency(int node)
 {
-       /* TODO Has to calculate freq as like 2xx */
-       if (cpu_is_xlp9xx())
-               return 250000000;
-
        if (cpu_is_xlpii())
-               return nlm_2xx_get_pic_frequency(node);
+               return nlm_xlp2_get_pic_frequency(node);
        else
                return 133333333;
 }