summaryrefslogtreecommitdiffstats
path: root/target/linux/brcm2708/patches-4.4/0253-clk-bcm2835-Support-for-clock-parent-selection.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/brcm2708/patches-4.4/0253-clk-bcm2835-Support-for-clock-parent-selection.patch')
-rw-r--r--target/linux/brcm2708/patches-4.4/0253-clk-bcm2835-Support-for-clock-parent-selection.patch188
1 files changed, 0 insertions, 188 deletions
diff --git a/target/linux/brcm2708/patches-4.4/0253-clk-bcm2835-Support-for-clock-parent-selection.patch b/target/linux/brcm2708/patches-4.4/0253-clk-bcm2835-Support-for-clock-parent-selection.patch
deleted file mode 100644
index 13bb740016..0000000000
--- a/target/linux/brcm2708/patches-4.4/0253-clk-bcm2835-Support-for-clock-parent-selection.patch
+++ /dev/null
@@ -1,188 +0,0 @@
-From 7a4e9397156fd222f04eb86564a04cc647b99b76 Mon Sep 17 00:00:00 2001
-From: Remi Pommarel <repk@triplefau.lt>
-Date: Sun, 6 Dec 2015 17:22:47 +0100
-Subject: [PATCH] clk: bcm2835: Support for clock parent selection
-
-Some bcm2835 clocks used by hardware (like "PWM" or "H264") can have multiple
-parent clocks. These clocks divide the rate of a parent which can be selected by
-setting the proper bits in the clock control register.
-
-Previously all these parents where handled by a mux clock. But a mux clock
-cannot be used because updating clock control register to select parent needs a
-password to be xor'd with the parent index.
-
-This patch get rid of mux clock and make these clocks handle their own parent,
-allowing them to select the one to use.
-
-Signed-off-by: Remi Pommarel <repk@triplefau.lt>
-Reviewed-by: Eric Anholt <eric@anholt.net>
-Signed-off-by: Michael Turquette <mturquette@baylibre.com>
-(cherry picked from commit 6d18b8adbe679b5947aa822b676efff230acc5f6)
----
- drivers/clk/bcm/clk-bcm2835.c | 122 ++++++++++++++++++++++++++----------------
- 1 file changed, 77 insertions(+), 45 deletions(-)
-
---- a/drivers/clk/bcm/clk-bcm2835.c
-+++ b/drivers/clk/bcm/clk-bcm2835.c
-@@ -1218,16 +1218,6 @@ static long bcm2835_clock_rate_from_divi
- return temp;
- }
-
--static long bcm2835_clock_round_rate(struct clk_hw *hw,
-- unsigned long rate,
-- unsigned long *parent_rate)
--{
-- struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
-- u32 div = bcm2835_clock_choose_div(hw, rate, *parent_rate, false);
--
-- return bcm2835_clock_rate_from_divisor(clock, *parent_rate, div);
--}
--
- static unsigned long bcm2835_clock_get_rate(struct clk_hw *hw,
- unsigned long parent_rate)
- {
-@@ -1299,13 +1289,75 @@ static int bcm2835_clock_set_rate(struct
- return 0;
- }
-
-+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;
-+ unsigned long rate, best_rate = 0;
-+ unsigned long prate, best_prate = 0;
-+ size_t i;
-+ u32 div;
-+
-+ /*
-+ * Select parent clock that results in the closest but lower rate
-+ */
-+ for (i = 0; i < clk_hw_get_num_parents(hw); ++i) {
-+ parent = clk_hw_get_parent_by_index(hw, i);
-+ if (!parent)
-+ 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);
-+ if (rate > best_rate && rate <= req->rate) {
-+ best_parent = parent;
-+ best_prate = prate;
-+ best_rate = rate;
-+ }
-+ }
-+
-+ if (!best_parent)
-+ return -EINVAL;
-+
-+ req->best_parent_hw = best_parent;
-+ req->best_parent_rate = best_prate;
-+
-+ req->rate = best_rate;
-+
-+ return 0;
-+}
-+
-+static int bcm2835_clock_set_parent(struct clk_hw *hw, u8 index)
-+{
-+ struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
-+ struct bcm2835_cprman *cprman = clock->cprman;
-+ const struct bcm2835_clock_data *data = clock->data;
-+ u8 src = (index << CM_SRC_SHIFT) & CM_SRC_MASK;
-+
-+ cprman_write(cprman, data->ctl_reg, src);
-+ return 0;
-+}
-+
-+static u8 bcm2835_clock_get_parent(struct clk_hw *hw)
-+{
-+ struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
-+ struct bcm2835_cprman *cprman = clock->cprman;
-+ const struct bcm2835_clock_data *data = clock->data;
-+ u32 src = cprman_read(cprman, data->ctl_reg);
-+
-+ return (src & CM_SRC_MASK) >> CM_SRC_SHIFT;
-+}
-+
-+
- static const struct clk_ops bcm2835_clock_clk_ops = {
- .is_prepared = bcm2835_clock_is_on,
- .prepare = bcm2835_clock_on,
- .unprepare = bcm2835_clock_off,
- .recalc_rate = bcm2835_clock_get_rate,
- .set_rate = bcm2835_clock_set_rate,
-- .round_rate = bcm2835_clock_round_rate,
-+ .determine_rate = bcm2835_clock_determine_rate,
-+ .set_parent = bcm2835_clock_set_parent,
-+ .get_parent = bcm2835_clock_get_parent,
- };
-
- static int bcm2835_vpu_clock_is_on(struct clk_hw *hw)
-@@ -1321,7 +1373,9 @@ static const struct clk_ops bcm2835_vpu_
- .is_prepared = bcm2835_vpu_clock_is_on,
- .recalc_rate = bcm2835_clock_get_rate,
- .set_rate = bcm2835_clock_set_rate,
-- .round_rate = bcm2835_clock_round_rate,
-+ .determine_rate = bcm2835_clock_determine_rate,
-+ .set_parent = bcm2835_clock_set_parent,
-+ .get_parent = bcm2835_clock_get_parent,
- };
-
- static struct clk *bcm2835_register_pll(struct bcm2835_cprman *cprman,
-@@ -1415,45 +1469,23 @@ static struct clk *bcm2835_register_cloc
- {
- struct bcm2835_clock *clock;
- struct clk_init_data init;
-- const char *parent;
-+ const char *parents[1 << CM_SRC_BITS];
-+ size_t i;
-
- /*
-- * Most of the clock generators have a mux field, so we
-- * instantiate a generic mux as our parent to handle it.
-+ * Replace our "xosc" references with the oscillator's
-+ * actual name.
- */
-- if (data->num_mux_parents) {
-- const char *parents[1 << CM_SRC_BITS];
-- int i;
--
-- parent = devm_kasprintf(cprman->dev, GFP_KERNEL,
-- "mux_%s", data->name);
-- if (!parent)
-- return NULL;
--
-- /*
-- * Replace our "xosc" references with the oscillator's
-- * actual name.
-- */
-- for (i = 0; i < data->num_mux_parents; i++) {
-- if (strcmp(data->parents[i], "xosc") == 0)
-- parents[i] = cprman->osc_name;
-- else
-- parents[i] = data->parents[i];
-- }
--
-- clk_register_mux(cprman->dev, parent,
-- parents, data->num_mux_parents,
-- CLK_SET_RATE_PARENT,
-- cprman->regs + data->ctl_reg,
-- CM_SRC_SHIFT, CM_SRC_BITS,
-- 0, &cprman->regs_lock);
-- } else {
-- parent = data->parents[0];
-+ for (i = 0; i < data->num_mux_parents; i++) {
-+ if (strcmp(data->parents[i], "xosc") == 0)
-+ parents[i] = cprman->osc_name;
-+ else
-+ parents[i] = data->parents[i];
- }
-
- memset(&init, 0, sizeof(init));
-- init.parent_names = &parent;
-- init.num_parents = 1;
-+ init.parent_names = parents;
-+ init.num_parents = data->num_mux_parents;
- init.name = data->name;
- init.flags = CLK_IGNORE_UNUSED;
-