From 0e321ec4d71e4d082380542ba1e961112f2c00ab Mon Sep 17 00:00:00 2001 From: dkl Date: Tue, 25 Mar 2014 20:00:30 +0800 Subject: [PATCH] rk3288: fix problem of mux clk with frac parent in rk3288 Mux clk with frac parent in rk3288, like i2s/spdif/uart, has problem when set rate before. --- arch/arm/boot/dts/rk3288-clocks.dtsi | 16 ++++++++---- drivers/clk/rockchip/clk-ops.c | 38 ++++++++++++++++++++++++++++ include/dt-bindings/clock/rockchip.h | 1 + 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/arch/arm/boot/dts/rk3288-clocks.dtsi b/arch/arm/boot/dts/rk3288-clocks.dtsi index 36661c0b989c..8fcd38cfe44b 100755 --- a/arch/arm/boot/dts/rk3288-clocks.dtsi +++ b/arch/arm/boot/dts/rk3288-clocks.dtsi @@ -427,7 +427,7 @@ clock-output-names = "clk_uart4"; #clock-cells = <0>; rockchip,clkops-idx = - ; + ; rockchip,flags = ; }; @@ -461,6 +461,8 @@ clocks = <&clk_i2s_pll>, <&i2s_frac>, <&i2s_clkin>, <&xin12m>; clock-output-names = "clk_i2s"; #clock-cells = <0>; + rockchip,clkops-idx = + ; rockchip,flags = ; }; @@ -509,6 +511,8 @@ clocks = <&spdif_div>, <&spdif_frac>, <&xin12m>, <&dummy>; clock-output-names = "clk_spdif"; #clock-cells = <0>; + rockchip,clkops-idx = + ; rockchip,flags = ; }; @@ -794,7 +798,7 @@ clock-output-names = "clk_uart0"; #clock-cells = <0>; rockchip,clkops-idx = - ; + ; rockchip,flags = ; }; @@ -850,7 +854,7 @@ clock-output-names = "clk_uart1"; #clock-cells = <0>; rockchip,clkops-idx = - ; + ; rockchip,flags = ; }; @@ -881,7 +885,7 @@ clock-output-names = "clk_uart2"; #clock-cells = <0>; rockchip,clkops-idx = - ; + ; rockchip,flags = ; }; @@ -912,7 +916,7 @@ clock-output-names = "clk_uart3"; #clock-cells = <0>; rockchip,clkops-idx = - ; + ; rockchip,flags = ; }; @@ -1882,6 +1886,8 @@ clocks = <&spdif_8ch_div>, <&spdif_8ch_frac>, <&xin12m>; clock-output-names = "clk_spdif_8ch"; #clock-cells = <0>; + rockchip,clkops-idx = + ; rockchip,flags = ; }; diff --git a/drivers/clk/rockchip/clk-ops.c b/drivers/clk/rockchip/clk-ops.c index 66795dd9d8f7..3b59e3def34f 100644 --- a/drivers/clk/rockchip/clk-ops.c +++ b/drivers/clk/rockchip/clk-ops.c @@ -476,6 +476,43 @@ const struct clk_ops clkops_rate_ddr = { .determine_rate = clk_ddr_determine_rate, }; +static unsigned long clk_3288_i2s_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return parent_rate; +} + +static long clk_3288_i2s_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + return rate; +} + +static int clk_3288_i2s_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk *parent = __clk_get_parent(hw->clk); + struct clk *grand_p = __clk_get_parent(parent); + + + if (IS_ERR_OR_NULL(parent) || IS_ERR_OR_NULL(grand_p)) { + return 0; + } + + if (parent->ops->set_rate) { + parent->ops->set_rate(parent->hw, rate/2, __clk_get_rate(grand_p)); + parent->ops->set_rate(parent->hw, rate, __clk_get_rate(grand_p)); + } + + return 0; +} + +const struct clk_ops clkops_rate_3288_i2s = { + .recalc_rate = clk_3288_i2s_recalc_rate, + .round_rate = clk_3288_i2s_round_rate, + .set_rate = clk_3288_i2s_set_rate, +}; + struct clk_ops_table rk_clkops_rate_table[] = { {.index = CLKOPS_RATE_MUX_DIV, .clk_ops = &clkops_rate_auto_parent}, {.index = CLKOPS_RATE_EVENDIV, .clk_ops = &clkops_rate_evendiv}, @@ -485,6 +522,7 @@ struct clk_ops_table rk_clkops_rate_table[] = { {.index = CLKOPS_RATE_CORE, .clk_ops = &clkops_rate_core}, {.index = CLKOPS_RATE_CORE_CHILD, .clk_ops = &clkops_rate_core_peri}, {.index = CLKOPS_RATE_DDR, .clk_ops = &clkops_rate_ddr}, + {.index = CLKOPS_RATE_RK3288_I2S, .clk_ops = &clkops_rate_3288_i2s}, {.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 eeca45ec68cb..d05d846d8406 100644 --- a/include/dt-bindings/clock/rockchip.h +++ b/include/dt-bindings/clock/rockchip.h @@ -50,6 +50,7 @@ #define CLKOPS_RATE_CORE 11 #define CLKOPS_RATE_CORE_CHILD 12 #define CLKOPS_RATE_DDR 13 +#define CLKOPS_RATE_RK3288_I2S 14 #define CLKOPS_TABLE_END (~0) #endif /* _DT_BINDINGS_CLOCK_ROCKCHIP_H */ -- 2.34.1