rk312x: correct clk_ddr rate
author陈亮 <cl@rock-chips.com>
Thu, 18 Sep 2014 09:32:51 +0000 (02:32 -0700)
committer陈亮 <cl@rock-chips.com>
Thu, 18 Sep 2014 09:33:31 +0000 (02:33 -0700)
Signed-off-by: 陈亮 <cl@rock-chips.com>
arch/arm/boot/dts/rk312x-clocks.dtsi
arch/arm/mach-rockchip/ddr_freq.c
arch/arm/mach-rockchip/dvfs.c
drivers/clk/rockchip/clk-ops.c
include/dt-bindings/clock/rockchip.h

index a2c62f302b79514434ffe60aae037993f0d71f9a..00f6af51ec8835b134d1cf33fafe95cddf6cdba9 100755 (executable)
                                                #clock-cells = <0>;
                                                rockchip,flags = <(CLK_GET_RATE_NOCACHE |
                                                                        CLK_SET_RATE_NO_REPARENT)>;
-                                               rockchip,clkops-idx = <CLKOPS_RATE_DDR>;
+                                               rockchip,clkops-idx = <CLKOPS_RATE_DDR_DIV2>;
                                        };
 
                                        /* reg[7:2]: reserved */
index dd09a5b307356771e17f244b0aa6a7d19aceaf2c..98297152204502bc3d3fd3c5d5cbb716d8de71b9 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/rockchip/grf.h>
 #include <linux/rockchip/iomap.h>
 #include <linux/clk-private.h>
+#include <linux/rockchip/cpu.h>
 #include "../../../drivers/clk/rockchip/clk-pd.h"
 #include "cpu_axi.h"
 
@@ -912,8 +913,13 @@ static int ddrfreq_scale_rate_for_dvfs(struct clk *clk, unsigned long rate)
        real_rate *= MHZ;
        if (!real_rate)
                return -EAGAIN;
-
-       clk->parent->rate = clk->rate = real_rate;
+       if (cpu_is_rk312x()) {
+               clk->parent->rate = 2 * real_rate;
+               clk->rate = real_rate;
+       } else {
+               clk->rate = real_rate;
+               clk->parent->rate = real_rate;
+       }
 
        return 0;
 }
index ba676f6864644d82b6883db43c7e75f1d28d975b..ea62aa4d6cd9dbc8df25525015d1a2d6905f30dc 100644 (file)
@@ -1028,9 +1028,10 @@ int dvfs_clk_enable_limit(struct dvfs_node *clk_dvfs_node, unsigned int min_rate
 
        }
 
-       DVFS_DBG("%s:clk(%s) last_set_rate=%u; [min_rate, max_rate]=[%u, %u]\n",
-                       __func__, __clk_get_name(clk_dvfs_node->clk), clk_dvfs_node->last_set_rate, 
-                       clk_dvfs_node->min_rate, clk_dvfs_node->max_rate);
+       DVFS_DBG("%s:clk(%s) last_set_rate=%lu; [min_rate, max_rate]=[%u, %u]\n",
+                __func__, __clk_get_name(clk_dvfs_node->clk),
+                clk_dvfs_node->last_set_rate,
+                clk_dvfs_node->min_rate, clk_dvfs_node->max_rate);
 
        return 0;
 }
@@ -1054,8 +1055,11 @@ int dvfs_clk_disable_limit(struct dvfs_node *clk_dvfs_node)
                mutex_unlock(&clk_dvfs_node->vd->mutex);
        }
 
-       DVFS_DBG("%s: clk(%s) last_set_rate=%u; [min_rate, max_rate]=[%u, %u]\n",
-                       __func__, __clk_get_name(clk_dvfs_node->clk), clk_dvfs_node->last_set_rate, clk_dvfs_node->min_rate, clk_dvfs_node->max_rate);
+       DVFS_DBG("%s: clk(%s) last_set_rate=%lu; [min_rate, max_rate]=[%u, %u]\n",
+                __func__, __clk_get_name(clk_dvfs_node->clk),
+                clk_dvfs_node->last_set_rate,
+                clk_dvfs_node->min_rate, clk_dvfs_node->max_rate);
+
        return 0;
 }
 EXPORT_SYMBOL(dvfs_clk_disable_limit);
@@ -1329,11 +1333,8 @@ static int dvfs_target(struct dvfs_node *clk_dvfs_node, unsigned long rate)
        if (!clk)
                return -EINVAL;
 
-       if (!clk_dvfs_node->enable_count){
-               DVFS_WARNING("%s:dvfs(%s) is disable\n", 
-                       __func__, clk_dvfs_node->name);
+       if (!clk_dvfs_node->enable_count)
                return 0;
-       }
        
        if (clk_dvfs_node->vd->volt_set_flag == DVFS_SET_VOLT_FAILURE) {
                /* It means the last time set voltage error */
index 7107134a8e7e56de6f684af95577d04b8e19c945..197051dec37edc20afe25f177a9f64d7ed24d632 100644 (file)
@@ -476,6 +476,24 @@ const struct clk_ops clkops_rate_ddr = {
        .determine_rate = clk_ddr_determine_rate,
 };
 
+static unsigned long clk_ddr_div2_recalc_rate(struct clk_hw *hw,
+                                             unsigned long parent_rate)
+{
+       /* Same as clk_core, we should NOT set clk_ddr's parent
+        * (dpll) rate directly as a side effect.
+        */
+       struct clk *parent = __clk_get_parent(hw->clk);
+
+       return clk_divider_recalc_rate(hw, __clk_get_rate(parent))/2;
+}
+
+const struct clk_ops clkops_rate_ddr_div2 = {
+       .recalc_rate    = clk_ddr_div2_recalc_rate,
+       .round_rate     = clk_ddr_round_rate,
+       .set_rate       = clk_ddr_set_rate,
+       .determine_rate = clk_ddr_determine_rate,
+};
+
 static unsigned long clk_3288_i2s_recalc_rate(struct clk_hw *hw,
                unsigned long parent_rate)
 {
@@ -692,6 +710,7 @@ struct clk_ops_table rk_clkops_rate_table[] = {
        {.index = CLKOPS_RATE_RK3288_USB480M,   .clk_ops = &clkops_rate_3288_usb480m},
        {.index = CLKOPS_RATE_RK3288_DCLK_LCDC0,.clk_ops = &clkops_rate_3288_dclk_lcdc0},
        {.index = CLKOPS_RATE_RK3288_DCLK_LCDC1,.clk_ops = &clkops_rate_3288_dclk_lcdc1},
+       {.index = CLKOPS_RATE_DDR_DIV2, .clk_ops = &clkops_rate_ddr_div2},
        {.index = CLKOPS_RATE_I2S,              .clk_ops = NULL},
        {.index = CLKOPS_RATE_CIFOUT,           .clk_ops = NULL},
        {.index = CLKOPS_RATE_UART,             .clk_ops = NULL},
index 8b9bc21e0e7e36a44a9df93754e563f89583b1bd..5c1234e967e3ab78b0b0ea007b2127c6fdab7744 100644 (file)
@@ -63,6 +63,7 @@
 #define CLKOPS_RATE_RK3288_USB480M     15
 #define CLKOPS_RATE_RK3288_DCLK_LCDC0  16
 #define CLKOPS_RATE_RK3288_DCLK_LCDC1  17
+#define CLKOPS_RATE_DDR_DIV2           18
 #define CLKOPS_TABLE_END               (~0)
 
 /* pd id */