From c83fb066befea4377f8a419cc95c4372074e990b Mon Sep 17 00:00:00 2001 From: dkl Date: Wed, 12 Nov 2014 15:15:59 +0800 Subject: [PATCH] rk3368: clk: add codes to make npll only used by dclk_vop Signed-off-by: dkl --- arch/arm64/boot/dts/rk3368-clocks.dtsi | 30 +++++++----- drivers/clk/rockchip/clk-ops.c | 67 ++++++++++++++++++++++++++ include/dt-bindings/clock/rockchip.h | 1 + 3 files changed, 86 insertions(+), 12 deletions(-) diff --git a/arch/arm64/boot/dts/rk3368-clocks.dtsi b/arch/arm64/boot/dts/rk3368-clocks.dtsi index 193e60669e8f..702d6071c228 100644 --- a/arch/arm64/boot/dts/rk3368-clocks.dtsi +++ b/arch/arm64/boot/dts/rk3368-clocks.dtsi @@ -13,6 +13,8 @@ */ #include + + /{ clocks { compatible = "rockchip,rk-clocks"; @@ -233,7 +235,7 @@ status-reg = <0x0480 5>; clocks = <&xin24m>; clock-output-names = "clk_npll"; - rockchip,pll-type = ; + rockchip,pll-type = ; #clock-cells = <0>; #clock-init-cells = <1>; }; @@ -439,7 +441,7 @@ clock-output-names = "aclk_cci"; rockchip,div-type = ; #clock-cells = <0>; - rockchip,clkops-idx = ; + rockchip,clkops-idx = ; }; /* 5 reserved */ @@ -490,6 +492,7 @@ clock-output-names = "hclk_bus"; rockchip,div-type = ; #clock-cells = <0>; + #clock-init-cells = <1>; }; /* 11:10 reserved */ @@ -501,6 +504,7 @@ clock-output-names = "pclk_bus"; rockchip,div-type = ; #clock-cells = <0>; + #clock-init-cells = <1>; }; }; @@ -598,6 +602,7 @@ clock-output-names = "clk_crypto"; rockchip,div-type = ; #clock-cells = <0>; + #clock-init-cells = <1>; }; }; @@ -706,7 +711,7 @@ clock-output-names = "clk_gpu_core"; rockchip,div-type = ; #clock-cells = <0>; - rockchip,clkops-idx = ; + rockchip,clkops-idx = ; rockchip,flags = ; }; @@ -755,7 +760,7 @@ clock-output-names = "aclk_vepu"; rockchip,div-type = ; #clock-cells = <0>; - rockchip,clkops-idx = ; + rockchip,clkops-idx = ; }; /* 5 reserved */ @@ -776,7 +781,7 @@ clock-output-names = "aclk_vdpu"; rockchip,div-type = ; #clock-cells = <0>; - rockchip,clkops-idx = ; + rockchip,clkops-idx = ; }; /* 13 reserved */ @@ -820,7 +825,7 @@ clock-output-names = "clk_hevc_cabac"; rockchip,div-type = ; #clock-cells = <0>; - rockchip,clkops-idx = ; + rockchip,clkops-idx = ; }; /* 5 reserved */ @@ -841,7 +846,7 @@ clock-output-names = "clk_hevc_core"; rockchip,div-type = ; #clock-cells = <0>; - rockchip,clkops-idx = ; + rockchip,clkops-idx = ; }; /* 13 reserved */ @@ -947,6 +952,7 @@ rockchip,div-type = ; #clock-cells = <0>; rockchip,clkops-idx = ; + rockchip,flags = ; }; dclk_vop0: dclk_vop0_mux { @@ -1030,7 +1036,7 @@ clock-output-names = "clk_isp"; rockchip,div-type = ; #clock-cells = <0>; - rockchip,clkops-idx = ; + rockchip,clkops-idx = ; }; clk_isp: clk_isp_mux { @@ -1056,7 +1062,7 @@ clock-output-names = "clk_edp"; rockchip,div-type = ; #clock-cells = <0>; - rockchip,clkops-idx = ; + rockchip,clkops-idx = ; }; clk_edp: clk_edp_mux { @@ -1519,7 +1525,7 @@ clock-output-names = "clk_mac_pll"; rockchip,div-type = ; #clock-cells = <0>; - rockchip,clkops-idx = ; + rockchip,clkops-idx = ; }; /* 5 reserved */ @@ -1613,7 +1619,7 @@ clock-output-names = "clk_tsp"; rockchip,div-type = ; #clock-cells = <0>; - rockchip,clkops-idx = ; + rockchip,clkops-idx = ; }; /* 5 reserved */ @@ -1866,7 +1872,7 @@ clock-output-names = "clk_hdcp"; rockchip,div-type = ; #clock-cells = <0>; - rockchip,clkops-idx = ; + rockchip,clkops-idx = ; }; clk_hdcp: clk_hdcp_mux { diff --git a/drivers/clk/rockchip/clk-ops.c b/drivers/clk/rockchip/clk-ops.c index 226541849d31..2bb5d0e168a6 100644 --- a/drivers/clk/rockchip/clk-ops.c +++ b/drivers/clk/rockchip/clk-ops.c @@ -714,6 +714,72 @@ const struct clk_ops clkops_rate_3288_dclk_lcdc1 = { .recalc_rate = clk_divider_recalc_rate, }; +#define CONFIG_RK3368_MUX_NO_USE_NPLL + +static long clk_3368_mux_div_determine_rate(struct clk_hw *div_hw, + unsigned long rate, + unsigned long *best_parent_rate, + struct clk **best_parent_p) +{ + struct clk *clk = div_hw->clk, *parent = NULL, *best_parent = NULL; + int i, num_parents; + unsigned long parent_rate = 0, best_prate = 0, best = 0, now = 0; + + parent = __clk_get_parent(clk); + if (!parent) { + best = __clk_get_rate(clk); + goto out; + } + + /* if NO_REPARENT flag set, pass through to current parent */ + if (clk->flags & CLK_SET_RATE_NO_REPARENT) { + best_prate = __clk_get_rate(parent); + best = clk_divider_ops.round_rate(div_hw, rate, &best_prate); + goto out; + } + + /* find the parent that can provide the fastest rate <= rate */ + num_parents = clk->num_parents; + for (i = 0; i < num_parents; i++) { + parent = clk_get_parent_by_index(clk, i); + if (!parent) + continue; + +#ifdef CONFIG_RK3368_MUX_NO_USE_NPLL + if (!strcmp(__clk_get_name(parent), "clk_npll")) + continue; +#endif + parent_rate = __clk_get_rate(parent); + now = clk_divider_ops.round_rate(div_hw, rate, &parent_rate); + + if (now <= rate && now > best) { + best_parent = parent; + best_prate = parent_rate; + best = now; + } + } + +out: + if (best_prate) + *best_parent_rate = best_prate; + + if (best_parent) + *best_parent_p = best_parent; + + clk_debug("clk name = %s, determine rate = %lu, best = %lu\n" + "\tbest_parent name = %s, best_prate = %lu\n", + clk->name, rate, best, + __clk_get_name(*best_parent_p), *best_parent_rate); + + return best; +} + +const struct clk_ops clkops_rate_3368_auto_parent = { + .recalc_rate = clk_divider_recalc_rate, + .round_rate = clk_divider_round_rate, + .set_rate = clk_divider_set_rate, + .determine_rate = clk_3368_mux_div_determine_rate, +}; struct clk_ops_table rk_clkops_rate_table[] = { {.index = CLKOPS_RATE_MUX_DIV, .clk_ops = &clkops_rate_auto_parent}, @@ -730,6 +796,7 @@ struct clk_ops_table rk_clkops_rate_table[] = { {.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_DDR_DIV4, .clk_ops = &clkops_rate_ddr_div4}, + {.index = CLKOPS_RATE_RK3368_MUX_DIV_NPLL, .clk_ops = &clkops_rate_3368_auto_parent}, {.index = CLKOPS_RATE_I2S, .clk_ops = NULL}, {.index = CLKOPS_RATE_CIFOUT, .clk_ops = NULL}, {.index = CLKOPS_RATE_UART, .clk_ops = NULL}, diff --git a/include/dt-bindings/clock/rockchip.h b/include/dt-bindings/clock/rockchip.h index c6d25f6aca0f..765d3ab15740 100644 --- a/include/dt-bindings/clock/rockchip.h +++ b/include/dt-bindings/clock/rockchip.h @@ -67,6 +67,7 @@ #define CLKOPS_RATE_RK3288_DCLK_LCDC1 17 #define CLKOPS_RATE_DDR_DIV2 18 #define CLKOPS_RATE_DDR_DIV4 19 +#define CLKOPS_RATE_RK3368_MUX_DIV_NPLL 20 #define CLKOPS_TABLE_END (~0) /* pd id */ -- 2.34.1