summaryrefslogtreecommitdiffstats
path: root/drivers/clk/qcom/clk-rcg2.c
diff options
context:
space:
mode:
authorGeorgi Djakov <georgi.djakov@linaro.org>2015-03-20 17:30:26 +0100
committerStephen Boyd <sboyd@codeaurora.org>2015-03-24 00:09:19 +0100
commit293d2e97b37f545bb36aef78cd549d9e6cd66e7f (patch)
tree4b8ba1c40d681b198dd67696087cf03531f03ca0 /drivers/clk/qcom/clk-rcg2.c
parentclk: qcom: Do some error handling in configure_bank() (diff)
downloadlinux-293d2e97b37f545bb36aef78cd549d9e6cd66e7f.tar.xz
linux-293d2e97b37f545bb36aef78cd549d9e6cd66e7f.zip
clk: qcom: Introduce parent_map tables
In the current parent mapping code, we can get duplicate or inconsistent indexes, which leads to discrepancy between the number of elements in the array and the number of parents. Until now, this was solved with some reordering but this is not always possible. This patch introduces index tables that are used to define the relations between the PLL source and the hardware mux configuration value. To accomplish this, here we do the following: - Define a parent_map struct to map the relations between PLL source index and register configuration value. - Add a qcom_find_src_index() function for finding the index of a clock matching the specific PLL configuration. - Update the {set,get}_parent RCG functions use the newly introduced parent_map struct. - Convert all existing drivers to the new parent_map tables. Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Diffstat (limited to 'drivers/clk/qcom/clk-rcg2.c')
-rw-r--r--drivers/clk/qcom/clk-rcg2.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index 10c2e45832b8..416becce4170 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -75,7 +75,7 @@ static u8 clk_rcg2_get_parent(struct clk_hw *hw)
cfg >>= CFG_SRC_SEL_SHIFT;
for (i = 0; i < num_parents; i++)
- if (cfg == rcg->parent_map[i])
+ if (cfg == rcg->parent_map[i].cfg)
return i;
err:
@@ -114,10 +114,10 @@ static int clk_rcg2_set_parent(struct clk_hw *hw, u8 index)
{
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
int ret;
+ u32 cfg = rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT;
ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG,
- CFG_SRC_SEL_MASK,
- rcg->parent_map[index] << CFG_SRC_SEL_SHIFT);
+ CFG_SRC_SEL_MASK, cfg);
if (ret)
return ret;
@@ -222,7 +222,11 @@ static long clk_rcg2_determine_rate(struct clk_hw *hw, unsigned long rate,
static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
{
u32 cfg, mask;
- int ret;
+ struct clk_hw *hw = &rcg->clkr.hw;
+ int ret, index = qcom_find_src_index(hw, rcg->parent_map, f->src);
+
+ if (index < 0)
+ return index;
if (rcg->mnd_width && f->n) {
mask = BIT(rcg->mnd_width) - 1;
@@ -245,7 +249,7 @@ static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
mask = BIT(rcg->hid_width) - 1;
mask |= CFG_SRC_SEL_MASK | CFG_MODE_MASK;
cfg = f->pre_div << CFG_SRC_DIV_SHIFT;
- cfg |= rcg->parent_map[f->src] << CFG_SRC_SEL_SHIFT;
+ cfg |= rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT;
if (rcg->mnd_width && f->n && (f->m != f->n))
cfg |= CFG_MODE_DUAL_EDGE;
ret = regmap_update_bits(rcg->clkr.regmap,