From 7348c1bed5da5654b9eefb79881910905d0a57a5 Mon Sep 17 00:00:00 2001 From: dkl Date: Sun, 20 Apr 2014 21:19:13 +0800 Subject: [PATCH] clk: rockchip: rk3288: adjust clock settings 1. add clkops_rate_3288_dclk_lcdc0/1 2. change gpll init_rate to 297M, and npll init_rate to 1250M --- arch/arm/boot/dts/rk3288-clocks.dtsi | 9 +- arch/arm/boot/dts/rk3288.dtsi | 7 +- drivers/clk/rockchip/clk-ops.c | 118 +++++++++++++++++++++++++++ drivers/clk/rockchip/clk-pll.c | 1 + include/dt-bindings/clock/rockchip.h | 2 + 5 files changed, 132 insertions(+), 5 deletions(-) diff --git a/arch/arm/boot/dts/rk3288-clocks.dtsi b/arch/arm/boot/dts/rk3288-clocks.dtsi index 92d69a422742..f3e007fe34d3 100755 --- a/arch/arm/boot/dts/rk3288-clocks.dtsi +++ b/arch/arm/boot/dts/rk3288-clocks.dtsi @@ -662,6 +662,7 @@ clocks = <&clk_cpll>, <&clk_gpll>; clock-output-names = "clk_spdif_pll"; #clock-cells = <0>; + #clock-init-cells = <1>; }; }; @@ -1417,7 +1418,8 @@ rockchip,div-type = ; #clock-cells = <0>; rockchip,clkops-idx = - ; + ; + rockchip,flags = ; }; }; @@ -1524,7 +1526,8 @@ rockchip,div-type = ; #clock-cells = <0>; rockchip,clkops-idx = - ; + ; + rockchip,flags = ; }; }; @@ -1594,6 +1597,7 @@ #clock-cells = <0>; rockchip,clkops-idx = ; + rockchip,flags = ; }; /* reg[5]: reserved */ @@ -1616,6 +1620,7 @@ #clock-cells = <0>; rockchip,clkops-idx = ; + rockchip,flags = ; }; /* reg[13]: reserved */ diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index b1e33458e2c2..3e0cb606d034 100755 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -479,10 +479,11 @@ rockchip,clocks-init-parent = <&clk_core &clk_apll>, <&aclk_bus_src &clk_gpll>, <&aclk_peri &clk_gpll>, <&uart_pll_mux &clk_gpll>, - <&clk_i2s_pll &clk_cpll>, <&usbphy_480m &otgphy2_480m>; + <&clk_i2s_pll &clk_gpll>, <&clk_spdif_pll &clk_gpll>, + <&usbphy_480m &otgphy2_480m>; rockchip,clocks-init-rate = - <&clk_core 792000000>, <&clk_gpll 594000000>, - <&clk_cpll 384000000>, <&clk_npll 500000000>, + <&clk_core 792000000>, <&clk_gpll 297000000>, + /*<&clk_cpll 47000000>,*/ <&clk_npll 1250000000>, <&aclk_bus_src 300000000>, <&aclk_bus 300000000>, <&hclk_bus 150000000>, <&pclk_bus 75000000>, <&clk_crypto 150000000>, <&aclk_peri 300000000>, diff --git a/drivers/clk/rockchip/clk-ops.c b/drivers/clk/rockchip/clk-ops.c index f74ce889d960..4e7aef47321c 100644 --- a/drivers/clk/rockchip/clk-ops.c +++ b/drivers/clk/rockchip/clk-ops.c @@ -558,6 +558,122 @@ const struct clk_ops clkops_rate_3288_usb480m = { .recalc_rate = clk_3288_usb480m_recalc_rate, }; +#define RK3288_LIMIT_PLL_VIO0 (400*MHZ) + +static long clk_3288_dclk_lcdc0_determine_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *best_parent_rate, + struct clk **best_parent_p) +{ + struct clk *gpll = clk_get(NULL, "clk_gpll"); + struct clk *cpll = clk_get(NULL, "clk_cpll"); + unsigned long best, div, prate; + + + if((rate <= (297*MHZ)) && ((297*MHZ)%rate == 0)) { + *best_parent_p = gpll; + best = rate; + } else { + *best_parent_p = cpll; + div = RK3288_LIMIT_PLL_VIO0/rate; + prate = div * rate; + *best_parent_rate = clk_round_rate(cpll, prate); + best = (*best_parent_rate)/div; + } + + return best; +} + +static long clk_3288_dclk_lcdc0_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + return clk_3288_dclk_lcdc0_determine_rate(hw, rate, prate, NULL); +} + +static int clk_3288_dclk_lcdc0_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk* aclk_vio0 = clk_get(NULL, "aclk_vio0"); + struct clk* parent; + + clk_divider_ops.set_rate(hw, rate, parent_rate); + + /* set aclk_vio */ + if(parent_rate == 297*MHZ) + parent = clk_get(NULL, "clk_gpll"); + else + parent = clk_get(NULL, "clk_cpll"); + + clk_set_parent(aclk_vio0, parent); + clk_set_rate(aclk_vio0, __clk_get_rate(parent)); + + return 0; +} + +const struct clk_ops clkops_rate_3288_dclk_lcdc0 = { + .determine_rate = clk_3288_dclk_lcdc0_determine_rate, + .set_rate = clk_3288_dclk_lcdc0_set_rate, + .round_rate = clk_3288_dclk_lcdc0_round_rate, + .recalc_rate = clk_divider_recalc_rate, +}; + +#define RK3288_LIMIT_PLL_VIO1 (348*MHZ) + +static long clk_3288_dclk_lcdc1_determine_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *best_parent_rate, + struct clk **best_parent_p) +{ + struct clk *gpll = clk_get(NULL, "clk_gpll"); + struct clk *cpll = clk_get(NULL, "clk_cpll"); + unsigned long best, div, prate; + + + if((rate <= (297*MHZ)) && ((297*MHZ)%rate == 0)) { + *best_parent_p = gpll; + best = rate; + } else { + *best_parent_p = cpll; + div = RK3288_LIMIT_PLL_VIO1/rate; + prate = div * rate; + *best_parent_rate = clk_round_rate(cpll, prate); + best = (*best_parent_rate)/div; + } + + return best; +} + +static long clk_3288_dclk_lcdc1_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + return clk_3288_dclk_lcdc1_determine_rate(hw, rate, prate, NULL); +} + +static int clk_3288_dclk_lcdc1_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk* aclk_vio1 = clk_get(NULL, "aclk_vio1"); + struct clk* parent; + + clk_divider_ops.set_rate(hw, rate, parent_rate); + + /* set aclk_vio */ + if(parent_rate == 297*MHZ) + parent = clk_get(NULL, "clk_gpll"); + else + parent = clk_get(NULL, "clk_cpll"); + + clk_set_parent(aclk_vio1, parent); + clk_set_rate(aclk_vio1, __clk_get_rate(parent)); + + return 0; +} + +const struct clk_ops clkops_rate_3288_dclk_lcdc1 = { + .determine_rate = clk_3288_dclk_lcdc1_determine_rate, + .set_rate = clk_3288_dclk_lcdc1_set_rate, + .round_rate = clk_3288_dclk_lcdc1_round_rate, + .recalc_rate = clk_divider_recalc_rate, +}; + struct clk_ops_table rk_clkops_rate_table[] = { {.index = CLKOPS_RATE_MUX_DIV, .clk_ops = &clkops_rate_auto_parent}, @@ -570,6 +686,8 @@ struct clk_ops_table rk_clkops_rate_table[] = { {.index = CLKOPS_RATE_DDR, .clk_ops = &clkops_rate_ddr}, {.index = CLKOPS_RATE_RK3288_I2S, .clk_ops = &clkops_rate_3288_i2s}, {.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_I2S, .clk_ops = NULL}, {.index = CLKOPS_RATE_CIFOUT, .clk_ops = NULL}, {.index = CLKOPS_RATE_UART, .clk_ops = NULL}, diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c index e3cd58124954..24f87c1f142c 100644 --- a/drivers/clk/rockchip/clk-pll.c +++ b/drivers/clk/rockchip/clk-pll.c @@ -6,6 +6,7 @@ static const struct pll_clk_set pll_com_table[] = { + _RK3188_PLL_SET_CLKS(1250000, 12, 625, 1), _RK3188_PLL_SET_CLKS(1200000, 1, 50, 1), _RK3188_PLL_SET_CLKS(1188000, 2, 99, 1), _RK3188_PLL_SET_CLKS(891000, 8, 594, 2), diff --git a/include/dt-bindings/clock/rockchip.h b/include/dt-bindings/clock/rockchip.h index 927a51d0a621..c216a0e9c109 100644 --- a/include/dt-bindings/clock/rockchip.h +++ b/include/dt-bindings/clock/rockchip.h @@ -54,6 +54,8 @@ #define CLKOPS_RATE_DDR 13 #define CLKOPS_RATE_RK3288_I2S 14 #define CLKOPS_RATE_RK3288_USB480M 15 +#define CLKOPS_RATE_RK3288_DCLK_LCDC0 16 +#define CLKOPS_RATE_RK3288_DCLK_LCDC1 17 #define CLKOPS_TABLE_END (~0) /* pd id */ -- 2.34.1