Commit a3561e77 authored by Elaine Zhang's avatar Elaine Zhang Committed by Heiko Stuebner
Browse files

clk: rockchip: support more core div setting



Use arrays to support more core independent div settings.
A55 supports each core to work at different frequencies, and each core
has an independent divider control.

Signed-off-by: default avatarElaine Zhang <zhangqing@rock-chips.com>
Reviewed-by: default avatarKever Yang <kever.yang@rock-chips.com>
Acked-by: default avatarStephen Boyd <sboyd@kernel.org>
Link: https://lore.kernel.org/r/20210315085608.16010-4-zhangqing@rock-chips.com


Signed-off-by: default avatarHeiko Stuebner <heiko@sntech.de>
parent 0cd74eec
Loading
Loading
Loading
Loading
+29 −24
Original line number Diff line number Diff line
@@ -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 {
		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);
	}
	       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,
	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);
	       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);
+4 −3
Original line number Diff line number Diff line
@@ -124,9 +124,10 @@ static struct rockchip_cpuclk_rate_table px30_cpuclk_rates[] __initdata = {
};

static const struct rockchip_cpuclk_reg_data px30_cpuclk_data = {
	.core_reg = PX30_CLKSEL_CON(0),
	.div_core_shift = 0,
	.div_core_mask = 0xf,
	.core_reg[0] = PX30_CLKSEL_CON(0),
	.div_core_shift[0] = 0,
	.div_core_mask[0] = 0xf,
	.num_cores = 1,
	.mux_core_alt = 1,
	.mux_core_main = 0,
	.mux_core_shift = 7,
+4 −3
Original line number Diff line number Diff line
@@ -102,9 +102,10 @@ static struct rockchip_cpuclk_rate_table rk3036_cpuclk_rates[] __initdata = {
};

static const struct rockchip_cpuclk_reg_data rk3036_cpuclk_data = {
	.core_reg = RK2928_CLKSEL_CON(0),
	.div_core_shift = 0,
	.div_core_mask = 0x1f,
	.core_reg[0] = RK2928_CLKSEL_CON(0),
	.div_core_shift[0] = 0,
	.div_core_mask[0] = 0x1f,
	.num_cores = 1,
	.mux_core_alt = 1,
	.mux_core_main = 0,
	.mux_core_shift = 7,
+4 −3
Original line number Diff line number Diff line
@@ -117,9 +117,10 @@ static struct rockchip_cpuclk_rate_table rk3128_cpuclk_rates[] __initdata = {
};

static const struct rockchip_cpuclk_reg_data rk3128_cpuclk_data = {
	.core_reg = RK2928_CLKSEL_CON(0),
	.div_core_shift = 0,
	.div_core_mask = 0x1f,
	.core_reg[0] = RK2928_CLKSEL_CON(0),
	.div_core_shift[0] = 0,
	.div_core_mask[0] = 0x1f,
	.num_cores = 1,
	.mux_core_alt = 1,
	.mux_core_main = 0,
	.mux_core_shift = 7,
+8 −6
Original line number Diff line number Diff line
@@ -145,9 +145,10 @@ static struct rockchip_cpuclk_rate_table rk3066_cpuclk_rates[] __initdata = {
};

static const struct rockchip_cpuclk_reg_data rk3066_cpuclk_data = {
	.core_reg = RK2928_CLKSEL_CON(0),
	.div_core_shift = 0,
	.div_core_mask = 0x1f,
	.core_reg[0] = RK2928_CLKSEL_CON(0),
	.div_core_shift[0] = 0,
	.div_core_mask[0] = 0x1f,
	.num_cores = 1,
	.mux_core_alt = 1,
	.mux_core_main = 0,
	.mux_core_shift = 8,
@@ -184,9 +185,10 @@ static struct rockchip_cpuclk_rate_table rk3188_cpuclk_rates[] __initdata = {
};

static const struct rockchip_cpuclk_reg_data rk3188_cpuclk_data = {
	.core_reg = RK2928_CLKSEL_CON(0),
	.div_core_shift = 9,
	.div_core_mask = 0x1f,
	.core_reg[0] = RK2928_CLKSEL_CON(0),
	.div_core_shift[0] = 9,
	.div_core_mask[0] = 0x1f,
	.num_cores = 1,
	.mux_core_alt = 1,
	.mux_core_main = 0,
	.mux_core_shift = 8,
Loading