diff options
Diffstat (limited to 'drivers/clk/rockchip/clk-cpu.c')
| -rw-r--r-- | drivers/clk/rockchip/clk-cpu.c | 53 | 
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); | 
