From: Zong Li <zong.li@sifive.com>
To: paul.walmsley@sifive.com, palmer@dabbelt.com, sboyd@kernel.org,
schwab@linux-m68k.org, pragnesh.patel@openfive.com,
aou@eecs.berkeley.edu, mturquette@baylibre.com,
yash.shah@sifive.com, linux-kernel@vger.kernel.org,
linux-clk@vger.kernel.org, linux-riscv@lists.infradead.org
Cc: Zong Li <zong.li@sifive.com>, Pragnesh Patel <pragnesh.patel@sifive.com>
Subject: [PATCH v7 5/5] clk: sifive: Add clock enable and disable ops
Date: Wed, 9 Dec 2020 17:49:16 +0800 [thread overview]
Message-ID: <20201209094916.17383-6-zong.li@sifive.com> (raw)
In-Reply-To: <20201209094916.17383-1-zong.li@sifive.com>
From: Pragnesh Patel <pragnesh.patel@sifive.com>
Add new functions "sifive_prci_clock_enable(), sifive_prci_clock_disable()
and sifive_clk_is_enabled()" to enable or disable the PRCI clock
Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
Tested-by: Zong Li <zong.li@sifive.com>
---
drivers/clk/sifive/fu540-prci.c | 6 +++
drivers/clk/sifive/fu740-prci.c | 9 ++++
drivers/clk/sifive/sifive-prci.c | 77 ++++++++++++++++++++++++++++----
drivers/clk/sifive/sifive-prci.h | 10 +++++
4 files changed, 93 insertions(+), 9 deletions(-)
diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/fu540-prci.c
index e2353dee8c52..3b558835984b 100644
--- a/drivers/clk/sifive/fu540-prci.c
+++ b/drivers/clk/sifive/fu540-prci.c
@@ -24,16 +24,19 @@
static struct __prci_wrpll_data __prci_corepll_data = {
.cfg0_offs = PRCI_COREPLLCFG0_OFFSET,
+ .cfg1_offs = PRCI_COREPLLCFG1_OFFSET,
.enable_bypass = sifive_prci_coreclksel_use_hfclk,
.disable_bypass = sifive_prci_coreclksel_use_corepll,
};
static struct __prci_wrpll_data __prci_ddrpll_data = {
.cfg0_offs = PRCI_DDRPLLCFG0_OFFSET,
+ .cfg1_offs = PRCI_DDRPLLCFG1_OFFSET,
};
static struct __prci_wrpll_data __prci_gemgxlpll_data = {
.cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET,
+ .cfg1_offs = PRCI_GEMGXLPLLCFG1_OFFSET,
};
/* Linux clock framework integration */
@@ -42,6 +45,9 @@ static const struct clk_ops sifive_fu540_prci_wrpll_clk_ops = {
.set_rate = sifive_prci_wrpll_set_rate,
.round_rate = sifive_prci_wrpll_round_rate,
.recalc_rate = sifive_prci_wrpll_recalc_rate,
+ .enable = sifive_prci_clock_enable,
+ .disable = sifive_prci_clock_disable,
+ .is_enabled = sifive_clk_is_enabled,
};
static const struct clk_ops sifive_fu540_prci_wrpll_ro_clk_ops = {
diff --git a/drivers/clk/sifive/fu740-prci.c b/drivers/clk/sifive/fu740-prci.c
index 41ddd4431497..db8300223745 100644
--- a/drivers/clk/sifive/fu740-prci.c
+++ b/drivers/clk/sifive/fu740-prci.c
@@ -12,32 +12,38 @@
static struct __prci_wrpll_data __prci_corepll_data = {
.cfg0_offs = PRCI_COREPLLCFG0_OFFSET,
+ .cfg1_offs = PRCI_COREPLLCFG1_OFFSET,
.enable_bypass = sifive_prci_coreclksel_use_hfclk,
.disable_bypass = sifive_prci_coreclksel_use_final_corepll,
};
static struct __prci_wrpll_data __prci_ddrpll_data = {
.cfg0_offs = PRCI_DDRPLLCFG0_OFFSET,
+ .cfg1_offs = PRCI_DDRPLLCFG1_OFFSET,
};
static struct __prci_wrpll_data __prci_gemgxlpll_data = {
.cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET,
+ .cfg1_offs = PRCI_GEMGXLPLLCFG1_OFFSET,
};
static struct __prci_wrpll_data __prci_dvfscorepll_data = {
.cfg0_offs = PRCI_DVFSCOREPLLCFG0_OFFSET,
+ .cfg1_offs = PRCI_DVFSCOREPLLCFG1_OFFSET,
.enable_bypass = sifive_prci_corepllsel_use_corepll,
.disable_bypass = sifive_prci_corepllsel_use_dvfscorepll,
};
static struct __prci_wrpll_data __prci_hfpclkpll_data = {
.cfg0_offs = PRCI_HFPCLKPLLCFG0_OFFSET,
+ .cfg1_offs = PRCI_HFPCLKPLLCFG1_OFFSET,
.enable_bypass = sifive_prci_hfpclkpllsel_use_hfclk,
.disable_bypass = sifive_prci_hfpclkpllsel_use_hfpclkpll,
};
static struct __prci_wrpll_data __prci_cltxpll_data = {
.cfg0_offs = PRCI_CLTXPLLCFG0_OFFSET,
+ .cfg1_offs = PRCI_CLTXPLLCFG1_OFFSET,
};
/* Linux clock framework integration */
@@ -46,6 +52,9 @@ static const struct clk_ops sifive_fu740_prci_wrpll_clk_ops = {
.set_rate = sifive_prci_wrpll_set_rate,
.round_rate = sifive_prci_wrpll_round_rate,
.recalc_rate = sifive_prci_wrpll_recalc_rate,
+ .enable = sifive_prci_clock_enable,
+ .disable = sifive_prci_clock_disable,
+ .is_enabled = sifive_clk_is_enabled,
};
static const struct clk_ops sifive_fu740_prci_wrpll_ro_clk_ops = {
diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
index cc4b4c6b4437..c78b042750e2 100644
--- a/drivers/clk/sifive/sifive-prci.c
+++ b/drivers/clk/sifive/sifive-prci.c
@@ -113,7 +113,7 @@ static u32 __prci_wrpll_pack(const struct wrpll_cfg *c)
}
/**
- * __prci_wrpll_read_cfg() - read the WRPLL configuration from the PRCI
+ * __prci_wrpll_read_cfg0() - read the WRPLL configuration from the PRCI
* @pd: PRCI context
* @pwd: PRCI WRPLL metadata
*
@@ -124,14 +124,14 @@ static u32 __prci_wrpll_pack(const struct wrpll_cfg *c)
* Context: Any context. Caller must prevent the records pointed to by
* @pd and @pwd from changing during execution.
*/
-static void __prci_wrpll_read_cfg(struct __prci_data *pd,
- struct __prci_wrpll_data *pwd)
+static void __prci_wrpll_read_cfg0(struct __prci_data *pd,
+ struct __prci_wrpll_data *pwd)
{
__prci_wrpll_unpack(&pwd->c, __prci_readl(pd, pwd->cfg0_offs));
}
/**
- * __prci_wrpll_write_cfg() - write WRPLL configuration into the PRCI
+ * __prci_wrpll_write_cfg0() - write WRPLL configuration into the PRCI
* @pd: PRCI context
* @pwd: PRCI WRPLL metadata
* @c: WRPLL configuration record to write
@@ -144,15 +144,29 @@ static void __prci_wrpll_read_cfg(struct __prci_data *pd,
* Context: Any context. Caller must prevent the records pointed to by
* @pd and @pwd from changing during execution.
*/
-static void __prci_wrpll_write_cfg(struct __prci_data *pd,
- struct __prci_wrpll_data *pwd,
- struct wrpll_cfg *c)
+static void __prci_wrpll_write_cfg0(struct __prci_data *pd,
+ struct __prci_wrpll_data *pwd,
+ struct wrpll_cfg *c)
{
__prci_writel(__prci_wrpll_pack(c), pwd->cfg0_offs, pd);
memcpy(&pwd->c, c, sizeof(*c));
}
+/**
+ * __prci_wrpll_write_cfg1() - write Clock enable/disable configuration
+ * into the PRCI
+ * @pd: PRCI context
+ * @pwd: PRCI WRPLL metadata
+ * @enable: Clock enable or disable value
+ */
+static void __prci_wrpll_write_cfg1(struct __prci_data *pd,
+ struct __prci_wrpll_data *pwd,
+ u32 enable)
+{
+ __prci_writel(enable, pwd->cfg1_offs, pd);
+}
+
/*
* Linux clock framework integration
*
@@ -199,16 +213,61 @@ int sifive_prci_wrpll_set_rate(struct clk_hw *hw,
if (pwd->enable_bypass)
pwd->enable_bypass(pd);
- __prci_wrpll_write_cfg(pd, pwd, &pwd->c);
+ __prci_wrpll_write_cfg0(pd, pwd, &pwd->c);
udelay(wrpll_calc_max_lock_us(&pwd->c));
+ return 0;
+}
+
+int sifive_clk_is_enabled(struct clk_hw *hw)
+{
+ struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+ struct __prci_wrpll_data *pwd = pc->pwd;
+ struct __prci_data *pd = pc->pd;
+ u32 r;
+
+ r = __prci_readl(pd, pwd->cfg1_offs);
+
+ if (r & PRCI_COREPLLCFG1_CKE_MASK)
+ return 1;
+ else
+ return 0;
+}
+
+int sifive_prci_clock_enable(struct clk_hw *hw)
+{
+ struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+ struct __prci_wrpll_data *pwd = pc->pwd;
+ struct __prci_data *pd = pc->pd;
+
+ if (sifive_clk_is_enabled(hw))
+ return 0;
+
+ __prci_wrpll_write_cfg1(pd, pwd, PRCI_COREPLLCFG1_CKE_MASK);
+
if (pwd->disable_bypass)
pwd->disable_bypass(pd);
return 0;
}
+void sifive_prci_clock_disable(struct clk_hw *hw)
+{
+ struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+ struct __prci_wrpll_data *pwd = pc->pwd;
+ struct __prci_data *pd = pc->pd;
+ u32 r;
+
+ if (pwd->enable_bypass)
+ pwd->enable_bypass(pd);
+
+ r = __prci_readl(pd, pwd->cfg1_offs);
+ r &= ~PRCI_COREPLLCFG1_CKE_MASK;
+
+ __prci_wrpll_write_cfg1(pd, pwd, r);
+}
+
/* TLCLKSEL clock integration */
unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw,
@@ -427,7 +486,7 @@ static int __prci_register_clocks(struct device *dev, struct __prci_data *pd,
pic->pd = pd;
if (pic->pwd)
- __prci_wrpll_read_cfg(pd, pic->pwd);
+ __prci_wrpll_read_cfg0(pd, pic->pwd);
r = devm_clk_hw_register(dev, &pic->hw);
if (r) {
diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h
index 88493f3b9edf..dbdbd1722688 100644
--- a/drivers/clk/sifive/sifive-prci.h
+++ b/drivers/clk/sifive/sifive-prci.h
@@ -40,6 +40,11 @@
#define PRCI_COREPLLCFG0_LOCK_SHIFT 31
#define PRCI_COREPLLCFG0_LOCK_MASK (0x1 << PRCI_COREPLLCFG0_LOCK_SHIFT)
+/* COREPLLCFG1 */
+#define PRCI_COREPLLCFG1_OFFSET 0x8
+#define PRCI_COREPLLCFG1_CKE_SHIFT 31
+#define PRCI_COREPLLCFG1_CKE_MASK (0x1 << PRCI_COREPLLCFG1_CKE_SHIFT)
+
/* DDRPLLCFG0 */
#define PRCI_DDRPLLCFG0_OFFSET 0xc
#define PRCI_DDRPLLCFG0_DIVR_SHIFT 0
@@ -220,6 +225,7 @@ struct __prci_data {
* @enable_bypass: fn ptr to code to bypass the WRPLL (if applicable; else NULL)
* @disable_bypass: fn ptr to code to not bypass the WRPLL (or NULL)
* @cfg0_offs: WRPLL CFG0 register offset (in bytes) from the PRCI base address
+ * @cfg1_offs: WRPLL CFG1 register offset (in bytes) from the PRCI base address
*
* @enable_bypass and @disable_bypass are used for WRPLL instances
* that contain a separate external glitchless clock mux downstream
@@ -230,6 +236,7 @@ struct __prci_wrpll_data {
void (*enable_bypass)(struct __prci_data *pd);
void (*disable_bypass)(struct __prci_data *pd);
u8 cfg0_offs;
+ u8 cfg1_offs;
};
/**
@@ -279,6 +286,9 @@ long sifive_prci_wrpll_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate);
int sifive_prci_wrpll_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate);
+int sifive_clk_is_enabled(struct clk_hw *hw);
+int sifive_prci_clock_enable(struct clk_hw *hw);
+void sifive_prci_clock_disable(struct clk_hw *hw);
unsigned long sifive_prci_wrpll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate);
unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw,
--
2.29.2
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
next prev parent reply other threads:[~2020-12-09 9:49 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-09 9:49 [PATCH v7 0/5] clk: add driver for the SiFive FU740 Zong Li
2020-12-09 9:49 ` [PATCH v7 1/5] clk: sifive: Extract prci core to common base Zong Li
2020-12-16 20:21 ` Stephen Boyd
2020-12-09 9:49 ` [PATCH v7 2/5] clk: sifive: Use common name for prci configuration Zong Li
2020-12-16 20:21 ` Stephen Boyd
2020-12-09 9:49 ` [PATCH v7 3/5] clk: sifive: Add a driver for the SiFive FU740 PRCI IP block Zong Li
2020-12-16 20:21 ` Stephen Boyd
2020-12-09 9:49 ` [PATCH v7 4/5] clk: sifive: Fix the wrong bit field shift Zong Li
2020-12-16 20:21 ` Stephen Boyd
2020-12-09 9:49 ` Zong Li [this message]
2020-12-16 20:21 ` [PATCH v7 5/5] clk: sifive: Add clock enable and disable ops Stephen Boyd
2021-03-16 19:45 ` [PATCH v7 0/5] clk: add driver for the SiFive FU740 Andreas Schwab
2021-03-18 2:07 ` Zong Li
2021-03-19 8:20 ` Zong Li
2021-03-19 8:44 ` Yixun Lan
2021-03-19 8:49 ` Andreas Schwab
2021-03-24 10:36 ` Andreas Schwab
2021-03-25 3:21 ` Zong Li
2021-03-25 9:22 ` Andreas Schwab
2021-03-26 9:10 ` Zong Li
2021-03-26 9:23 ` Andreas Schwab
2021-03-29 10:18 ` Zong Li
2021-03-29 10:37 ` Andreas Schwab
2021-03-31 8:11 ` Zong Li
2021-04-12 11:31 ` Andreas Schwab
2021-04-14 14:13 ` Zong Li
2021-05-11 8:53 ` Yixun Lan
2021-05-19 15:53 ` Zong Li
2021-05-19 18:17 ` Geert Uytterhoeven
2021-05-21 10:34 ` Zong Li
2021-05-21 12:52 ` Zong Li
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=20201209094916.17383-6-zong.li@sifive.com \
--to=zong.li@sifive.com \
--cc=aou@eecs.berkeley.edu \
--cc=linux-clk@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=mturquette@baylibre.com \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
--cc=pragnesh.patel@openfive.com \
--cc=pragnesh.patel@sifive.com \
--cc=sboyd@kernel.org \
--cc=schwab@linux-m68k.org \
--cc=yash.shah@sifive.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).