Commit 2d6f2577 authored by Wolfram Sang's avatar Wolfram Sang Committed by Geert Uytterhoeven

clk: renesas: rcar-gen3-cpg: Refactor checks for accessing the div table

Do the checks for accessing the SD divider table only when the rate gets
updated, namely on init and set_rate. In all other cases, reuse the last
value. This simplifies code, runtime load, and error reporting.
Signed-off-by: default avatarWolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
parent f317880c
...@@ -60,6 +60,7 @@ struct sd_clock { ...@@ -60,6 +60,7 @@ struct sd_clock {
unsigned int div_num; unsigned int div_num;
unsigned int div_min; unsigned int div_min;
unsigned int div_max; unsigned int div_max;
unsigned int cur_div_idx;
}; };
/* SDn divider /* SDn divider
...@@ -96,21 +97,10 @@ static const struct sd_div_table cpg_sd_div_table[] = { ...@@ -96,21 +97,10 @@ static const struct sd_div_table cpg_sd_div_table[] = {
static int cpg_sd_clock_enable(struct clk_hw *hw) static int cpg_sd_clock_enable(struct clk_hw *hw)
{ {
struct sd_clock *clock = to_sd_clock(hw); struct sd_clock *clock = to_sd_clock(hw);
u32 val, sd_fc; u32 val = readl(clock->reg);
unsigned int i;
val = readl(clock->reg);
sd_fc = val & CPG_SD_FC_MASK;
for (i = 0; i < clock->div_num; i++)
if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK))
break;
if (i >= clock->div_num)
return -EINVAL;
val &= ~(CPG_SD_STP_MASK); val &= ~(CPG_SD_STP_MASK);
val |= clock->div_table[i].val & CPG_SD_STP_MASK; val |= clock->div_table[clock->cur_div_idx].val & CPG_SD_STP_MASK;
writel(val, clock->reg); writel(val, clock->reg);
...@@ -135,20 +125,9 @@ static unsigned long cpg_sd_clock_recalc_rate(struct clk_hw *hw, ...@@ -135,20 +125,9 @@ static unsigned long cpg_sd_clock_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate) unsigned long parent_rate)
{ {
struct sd_clock *clock = to_sd_clock(hw); struct sd_clock *clock = to_sd_clock(hw);
u32 val, sd_fc;
unsigned int i;
val = readl(clock->reg);
sd_fc = val & CPG_SD_FC_MASK;
for (i = 0; i < clock->div_num; i++)
if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK))
break;
if (i >= clock->div_num)
return -EINVAL;
return DIV_ROUND_CLOSEST(parent_rate, clock->div_table[i].div); return DIV_ROUND_CLOSEST(parent_rate,
clock->div_table[clock->cur_div_idx].div);
} }
static unsigned int cpg_sd_clock_calc_div(struct sd_clock *clock, static unsigned int cpg_sd_clock_calc_div(struct sd_clock *clock,
...@@ -189,6 +168,8 @@ static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate, ...@@ -189,6 +168,8 @@ static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate,
if (i >= clock->div_num) if (i >= clock->div_num)
return -EINVAL; return -EINVAL;
clock->cur_div_idx = i;
val = readl(clock->reg); val = readl(clock->reg);
val &= ~(CPG_SD_STP_MASK | CPG_SD_FC_MASK); val &= ~(CPG_SD_STP_MASK | CPG_SD_FC_MASK);
val |= clock->div_table[i].val & (CPG_SD_STP_MASK | CPG_SD_FC_MASK); val |= clock->div_table[i].val & (CPG_SD_STP_MASK | CPG_SD_FC_MASK);
...@@ -214,6 +195,7 @@ static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core, ...@@ -214,6 +195,7 @@ static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core,
struct sd_clock *clock; struct sd_clock *clock;
struct clk *clk; struct clk *clk;
unsigned int i; unsigned int i;
u32 sd_fc;
clock = kzalloc(sizeof(*clock), GFP_KERNEL); clock = kzalloc(sizeof(*clock), GFP_KERNEL);
if (!clock) if (!clock)
...@@ -230,6 +212,18 @@ static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core, ...@@ -230,6 +212,18 @@ static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core,
clock->div_table = cpg_sd_div_table; clock->div_table = cpg_sd_div_table;
clock->div_num = ARRAY_SIZE(cpg_sd_div_table); clock->div_num = ARRAY_SIZE(cpg_sd_div_table);
sd_fc = readl(clock->reg) & CPG_SD_FC_MASK;
for (i = 0; i < clock->div_num; i++)
if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK))
break;
if (WARN_ON(i >= clock->div_num)) {
kfree(clock);
return ERR_PTR(-EINVAL);
}
clock->cur_div_idx = i;
clock->div_max = clock->div_table[0].div; clock->div_max = clock->div_table[0].div;
clock->div_min = clock->div_max; clock->div_min = clock->div_max;
for (i = 1; i < clock->div_num; i++) { for (i = 1; i < clock->div_num; i++) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment