All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peng Fan <peng.fan@nxp.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH V3 2/4] clk: prograte clk enable/disable to parent
Date: Wed, 21 Aug 2019 13:35:09 +0000	[thread overview]
Message-ID: <20190821135056.27052-2-peng.fan@nxp.com> (raw)
In-Reply-To: <20190821135056.27052-1-peng.fan@nxp.com>

On i.MX8MM, thinking such as clk path
OSC->PLL->PLL GATE->CCM ROOT->CCGR GATE->Device

Only enabling CCGR GATE is not enough, we also need to enable PLL GATE
to make sure the clk path work. So when enabling CCGR GATE,
we could prograte to enabling PLL GATE to make life easier.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---

V3:
 None
V2:
 Improve commit log
 Check enable_count when enable/disable to avoid touch hardware
 following Linux

 drivers/clk/clk-uclass.c | 77 ++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 71 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index c66b6f3c4e..64c181f4ad 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -449,13 +449,45 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
 int clk_enable(struct clk *clk)
 {
 	const struct clk_ops *ops = clk_dev_ops(clk->dev);
+	struct clk *clkp = NULL;
+	int ret;
 
 	debug("%s(clk=%p)\n", __func__, clk);
 
-	if (!ops->enable)
-		return -ENOSYS;
+	if (CONFIG_IS_ENABLED(CLK_CCF)) {
+		/* Take id 0 as a non-valid clk, such as dummy */
+		if (clk->id && !clk_get_by_id(clk->id, &clkp)) {
+			if (clkp->enable_count) {
+				clkp->enable_count++;
+				return 0;
+			}
+			if (clkp->dev->parent &&
+			    device_get_uclass_id(clkp->dev) == UCLASS_CLK) {
+				ret = clk_enable(dev_get_clk_ptr(clkp->dev->parent));
+				if (ret) {
+					printf("Enable %s failed\n",
+					       clkp->dev->parent->name);
+					return ret;
+				}
+			}
+		}
 
-	return ops->enable(clk);
+		if (ops->enable) {
+			ret = ops->enable(clk);
+			if (ret) {
+				printf("Enable %s failed\n", clk->dev->name);
+				return ret;
+			}
+		}
+		if (clkp)
+			clkp->enable_count++;
+	} else {
+		if (!ops->enable)
+			return -ENOSYS;
+		return ops->enable(clk);
+	}
+
+	return 0;
 }
 
 int clk_enable_bulk(struct clk_bulk *bulk)
@@ -474,13 +506,46 @@ int clk_enable_bulk(struct clk_bulk *bulk)
 int clk_disable(struct clk *clk)
 {
 	const struct clk_ops *ops = clk_dev_ops(clk->dev);
+	struct clk *clkp = NULL;
+	int ret;
 
 	debug("%s(clk=%p)\n", __func__, clk);
 
-	if (!ops->disable)
-		return -ENOSYS;
+	if (CONFIG_IS_ENABLED(CLK_CCF)) {
+		if (clk->id && !clk_get_by_id(clk->id, &clkp)) {
+			if (clkp->enable_count == 0) {
+				printf("clk %s already disabled\n",
+				       clkp->dev->name);
+				return 0;
+			}
 
-	return ops->disable(clk);
+			if (--clkp->enable_count > 0)
+				return 0;
+		}
+
+		if (ops->disable) {
+			ret = ops->disable(clk);
+			if (ret)
+				return ret;
+		}
+
+		if (clkp && clkp->dev->parent &&
+		    device_get_uclass_id(clkp->dev) == UCLASS_CLK) {
+			ret = clk_disable(dev_get_clk_ptr(clkp->dev->parent));
+			if (ret) {
+				printf("Disable %s failed\n",
+				       clkp->dev->parent->name);
+				return ret;
+			}
+		}
+	} else {
+		if (!ops->disable)
+			return -ENOSYS;
+
+		return ops->disable(clk);
+	}
+
+	return 0;
 }
 
 int clk_disable_bulk(struct clk_bulk *bulk)
-- 
2.16.4

  reply	other threads:[~2019-08-21 13:35 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-21 13:35 [U-Boot] [PATCH V3 1/4] clk: introduce enable_count Peng Fan
2019-08-21 13:35 ` Peng Fan [this message]
2019-08-21 13:35 ` [U-Boot] [PATCH V3 3/4] clk: support clk tree dump Peng Fan
2019-08-23 21:48   ` Simon Glass
2019-08-26  1:08     ` Peng Fan
2019-08-21 13:35 ` [U-Boot] [PATCH V3 4/4] sandbox: clk: add clk enable/disable test code Peng Fan
2019-08-23 21:49   ` Simon Glass
2019-08-23 21:48 ` [U-Boot] [PATCH V3 1/4] clk: introduce enable_count Simon Glass
2019-08-26  1:08   ` Peng Fan

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=20190821135056.27052-2-peng.fan@nxp.com \
    --to=peng.fan@nxp.com \
    --cc=u-boot@lists.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.