summaryrefslogtreecommitdiff
path: root/drivers/clk/rockchip/clk-cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/rockchip/clk-cpu.c')
-rw-r--r--drivers/clk/rockchip/clk-cpu.c53
1 files changed, 29 insertions, 24 deletions
diff --git a/drivers/clk/rockchip/clk-cpu.c b/drivers/clk/rockchip/clk-cpu.c
index fa9027fb1920..47288197c9d7 100644
--- a/drivers/clk/rockchip/clk-cpu.c
+++ b/drivers/clk/rockchip/clk-cpu.c
@@ -84,10 +84,10 @@ static unsigned long rockchip_cpuclk_recalc_rate(struct clk_hw *hw,
{
struct rockchip_cpuclk *cpuclk = to_rockchip_cpuclk_hw(hw);
const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data;
- u32 clksel0 = readl_relaxed(cpuclk->reg_base + reg_data->core_reg);
+ u32 clksel0 = readl_relaxed(cpuclk->reg_base + reg_data->core_reg[0]);
- clksel0 >>= reg_data->div_core_shift;
- clksel0 &= reg_data->div_core_mask;
+ clksel0 >>= reg_data->div_core_shift[0];
+ clksel0 &= reg_data->div_core_mask[0];
return parent_rate / (clksel0 + 1);
}
@@ -120,6 +120,7 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk,
const struct rockchip_cpuclk_rate_table *rate;
unsigned long alt_prate, alt_div;
unsigned long flags;
+ int i = 0;
/* check validity of the new rate */
rate = rockchip_get_cpuclk_settings(cpuclk, ndata->new_rate);
@@ -142,10 +143,10 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk,
if (alt_prate > ndata->old_rate) {
/* calculate dividers */
alt_div = DIV_ROUND_UP(alt_prate, ndata->old_rate) - 1;
- if (alt_div > reg_data->div_core_mask) {
+ if (alt_div > reg_data->div_core_mask[0]) {
pr_warn("%s: limiting alt-divider %lu to %d\n",
- __func__, alt_div, reg_data->div_core_mask);
- alt_div = reg_data->div_core_mask;
+ __func__, alt_div, reg_data->div_core_mask[0]);
+ alt_div = reg_data->div_core_mask[0];
}
/*
@@ -158,19 +159,17 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk,
pr_debug("%s: setting div %lu as alt-rate %lu > old-rate %lu\n",
__func__, alt_div, alt_prate, ndata->old_rate);
- writel(HIWORD_UPDATE(alt_div, reg_data->div_core_mask,
- reg_data->div_core_shift) |
- HIWORD_UPDATE(reg_data->mux_core_alt,
- reg_data->mux_core_mask,
- reg_data->mux_core_shift),
- cpuclk->reg_base + reg_data->core_reg);
- } else {
- /* select alternate parent */
- writel(HIWORD_UPDATE(reg_data->mux_core_alt,
- reg_data->mux_core_mask,
- reg_data->mux_core_shift),
- cpuclk->reg_base + reg_data->core_reg);
+ for (i = 0; i < reg_data->num_cores; i++) {
+ writel(HIWORD_UPDATE(alt_div, reg_data->div_core_mask[i],
+ reg_data->div_core_shift[i]),
+ cpuclk->reg_base + reg_data->core_reg[i]);
+ }
}
+ /* select alternate parent */
+ writel(HIWORD_UPDATE(reg_data->mux_core_alt,
+ reg_data->mux_core_mask,
+ reg_data->mux_core_shift),
+ cpuclk->reg_base + reg_data->core_reg[0]);
spin_unlock_irqrestore(cpuclk->lock, flags);
return 0;
@@ -182,6 +181,7 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk,
const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data;
const struct rockchip_cpuclk_rate_table *rate;
unsigned long flags;
+ int i = 0;
rate = rockchip_get_cpuclk_settings(cpuclk, ndata->new_rate);
if (!rate) {
@@ -202,12 +202,17 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk,
* primary parent by the extra dividers that were needed for the alt.
*/
- writel(HIWORD_UPDATE(0, reg_data->div_core_mask,
- reg_data->div_core_shift) |
- HIWORD_UPDATE(reg_data->mux_core_main,
- reg_data->mux_core_mask,
- reg_data->mux_core_shift),
- cpuclk->reg_base + reg_data->core_reg);
+ writel(HIWORD_UPDATE(reg_data->mux_core_main,
+ reg_data->mux_core_mask,
+ reg_data->mux_core_shift),
+ cpuclk->reg_base + reg_data->core_reg[0]);
+
+ /* remove dividers */
+ for (i = 0; i < reg_data->num_cores; i++) {
+ writel(HIWORD_UPDATE(0, reg_data->div_core_mask[i],
+ reg_data->div_core_shift[i]),
+ cpuclk->reg_base + reg_data->core_reg[i]);
+ }
if (ndata->old_rate > ndata->new_rate)
rockchip_cpuclk_set_dividers(cpuclk, rate);