From 908c361b3c3a139eb3e6a798cb620a6da7514d5c Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Fri, 23 Sep 2022 19:05:39 +0200 Subject: [PATCH 2/4] clk: qcom: clk-krait: generilize div functions Generilize div functions and remove hardcode to a divisor of 2. This is just a cleanup and permit to make it more clear the settings of the devisor when used by the krait-cc driver. Signed-off-by: Christian Marangi --- drivers/clk/qcom/clk-krait.c | 57 ++++++++++++++++++++---------------- drivers/clk/qcom/clk-krait.h | 11 ++++--- drivers/clk/qcom/krait-cc.c | 7 +++-- 3 files changed, 42 insertions(+), 33 deletions(-) --- a/drivers/clk/qcom/clk-krait.c +++ b/drivers/clk/qcom/clk-krait.c @@ -97,53 +97,58 @@ const struct clk_ops krait_mux_clk_ops = EXPORT_SYMBOL_GPL(krait_mux_clk_ops); /* The divider can divide by 2, 4, 6 and 8. But we only really need div-2. */ -static long krait_div2_round_rate(struct clk_hw *hw, unsigned long rate, +static long krait_div_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate) { - *parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), rate * 2); - return DIV_ROUND_UP(*parent_rate, 2); + struct krait_div_clk *d = to_krait_div_clk(hw); + + *parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), + rate * d->divisor); + + return DIV_ROUND_UP(*parent_rate, d->divisor); } -static int krait_div2_set_rate(struct clk_hw *hw, unsigned long rate, +static int krait_div_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { - struct krait_div2_clk *d = to_krait_div2_clk(hw); + struct krait_div_clk *d = to_krait_div_clk(hw); + u8 div_val = krait_div_to_val(d->divisor); unsigned long flags; - u32 val; - u32 mask = BIT(d->width) - 1; - - if (d->lpl) - mask = mask << (d->shift + LPL_SHIFT) | mask << d->shift; - else - mask <<= d->shift; + u32 regval; spin_lock_irqsave(&krait_clock_reg_lock, flags); - val = krait_get_l2_indirect_reg(d->offset); - val &= ~mask; - krait_set_l2_indirect_reg(d->offset, val); + regval = krait_get_l2_indirect_reg(d->offset); + + regval &= ~(d->mask << d->shift); + regval |= (div_val & d->mask) << d->shift; + + if (d->lpl) { + regval &= ~(d->mask << (d->shift + LPL_SHIFT)); + regval |= (div_val & d->mask) << (d->shift + LPL_SHIFT); + } + + krait_set_l2_indirect_reg(d->offset, regval); spin_unlock_irqrestore(&krait_clock_reg_lock, flags); return 0; } static unsigned long -krait_div2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +krait_div_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { - struct krait_div2_clk *d = to_krait_div2_clk(hw); - u32 mask = BIT(d->width) - 1; + struct krait_div_clk *d = to_krait_div_clk(hw); u32 div; div = krait_get_l2_indirect_reg(d->offset); div >>= d->shift; - div &= mask; - div = (div + 1) * 2; + div &= d->mask; - return DIV_ROUND_UP(parent_rate, div); + return DIV_ROUND_UP(parent_rate, krait_val_to_div(div)); } -const struct clk_ops krait_div2_clk_ops = { - .round_rate = krait_div2_round_rate, - .set_rate = krait_div2_set_rate, - .recalc_rate = krait_div2_recalc_rate, +const struct clk_ops krait_div_clk_ops = { + .round_rate = krait_div_round_rate, + .set_rate = krait_div_set_rate, + .recalc_rate = krait_div_recalc_rate, }; -EXPORT_SYMBOL_GPL(krait_div2_clk_ops); +EXPORT_SYMBOL_GPL(krait_div_clk_ops); --- a/drivers/clk/qcom/clk-krait.h +++ b/drivers/clk/qcom/clk-krait.h @@ -25,17 +25,20 @@ struct krait_mux_clk { extern const struct clk_ops krait_mux_clk_ops; -struct krait_div2_clk { +struct krait_div_clk { u32 offset; - u8 width; + u32 mask; + u8 divisor; u32 shift; bool lpl; struct clk_hw hw; }; -#define to_krait_div2_clk(_hw) container_of(_hw, struct krait_div2_clk, hw) +#define to_krait_div_clk(_hw) container_of(_hw, struct krait_div_clk, hw) +#define krait_div_to_val(_div) ((_div) / 2) - 1 +#define krait_val_to_div(_val) ((_val) + 1) * 2 -extern const struct clk_ops krait_div2_clk_ops; +extern const struct clk_ops krait_div_clk_ops; #endif --- a/drivers/clk/qcom/krait-cc.c +++ b/drivers/clk/qcom/krait-cc.c @@ -86,11 +86,11 @@ static int krait_notifier_register(struc static struct clk_hw * krait_add_div(struct device *dev, int id, const char *s, unsigned int offset) { - struct krait_div2_clk *div; + struct krait_div_clk *div; static struct clk_parent_data p_data[1]; struct clk_init_data init = { .num_parents = ARRAY_SIZE(p_data), - .ops = &krait_div2_clk_ops, + .ops = &krait_div_clk_ops, .flags = CLK_SET_RATE_PARENT, }; struct clk_hw *clk; @@ -101,7 +101,8 @@ krait_add_div(struct device *dev, int id if (!div) return ERR_PTR(-ENOMEM); - div->width = 2; + div->mask = 0x3; + div->divisor = 2; div->shift = 6; div->lpl = id >= 0; div->offset = offset;