diff options
Diffstat (limited to 'target/linux/brcm2708/patches-4.9/950-0152-clk-bcm-Support-rate-change-propagation-on-bcm2835-c.patch')
-rw-r--r-- | target/linux/brcm2708/patches-4.9/950-0152-clk-bcm-Support-rate-change-propagation-on-bcm2835-c.patch | 124 |
1 files changed, 0 insertions, 124 deletions
diff --git a/target/linux/brcm2708/patches-4.9/950-0152-clk-bcm-Support-rate-change-propagation-on-bcm2835-c.patch b/target/linux/brcm2708/patches-4.9/950-0152-clk-bcm-Support-rate-change-propagation-on-bcm2835-c.patch deleted file mode 100644 index 0fa32dc7b9..0000000000 --- a/target/linux/brcm2708/patches-4.9/950-0152-clk-bcm-Support-rate-change-propagation-on-bcm2835-c.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 2988239956fddb3fb808cfb50fa8d4e68b893f3d Mon Sep 17 00:00:00 2001 -From: Boris Brezillon <boris.brezillon@free-electrons.com> -Date: Thu, 1 Dec 2016 22:00:19 +0100 -Subject: [PATCH] clk: bcm: Support rate change propagation on bcm2835 clocks - -Some peripheral clocks, like the VEC (Video EnCoder) clock need to be set -to a precise rate (in our case 108MHz). With the current implementation, -where peripheral clocks are not allowed to forward rate change requests -to their parents, it is impossible to match this requirement unless the -bootloader has configured things correctly, or a specific rate has been -assigned through the DT (with the assigned-clk-rates property). - -Add a new field to struct bcm2835_clock_data to specify which parent -clocks accept rate change propagation, and support set rate propagation -in bcm2835_clock_determine_rate(). - -Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> -Reviewed-by: Eric Anholt <eric@anholt.net> -Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> -(cherry picked from commit 155e8b3b0ee320ae866b97dd31eba8a1f080a772) ---- - drivers/clk/bcm/clk-bcm2835.c | 67 ++++++++++++++++++++++++++++++++++++++++--- - 1 file changed, 63 insertions(+), 4 deletions(-) - ---- a/drivers/clk/bcm/clk-bcm2835.c -+++ b/drivers/clk/bcm/clk-bcm2835.c -@@ -436,6 +436,9 @@ struct bcm2835_clock_data { - const char *const *parents; - int num_mux_parents; - -+ /* Bitmap encoding which parents accept rate change propagation. */ -+ unsigned int set_rate_parent; -+ - u32 ctl_reg; - u32 div_reg; - -@@ -1023,10 +1026,60 @@ bcm2835_clk_is_pllc(struct clk_hw *hw) - return strncmp(clk_hw_get_name(hw), "pllc", 4) == 0; - } - -+static unsigned long bcm2835_clock_choose_div_and_prate(struct clk_hw *hw, -+ int parent_idx, -+ unsigned long rate, -+ u32 *div, -+ unsigned long *prate) -+{ -+ struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); -+ struct bcm2835_cprman *cprman = clock->cprman; -+ const struct bcm2835_clock_data *data = clock->data; -+ unsigned long best_rate; -+ u32 curdiv, mindiv, maxdiv; -+ struct clk_hw *parent; -+ -+ parent = clk_hw_get_parent_by_index(hw, parent_idx); -+ -+ if (!(BIT(parent_idx) & data->set_rate_parent)) { -+ *prate = clk_hw_get_rate(parent); -+ *div = bcm2835_clock_choose_div(hw, rate, *prate, true); -+ -+ return bcm2835_clock_rate_from_divisor(clock, *prate, -+ *div); -+ } -+ -+ if (data->frac_bits) -+ dev_warn(cprman->dev, -+ "frac bits are not used when propagating rate change"); -+ -+ /* clamp to min divider of 2 if we're dealing with a mash clock */ -+ mindiv = data->is_mash_clock ? 2 : 1; -+ maxdiv = BIT(data->int_bits) - 1; -+ -+ /* TODO: Be smart, and only test a subset of the available divisors. */ -+ for (curdiv = mindiv; curdiv <= maxdiv; curdiv++) { -+ unsigned long tmp_rate; -+ -+ tmp_rate = clk_hw_round_rate(parent, rate * curdiv); -+ tmp_rate /= curdiv; -+ if (curdiv == mindiv || -+ (tmp_rate > best_rate && tmp_rate <= rate)) -+ best_rate = tmp_rate; -+ -+ if (best_rate == rate) -+ break; -+ } -+ -+ *div = curdiv << CM_DIV_FRAC_BITS; -+ *prate = curdiv * best_rate; -+ -+ return best_rate; -+} -+ - static int bcm2835_clock_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) - { -- struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); - struct clk_hw *parent, *best_parent = NULL; - bool current_parent_is_pllc; - unsigned long rate, best_rate = 0; -@@ -1054,9 +1107,8 @@ static int bcm2835_clock_determine_rate( - if (bcm2835_clk_is_pllc(parent) && !current_parent_is_pllc) - continue; - -- prate = clk_hw_get_rate(parent); -- div = bcm2835_clock_choose_div(hw, req->rate, prate, true); -- rate = bcm2835_clock_rate_from_divisor(clock, prate, div); -+ rate = bcm2835_clock_choose_div_and_prate(hw, i, req->rate, -+ &div, &prate); - if (rate > best_rate && rate <= req->rate) { - best_parent = parent; - best_prate = prate; -@@ -1277,6 +1329,13 @@ static struct clk_hw *bcm2835_register_c - if ((cprman_read(cprman, data->ctl_reg) & CM_ENABLE) == 0) - init.flags &= ~CLK_IS_CRITICAL; - -+ /* -+ * Pass the CLK_SET_RATE_PARENT flag if we are allowed to propagate -+ * rate changes on at least of the parents. -+ */ -+ if (data->set_rate_parent) -+ init.flags |= CLK_SET_RATE_PARENT; -+ - if (data->is_vpu_clock) { - init.ops = &bcm2835_vpu_clock_clk_ops; - } else { |