summaryrefslogtreecommitdiffstats
path: root/drivers/clk/clk.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2021-06-02 11:55:04 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2021-06-08 08:38:25 +0200
commit3041f8fea28b2e339f044c1b9d1fa784a5153c5e (patch)
tree951dedd1fe0706d6ecd0dfa854eac1a06dfc20d0 /drivers/clk/clk.c
parent2d5f1eb391b2a66546236e92f60076fc76360a90 (diff)
downloadbarebox-3041f8fea28b2e339f044c1b9d1fa784a5153c5e.tar.gz
barebox-3041f8fea28b2e339f044c1b9d1fa784a5153c5e.tar.xz
clk: implement set/get phase
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@pengutronix.de> Link: https://lore.barebox.org/20210602095507.24609-22-s.hauer@pengutronix.de Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/clk/clk.c')
-rw-r--r--drivers/clk/clk.c55
1 files changed, 55 insertions, 0 deletions
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);