All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
To: cip-dev@lists.cip-project.org,
	Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>,
	Pavel Machek <pavel@denx.de>
Cc: Biju Das <biju.das.jz@bp.renesas.com>
Subject: [PATCH 5.10.y-cip 23/24] clk: renesas: rzg2l: Add support to handle coupled clocks
Date: Thu, 16 Dec 2021 12:54:45 +0000	[thread overview]
Message-ID: <20211216125446.15451-24-prabhakar.mahadev-lad.rj@bp.renesas.com> (raw)
In-Reply-To: <20211216125446.15451-1-prabhakar.mahadev-lad.rj@bp.renesas.com>

From: Biju Das <biju.das.jz@bp.renesas.com>

commit 32897e6fff196a5de4981030466ae391dfe56c7b upstream.

The AXI and CHI clocks use the same register bit for controlling clock
output. Add a new clock type for coupled clocks, which sets the
CPG_CLKON_ETH.CLK[01]_ON bit when at least one clock is enabled, and
clears the bit only when both clocks are disabled.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Link: https://lore.kernel.org/r/20210922155145.28156-4-biju.das.jz@bp.renesas.com
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
 drivers/clk/renesas/rzg2l-cpg.c | 71 +++++++++++++++++++++++++++++++++
 drivers/clk/renesas/rzg2l-cpg.h | 11 ++++-
 2 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c
index 597efc2504eb..834a7a73de33 100644
--- a/drivers/clk/renesas/rzg2l-cpg.c
+++ b/drivers/clk/renesas/rzg2l-cpg.c
@@ -333,13 +333,17 @@ rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core,
  * @hw: handle between common and hardware-specific interfaces
  * @off: register offset
  * @bit: ON/MON bit
+ * @enabled: soft state of the clock, if it is coupled with another clock
  * @priv: CPG/MSTP private data
+ * @sibling: pointer to the other coupled clock
  */
 struct mstp_clock {
 	struct clk_hw hw;
 	u16 off;
 	u8 bit;
+	bool enabled;
 	struct rzg2l_cpg_priv *priv;
+	struct mstp_clock *sibling;
 };
 
 #define to_mod_clock(_hw) container_of(_hw, struct mstp_clock, hw)
@@ -392,11 +396,41 @@ static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable)
 
 static int rzg2l_mod_clock_enable(struct clk_hw *hw)
 {
+	struct mstp_clock *clock = to_mod_clock(hw);
+
+	if (clock->sibling) {
+		struct rzg2l_cpg_priv *priv = clock->priv;
+		unsigned long flags;
+		bool enabled;
+
+		spin_lock_irqsave(&priv->rmw_lock, flags);
+		enabled = clock->sibling->enabled;
+		clock->enabled = true;
+		spin_unlock_irqrestore(&priv->rmw_lock, flags);
+		if (enabled)
+			return 0;
+	}
+
 	return rzg2l_mod_clock_endisable(hw, true);
 }
 
 static void rzg2l_mod_clock_disable(struct clk_hw *hw)
 {
+	struct mstp_clock *clock = to_mod_clock(hw);
+
+	if (clock->sibling) {
+		struct rzg2l_cpg_priv *priv = clock->priv;
+		unsigned long flags;
+		bool enabled;
+
+		spin_lock_irqsave(&priv->rmw_lock, flags);
+		enabled = clock->sibling->enabled;
+		clock->enabled = false;
+		spin_unlock_irqrestore(&priv->rmw_lock, flags);
+		if (enabled)
+			return;
+	}
+
 	rzg2l_mod_clock_endisable(hw, false);
 }
 
@@ -412,6 +446,9 @@ static int rzg2l_mod_clock_is_enabled(struct clk_hw *hw)
 		return 1;
 	}
 
+	if (clock->sibling)
+		return clock->enabled;
+
 	value = readl(priv->base + CLK_MON_R(clock->off));
 
 	return !(value & bitmask);
@@ -423,6 +460,28 @@ static const struct clk_ops rzg2l_mod_clock_ops = {
 	.is_enabled = rzg2l_mod_clock_is_enabled,
 };
 
+static struct mstp_clock
+*rzg2l_mod_clock__get_sibling(struct mstp_clock *clock,
+			      struct rzg2l_cpg_priv *priv)
+{
+	struct clk_hw *hw;
+	unsigned int i;
+
+	for (i = 0; i < priv->num_mod_clks; i++) {
+		struct mstp_clock *clk;
+
+		if (priv->clks[priv->num_core_clks + i] == ERR_PTR(-ENOENT))
+			continue;
+
+		hw = __clk_get_hw(priv->clks[priv->num_core_clks + i]);
+		clk = to_mod_clock(hw);
+		if (clock->off == clk->off && clock->bit == clk->bit)
+			return clk;
+	}
+
+	return NULL;
+}
+
 static void __init
 rzg2l_cpg_register_mod_clk(const struct rzg2l_mod_clk *mod,
 			   const struct rzg2l_cpg_info *info,
@@ -484,6 +543,18 @@ rzg2l_cpg_register_mod_clk(const struct rzg2l_mod_clk *mod,
 
 	dev_dbg(dev, "Module clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
 	priv->clks[id] = clk;
+
+	if (mod->is_coupled) {
+		struct mstp_clock *sibling;
+
+		clock->enabled = rzg2l_mod_clock_is_enabled(&clock->hw);
+		sibling = rzg2l_mod_clock__get_sibling(clock, priv);
+		if (sibling) {
+			clock->sibling = sibling;
+			sibling->sibling = clock;
+		}
+	}
+
 	return;
 
 fail:
diff --git a/drivers/clk/renesas/rzg2l-cpg.h b/drivers/clk/renesas/rzg2l-cpg.h
index f538ffa3371c..ebf716bb913e 100644
--- a/drivers/clk/renesas/rzg2l-cpg.h
+++ b/drivers/clk/renesas/rzg2l-cpg.h
@@ -90,6 +90,7 @@ enum clk_types {
  * @parent: id of parent clock
  * @off: register offset
  * @bit: ON/MON bit
+ * @is_coupled: flag to indicate coupled clock
  */
 struct rzg2l_mod_clk {
 	const char *name;
@@ -97,17 +98,25 @@ struct rzg2l_mod_clk {
 	unsigned int parent;
 	u16 off;
 	u8 bit;
+	bool is_coupled;
 };
 
-#define DEF_MOD(_name, _id, _parent, _off, _bit)	\
+#define DEF_MOD_BASE(_name, _id, _parent, _off, _bit, _is_coupled)	\
 	{ \
 		.name = _name, \
 		.id = MOD_CLK_BASE + (_id), \
 		.parent = (_parent), \
 		.off = (_off), \
 		.bit = (_bit), \
+		.is_coupled = (_is_coupled), \
 	}
 
+#define DEF_MOD(_name, _id, _parent, _off, _bit)	\
+	DEF_MOD_BASE(_name, _id, _parent, _off, _bit, false)
+
+#define DEF_COUPLED(_name, _id, _parent, _off, _bit)	\
+	DEF_MOD_BASE(_name, _id, _parent, _off, _bit, true)
+
 /**
  * struct rzg2l_reset - Reset definitions
  *
-- 
2.17.1



  parent reply	other threads:[~2021-12-16 12:55 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-16 12:54 [PATCH 5.10.y-cip 00/24] Add CPG and initial DTS/I for Renesas RZ/G2L SoC + SMARC EVK Lad Prabhakar
2021-12-16 12:54 ` [PATCH 5.10.y-cip 01/24] dt-bindings: serial: renesas,scif: Document r9a07g044 bindings Lad Prabhakar
2021-12-16 12:54 ` [PATCH 5.10.y-cip 02/24] serial: sh-sci: Add support for RZ/G2L SoC Lad Prabhakar
2021-12-16 12:54 ` [PATCH 5.10.y-cip 03/24] dt-bindings: clock: renesas: Document RZ/G2L SoC CPG driver Lad Prabhakar
2021-12-16 12:54 ` [PATCH 5.10.y-cip 04/24] dt-bindings: clock: Add r9a07g044 CPG Clock Definitions Lad Prabhakar
2021-12-16 12:54 ` [PATCH 5.10.y-cip 05/24] clk: renesas: Add CPG core wrapper for RZ/G2L SoC Lad Prabhakar
2021-12-17 10:10   ` Pavel Machek
2021-12-17 11:03     ` Prabhakar Mahadev Lad
2021-12-16 12:54 ` [PATCH 5.10.y-cip 06/24] clk: renesas: Add support for R9A07G044 SoC Lad Prabhakar
2021-12-16 12:54 ` [PATCH 5.10.y-cip 07/24] clk: renesas: r9a07g044: Rename divider table Lad Prabhakar
2021-12-16 12:54 ` [PATCH 5.10.y-cip 08/24] clk: renesas: r9a07g044: Fix P1 Clock Lad Prabhakar
2021-12-16 12:54 ` [PATCH 5.10.y-cip 09/24] clk: renesas: r9a07g044: Add P2 Clock support Lad Prabhakar
2021-12-16 12:54 ` [PATCH 5.10.y-cip 10/24] clk: renesas: rzg2l: Add multi clock PM support Lad Prabhakar
2021-12-16 12:54 ` [PATCH 5.10.y-cip 11/24] arm64: dts: renesas: Add initial DTSI for RZ/G2{L,LC} SoC's Lad Prabhakar
2021-12-17 10:19   ` Pavel Machek
2021-12-17 11:11     ` Prabhakar Mahadev Lad
2021-12-16 12:54 ` [PATCH 5.10.y-cip 12/24] arm64: dts: renesas: Add initial device tree for RZ/G2L SMARC EVK Lad Prabhakar
2021-12-16 12:54 ` [PATCH 5.10.y-cip 13/24] arm64: dts: renesas: r9a07g044: Add SYSC node Lad Prabhakar
2021-12-16 12:54 ` [PATCH 5.10.y-cip 14/24] dt-bindings: clock: r9a07g044-cpg: Update clock/reset definitions Lad Prabhakar
2021-12-16 12:54 ` [PATCH 5.10.y-cip 15/24] clk: renesas: rzg2l: Remove unneeded semicolon Lad Prabhakar
2021-12-16 12:54 ` [PATCH 5.10.y-cip 16/24] clk: renesas: rzg2l: Fix return value and unused assignment Lad Prabhakar
2021-12-16 12:54 ` [PATCH 5.10.y-cip 17/24] clk: renesas: rzg2l: Fix a double free on error Lad Prabhakar
2021-12-16 12:54 ` [PATCH 5.10.y-cip 18/24] clk: renesas: rzg2l: Avoid mixing error pointers and NULL Lad Prabhakar
2021-12-16 12:54 ` [PATCH 5.10.y-cip 19/24] clk: renesas: rzg2l: Fix off-by-one check in rzg2l_cpg_clk_src_twocell_get() Lad Prabhakar
2021-12-16 12:54 ` [PATCH 5.10.y-cip 20/24] clk: renesas: Rename renesas-rzg2l-cpg.[ch] to rzg2l-cpg.[ch] Lad Prabhakar
2021-12-16 12:54 ` [PATCH 5.10.y-cip 21/24] clk: mux: provide devm_clk_hw_register_mux() Lad Prabhakar
2021-12-16 12:54 ` [PATCH 5.10.y-cip 22/24] clk: renesas: rzg2l: Add support to handle MUX clocks Lad Prabhakar
2021-12-16 12:54 ` Lad Prabhakar [this message]
2021-12-17 10:38   ` [PATCH 5.10.y-cip 23/24] clk: renesas: rzg2l: Add support to handle coupled clocks Pavel Machek
2021-12-17 11:29     ` Prabhakar Mahadev Lad
2021-12-16 12:54 ` [PATCH 5.10.y-cip 24/24] clk: renesas: rzg2l: Fix clk status function Lad Prabhakar
2021-12-17  7:42 ` [cip-dev] [PATCH 5.10.y-cip 00/24] Add CPG and initial DTS/I for Renesas RZ/G2L SoC + SMARC EVK nobuhiro1.iwamatsu
2021-12-17 10:39   ` Pavel Machek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211216125446.15451-24-prabhakar.mahadev-lad.rj@bp.renesas.com \
    --to=prabhakar.mahadev-lad.rj@bp.renesas.com \
    --cc=biju.das.jz@bp.renesas.com \
    --cc=cip-dev@lists.cip-project.org \
    --cc=nobuhiro1.iwamatsu@toshiba.co.jp \
    --cc=pavel@denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.