Message ID | 20210517203724.1006254-3-martin.blumenstingl@googlemail.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Neil Armstrong |
Headers | show |
Series | clk: meson: rounding for fast clocks on 32-bit SoCs | expand |
On Mon 17 May 2021 at 22:37, Martin Blumenstingl <martin.blumenstingl@googlemail.com> wrote: > This increases the maxmium supported frequency on 32-bit systems from > 2^31 (signed long as used by clk_ops.round_rate, maximum value: > approx. 2.14GHz) to 2^32 (unsigned long as used by > clk_ops.determine_rate, maximum value: approx. 4.29GHz). > On Meson8/8b/8m2 the HDMI PLL and it's OD (post-dividers) are > capable of running at up to 2.97GHz. So switch the divider > implementation in clk-regmap to clk_ops.determine_rate to support these > higher frequencies on 32-bit systems. > > Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Reviewed-by: Jerome Brunet <jbrunet@baylibre.com> > --- > drivers/clk/meson/clk-regmap.c | 19 +++++++++---------- > 1 file changed, 9 insertions(+), 10 deletions(-) > > diff --git a/drivers/clk/meson/clk-regmap.c b/drivers/clk/meson/clk-regmap.c > index dcd1757cc5df..8ad8977cf1c2 100644 > --- a/drivers/clk/meson/clk-regmap.c > +++ b/drivers/clk/meson/clk-regmap.c > @@ -75,8 +75,8 @@ static unsigned long clk_regmap_div_recalc_rate(struct clk_hw *hw, > div->width); > } > > -static long clk_regmap_div_round_rate(struct clk_hw *hw, unsigned long rate, > - unsigned long *prate) > +static int clk_regmap_div_determine_rate(struct clk_hw *hw, > + struct clk_rate_request *req) > { > struct clk_regmap *clk = to_clk_regmap(hw); > struct clk_regmap_div_data *div = clk_get_regmap_div_data(clk); > @@ -87,18 +87,17 @@ static long clk_regmap_div_round_rate(struct clk_hw *hw, unsigned long rate, > if (div->flags & CLK_DIVIDER_READ_ONLY) { > ret = regmap_read(clk->map, div->offset, &val); > if (ret) > - /* Gives a hint that something is wrong */ > - return 0; > + return ret; > > val >>= div->shift; > val &= clk_div_mask(div->width); > > - return divider_ro_round_rate(hw, rate, prate, div->table, > - div->width, div->flags, val); > + return divider_ro_determine_rate(hw, req, div->table, > + div->width, div->flags, val); > } > > - return divider_round_rate(hw, rate, prate, div->table, div->width, > - div->flags); > + return divider_determine_rate(hw, req, div->table, div->width, > + div->flags); > } > > static int clk_regmap_div_set_rate(struct clk_hw *hw, unsigned long rate, > @@ -123,14 +122,14 @@ static int clk_regmap_div_set_rate(struct clk_hw *hw, unsigned long rate, > > const struct clk_ops clk_regmap_divider_ops = { > .recalc_rate = clk_regmap_div_recalc_rate, > - .round_rate = clk_regmap_div_round_rate, > + .determine_rate = clk_regmap_div_determine_rate, > .set_rate = clk_regmap_div_set_rate, > }; > EXPORT_SYMBOL_GPL(clk_regmap_divider_ops); > > const struct clk_ops clk_regmap_divider_ro_ops = { > .recalc_rate = clk_regmap_div_recalc_rate, > - .round_rate = clk_regmap_div_round_rate, > + .determine_rate = clk_regmap_div_determine_rate, > }; > EXPORT_SYMBOL_GPL(clk_regmap_divider_ro_ops);
diff --git a/drivers/clk/meson/clk-regmap.c b/drivers/clk/meson/clk-regmap.c index dcd1757cc5df..8ad8977cf1c2 100644 --- a/drivers/clk/meson/clk-regmap.c +++ b/drivers/clk/meson/clk-regmap.c @@ -75,8 +75,8 @@ static unsigned long clk_regmap_div_recalc_rate(struct clk_hw *hw, div->width); } -static long clk_regmap_div_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_regmap_div_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_regmap *clk = to_clk_regmap(hw); struct clk_regmap_div_data *div = clk_get_regmap_div_data(clk); @@ -87,18 +87,17 @@ static long clk_regmap_div_round_rate(struct clk_hw *hw, unsigned long rate, if (div->flags & CLK_DIVIDER_READ_ONLY) { ret = regmap_read(clk->map, div->offset, &val); if (ret) - /* Gives a hint that something is wrong */ - return 0; + return ret; val >>= div->shift; val &= clk_div_mask(div->width); - return divider_ro_round_rate(hw, rate, prate, div->table, - div->width, div->flags, val); + return divider_ro_determine_rate(hw, req, div->table, + div->width, div->flags, val); } - return divider_round_rate(hw, rate, prate, div->table, div->width, - div->flags); + return divider_determine_rate(hw, req, div->table, div->width, + div->flags); } static int clk_regmap_div_set_rate(struct clk_hw *hw, unsigned long rate, @@ -123,14 +122,14 @@ static int clk_regmap_div_set_rate(struct clk_hw *hw, unsigned long rate, const struct clk_ops clk_regmap_divider_ops = { .recalc_rate = clk_regmap_div_recalc_rate, - .round_rate = clk_regmap_div_round_rate, + .determine_rate = clk_regmap_div_determine_rate, .set_rate = clk_regmap_div_set_rate, }; EXPORT_SYMBOL_GPL(clk_regmap_divider_ops); const struct clk_ops clk_regmap_divider_ro_ops = { .recalc_rate = clk_regmap_div_recalc_rate, - .round_rate = clk_regmap_div_round_rate, + .determine_rate = clk_regmap_div_determine_rate, }; EXPORT_SYMBOL_GPL(clk_regmap_divider_ro_ops);
This increases the maxmium supported frequency on 32-bit systems from 2^31 (signed long as used by clk_ops.round_rate, maximum value: approx. 2.14GHz) to 2^32 (unsigned long as used by clk_ops.determine_rate, maximum value: approx. 4.29GHz). On Meson8/8b/8m2 the HDMI PLL and it's OD (post-dividers) are capable of running at up to 2.97GHz. So switch the divider implementation in clk-regmap to clk_ops.determine_rate to support these higher frequencies on 32-bit systems. Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com> --- drivers/clk/meson/clk-regmap.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-)