[PATCH 21/24] clk: implement set/get phase

Sascha Hauer s.hauer at pengutronix.de
Wed Jun 2 02:55:04 PDT 2021


Linux has clk_set_phase() and clk_get_phase() along with the
corresponding callbacks in struct clk_ops. Implement the same for
barebox as well.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/clk/clk.c   | 55 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/clk.h |  5 +++++
 2 files changed, 60 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index fe2424dc8a..8b90f30486 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -320,6 +320,61 @@ struct clk_hw *clk_hw_get_parent(struct clk_hw *hw)
 	return clk_to_clk_hw(clk);
 }
 
+/**
+ * clk_set_phase - adjust the phase shift of a clock signal
+ * @clk: clock signal source
+ * @degrees: number of degrees the signal is shifted
+ *
+ * Shifts the phase of a clock signal by the specified
+ * degrees. Returns 0 on success, -EERROR otherwise.
+ *
+ * This function makes no distinction about the input or reference
+ * signal that we adjust the clock signal phase against. For example
+ * phase locked-loop clock signal generators we may shift phase with
+ * respect to feedback clock signal input, but for other cases the
+ * clock phase may be shifted with respect to some other, unspecified
+ * signal.
+ *
+ * Additionally the concept of phase shift does not propagate through
+ * the clock tree hierarchy, which sets it apart from clock rates and
+ * clock accuracy. A parent clock phase attribute does not have an
+ * impact on the phase attribute of a child clock.
+ */
+int clk_set_phase(struct clk *clk, int degrees)
+{
+	if (!clk)
+		return 0;
+
+	/* sanity check degrees */
+	degrees %= 360;
+	if (degrees < 0)
+		degrees += 360;
+
+	if (!clk->ops->set_phase)
+		return -EINVAL;
+
+	return clk->ops->set_phase(clk_to_clk_hw(clk), degrees);
+}
+
+/**
+ * clk_get_phase - return the phase shift of a clock signal
+ * @clk: clock signal source
+ *
+ * Returns the phase shift of a clock node in degrees, otherwise returns
+ * -EERROR.
+ */
+int clk_get_phase(struct clk *clk)
+{
+	int ret;
+
+	if (!clk->ops->get_phase)
+		return 0;
+
+	ret = clk->ops->get_phase(clk_to_clk_hw(clk));
+
+	return ret;
+}
+
 int bclk_register(struct clk *clk)
 {
 	struct clk_hw *hw = clk_to_clk_hw(clk);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 72971c8e27..6b4c368231 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -237,6 +237,9 @@ int clk_hw_set_parent(struct clk_hw *hw, struct clk_hw *hwp);
 struct clk *clk_get_parent(struct clk *clk);
 struct clk_hw *clk_hw_get_parent(struct clk_hw *hw);
 
+int clk_set_phase(struct clk *clk, int degrees);
+int clk_get_phase(struct clk *clk);
+
 /**
  * clk_get_sys - get a clock based upon the device name
  * @dev_id: device name
@@ -356,6 +359,8 @@ struct clk_ops {
 	int		(*get_parent)(struct clk_hw *hw);
 	int		(*set_rate)(struct clk_hw *hw, unsigned long,
 				    unsigned long);
+	int		(*set_phase)(struct clk_hw *hw, int degrees);
+	int		(*get_phase)(struct clk_hw *hw);
 };
 
 /**
-- 
2.29.2




More information about the barebox mailing list