rk3188: add setting rate in dump clocks
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-rk3188 / clock_data.c
index 3f9d2420b96eb42c71cb4ac4c5f92f34e7808031..2f010a80bc5612c88f8ebb280467826b8bb3368a 100755 (executable)
@@ -36,7 +36,7 @@
 #define CLK_LOOPS_RATE_REF (1200UL) //Mhz
 #define CLK_LOOPS_RECALC(new_rate)  div_u64(CLK_LOOPS_JIFFY_REF*(new_rate),CLK_LOOPS_RATE_REF*MHZ)
 void rk30_clk_dump_regs(void);
-
+static int flag_uboot_display = 0;
 //flags bit
 //has extern 27mhz
 #define CLK_FLG_EXT_27MHZ                      (1<<0)
@@ -304,9 +304,11 @@ static int clksel_set_rate_shift_2(struct clk *clk, unsigned long rate)
 //for div 1 2 4 2*n
 static int clksel_set_rate_even(struct clk *clk, unsigned long rate)
 {
-       u32 div;
-       for (div = 2; div < clk->div_max; div += 2) {
-               u32 new_rate = clk->parent->rate / div;
+       u32 div = 0, new_rate = 0;
+       for (div = 1; div < clk->div_max; div++) {
+               if (div >= 3 && div % 2 != 0)
+                       continue;
+               new_rate = clk->parent->rate / div;
                if (new_rate <= rate) {
                        set_cru_bits_w_msk(div - 1, clk->div_mask, clk->div_shift, clk->clksel_con);
                        clk->rate = new_rate;
@@ -614,6 +616,12 @@ static void pll_wait_lock(int pll_idx)
                delay--;
        }
        if (delay == 0) {
+               CLKDATA_ERR("PLL_ID=%d\npll_con0=%08x\npll_con1=%08x\npll_con2=%08x\npll_con3=%08x\n", pll_idx,
+                               cru_readl(PLL_CONS(pll_idx, 0)),
+                               cru_readl(PLL_CONS(pll_idx, 1)),
+                               cru_readl(PLL_CONS(pll_idx, 2)),
+                               cru_readl(PLL_CONS(pll_idx, 3)));
+
                CLKDATA_ERR("wait pll bit 0x%x time out!\n", bit);
                while(1);
        }
@@ -1288,6 +1296,7 @@ static const struct pll_clk_set cpll_clks[] = {
        _PLL_SET_CLKS(456000, 1,  76,   4),
        _PLL_SET_CLKS(504000, 1,  84,   4),
        _PLL_SET_CLKS(552000, 1,  46,   2),
+       _PLL_SET_CLKS(594000, 2,  198,  4),
        _PLL_SET_CLKS(600000, 1,  50,   2),
        _PLL_SET_CLKS(742500, 8,  495,  2),
        _PLL_SET_CLKS(768000, 1,  64,   2),
@@ -1309,7 +1318,9 @@ static const struct pll_clk_set gpll_clks[] = {
        _PLL_SET_CLKS(148500,   2,      99,     8),
        _PLL_SET_CLKS(297000,   2,      198,    8),
        _PLL_SET_CLKS(300000,   1,      50,     4),
+       _PLL_SET_CLKS(384000,   2,      128,    4),
        _PLL_SET_CLKS(594000,   2,      198,    4),
+       _PLL_SET_CLKS(768000,   1,      64,     2),
        _PLL_SET_CLKS(891000,   8,      594,    2),
        _PLL_SET_CLKS(1188000,  2,      99,     1),
        _PLL_SET_CLKS(1200000,  1,      50,     1),
@@ -1927,12 +1938,19 @@ static struct clk clk_spdif_div = {
 static int clk_i2s_fracdiv_set_rate(struct clk *clk, unsigned long rate)
 {
        u32 numerator, denominator;
+       int i = 10;
        //clk_i2s_div->clk_i2s_pll->gpll/cpll
        //clk->parent->parent
        if(frac_div_get_seting(rate, clk->parent->parent->rate,
                                &numerator, &denominator) == 0) {
                clk_set_rate_nolock(clk->parent, clk->parent->parent->rate); //PLL:DIV 1:
-               cru_writel_frac(numerator << 16 | denominator, clk->clksel_con);
+
+               while (i--) {
+                       cru_writel_frac((numerator - 1) << 16 | denominator, clk->clksel_con);
+                       mdelay(1);
+                       cru_writel_frac(numerator << 16 | denominator, clk->clksel_con);
+                       mdelay(1);
+               }
                CLKDATA_DBG("%s set rate=%lu,is ok\n", clk->name, rate);
        } else {
                CLKDATA_ERR("clk_frac_div can't get rate=%lu,%s\n", rate, clk->name);
@@ -2325,7 +2343,7 @@ static struct clk clk_emmc = {
        .parent         = &hclk_periph,
        .mode           = gate_mode,
        .recalc         = clksel_recalc_div,
-       .set_rate       = clksel_set_rate_freediv,
+       .set_rate       = clksel_set_rate_even,
        .gate_idx       = CLK_GATE_EMMC_SRC,
        .clksel_con     = CRU_CLKSELS_CON(12),
        CRU_DIV_SET(0x3f, 8, 64),
@@ -3013,6 +3031,7 @@ static void __init rk30_init_enable_clocks(void)
        //clk_enable_nolock(&clk_core);
        clk_enable_nolock(&clk_cpu_div);
        clk_enable_nolock(&clk_core_gpll_path);
+       clk_enable_nolock(&clk_ddr_gpll_path);
        clk_enable_nolock(&clk_l2c);
        clk_enable_nolock(&clk_core_dbg);
        clk_enable_nolock(&core_periph);
@@ -3022,6 +3041,18 @@ static void __init rk30_init_enable_clocks(void)
        clk_enable_nolock(&atclk_cpu);
        //clk_enable_nolock(&hclk_cpu);
        clk_enable_nolock(&ahb2apb_cpu);
+       if (flag_uboot_display) {
+               clk_enable_nolock(&dclk_lcdc0);
+               clk_enable_nolock(&dclk_lcdc1);
+               clk_enable_nolock(&clk_hclk_lcdc0);
+               clk_enable_nolock(&clk_hclk_lcdc1);
+               clk_enable_nolock(&clk_aclk_lcdc0);
+               clk_enable_nolock(&clk_aclk_lcdc1);
+               clk_enable_nolock(&aclk_lcdc0_pre);
+               clk_enable_nolock(&aclk_lcdc1_pre);
+               clk_enable_nolock(&pd_lcdc0);
+               clk_enable_nolock(&pd_lcdc1);
+       }
        #if 0
         clk_enable_nolock(&clk_gpu);
         clk_enable_nolock(&aclk_gpu);
@@ -3033,17 +3064,12 @@ static void __init rk30_init_enable_clocks(void)
         clk_enable_nolock(&aclk_vdpu);
         clk_enable_nolock(&hclk_vdpu);
 
-        clk_enable_nolock(&aclk_lcdc0_pre);
-        clk_enable_nolock(&aclk_lcdc1_pre);
 
         clk_enable_nolock(&aclk_periph);
        clk_enable_nolock(&pclk_periph);
        clk_enable_nolock(&hclk_periph);
        #endif
        #if 0
-        clk_enable_nolock(&dclk_lcdc0);
-        clk_enable_nolock(&dclk_lcdc1);
-       
         clk_enable_nolock(&cif_out_pll);
         clk_enable_nolock(&cif0_out_div);
 
@@ -3159,8 +3185,6 @@ static void __init rk30_init_enable_clocks(void)
        clk_enable_nolock(&clk_hclk_ahb2apb);
        clk_enable_nolock(&clk_hclk_vio_bus);
        #if 0
-       clk_enable_nolock(&clk_hclk_lcdc0);
-       clk_enable_nolock(&clk_hclk_lcdc1);
        clk_enable_nolock(&clk_hclk_cif0);
        clk_enable_nolock(&clk_hclk_ipp);
        clk_enable_nolock(&clk_hclk_rga);
@@ -3236,14 +3260,12 @@ static void __init rk30_init_enable_clocks(void)
        /*************************aclk_lcdc0***********************/
 #if 1
        //clk_enable_nolock(&clk_aclk_vio0);
-       //clk_enable_nolock(&clk_aclk_lcdc0);
        //clk_enable_nolock(&clk_aclk_cif0);
        //clk_enable_nolock(&clk_aclk_ipp);
 #endif
        /*************************aclk_lcdc1***********************/
 #if 1
        //clk_enable_nolock(&clk_aclk_vio1);
-       //clk_enable_nolock(&clk_aclk_lcdc1);
        //clk_enable_nolock(&clk_aclk_rga);
 #endif
        /************************power domain**********************/
@@ -3272,11 +3294,21 @@ static void periph_clk_set_init(void)
                        hclk_p = aclk_p >> 0;
                        pclk_p = aclk_p >> 1;
                        break;
+               case 384 * MHZ: 
+                       aclk_p = ppll_rate >> 1; 
+                       hclk_p = aclk_p >> 1; 
+                       pclk_p = aclk_p >> 2; 
+                       break; 
                case 594 * MHZ:
                        aclk_p = ppll_rate >> 2;
                        hclk_p = aclk_p >> 0;
                        pclk_p = aclk_p >> 1;
                        break;
+               case 768 * MHZ: 
+                       aclk_p = ppll_rate >> 2; 
+                       hclk_p = aclk_p >> 1; 
+                       pclk_p = aclk_p >> 2; 
+                       break; 
                case 891 * MHZ:
                        aclk_p = ppll_rate / 6;
                        hclk_p = aclk_p >> 0;
@@ -3302,7 +3334,8 @@ static void periph_clk_set_init(void)
 
 static void cpu_axi_init(void)
 {
-       unsigned long cpu_div_rate, aclk_cpu_rate, hclk_cpu_rate, pclk_cpu_rate, ahb2apb_cpu_rate;
+       unsigned long cpu_div_rate = 0, aclk_cpu_rate = 0, hclk_cpu_rate = 0,
+                     pclk_cpu_rate = 0, ahb2apb_cpu_rate = 0;
        unsigned long gpll_rate = general_pll_clk.rate;
 
        switch (gpll_rate) {
@@ -3313,6 +3346,13 @@ static void cpu_axi_init(void)
                        pclk_cpu_rate = aclk_cpu_rate >> 2;
                        break;
 
+               case 384 * MHZ:
+                       cpu_div_rate = gpll_rate >> 1;
+                       aclk_cpu_rate = cpu_div_rate >> 0;
+                       hclk_cpu_rate = aclk_cpu_rate >> 1;
+                       pclk_cpu_rate = aclk_cpu_rate >> 2;
+                       break;
+
                case 594 * MHZ:
                        cpu_div_rate = gpll_rate >> 1;
                        aclk_cpu_rate = cpu_div_rate >> 0;
@@ -3320,6 +3360,13 @@ static void cpu_axi_init(void)
                        pclk_cpu_rate = aclk_cpu_rate >> 2;
                        break;
 
+               case 768 * MHZ:
+                       cpu_div_rate = gpll_rate >> 2;
+                       aclk_cpu_rate = cpu_div_rate >> 0;
+                       hclk_cpu_rate = aclk_cpu_rate >> 1;
+                       pclk_cpu_rate = aclk_cpu_rate >> 2;
+                       break;
+
                case 891 * MHZ:
                        cpu_div_rate = gpll_rate / 3;
                        aclk_cpu_rate = cpu_div_rate >> 0;
@@ -3366,10 +3413,14 @@ void rk30_clock_common_i2s_init(void)
                i2s_rate = 49152000;
        }
 
-       if(((i2s_rate * 20) <= general_pll_clk.rate) || !(general_pll_clk.rate % i2s_rate)) {
-               clk_set_parent_nolock(&clk_i2s_pll, &general_pll_clk);
-       } else if(((i2s_rate * 20) <= codec_pll_clk.rate) || !(codec_pll_clk.rate % i2s_rate)) {
+       /*
+        * Priority setting i2s under cpll to fix i2s frac div do not effect, let
+        * axi_cpu's pll different with i2s's
+        * */
+       if(((i2s_rate * 20) <= codec_pll_clk.rate) || !(codec_pll_clk.rate % i2s_rate)) {
                clk_set_parent_nolock(&clk_i2s_pll, &codec_pll_clk);
+       } else if(((i2s_rate * 20) <= general_pll_clk.rate) || !(general_pll_clk.rate % i2s_rate)) {
+               clk_set_parent_nolock(&clk_i2s_pll, &general_pll_clk);
        } else {
                if(general_pll_clk.rate > codec_pll_clk.rate)
                        clk_set_parent_nolock(&clk_i2s_pll, &general_pll_clk);
@@ -3377,6 +3428,48 @@ void rk30_clock_common_i2s_init(void)
                        clk_set_parent_nolock(&clk_i2s_pll, &codec_pll_clk);
        }
 }
+void rk30_clock_common_uart_init(struct clk *cpll_clk,struct clk *gpll_clk)
+{
+       struct clk *p_clk;
+       unsigned long rate;
+       if(!(gpll_clk->rate%(48*MHZ)))
+       {
+               p_clk=gpll_clk;
+               rate=48*MHZ;
+       }
+       else if(!(cpll_clk->rate%(48*MHZ)))
+       {
+               p_clk=cpll_clk;
+               rate=48*MHZ;
+       }
+       else if(!(gpll_clk->rate%(49500*KHZ)))
+       {
+               p_clk=gpll_clk;
+               rate=(49500*KHZ);
+       }
+       else if(!(cpll_clk->rate%(49500*KHZ)))
+       {
+               p_clk=cpll_clk;
+               rate=(49500*KHZ);
+       }
+       else
+       {
+               if(cpll_clk->rate>gpll_clk->rate)
+               {
+                       p_clk=cpll_clk;
+               }
+               else
+               {
+                       p_clk=gpll_clk;
+               }       
+               rate=50*MHZ;
+       }
+       clk_set_parent_nolock(&clk_uart_pll, p_clk);
+       clk_set_rate_nolock(&clk_uart0_div,rate);
+       clk_set_rate_nolock(&clk_uart1_div,rate);
+       clk_set_rate_nolock(&clk_uart2_div,rate);
+       clk_set_rate_nolock(&clk_uart3_div,rate);
+}
 
 static void inline clock_set_div(struct clk *clk,u32 div)
 {
@@ -3394,11 +3487,13 @@ static void div_clk_for_pll_init(void)
        clock_set_max_div(&aclk_vdpu);
        clock_set_max_div(&aclk_vepu);
        clock_set_max_div(&aclk_gpu);
-       clock_set_max_div(&aclk_lcdc0_pre);
-       clock_set_max_div(&aclk_lcdc1_pre);
+       if (!flag_uboot_display) {
+               clock_set_max_div(&aclk_lcdc0_pre);
+               clock_set_max_div(&aclk_lcdc1_pre);
+               clock_set_max_div(&dclk_lcdc0);
+               clock_set_max_div(&dclk_lcdc1);
+       }
        clock_set_max_div(&aclk_periph);
-       clock_set_max_div(&dclk_lcdc0);
-       clock_set_max_div(&dclk_lcdc1);
        clock_set_max_div(&cif0_out_div);
        clock_set_max_div(&clk_i2s0_div);
        clock_set_max_div(&clk_spdif_div);
@@ -3416,9 +3511,13 @@ static u8 pll_flag = 0;
 static void __init rk30_clock_common_init(unsigned long gpll_rate, unsigned long cpll_rate)
 {
        //general
-       clk_set_rate_nolock(&general_pll_clk, gpll_rate);
+       if (!flag_uboot_display)
+               clk_set_rate_nolock(&general_pll_clk, gpll_rate);
+       lpj_gpll = CLK_LOOPS_RECALC(general_pll_clk.rate);
+
        //code pll
-       clk_set_rate_nolock(&codec_pll_clk, cpll_rate);
+       if (!flag_uboot_display)
+               clk_set_rate_nolock(&codec_pll_clk, cpll_rate);
 
        cpu_axi_init();
        clk_set_rate_nolock(&clk_core, 816 * MHZ);
@@ -3433,10 +3532,8 @@ static void __init rk30_clock_common_init(unsigned long gpll_rate, unsigned long
        clk_set_rate_nolock(&clk_spi1, clk_spi1.parent->rate);
 
        // uart
-       if((rk30_clock_flags & CLK_FLG_UART_1_3M) && (cpll_rate != 24 * MHZ))
-               clk_set_parent_nolock(&clk_uart_pll, &codec_pll_clk);
-       else
-               clk_set_parent_nolock(&clk_uart_pll, &general_pll_clk);
+       rk30_clock_common_uart_init(&codec_pll_clk,&general_pll_clk);
+
        //mac
        if(!(gpll_rate % (50 * MHZ))) {
                clk_set_parent_nolock(&clk_mac_pll_div, &general_pll_clk);
@@ -3453,19 +3550,20 @@ static void __init rk30_clock_common_init(unsigned long gpll_rate, unsigned long
        //auto pll sel
        //clk_set_parent_nolock(&clk_hsadc_pll_div, &general_pll_clk);
 
-       //lcdc0 lcd auto sel pll
-       clk_set_parent_nolock(&dclk_lcdc0, &general_pll_clk);
-       clk_set_parent_nolock(&dclk_lcdc1, &general_pll_clk);
+       if (!flag_uboot_display) {
+               //lcdc0 lcd auto sel pll
+               clk_set_parent_nolock(&dclk_lcdc0, &general_pll_clk);
+               clk_set_parent_nolock(&dclk_lcdc1, &general_pll_clk);
 
+               //axi lcdc auto sel
+               clk_set_parent_nolock(&aclk_lcdc0_pre, &general_pll_clk);
+               clk_set_parent_nolock(&aclk_lcdc1_pre, &general_pll_clk);
+               clk_set_rate_nolock(&aclk_lcdc0_pre, 300 * MHZ);
+               clk_set_rate_nolock(&aclk_lcdc1_pre, 300 * MHZ);
+       }
        //cif
        clk_set_parent_nolock(&cif_out_pll, &general_pll_clk);
 
-       //axi lcdc auto sel
-       clk_set_parent_nolock(&aclk_lcdc0_pre, &general_pll_clk);
-       clk_set_parent_nolock(&aclk_lcdc1_pre, &general_pll_clk);
-       clk_set_rate_nolock(&aclk_lcdc0_pre, 300 * MHZ);
-       clk_set_rate_nolock(&aclk_lcdc1_pre, 300 * MHZ);
-
        //axi vepu auto sel
        //clk_set_parent_nolock(&aclk_vepu, &general_pll_clk);
        //clk_set_parent_nolock(&aclk_vdpu, &general_pll_clk);
@@ -3476,7 +3574,7 @@ static void __init rk30_clock_common_init(unsigned long gpll_rate, unsigned long
        clk_set_parent_nolock(&aclk_gpu, &general_pll_clk);
        clk_set_rate_nolock(&aclk_gpu, 200 * MHZ);
        
-       clk_set_rate_nolock(&clk_uart0, 49500000);
+       clk_set_rate_nolock(&clk_uart0, 48000000);
        clk_set_rate_nolock(&clk_sdmmc, 24750000);
        clk_set_rate_nolock(&clk_sdio, 24750000);
 }
@@ -3512,6 +3610,7 @@ void __init _rk30_clock_data_init(unsigned long gpll, unsigned long cpll, int fl
        if (0 != pll_flag) {
                CLKDATA_DBG("CPLL=%lu, GPLL=%lu;CPLL CAN NOT LOCK, SET CPLL BY PASS, USE GPLL REPLACE CPLL\n",
                                cpll, gpll);
+               codec_pll_clk.mode = NULL;
                cpll = 24 * MHZ;
                gpll = 891 * MHZ;
        }
@@ -3554,6 +3653,7 @@ void __init _rk30_clock_data_init(unsigned long gpll, unsigned long cpll, int fl
        rk30_clock_common_init(gpll, cpll);
        preset_lpj = loops_per_jiffy;
 
+
        //gpio6_b7
        //regfile_writel(0xc0004000,0x10c);
        //cru_writel(0x07000000,CRU_MISC_CON);
@@ -3568,7 +3668,21 @@ void __init rk30_clock_data_init(unsigned long gpll, unsigned long cpll, u32 fla
        _rk30_clock_data_init(gpll, cpll, flags);
        rk3188_dvfs_init();
 }
+#define STR_UBOOT_DISPLAY      "fastboot"
+static int __init bootloader_setup(char *str)
+{
+       if (0 == strncmp(str, STR_UBOOT_DISPLAY, strlen(STR_UBOOT_DISPLAY))) {
+               printk("CLKDATA_MSG: get uboot display\n");
+               flag_uboot_display = 1;
+       }
+       return 0;
+}
+early_param("androidboot.bootloader", bootloader_setup);
 
+int support_uboot_display(void)
+{
+       return flag_uboot_display;
+}
 /*
  * You can override arm_clk rate with armclk= cmdline option.
  */
@@ -3727,6 +3841,9 @@ static void dump_clock(struct seq_file *s, struct clk *clk, int deep, const stru
        if (clk->parent)
                seq_printf(s, " parent = %s", clk->parent->name);
 
+       if (clk->last_set_rate != 0)
+               seq_printf(s, " [set %lu Hz]", clk->last_set_rate);
+
        seq_printf(s, "\n");
 
        list_for_each_entry(ck, root_clocks, node) {