UPSTREAM: 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.

Change-Id: I40dde15e25843090160bbc32d2de8e2cddffc96e
Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
Acked-by: Stephen Boyd <sboyd@kernel.org>
Link: https://lore.kernel.org/r/20210315085608.16010-4-zhangqing@rock-chips.com
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
(cherry picked from commit a3561e77cf)
This commit is contained in:
Elaine Zhang
2021-03-15 16:56:07 +08:00
committed by Tao Huang
parent c655ba882d
commit c953ed2a09
16 changed files with 112 additions and 126 deletions

View File

@@ -92,10 +92,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);
}
@@ -164,6 +164,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);
@@ -188,40 +189,29 @@ 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];
}
pr_debug("%s: setting div %lu as alt-rate %lu > old-rate %lu\n",
__func__, alt_div, alt_prate, ndata->old_rate);
/* add dividers */
writel(HIWORD_UPDATE(alt_div, reg_data->div_core_mask,
reg_data->div_core_shift),
cpuclk->reg_base + reg_data->core_reg);
if (reg_data->core1_reg)
writel(HIWORD_UPDATE(alt_div, reg_data->div_core1_mask,
reg_data->div_core1_shift),
cpuclk->reg_base + reg_data->core1_reg);
if (reg_data->core2_reg)
writel(HIWORD_UPDATE(alt_div, reg_data->div_core2_mask,
reg_data->div_core2_shift),
cpuclk->reg_base + reg_data->core2_reg);
if (reg_data->core3_reg)
writel(HIWORD_UPDATE(alt_div, reg_data->div_core3_mask,
reg_data->div_core3_shift),
cpuclk->reg_base + reg_data->core3_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]);
}
}
rockchip_boost_add_core_div(cpuclk->pll_hw, alt_prate);
/* 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]);
rockchip_cpuclk_set_pre_muxs(cpuclk, rate);
@@ -235,6 +225,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) {
@@ -252,26 +243,16 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk,
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]);
rockchip_cpuclk_set_post_muxs(cpuclk, rate);
/* remove dividers */
writel(HIWORD_UPDATE(0, reg_data->div_core_mask,
reg_data->div_core_shift),
cpuclk->reg_base + reg_data->core_reg);
if (reg_data->core1_reg)
writel(HIWORD_UPDATE(0, reg_data->div_core1_mask,
reg_data->div_core1_shift),
cpuclk->reg_base + reg_data->core1_reg);
if (reg_data->core2_reg)
writel(HIWORD_UPDATE(0, reg_data->div_core2_mask,
reg_data->div_core2_shift),
cpuclk->reg_base + reg_data->core2_reg);
if (reg_data->core3_reg)
writel(HIWORD_UPDATE(0, reg_data->div_core3_mask,
reg_data->div_core3_shift),
cpuclk->reg_base + reg_data->core3_reg);
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);

View File

@@ -133,9 +133,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,

View File

@@ -116,9 +116,10 @@ static struct rockchip_cpuclk_rate_table rk1808_cpuclk_rates[] __initdata = {
};
static const struct rockchip_cpuclk_reg_data rk1808_cpuclk_data = {
.core_reg = RK1808_CLKSEL_CON(0),
.div_core_shift = 0,
.div_core_mask = 0xf,
.core_reg[0] = RK1808_CLKSEL_CON(0),
.div_core_shift[0] = 0,
.div_core_mask[0] = 0xf,
.num_cores = 1,
.mux_core_alt = 2,
.mux_core_main = 0,
.mux_core_shift = 6,

View File

@@ -116,9 +116,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,

View File

@@ -129,9 +129,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,

View File

@@ -157,9 +157,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,
@@ -196,9 +197,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,

View File

@@ -131,9 +131,10 @@ static struct rockchip_cpuclk_rate_table rk3228_cpuclk_rates[] __initdata = {
};
static const struct rockchip_cpuclk_reg_data rk3228_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 = 6,

View File

@@ -167,9 +167,10 @@ static struct rockchip_cpuclk_rate_table rk3288_cpuclk_rates[] __initdata = {
};
static const struct rockchip_cpuclk_reg_data rk3288_cpuclk_data = {
.core_reg = RK3288_CLKSEL_CON(0),
.div_core_shift = 8,
.div_core_mask = 0x1f,
.core_reg[0] = RK3288_CLKSEL_CON(0),
.div_core_shift[0] = 8,
.div_core_mask[0] = 0x1f,
.num_cores = 1,
.mux_core_alt = 1,
.mux_core_main = 0,
.mux_core_shift = 15,

View File

@@ -124,9 +124,10 @@ static struct rockchip_cpuclk_rate_table rk3308_cpuclk_rates[] __initdata = {
};
static const struct rockchip_cpuclk_reg_data rk3308_cpuclk_data = {
.core_reg = RK3308_CLKSEL_CON(0),
.div_core_shift = 0,
.div_core_mask = 0xf,
.core_reg[0] = RK3308_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 = 6,

View File

@@ -141,9 +141,10 @@ static struct rockchip_cpuclk_rate_table rk3328_cpuclk_rates[] __initdata = {
};
static const struct rockchip_cpuclk_reg_data rk3328_cpuclk_data = {
.core_reg = RK3328_CLKSEL_CON(0),
.div_core_shift = 0,
.div_core_mask = 0x1f,
.core_reg[0] = RK3328_CLKSEL_CON(0),
.div_core_shift[0] = 0,
.div_core_mask[0] = 0x1f,
.num_cores = 1,
.mux_core_alt = 1,
.mux_core_main = 3,
.mux_core_shift = 6,

View File

@@ -186,9 +186,10 @@ static struct clk_div_table div_ddrphy_t[] = {
#define IFLAGS ROCKCHIP_INVERTER_HIWORD_MASK
static const struct rockchip_cpuclk_reg_data rk3368_cpuclkb_data = {
.core_reg = RK3368_CLKSEL_CON(0),
.div_core_shift = 0,
.div_core_mask = 0x1f,
.core_reg[0] = RK3368_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,
@@ -196,11 +197,12 @@ static const struct rockchip_cpuclk_reg_data rk3368_cpuclkb_data = {
};
static const struct rockchip_cpuclk_reg_data rk3368_cpuclkl_data = {
.core_reg = RK3368_CLKSEL_CON(2),
.div_core_shift = 0,
.core_reg[0] = RK3368_CLKSEL_CON(2),
.div_core_shift[0] = 0,
.mux_core_alt = 1,
.num_cores = 1,
.mux_core_main = 0,
.div_core_mask = 0x1f,
.div_core_mask[0] = 0x1f,
.mux_core_shift = 7,
.mux_core_mask = 0x1,
};

View File

@@ -391,9 +391,10 @@ static struct rockchip_clk_branch rk3399_pmuclk_wifi_fracmux __initdata =
RK3399_PMU_CLKSEL_CON(1), 14, 1, MFLAGS);
static const struct rockchip_cpuclk_reg_data rk3399_cpuclkl_data = {
.core_reg = RK3399_CLKSEL_CON(0),
.div_core_shift = 0,
.div_core_mask = 0x1f,
.core_reg[0] = RK3399_CLKSEL_CON(0),
.div_core_shift[0] = 0,
.div_core_mask[0] = 0x1f,
.num_cores = 1,
.mux_core_alt = 3,
.mux_core_main = 0,
.mux_core_shift = 6,
@@ -401,9 +402,10 @@ static const struct rockchip_cpuclk_reg_data rk3399_cpuclkl_data = {
};
static const struct rockchip_cpuclk_reg_data rk3399_cpuclkb_data = {
.core_reg = RK3399_CLKSEL_CON(2),
.div_core_shift = 0,
.div_core_mask = 0x1f,
.core_reg[0] = RK3399_CLKSEL_CON(2),
.div_core_shift[0] = 0,
.div_core_mask[0] = 0x1f,
.num_cores = 1,
.mux_core_alt = 3,
.mux_core_main = 1,
.mux_core_shift = 6,

View File

@@ -221,18 +221,19 @@ static struct rockchip_cpuclk_rate_table rk3568_cpuclk_rates[] __initdata = {
};
static const struct rockchip_cpuclk_reg_data rk3568_cpuclk_data = {
.core_reg = RK3568_CLKSEL_CON(0),
.div_core_shift = 0,
.div_core_mask = 0x1f,
.core1_reg = RK3568_CLKSEL_CON(0),
.div_core1_shift = 8,
.div_core1_mask = 0x1f,
.core2_reg = RK3568_CLKSEL_CON(1),
.div_core2_shift = 0,
.div_core2_mask = 0x1f,
.core3_reg = RK3568_CLKSEL_CON(1),
.div_core3_shift = 8,
.div_core3_mask = 0x1f,
.core_reg[0] = RK3568_CLKSEL_CON(0),
.div_core_shift[0] = 0,
.div_core_mask[0] = 0x1f,
.core_reg[1] = RK3568_CLKSEL_CON(0),
.div_core_shift[1] = 8,
.div_core_mask[1] = 0x1f,
.core_reg[2] = RK3568_CLKSEL_CON(1),
.div_core_shift[2] = 0,
.div_core_mask[2] = 0x1f,
.core_reg[3] = RK3568_CLKSEL_CON(1),
.div_core_shift[3] = 8,
.div_core_mask[3] = 0x1f,
.num_cores = 4,
.mux_core_alt = 1,
.mux_core_main = 0,
.mux_core_shift = 6,

View File

@@ -116,9 +116,10 @@ static struct rockchip_cpuclk_rate_table rv1108_cpuclk_rates[] __initdata = {
};
static const struct rockchip_cpuclk_reg_data rv1108_cpuclk_data = {
.core_reg = RV1108_CLKSEL_CON(0),
.div_core_shift = 0,
.div_core_mask = 0x1f,
.core_reg[0] = RV1108_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,

View File

@@ -137,9 +137,10 @@ static struct rockchip_cpuclk_rate_table rv1126_cpuclk_rates[] __initdata = {
};
static const struct rockchip_cpuclk_reg_data rv1126_cpuclk_data = {
.core_reg = RV1126_CLKSEL_CON(0),
.div_core_shift = 0,
.div_core_mask = 0x1f,
.core_reg[0] = RV1126_CLKSEL_CON(0),
.div_core_shift[0] = 0,
.div_core_mask[0] = 0x1f,
.num_cores = 1,
.mux_core_alt = 0,
.mux_core_main = 2,
.mux_core_shift = 6,

View File

@@ -427,6 +427,7 @@ struct rockchip_cpuclk_clksel {
};
#define ROCKCHIP_CPUCLK_NUM_DIVIDERS 5
#define ROCKCHIP_CPUCLK_MAX_CORES 4
struct rockchip_cpuclk_rate_table {
unsigned long prate;
struct rockchip_cpuclk_clksel divs[ROCKCHIP_CPUCLK_NUM_DIVIDERS];
@@ -436,37 +437,24 @@ struct rockchip_cpuclk_rate_table {
/**
* struct rockchip_cpuclk_reg_data - register offsets and masks of the cpuclock
* @core_reg: register offset of the core settings register
* @div_core_shift: core divider offset used to divide the pll value
* @div_core_mask: core divider mask
* @div_core1_shift: core1 divider offset used to divide the pll value
* @div_core1_mask: core1 divider mask
* @div_core2_shift: core2 divider offset used to divide the pll value
* @div_core2_mask: core2 divider mask
* @div_core3_shift: core3 divider offset used to divide the pll value
* @div_core3_mask: core3 divider mask
* @mux_core_alt: mux value to select alternate parent
* @core_reg[]: register offset of the cores setting register
* @div_core_shift[]: cores divider offset used to divide the pll value
* @div_core_mask[]: cores divider mask
* @num_cores: number of cpu cores
* @mux_core_alt: mux value to select alternate parent
* @mux_core_main: mux value to select main parent of core
* @mux_core_shift: offset of the core multiplexer
* @mux_core_mask: core multiplexer mask
*/
struct rockchip_cpuclk_reg_data {
int core_reg;
u8 div_core_shift;
u32 div_core_mask;
int core1_reg;
u8 div_core1_shift;
u32 div_core1_mask;
int core2_reg;
u8 div_core2_shift;
u32 div_core2_mask;
int core3_reg;
u8 div_core3_shift;
u32 div_core3_mask;
u8 mux_core_alt;
u8 mux_core_main;
u8 mux_core_shift;
u32 mux_core_mask;
int core_reg[ROCKCHIP_CPUCLK_MAX_CORES];
u8 div_core_shift[ROCKCHIP_CPUCLK_MAX_CORES];
u32 div_core_mask[ROCKCHIP_CPUCLK_MAX_CORES];
int num_cores;
u8 mux_core_alt;
u8 mux_core_main;
u8 mux_core_shift;
u32 mux_core_mask;
const char *pll_name;
};