Skip to content

Commit

Permalink
clk: renesas: rcar-gen3: Add boost support to Z clocks
Browse files Browse the repository at this point in the history
Add support for switching the Z and Z2 clocks between normal and boost
modes, by requesting clock rate changes to parent PLLs.

Inspired by a patch in the BSP by Takeshi Kihara
<takeshi.kihara.df@renesas.com>.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Stephen Boyd <sboyd@kernel.org>
Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Link: https://lore.kernel.org/r/20210326120100.1577596-8-geert+renesas@glider.be
  • Loading branch information
Geert Uytterhoeven committed May 11, 2021
1 parent 3f70795 commit 3a0e848
Showing 1 changed file with 20 additions and 4 deletions.
24 changes: 20 additions & 4 deletions drivers/clk/renesas/rcar-gen3-cpg.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ struct cpg_z_clk {
struct clk_hw hw;
void __iomem *reg;
void __iomem *kick_reg;
unsigned long max_rate; /* Maximum rate for normal mode */
unsigned int fixed_div;
u32 mask;
};
Expand All @@ -190,15 +191,26 @@ static int cpg_z_clk_determine_rate(struct clk_hw *hw,
{
struct cpg_z_clk *zclk = to_z_clk(hw);
unsigned int min_mult, max_mult, mult;
unsigned long prate;
unsigned long rate, prate;

rate = min(req->rate, req->max_rate);
if (rate <= zclk->max_rate) {
/* Set parent rate to initial value for normal modes */
prate = zclk->max_rate;
} else {
/* Set increased parent rate for boost modes */
prate = rate;
}
req->best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
prate * zclk->fixed_div);

prate = req->best_parent_rate / zclk->fixed_div;
min_mult = max(div64_ul(req->min_rate * 32ULL, prate), 1ULL);
max_mult = min(div64_ul(req->max_rate * 32ULL, prate), 32ULL);
if (max_mult < min_mult)
return -EINVAL;

mult = DIV_ROUND_CLOSEST_ULL(req->rate * 32ULL, prate);
mult = DIV_ROUND_CLOSEST_ULL(rate * 32ULL, prate);
mult = clamp(mult, min_mult, max_mult);

req->rate = DIV_ROUND_CLOSEST_ULL((u64)prate * mult, 32);
Expand Down Expand Up @@ -268,7 +280,7 @@ static struct clk * __init cpg_z_clk_register(const char *name,

init.name = name;
init.ops = &cpg_z_clk_ops;
init.flags = 0;
init.flags = CLK_SET_RATE_PARENT;
init.parent_names = &parent_name;
init.num_parents = 1;

Expand All @@ -279,9 +291,13 @@ static struct clk * __init cpg_z_clk_register(const char *name,
zclk->fixed_div = div; /* PLLVCO x 1/div x SYS-CPU divider */

clk = clk_register(NULL, &zclk->hw);
if (IS_ERR(clk))
if (IS_ERR(clk)) {
kfree(zclk);
return clk;
}

zclk->max_rate = clk_hw_get_rate(clk_hw_get_parent(&zclk->hw)) /
zclk->fixed_div;
return clk;
}

Expand Down

0 comments on commit 3a0e848

Please sign in to comment.