From: Kever Yang <kever.yang@rock-chips.com> To: Mike Turquette <mturquette@linaro.org>, Heiko Stuebner <heiko@sntech.de> Cc: dianders@chromium.org, sonnyrao@chromium.org, addy.ke@rock-chips.com, cf@rock-chips.com, fzf@rock-chips.com, ykk@rock-chips.com, yzq@rock-chips.com, dkl@rock-chips.com, huangtao@rock-chips.com, Kever Yang <kever.yang@rock-chips.com>, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH 4/5] clk: rockchip: add the vop_determine_rate for vop dclock Date: Tue, 4 Nov 2014 15:52:38 +0800 [thread overview] Message-ID: <1415087559-19444-5-git-send-email-kever.yang@rock-chips.com> (raw) In-Reply-To: <1415087559-19444-1-git-send-email-kever.yang@rock-chips.com> Rk3288 has 5 PLLs(APLL, DPLL, CPLL, GPLL, NPLL), APLL is for CPU clock only and DPLL is for DRAM clock only, and other 3 PLls used for all other peripherals. We have to make a total solution for how to campatible all kinds of clock requirement by on chip peripheral controllers. Some controllers like I2S and HDMI need accurate frequency while others controllers accept clock rate with margin. According to our experience on rk3288, we prefer to use CPLL and GPLL fixed at 400MHz and 594MHz for general use for most peripheral. The fraction divider should be enough for I2S controller. The HDMI is the most diffical one if we have to support all the resolution requirement for frequency. Most people use 720p and 1080 i/p resolution with 74.25MHz/148.5MHz, which can get clock rate from 594MHz(maybe from GPLL). some other resolution like 640*480 will use 25.175MHz, which is hard to get from general used PLLs. So it is better to make HDMI controller has the right to change the PLL frequency and get the clock rate it wants. We set NPLL to 500MHz as default, if HDMI can get what it need from existent clock provider, then change its divider and switch to that parent; if not, we have to change the NPLL's output and always make CPLL&GPLL not change. This patch add vop_determinate_rate as a div_ops to handle the HDMI clock things. Signed-off-by: Kever Yang <kever.yang@rock-chips.com> --- drivers/clk/rockchip/clk-rk3288.c | 69 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 48412e9..0151140 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -14,6 +14,7 @@ */ #include <linux/clk-provider.h> +#include <linux/clk-private.h> #include <linux/of.h> #include <linux/of_address.h> #include <dt-bindings/clock/rk3288-cru.h> @@ -25,6 +26,7 @@ enum rk3288_plls { apll, dpll, cpll, gpll, npll, }; +const struct clk_ops dclk_vop_ops; struct rockchip_pll_rate_table rk3288_pll_rates[] = { RK3066_PLL_RATE(2208000000, 1, 92, 1), @@ -766,6 +768,73 @@ static const char *rk3288_critical_clocks[] __initconst = { "aclk_peri", "hclk_peri", }; +#define DCLK_VOP_PARENT_NPLL 2 + +long dclk_vop_determine_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *best_parent_rate, + struct clk **best_parent_p) +{ + struct clk *clk = hw->clk, *parent; + unsigned long parent_rate, best = 0; + int num_parents = clk->num_parents; + int i; + + /* + * check if one of the generic plls can provide a cleanly dividable + * rate without changing them. + */ + for (i = 0; i < (num_parents - 1); i++) { + parent = clk_get_parent_by_index(clk, i); + parent_rate = __clk_get_rate(parent); + if (parent_rate % rate == 0) { + *best_parent_p = parent; + *best_parent_rate = parent_rate; + return rate; + } + } + + /* take the npll and set its rate to something suitable */ + for (i = 0; rk3288_pll_rates[i].rate != 0; i++) { + if (rk3288_pll_rates[i].rate % rate == 0) { + *best_parent_p = clk_get_parent_by_index(clk, + DCLK_VOP_PARENT_NPLL); + *best_parent_rate = rk3288_pll_rates[i].rate; + return rk3288_pll_rates[i].rate; + } + } + + /* + * We were not able to find a matching rate, so falling back + * to finding the fastest rate < rate. + * We allow the npll to change its rate while the other plls + * are not allowed to change. + */ + for (i = 0; i < num_parents; i++) { + parent = clk_get_parent_by_index(clk, i); + if (!parent) + continue; + + if (i == DCLK_VOP_PARENT_NPLL) + parent_rate = __clk_round_rate(parent, rate); + else + parent_rate = __clk_get_rate(parent); + if (parent_rate <= rate && parent_rate > best) { + int div = DIV_ROUND_UP(parent_rate, rate); + *best_parent_p = parent; + *best_parent_rate = parent_rate; + best = DIV_ROUND_UP(parent_rate, div); + } + } + + return best; +} + + +const struct clk_ops dclk_vop_ops = { + .recalc_rate = clk_divider_recalc_rate, + .set_rate = clk_divider_set_rate, + .determine_rate = dclk_vop_determine_rate, +}; static void __init rk3288_clk_init(struct device_node *np) { -- 1.9.1
WARNING: multiple messages have this Message-ID (diff)
From: kever.yang@rock-chips.com (Kever Yang) To: linux-arm-kernel@lists.infradead.org Subject: [PATCH 4/5] clk: rockchip: add the vop_determine_rate for vop dclock Date: Tue, 4 Nov 2014 15:52:38 +0800 [thread overview] Message-ID: <1415087559-19444-5-git-send-email-kever.yang@rock-chips.com> (raw) In-Reply-To: <1415087559-19444-1-git-send-email-kever.yang@rock-chips.com> Rk3288 has 5 PLLs(APLL, DPLL, CPLL, GPLL, NPLL), APLL is for CPU clock only and DPLL is for DRAM clock only, and other 3 PLls used for all other peripherals. We have to make a total solution for how to campatible all kinds of clock requirement by on chip peripheral controllers. Some controllers like I2S and HDMI need accurate frequency while others controllers accept clock rate with margin. According to our experience on rk3288, we prefer to use CPLL and GPLL fixed at 400MHz and 594MHz for general use for most peripheral. The fraction divider should be enough for I2S controller. The HDMI is the most diffical one if we have to support all the resolution requirement for frequency. Most people use 720p and 1080 i/p resolution with 74.25MHz/148.5MHz, which can get clock rate from 594MHz(maybe from GPLL). some other resolution like 640*480 will use 25.175MHz, which is hard to get from general used PLLs. So it is better to make HDMI controller has the right to change the PLL frequency and get the clock rate it wants. We set NPLL to 500MHz as default, if HDMI can get what it need from existent clock provider, then change its divider and switch to that parent; if not, we have to change the NPLL's output and always make CPLL&GPLL not change. This patch add vop_determinate_rate as a div_ops to handle the HDMI clock things. Signed-off-by: Kever Yang <kever.yang@rock-chips.com> --- drivers/clk/rockchip/clk-rk3288.c | 69 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 48412e9..0151140 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -14,6 +14,7 @@ */ #include <linux/clk-provider.h> +#include <linux/clk-private.h> #include <linux/of.h> #include <linux/of_address.h> #include <dt-bindings/clock/rk3288-cru.h> @@ -25,6 +26,7 @@ enum rk3288_plls { apll, dpll, cpll, gpll, npll, }; +const struct clk_ops dclk_vop_ops; struct rockchip_pll_rate_table rk3288_pll_rates[] = { RK3066_PLL_RATE(2208000000, 1, 92, 1), @@ -766,6 +768,73 @@ static const char *rk3288_critical_clocks[] __initconst = { "aclk_peri", "hclk_peri", }; +#define DCLK_VOP_PARENT_NPLL 2 + +long dclk_vop_determine_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *best_parent_rate, + struct clk **best_parent_p) +{ + struct clk *clk = hw->clk, *parent; + unsigned long parent_rate, best = 0; + int num_parents = clk->num_parents; + int i; + + /* + * check if one of the generic plls can provide a cleanly dividable + * rate without changing them. + */ + for (i = 0; i < (num_parents - 1); i++) { + parent = clk_get_parent_by_index(clk, i); + parent_rate = __clk_get_rate(parent); + if (parent_rate % rate == 0) { + *best_parent_p = parent; + *best_parent_rate = parent_rate; + return rate; + } + } + + /* take the npll and set its rate to something suitable */ + for (i = 0; rk3288_pll_rates[i].rate != 0; i++) { + if (rk3288_pll_rates[i].rate % rate == 0) { + *best_parent_p = clk_get_parent_by_index(clk, + DCLK_VOP_PARENT_NPLL); + *best_parent_rate = rk3288_pll_rates[i].rate; + return rk3288_pll_rates[i].rate; + } + } + + /* + * We were not able to find a matching rate, so falling back + * to finding the fastest rate < rate. + * We allow the npll to change its rate while the other plls + * are not allowed to change. + */ + for (i = 0; i < num_parents; i++) { + parent = clk_get_parent_by_index(clk, i); + if (!parent) + continue; + + if (i == DCLK_VOP_PARENT_NPLL) + parent_rate = __clk_round_rate(parent, rate); + else + parent_rate = __clk_get_rate(parent); + if (parent_rate <= rate && parent_rate > best) { + int div = DIV_ROUND_UP(parent_rate, rate); + *best_parent_p = parent; + *best_parent_rate = parent_rate; + best = DIV_ROUND_UP(parent_rate, div); + } + } + + return best; +} + + +const struct clk_ops dclk_vop_ops = { + .recalc_rate = clk_divider_recalc_rate, + .set_rate = clk_divider_set_rate, + .determine_rate = dclk_vop_determine_rate, +}; static void __init rk3288_clk_init(struct device_node *np) { -- 1.9.1
next prev parent reply other threads:[~2014-11-04 7:55 UTC|newest] Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top 2014-11-04 7:52 [PATCH 0/5] clk: rockchip: add full support for HDMI clock on rk3288 Kever Yang 2014-11-04 7:52 ` Kever Yang 2014-11-04 7:52 ` [PATCH 1/5] clk: rockchip: add some clock rate into rate table for rk3288 Kever Yang 2014-11-04 7:52 ` Kever Yang 2014-11-04 7:52 ` [PATCH 2/5] clk: divider: make clk_divider_recalc/set_rate available Kever Yang 2014-11-04 7:52 ` [PATCH 3/5] clk: rockchip: introduce the div_ops handling for composite branches Kever Yang 2014-11-04 7:52 ` Kever Yang 2014-11-04 7:52 ` Kever Yang [this message] 2014-11-04 7:52 ` [PATCH 4/5] clk: rockchip: add the vop_determine_rate for vop dclock Kever Yang 2014-11-04 7:52 ` [PATCH 5/5] clk: rockchip: change DCLK_VOP0 to use new COMPOSITE_DIVOPS Kever Yang 2014-11-04 7:52 ` Kever Yang 2014-11-06 21:06 ` [PATCH 0/5] clk: rockchip: add full support for HDMI clock on rk3288 Heiko Stübner 2014-11-06 21:06 ` Heiko Stübner 2014-11-13 8:52 ` Kever Yang 2014-11-13 8:52 ` Kever Yang 2014-11-13 22:59 ` Doug Anderson 2014-11-13 22:59 ` Doug Anderson [not found] ` <20141114014605.25314.49766@quantum> 2014-11-14 8:58 ` Kever Yang 2014-11-14 8:58 ` Kever Yang 2016-01-19 12:02 ` Tomeu Vizoso 2016-01-19 12:02 ` Tomeu Vizoso 2016-01-20 16:50 ` Doug Anderson 2016-01-20 16:50 ` Doug Anderson 2016-01-21 9:03 ` Tomeu Vizoso 2016-01-21 9:03 ` Tomeu Vizoso 2016-01-21 20:11 ` Doug Anderson 2016-01-21 20:11 ` Doug Anderson 2016-01-22 14:00 ` Tomeu Vizoso 2016-01-22 14:00 ` Tomeu Vizoso 2016-01-22 17:07 ` Doug Anderson 2016-01-22 17:07 ` Doug Anderson 2016-01-26 8:28 ` Tomeu Vizoso 2016-01-26 8:28 ` Tomeu Vizoso 2016-01-26 16:32 ` Doug Anderson 2016-01-26 16:32 ` Doug Anderson 2016-01-27 10:20 ` Tomeu Vizoso 2016-01-27 10:20 ` Tomeu Vizoso 2016-01-27 16:46 ` Doug Anderson 2016-01-27 16:46 ` Doug Anderson
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1415087559-19444-5-git-send-email-kever.yang@rock-chips.com \ --to=kever.yang@rock-chips.com \ --cc=addy.ke@rock-chips.com \ --cc=cf@rock-chips.com \ --cc=dianders@chromium.org \ --cc=dkl@rock-chips.com \ --cc=fzf@rock-chips.com \ --cc=heiko@sntech.de \ --cc=huangtao@rock-chips.com \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-rockchip@lists.infradead.org \ --cc=mturquette@linaro.org \ --cc=sonnyrao@chromium.org \ --cc=ykk@rock-chips.com \ --cc=yzq@rock-chips.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.