All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/3] clk: qcom: PLL updates..take2
@ 2016-11-14 11:00 Rajendra Nayak
  2016-11-14 11:00 ` [PATCH v4 1/3] clk: qcom: Fix .set_rate to handle alpha PLLs w/wo dynamic update Rajendra Nayak
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Rajendra Nayak @ 2016-11-14 11:00 UTC (permalink / raw)
  To: sboyd, mturquette
  Cc: linux-clk, linux-arm-msm, linux-kernel, tdas, Rajendra Nayak

This is a v4 of the patches left over from v3.
Reworked and rebased on top of clk-next.

Changes in v4:
* got rid of the use of init structures from the .set_rate ops

Rajendra Nayak (1):
  clk: qcom: mmcc-8996: Add capability flags for some alpha PLLs

Taniya Das (2):
  clk: qcom: Fix .set_rate to handle alpha PLLs w/wo dynamic update
  clk: qcom: support dynamic update using latched interface

 drivers/clk/qcom/clk-alpha-pll.c | 106 +++++++++++++++++++++++++++++++++++----
 drivers/clk/qcom/clk-alpha-pll.h |  10 ++++
 drivers/clk/qcom/mmcc-msm8996.c  |   4 ++
 3 files changed, 109 insertions(+), 11 deletions(-)

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v4 1/3] clk: qcom: Fix .set_rate to handle alpha PLLs w/wo dynamic update
  2016-11-14 11:00 [PATCH v4 0/3] clk: qcom: PLL updates..take2 Rajendra Nayak
@ 2016-11-14 11:00 ` Rajendra Nayak
  2016-11-14 11:00 ` [PATCH v4 2/3] clk: qcom: support dynamic update using latched interface Rajendra Nayak
  2016-11-14 11:00 ` [PATCH v4 3/3] clk: qcom: mmcc-8996: Add capability flags for some alpha PLLs Rajendra Nayak
  2 siblings, 0 replies; 4+ messages in thread
From: Rajendra Nayak @ 2016-11-14 11:00 UTC (permalink / raw)
  To: sboyd, mturquette
  Cc: linux-clk, linux-arm-msm, linux-kernel, tdas, Rajendra Nayak

From: Taniya Das <tdas@codeaurora.org>

Alpha PLLs which do not support dynamic update feature
need to be explicitly disabled before a rate change.
The ones which do support dynamic update do so within a
single vco range, so add a min/max freq check for such
PLLs so they fall in the vco range.

Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
Signed-off-by: Taniya Das <tdas@codeaurora.org>
---
 drivers/clk/qcom/clk-alpha-pll.c | 71 +++++++++++++++++++++++++++++++++-------
 drivers/clk/qcom/clk-alpha-pll.h |  5 +++
 2 files changed, 65 insertions(+), 11 deletions(-)

diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 47a1da3..ecb9e7f 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -376,19 +376,46 @@ static unsigned long alpha_pll_calc_rate(u64 prate, u32 l, u32 a)
 	return alpha_pll_calc_rate(prate, l, a);
 }
 
-static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
-				  unsigned long prate)
+static int alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+			      unsigned long prate,
+			      int (*enable)(struct clk_hw *hw),
+			      void (*disable)(struct clk_hw *hw))
 {
+	bool enabled;
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
 	const struct pll_vco *vco;
 	u32 l, off = pll->offset;
 	u64 a;
 
 	rate = alpha_pll_round_rate(rate, prate, &l, &a);
-	vco = alpha_pll_find_vco(pll, rate);
-	if (!vco) {
-		pr_err("alpha pll not in a valid vco range\n");
-		return -EINVAL;
+	enabled = clk_hw_is_enabled(hw);
+
+	if (pll->flags & SUPPORTS_DYNAMIC_UPDATE) {
+		/*
+		 * PLLs which support dynamic updates support one single
+		 * vco range, between min_rate and max_rate supported
+		 */
+		if (rate < pll->min_rate || rate > pll->max_rate) {
+			pr_err("alpha pll rate outside supported min/max range\n");
+			return -EINVAL;
+		}
+	} else {
+		/*
+		 * All alpha PLLs which do not support dynamic update,
+		 * should be disabled before a vco update.
+		 */
+		if (enabled)
+			disable(hw);
+
+		vco = alpha_pll_find_vco(pll, rate);
+		if (!vco) {
+			pr_err("alpha pll not in a valid vco range\n");
+			return -EINVAL;
+		}
+
+		regmap_update_bits(pll->clkr.regmap, off + PLL_USER_CTL,
+				   PLL_VCO_MASK << PLL_VCO_SHIFT,
+				   vco->val << PLL_VCO_SHIFT);
 	}
 
 	regmap_write(pll->clkr.regmap, off + PLL_L_VAL, l);
@@ -401,16 +428,29 @@ static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 		regmap_write(pll->clkr.regmap, off + PLL_ALPHA_VAL_U, a >> 32);
 	}
 
-	regmap_update_bits(pll->clkr.regmap, off + PLL_USER_CTL,
-			   PLL_VCO_MASK << PLL_VCO_SHIFT,
-			   vco->val << PLL_VCO_SHIFT);
-
 	regmap_update_bits(pll->clkr.regmap, off + PLL_USER_CTL, PLL_ALPHA_EN,
 			   PLL_ALPHA_EN);
 
+	if (!(pll->flags & SUPPORTS_DYNAMIC_UPDATE) && enabled)
+		enable(hw);
+
 	return 0;
 }
 
+static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+				  unsigned long prate)
+{
+	return alpha_pll_set_rate(hw, rate, prate, clk_alpha_pll_enable,
+				  clk_alpha_pll_disable);
+}
+
+static int clk_alpha_pll_hwfsm_set_rate(struct clk_hw *hw, unsigned long rate,
+					unsigned long prate)
+{
+	return alpha_pll_set_rate(hw, rate, prate, clk_alpha_pll_hwfsm_enable,
+				  clk_alpha_pll_hwfsm_disable);
+}
+
 static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 				     unsigned long *prate)
 {
@@ -420,6 +460,15 @@ static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 	unsigned long min_freq, max_freq;
 
 	rate = alpha_pll_round_rate(rate, *prate, &l, &a);
+
+	if (pll->flags & SUPPORTS_DYNAMIC_UPDATE) {
+		if (rate < pll->min_rate)
+			rate = pll->min_rate;
+		else if (rate > pll->max_rate)
+			rate = pll->max_rate;
+		return rate;
+	}
+
 	if (alpha_pll_find_vco(pll, rate))
 		return rate;
 
@@ -445,7 +494,7 @@ static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 	.is_enabled = clk_alpha_pll_hwfsm_is_enabled,
 	.recalc_rate = clk_alpha_pll_recalc_rate,
 	.round_rate = clk_alpha_pll_round_rate,
-	.set_rate = clk_alpha_pll_set_rate,
+	.set_rate = clk_alpha_pll_hwfsm_set_rate,
 };
 EXPORT_SYMBOL_GPL(clk_alpha_pll_hwfsm_ops);
 
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
index d6e1ee2..7aaa11c 100644
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -27,6 +27,8 @@ struct pll_vco {
  * struct clk_alpha_pll - phase locked loop (PLL)
  * @offset: base address of registers
  * @vco_table: array of VCO settings
+ * @min_rate: Minimim rate for PLLs with single VCO range
+ * @max_rate: Maximun rate for PLLs with single VCO range
  * @clkr: regmap clock handle
  */
 struct clk_alpha_pll {
@@ -37,8 +39,11 @@ struct clk_alpha_pll {
 #define SUPPORTS_OFFLINE_REQ	BIT(0)
 #define SUPPORTS_16BIT_ALPHA	BIT(1)
 #define SUPPORTS_FSM_MODE	BIT(2)
+#define SUPPORTS_DYNAMIC_UPDATE	BIT(3)
 	u8 flags;
 
+	unsigned long min_rate;
+	unsigned long max_rate;
 	struct clk_regmap clkr;
 };
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v4 2/3] clk: qcom: support dynamic update using latched interface
  2016-11-14 11:00 [PATCH v4 0/3] clk: qcom: PLL updates..take2 Rajendra Nayak
  2016-11-14 11:00 ` [PATCH v4 1/3] clk: qcom: Fix .set_rate to handle alpha PLLs w/wo dynamic update Rajendra Nayak
@ 2016-11-14 11:00 ` Rajendra Nayak
  2016-11-14 11:00 ` [PATCH v4 3/3] clk: qcom: mmcc-8996: Add capability flags for some alpha PLLs Rajendra Nayak
  2 siblings, 0 replies; 4+ messages in thread
From: Rajendra Nayak @ 2016-11-14 11:00 UTC (permalink / raw)
  To: sboyd, mturquette
  Cc: linux-clk, linux-arm-msm, linux-kernel, tdas, Rajendra Nayak

From: Taniya Das <tdas@codeaurora.org>

Alpha PLLs can support 2 kinds of input signals, normal and latched. The
normal input is directly passed to the core, while the latched input
requires a latch and acknowledge sequence to be performed for the
changed input to propagate.

Alpha PLLs can support dynamic update with both kind of input signals.
The ones which support this using a latched interface however need to
follow the latch/wait-for-ack sequence to be performed when the rate changes.
Mark these with a new flag 'SUPPORTS_LATCHED_INPUT' to handle this as
part of clk_alpha_pll_set_rate()

Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
Signed-off-by: Taniya Das <tdas@codeaurora.org>
---
 drivers/clk/qcom/clk-alpha-pll.c | 37 ++++++++++++++++++++++++++++++++++++-
 drivers/clk/qcom/clk-alpha-pll.h |  5 +++++
 2 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index ecb9e7f..15703b4 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -32,6 +32,7 @@
 # define PLL_VOTE_FSM_ENA	BIT(20)
 # define PLL_FSM_ENA		BIT(20)
 # define PLL_VOTE_FSM_RESET	BIT(21)
+# define PLL_UPDATE		BIT(22)
 # define PLL_OFFLINE_ACK	BIT(28)
 # define PLL_ACTIVE_FLAG	BIT(30)
 # define PLL_LOCK_DET		BIT(31)
@@ -48,6 +49,7 @@
 # define PLL_VCO_MASK		0x3
 
 #define PLL_USER_CTL_U		0x14
+# define PLL_LATCH_INTERFACE	BIT(11)
 
 #define PLL_CONFIG_CTL		0x18
 #define PLL_CONFIG_CTL_U	0x20
@@ -109,6 +111,10 @@ static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse,
 #define wait_for_pll_offline(pll) \
 	wait_for_pll(pll, PLL_OFFLINE_ACK, 0, "offline")
 
+#define wait_for_pll_latch_ack(pll) \
+	wait_for_pll(pll, BIT(pll->latch_ack_bit), pll->latch_ack_inverse, \
+		     "latch ack")
+
 void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
 			     const struct alpha_pll_config *config)
 {
@@ -140,6 +146,10 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
 
 	if (pll->flags & SUPPORTS_FSM_MODE)
 		qcom_pll_set_fsm_mode(regmap, off + PLL_MODE, 6, 0);
+
+	if (pll->flags & SUPPORTS_LATCHED_INPUT)
+		regmap_update_bits(regmap, off + PLL_USER_CTL_U,
+				   PLL_LATCH_INTERFACE, 0);
 }
 
 static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
@@ -376,6 +386,27 @@ static unsigned long alpha_pll_calc_rate(u64 prate, u32 l, u32 a)
 	return alpha_pll_calc_rate(prate, l, a);
 }
 
+static int clk_alpha_pll_update_latch(struct clk_alpha_pll *pll)
+{
+	/* Latch the input to the PLL */
+	regmap_update_bits(pll->clkr.regmap, pll->offset + PLL_MODE,
+			   PLL_UPDATE, PLL_UPDATE);
+
+	/* Wait for 2 reference cycle before checking ACK bit */
+	udelay(1);
+
+	wait_for_pll_latch_ack(pll);
+
+	/* Return latch input to 0 */
+	regmap_update_bits(pll->clkr.regmap, pll->offset + PLL_MODE,
+			   PLL_UPDATE, 0);
+
+	/* Wait for PLL output to stabilize */
+	udelay(100);
+
+	return 0;
+}
+
 static int alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 			      unsigned long prate,
 			      int (*enable)(struct clk_hw *hw),
@@ -431,8 +462,12 @@ static int alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 	regmap_update_bits(pll->clkr.regmap, off + PLL_USER_CTL, PLL_ALPHA_EN,
 			   PLL_ALPHA_EN);
 
-	if (!(pll->flags & SUPPORTS_DYNAMIC_UPDATE) && enabled)
+	if (pll->flags & SUPPORTS_DYNAMIC_UPDATE) {
+		if (pll->flags & SUPPORTS_LATCHED_INPUT)
+			clk_alpha_pll_update_latch(pll);
+	} else if (enabled) {
 		enable(hw);
+	}
 
 	return 0;
 }
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
index 7aaa11c..c580d20 100644
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -27,6 +27,8 @@ struct pll_vco {
  * struct clk_alpha_pll - phase locked loop (PLL)
  * @offset: base address of registers
  * @vco_table: array of VCO settings
+ * @latch_ack_bit: Bit to check for latch acknowledge
+ * @latch_ack_inverse: Bit set to 0 signifies an ack
  * @min_rate: Minimim rate for PLLs with single VCO range
  * @max_rate: Maximun rate for PLLs with single VCO range
  * @clkr: regmap clock handle
@@ -40,7 +42,10 @@ struct clk_alpha_pll {
 #define SUPPORTS_16BIT_ALPHA	BIT(1)
 #define SUPPORTS_FSM_MODE	BIT(2)
 #define SUPPORTS_DYNAMIC_UPDATE	BIT(3)
+#define SUPPORTS_LATCHED_INPUT	BIT(4)
 	u8 flags;
+	u8 latch_ack_bit;
+	bool latch_ack_inverse;
 
 	unsigned long min_rate;
 	unsigned long max_rate;
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v4 3/3] clk: qcom: mmcc-8996: Add capability flags for some alpha PLLs
  2016-11-14 11:00 [PATCH v4 0/3] clk: qcom: PLL updates..take2 Rajendra Nayak
  2016-11-14 11:00 ` [PATCH v4 1/3] clk: qcom: Fix .set_rate to handle alpha PLLs w/wo dynamic update Rajendra Nayak
  2016-11-14 11:00 ` [PATCH v4 2/3] clk: qcom: support dynamic update using latched interface Rajendra Nayak
@ 2016-11-14 11:00 ` Rajendra Nayak
  2 siblings, 0 replies; 4+ messages in thread
From: Rajendra Nayak @ 2016-11-14 11:00 UTC (permalink / raw)
  To: sboyd, mturquette
  Cc: linux-clk, linux-arm-msm, linux-kernel, tdas, Rajendra Nayak

Flag alpha PLLs which support fsmmode, dynamic update and the ones
with latched input interface.

Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
---
 drivers/clk/qcom/mmcc-msm8996.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/clk/qcom/mmcc-msm8996.c b/drivers/clk/qcom/mmcc-msm8996.c
index f77206f..c6122e1 100644
--- a/drivers/clk/qcom/mmcc-msm8996.c
+++ b/drivers/clk/qcom/mmcc-msm8996.c
@@ -269,6 +269,7 @@ enum {
 	.offset = 0x0,
 	.vco_table = mmpll_p_vco,
 	.num_vco = ARRAY_SIZE(mmpll_p_vco),
+	.flags = SUPPORTS_FSM_MODE,
 	.clkr = {
 		.enable_reg = 0x100,
 		.enable_mask = BIT(0),
@@ -297,6 +298,7 @@ enum {
 	.offset = 0x30,
 	.vco_table = mmpll_p_vco,
 	.num_vco = ARRAY_SIZE(mmpll_p_vco),
+	.flags = SUPPORTS_FSM_MODE,
 	.clkr = {
 		.enable_reg = 0x100,
 		.enable_mask = BIT(1),
@@ -445,6 +447,8 @@ enum {
 	.offset = 0x4200,
 	.vco_table = mmpll_t_vco,
 	.num_vco = ARRAY_SIZE(mmpll_t_vco),
+	.flags = SUPPORTS_DYNAMIC_UPDATE | SUPPORTS_LATCHED_INPUT,
+	.latch_ack_bit = 29,
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "mmpll9_early",
 		.parent_names = (const char *[]){ "xo" },
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2016-11-14 11:00 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-14 11:00 [PATCH v4 0/3] clk: qcom: PLL updates..take2 Rajendra Nayak
2016-11-14 11:00 ` [PATCH v4 1/3] clk: qcom: Fix .set_rate to handle alpha PLLs w/wo dynamic update Rajendra Nayak
2016-11-14 11:00 ` [PATCH v4 2/3] clk: qcom: support dynamic update using latched interface Rajendra Nayak
2016-11-14 11:00 ` [PATCH v4 3/3] clk: qcom: mmcc-8996: Add capability flags for some alpha PLLs Rajendra Nayak

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.