Re: [PATCH v2] clk: qcom: clk-rcg2: Add support for duty-cycle for RCG

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Stephen,

Thanks for your review.

On 3/14/2021 4:29 AM, Stephen Boyd wrote:
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.


Sure, will fail the call for non-MND(HID)RCGs, will be part of my next patch.

+
+       mask = BIT(rcg->mnd_width) - 1;
+
+       regmap_read(rcg->clkr.regmap, RCG_N_OFFSET(rcg), &notn_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?


Will take care of it in the next patch.


+       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?


Sure, will implement the same.

  };
  EXPORT_SYMBOL_GPL(clk_rcg2_ops);


--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation.

--



[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux