Quoting Taniya Das (2021-03-11 04:51:32) > The root clock generators with MND divider has the capability to support > change in duty-cycle by updating the 'D'. Add the clock ops which would > check all the boundary conditions and enable setting the desired duty-cycle > as per the consumer. > > Signed-off-by: Taniya Das <tdas@xxxxxxxxxxxxxx> > --- > drivers/clk/qcom/clk-rcg2.c | 42 ++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 42 insertions(+) > > diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c > index 42f13a2..aac6893 100644 > --- a/drivers/clk/qcom/clk-rcg2.c > +++ b/drivers/clk/qcom/clk-rcg2.c > @@ -357,6 +357,46 @@ static int clk_rcg2_set_floor_rate_and_parent(struct clk_hw *hw, > return __clk_rcg2_set_rate(hw, rate, FLOOR); > } > > +static int clk_rcg2_set_duty_cycle(struct clk_hw *hw, struct clk_duty *duty) > +{ > + struct clk_rcg2 *rcg = to_clk_rcg2(hw); > + u32 notn_m_val, n_val, m_val, d_val, not2d_val, mask, duty_per; > + int ret; > + > + if (!rcg->mnd_width) > + return 0; Shouldn't we fail this call if the duty cycle can't be changed? Or have another set of clk ops that doesn't support this clk op if the mnd isn't present. > + > + mask = BIT(rcg->mnd_width) - 1; > + > + regmap_read(rcg->clkr.regmap, RCG_N_OFFSET(rcg), ¬n_m_val); > + regmap_read(rcg->clkr.regmap, RCG_M_OFFSET(rcg), &m_val); > + > + n_val = (~(notn_m_val) + m_val) & mask; > + > + duty_per = (duty->num * 100) / duty->den; > + > + /* Calculate 2d value */ > + d_val = DIV_ROUND_CLOSEST(n_val * duty_per * 2, 100); > + > + /* Check BIT WIDTHS OF 2d. If D is too big reduce Duty cycle. */ Why is BIT WIDTHS capitalized? And Duty? > + if (d_val > mask) > + d_val = mask; > + > + if ((d_val / 2) > (n_val - m_val)) > + d_val = (n_val - m_val) * 2; > + else if ((d_val / 2) < (m_val / 2)) > + d_val = m_val; > + > + not2d_val = ~d_val & mask; > + > + ret = regmap_update_bits(rcg->clkr.regmap, RCG_D_OFFSET(rcg), mask, > + not2d_val); > + if (ret) > + return ret; > + > + return update_config(rcg); > +} > + > const struct clk_ops clk_rcg2_ops = { > .is_enabled = clk_rcg2_is_enabled, > .get_parent = clk_rcg2_get_parent, > @@ -365,6 +405,7 @@ const struct clk_ops clk_rcg2_ops = { > .determine_rate = clk_rcg2_determine_rate, > .set_rate = clk_rcg2_set_rate, > .set_rate_and_parent = clk_rcg2_set_rate_and_parent, > + .set_duty_cycle = clk_rcg2_set_duty_cycle, Can you also implement get_duty_cycle? > }; > EXPORT_SYMBOL_GPL(clk_rcg2_ops); >