linux-arm-msm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC v2 00/12] Misc patches for QCOM clocks
@ 2017-08-08 18:24 Abhishek Sahu
  2017-08-08 18:24 ` [RFC v2 01/12] clk: qcom: flag for 64 bit CONFIG_CTL Abhishek Sahu
                   ` (11 more replies)
  0 siblings, 12 replies; 13+ messages in thread
From: Abhishek Sahu @ 2017-08-08 18:24 UTC (permalink / raw)
  To: sboyd, mturquette
  Cc: andy.gross, david.brown, rnayak, linux-arm-msm, linux-soc,
	linux-clk, linux-kernel, Abhishek Sahu

* v2:

1. Discussion is going on with HW team to fix the offset issue in next chip
   version so removed the RCG patch
2. Made “fix 16 bit alpha support calculation” generic to support all cases.

3. Clubbed the [1] and Patch [2] for "support for dynamic updating the PLL"
   a. The PLL_LATCH_INTERFACE bit is not available in every Alpha PLL and it
      will be turned off after default power on. If the PLL user want to turn
      off the LATCH_INTERFACE then they can directly set this bit in
      PLL_USER_CTL_U during alpha_pll_configure and clear the dynamic update
      flag bit
   b. The latching procedure is only required if PLL is enabled
   c. The handling is different according to PLL_UPDATE_BYPASS bit

4. Added the patch for “2 bit PLL post divider”

[1] https://www.spinics.net/lists/linux-arm-msm/msg24569.html
[2] https://www.spinics.net/lists/kernel/msg2566714.html

* v1:

https://www.spinics.net/lists/kernel/msg2566710.html

Abhishek Sahu (12):
  clk: qcom: flag for 64 bit CONFIG_CTL
  clk: qcom: support for alpha mode configuration
  clk: qcom: use offset from alpha pll node
  clk: qcom: fix 16 bit alpha support calculation
  clk: qcom: support for dynamic updating the PLL
  clk: qcom: add flag for VCO operation
  clk: qcom: support for Huayra PLL
  clk: qcom: support for Brammo PLL
  clk: qcom: support for 2 bit PLL post divider
  clk: qcom: add read-only alpha pll post divider operations
  clk: qcom: add read-only divider operations
  clk: qcom: add parent map for regmap mux

 drivers/clk/qcom/clk-alpha-pll.c      | 507 +++++++++++++++++++++++++++-------
 drivers/clk/qcom/clk-alpha-pll.h      |  49 +++-
 drivers/clk/qcom/clk-rcg.h            |  10 -
 drivers/clk/qcom/clk-regmap-divider.c |  29 ++
 drivers/clk/qcom/clk-regmap-divider.h |   1 +
 drivers/clk/qcom/clk-regmap-mux.c     |   6 +
 drivers/clk/qcom/clk-regmap-mux.h     |   2 +
 drivers/clk/qcom/common.h             |  11 +-
 drivers/clk/qcom/gcc-ipq8074.c        |   6 +-
 drivers/clk/qcom/gcc-msm8994.c        |  12 +-
 drivers/clk/qcom/gcc-msm8996.c        |  12 +-
 drivers/clk/qcom/mmcc-msm8996.c       |  48 ++--
 12 files changed, 554 insertions(+), 139 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] 13+ messages in thread

* [RFC v2 01/12] clk: qcom: flag for 64 bit CONFIG_CTL
  2017-08-08 18:24 [RFC v2 00/12] Misc patches for QCOM clocks Abhishek Sahu
@ 2017-08-08 18:24 ` Abhishek Sahu
  2017-08-08 18:24 ` [RFC v2 02/12] clk: qcom: support for alpha mode configuration Abhishek Sahu
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Abhishek Sahu @ 2017-08-08 18:24 UTC (permalink / raw)
  To: sboyd, mturquette
  Cc: andy.gross, david.brown, rnayak, linux-arm-msm, linux-soc,
	linux-clk, linux-kernel, Abhishek Sahu

Some of the Alpha PLL’s (like Spark, Brammo PLL) do not have
CONFIG_CTL_U register. This patch adds the flag for PLL’s
which have CONFIG_CTL_U register and checks the same while
doing PLL initial configuration.

Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---
 drivers/clk/qcom/clk-alpha-pll.c | 5 ++++-
 drivers/clk/qcom/clk-alpha-pll.h | 7 ++++---
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 47a1da3..e6cde2d 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -118,7 +118,10 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
 	regmap_write(regmap, off + PLL_L_VAL, config->l);
 	regmap_write(regmap, off + PLL_ALPHA_VAL, config->alpha);
 	regmap_write(regmap, off + PLL_CONFIG_CTL, config->config_ctl_val);
-	regmap_write(regmap, off + PLL_CONFIG_CTL_U, config->config_ctl_hi_val);
+
+	if (pll->flags & SUPPORTS_64BIT_CONFIG_CTL)
+		regmap_write(regmap, off + PLL_CONFIG_CTL_U,
+			     config->config_ctl_hi_val);
 
 	val = config->main_output_mask;
 	val |= config->aux_output_mask;
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
index d6e1ee2..bbd6aa9 100644
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -34,9 +34,10 @@ struct clk_alpha_pll {
 
 	const struct pll_vco *vco_table;
 	size_t num_vco;
-#define SUPPORTS_OFFLINE_REQ	BIT(0)
-#define SUPPORTS_16BIT_ALPHA	BIT(1)
-#define SUPPORTS_FSM_MODE	BIT(2)
+#define SUPPORTS_OFFLINE_REQ		BIT(0)
+#define SUPPORTS_16BIT_ALPHA		BIT(1)
+#define SUPPORTS_FSM_MODE		BIT(2)
+#define SUPPORTS_64BIT_CONFIG_CTL	BIT(3)
 	u8 flags;
 
 	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] 13+ messages in thread

* [RFC v2 02/12] clk: qcom: support for alpha mode configuration
  2017-08-08 18:24 [RFC v2 00/12] Misc patches for QCOM clocks Abhishek Sahu
  2017-08-08 18:24 ` [RFC v2 01/12] clk: qcom: flag for 64 bit CONFIG_CTL Abhishek Sahu
@ 2017-08-08 18:24 ` Abhishek Sahu
  2017-08-08 18:24 ` [RFC v2 03/12] clk: qcom: use offset from alpha pll node Abhishek Sahu
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Abhishek Sahu @ 2017-08-08 18:24 UTC (permalink / raw)
  To: sboyd, mturquette
  Cc: andy.gross, david.brown, rnayak, linux-arm-msm, linux-soc,
	linux-clk, linux-kernel, Abhishek Sahu

The current configuration does not fully configure PLL alpha mode
and values so this patch

1. Configures PLL_ALPHA_VAL_U for PLL which supports 40 bit alpha.
2. Adds alpha enable and alpha mode configuration support.

Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---
 drivers/clk/qcom/clk-alpha-pll.c | 5 +++++
 drivers/clk/qcom/clk-alpha-pll.h | 3 +++
 2 files changed, 8 insertions(+)

diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index e6cde2d..6291048 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -123,6 +123,9 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
 		regmap_write(regmap, off + PLL_CONFIG_CTL_U,
 			     config->config_ctl_hi_val);
 
+	if (!(pll->flags & SUPPORTS_16BIT_ALPHA))
+		regmap_write(regmap, off + PLL_ALPHA_VAL_U, config->alpha_hi);
+
 	val = config->main_output_mask;
 	val |= config->aux_output_mask;
 	val |= config->aux2_output_mask;
@@ -130,6 +133,8 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
 	val |= config->pre_div_val;
 	val |= config->post_div_val;
 	val |= config->vco_val;
+	val |= config->alpha_en_mask;
+	val |= config->alpha_mode_mask;
 
 	mask = config->main_output_mask;
 	mask |= config->aux_output_mask;
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
index bbd6aa9..39686db 100644
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -59,12 +59,15 @@ struct clk_alpha_pll_postdiv {
 struct alpha_pll_config {
 	u32 l;
 	u32 alpha;
+	u32 alpha_hi;
 	u32 config_ctl_val;
 	u32 config_ctl_hi_val;
 	u32 main_output_mask;
 	u32 aux_output_mask;
 	u32 aux2_output_mask;
 	u32 early_output_mask;
+	u32 alpha_en_mask;
+	u32 alpha_mode_mask;
 	u32 pre_div_val;
 	u32 pre_div_mask;
 	u32 post_div_val;
-- 
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] 13+ messages in thread

* [RFC v2 03/12] clk: qcom: use offset from alpha pll node
  2017-08-08 18:24 [RFC v2 00/12] Misc patches for QCOM clocks Abhishek Sahu
  2017-08-08 18:24 ` [RFC v2 01/12] clk: qcom: flag for 64 bit CONFIG_CTL Abhishek Sahu
  2017-08-08 18:24 ` [RFC v2 02/12] clk: qcom: support for alpha mode configuration Abhishek Sahu
@ 2017-08-08 18:24 ` Abhishek Sahu
  2017-08-08 18:24 ` [RFC v2 04/12] clk: qcom: fix 16 bit alpha support calculation Abhishek Sahu
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Abhishek Sahu @ 2017-08-08 18:24 UTC (permalink / raw)
  To: sboyd, mturquette
  Cc: andy.gross, david.brown, rnayak, linux-arm-msm, linux-soc,
	linux-clk, linux-kernel, Abhishek Sahu

Alpha PLL is a generic name used for Qualcomm PLL’s which uses L
and Alpha values for configuring the integer and fractional part.
Qualcomm SoC’s use different types of Alpha PLL’s for which basic
software configuration part is common. These PLL’s will have same
basic registers like PLL_MODE, L_VAL, ALPHA_VAL but some of the
register offsets are different in each PLL type.
Also, the offsets are not same in different instances of same
type of PLL in some cases so it’s better to get the offsets
from PLL node itself instead of hardcoding it.

This patch adds the support for giving the PLL offsets array in
PLL node itself and uses the same for calculating the offsets.
Now, this offsets array will be mandatory for all alpha PLL nodes.
This patch provides the default array of offsets which driver can use
where the PLL offsets are same. Some of the existing
Qualcomm SoC’s uses the alpha PLL nodes so this patch added the
default offsets in its nodes.

Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---
 drivers/clk/qcom/clk-alpha-pll.c | 130 ++++++++++++++++++++-------------------
 drivers/clk/qcom/clk-alpha-pll.h |  28 +++++++--
 drivers/clk/qcom/gcc-ipq8074.c   |   6 +-
 drivers/clk/qcom/gcc-msm8994.c   |  12 ++--
 drivers/clk/qcom/gcc-msm8996.c   |  12 ++--
 drivers/clk/qcom/mmcc-msm8996.c  |  48 ++++++++++-----
 6 files changed, 142 insertions(+), 94 deletions(-)

diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 6291048..084fbdc 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -20,7 +20,6 @@
 #include "clk-alpha-pll.h"
 #include "common.h"
 
-#define PLL_MODE		0x00
 # define PLL_OUTCTRL		BIT(0)
 # define PLL_BYPASSNL		BIT(1)
 # define PLL_RESET_N		BIT(2)
@@ -36,25 +35,12 @@
 # define PLL_ACTIVE_FLAG	BIT(30)
 # define PLL_LOCK_DET		BIT(31)
 
-#define PLL_L_VAL		0x04
-#define PLL_ALPHA_VAL		0x08
-#define PLL_ALPHA_VAL_U		0x0c
-
-#define PLL_USER_CTL		0x10
 # define PLL_POST_DIV_SHIFT	8
 # define PLL_POST_DIV_MASK	0xf
 # define PLL_ALPHA_EN		BIT(24)
 # define PLL_VCO_SHIFT		20
 # define PLL_VCO_MASK		0x3
 
-#define PLL_USER_CTL_U		0x14
-
-#define PLL_CONFIG_CTL		0x18
-#define PLL_CONFIG_CTL_U	0x20
-#define PLL_TEST_CTL		0x1c
-#define PLL_TEST_CTL_U		0x20
-#define PLL_STATUS		0x24
-
 /*
  * Even though 40 bits are present, use only 32 for ease of calculation.
  */
@@ -62,27 +48,52 @@
 #define ALPHA_BITWIDTH		32
 #define ALPHA_16BIT_MASK	0xffff
 
+#define pll_mode(pll)		(pll->base + pll->offsets[ALPHA_PLL_MODE])
+#define pll_l(pll)		(pll->base + pll->offsets[ALPHA_PLL_L_VAL])
+#define pll_alpha(pll)		(pll->base + pll->offsets[ALPHA_PLL_ALPHA_VAL])
+#define pll_alpha_u(pll)	(pll->base + pll->offsets[ALPHA_PLL_ALPHA_VAL_U])
+#define pll_user_ctl(pll)	(pll->base + pll->offsets[ALPHA_PLL_USER_CTL])
+#define pll_user_ctl_u(pll)	(pll->base + pll->offsets[ALPHA_PLL_USER_CTL_U])
+#define pll_cfg_ctl(pll)	(pll->base + pll->offsets[ALPHA_PLL_CONFIG_CTL])
+#define pll_test_ctl(pll)	(pll->base + pll->offsets[ALPHA_PLL_TEST_CTL])
+#define pll_test_ctl_u(pll)	(pll->base + pll->offsets[ALPHA_PLL_TEST_CTL_U])
+#define pll_status(pll)		(pll->base + pll->offsets[ALPHA_PLL_STATUS])
+#define pll_cfg_ctl_u(pll)	(pll->base + pll->offsets[ALPHA_PLL_CONFIG_CTL_U])
+
 #define to_clk_alpha_pll(_hw) container_of(to_clk_regmap(_hw), \
 					   struct clk_alpha_pll, clkr)
 
 #define to_clk_alpha_pll_postdiv(_hw) container_of(to_clk_regmap(_hw), \
 					   struct clk_alpha_pll_postdiv, clkr)
 
+const u8 clk_alpha_pll_offsets[] = {
+	[ALPHA_PLL_MODE] = 0x00,
+	[ALPHA_PLL_L_VAL] = 0x04,
+	[ALPHA_PLL_ALPHA_VAL] = 0x08,
+	[ALPHA_PLL_ALPHA_VAL_U] = 0x0c,
+	[ALPHA_PLL_USER_CTL] = 0x10,
+	[ALPHA_PLL_USER_CTL_U] = 0x14,
+	[ALPHA_PLL_CONFIG_CTL] = 0x18,
+	[ALPHA_PLL_TEST_CTL] = 0x1c,
+	[ALPHA_PLL_TEST_CTL_U] = 0x20,
+	[ALPHA_PLL_STATUS] = 0x24,
+};
+EXPORT_SYMBOL_GPL(clk_alpha_pll_offsets);
+
 static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse,
 			const char *action)
 {
-	u32 val, off;
+	u32 val;
 	int count;
 	int ret;
 	const char *name = clk_hw_get_name(&pll->clkr.hw);
 
-	off = pll->offset;
-	ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
+	ret = regmap_read(pll->clkr.regmap, pll_mode(pll), &val);
 	if (ret)
 		return ret;
 
 	for (count = 100; count > 0; count--) {
-		ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
+		ret = regmap_read(pll->clkr.regmap, pll_mode(pll), &val);
 		if (ret)
 			return ret;
 		if (inverse && !(val & mask))
@@ -113,18 +124,17 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
 			     const struct alpha_pll_config *config)
 {
 	u32 val, mask;
-	u32 off = pll->offset;
 
-	regmap_write(regmap, off + PLL_L_VAL, config->l);
-	regmap_write(regmap, off + PLL_ALPHA_VAL, config->alpha);
-	regmap_write(regmap, off + PLL_CONFIG_CTL, config->config_ctl_val);
+	regmap_write(regmap, pll_l(pll), config->l);
+	regmap_write(regmap, pll_alpha(pll), config->alpha);
+	regmap_write(regmap, pll_cfg_ctl(pll), config->config_ctl_val);
 
 	if (pll->flags & SUPPORTS_64BIT_CONFIG_CTL)
-		regmap_write(regmap, off + PLL_CONFIG_CTL_U,
+		regmap_write(regmap, pll_cfg_ctl_u(pll),
 			     config->config_ctl_hi_val);
 
 	if (!(pll->flags & SUPPORTS_16BIT_ALPHA))
-		regmap_write(regmap, off + PLL_ALPHA_VAL_U, config->alpha_hi);
+		regmap_write(regmap, pll_alpha_u(pll), config->alpha_hi);
 
 	val = config->main_output_mask;
 	val |= config->aux_output_mask;
@@ -144,20 +154,19 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
 	mask |= config->post_div_mask;
 	mask |= config->vco_mask;
 
-	regmap_update_bits(regmap, off + PLL_USER_CTL, mask, val);
+	regmap_update_bits(regmap, pll_user_ctl(pll), mask, val);
 
 	if (pll->flags & SUPPORTS_FSM_MODE)
-		qcom_pll_set_fsm_mode(regmap, off + PLL_MODE, 6, 0);
+		qcom_pll_set_fsm_mode(regmap, pll_mode(pll), 6, 0);
 }
 
 static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
 {
 	int ret;
-	u32 val, off;
+	u32 val;
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
 
-	off = pll->offset;
-	ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
+	ret = regmap_read(pll->clkr.regmap, pll_mode(pll), &val);
 	if (ret)
 		return ret;
 
@@ -166,7 +175,7 @@ static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
 	if (pll->flags & SUPPORTS_OFFLINE_REQ)
 		val &= ~PLL_OFFLINE_REQ;
 
-	ret = regmap_write(pll->clkr.regmap, off + PLL_MODE, val);
+	ret = regmap_write(pll->clkr.regmap, pll_mode(pll), val);
 	if (ret)
 		return ret;
 
@@ -179,16 +188,15 @@ static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
 static void clk_alpha_pll_hwfsm_disable(struct clk_hw *hw)
 {
 	int ret;
-	u32 val, off;
+	u32 val;
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
 
-	off = pll->offset;
-	ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
+	ret = regmap_read(pll->clkr.regmap, pll_mode(pll), &val);
 	if (ret)
 		return;
 
 	if (pll->flags & SUPPORTS_OFFLINE_REQ) {
-		ret = regmap_update_bits(pll->clkr.regmap, off + PLL_MODE,
+		ret = regmap_update_bits(pll->clkr.regmap, pll_mode(pll),
 					 PLL_OFFLINE_REQ, PLL_OFFLINE_REQ);
 		if (ret)
 			return;
@@ -199,7 +207,7 @@ static void clk_alpha_pll_hwfsm_disable(struct clk_hw *hw)
 	}
 
 	/* Disable hwfsm */
-	ret = regmap_update_bits(pll->clkr.regmap, off + PLL_MODE,
+	ret = regmap_update_bits(pll->clkr.regmap, pll_mode(pll),
 				 PLL_FSM_ENA, 0);
 	if (ret)
 		return;
@@ -210,11 +218,10 @@ static void clk_alpha_pll_hwfsm_disable(struct clk_hw *hw)
 static int pll_is_enabled(struct clk_hw *hw, u32 mask)
 {
 	int ret;
-	u32 val, off;
+	u32 val;
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
 
-	off = pll->offset;
-	ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
+	ret = regmap_read(pll->clkr.regmap, pll_mode(pll), &val);
 	if (ret)
 		return ret;
 
@@ -235,12 +242,10 @@ static int clk_alpha_pll_enable(struct clk_hw *hw)
 {
 	int ret;
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
-	u32 val, mask, off;
-
-	off = pll->offset;
+	u32 val, mask;
 
 	mask = PLL_OUTCTRL | PLL_RESET_N | PLL_BYPASSNL;
-	ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
+	ret = regmap_read(pll->clkr.regmap, pll_mode(pll), &val);
 	if (ret)
 		return ret;
 
@@ -256,7 +261,7 @@ static int clk_alpha_pll_enable(struct clk_hw *hw)
 	if ((val & mask) == mask)
 		return 0;
 
-	ret = regmap_update_bits(pll->clkr.regmap, off + PLL_MODE,
+	ret = regmap_update_bits(pll->clkr.regmap, pll_mode(pll),
 				 PLL_BYPASSNL, PLL_BYPASSNL);
 	if (ret)
 		return ret;
@@ -268,7 +273,7 @@ static int clk_alpha_pll_enable(struct clk_hw *hw)
 	mb();
 	udelay(5);
 
-	ret = regmap_update_bits(pll->clkr.regmap, off + PLL_MODE,
+	ret = regmap_update_bits(pll->clkr.regmap, pll_mode(pll),
 				 PLL_RESET_N, PLL_RESET_N);
 	if (ret)
 		return ret;
@@ -277,7 +282,7 @@ static int clk_alpha_pll_enable(struct clk_hw *hw)
 	if (ret)
 		return ret;
 
-	ret = regmap_update_bits(pll->clkr.regmap, off + PLL_MODE,
+	ret = regmap_update_bits(pll->clkr.regmap, pll_mode(pll),
 				 PLL_OUTCTRL, PLL_OUTCTRL);
 
 	/* Ensure that the write above goes through before returning. */
@@ -289,11 +294,9 @@ static void clk_alpha_pll_disable(struct clk_hw *hw)
 {
 	int ret;
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
-	u32 val, mask, off;
-
-	off = pll->offset;
+	u32 val, mask;
 
-	ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
+	ret = regmap_read(pll->clkr.regmap, pll_mode(pll), &val);
 	if (ret)
 		return;
 
@@ -304,14 +307,14 @@ static void clk_alpha_pll_disable(struct clk_hw *hw)
 	}
 
 	mask = PLL_OUTCTRL;
-	regmap_update_bits(pll->clkr.regmap, off + PLL_MODE, mask, 0);
+	regmap_update_bits(pll->clkr.regmap, pll_mode(pll), mask, 0);
 
 	/* Delay of 2 output clock ticks required until output is disabled */
 	mb();
 	udelay(1);
 
 	mask = PLL_RESET_N | PLL_BYPASSNL;
-	regmap_update_bits(pll->clkr.regmap, off + PLL_MODE, mask, 0);
+	regmap_update_bits(pll->clkr.regmap, pll_mode(pll), mask, 0);
 }
 
 static unsigned long alpha_pll_calc_rate(u64 prate, u32 l, u32 a)
@@ -364,17 +367,16 @@ static unsigned long alpha_pll_calc_rate(u64 prate, u32 l, u32 a)
 	u32 l, low, high, ctl;
 	u64 a = 0, prate = parent_rate;
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
-	u32 off = pll->offset;
 
-	regmap_read(pll->clkr.regmap, off + PLL_L_VAL, &l);
+	regmap_read(pll->clkr.regmap, pll_l(pll), &l);
 
-	regmap_read(pll->clkr.regmap, off + PLL_USER_CTL, &ctl);
+	regmap_read(pll->clkr.regmap, pll_user_ctl(pll), &ctl);
 	if (ctl & PLL_ALPHA_EN) {
-		regmap_read(pll->clkr.regmap, off + PLL_ALPHA_VAL, &low);
+		regmap_read(pll->clkr.regmap, pll_alpha(pll), &low);
 		if (pll->flags & SUPPORTS_16BIT_ALPHA) {
 			a = low & ALPHA_16BIT_MASK;
 		} else {
-			regmap_read(pll->clkr.regmap, off + PLL_ALPHA_VAL_U,
+			regmap_read(pll->clkr.regmap, pll_alpha_u(pll),
 				    &high);
 			a = (u64)high << 32 | low;
 			a >>= ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH;
@@ -389,7 +391,7 @@ static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 {
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
 	const struct pll_vco *vco;
-	u32 l, off = pll->offset;
+	u32 l;
 	u64 a;
 
 	rate = alpha_pll_round_rate(rate, prate, &l, &a);
@@ -399,21 +401,21 @@ static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 		return -EINVAL;
 	}
 
-	regmap_write(pll->clkr.regmap, off + PLL_L_VAL, l);
+	regmap_write(pll->clkr.regmap, pll_l(pll), l);
 
 	if (pll->flags & SUPPORTS_16BIT_ALPHA) {
-		regmap_write(pll->clkr.regmap, off + PLL_ALPHA_VAL,
+		regmap_write(pll->clkr.regmap, pll_alpha(pll),
 			     a & ALPHA_16BIT_MASK);
 	} else {
 		a <<= (ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH);
-		regmap_write(pll->clkr.regmap, off + PLL_ALPHA_VAL_U, a >> 32);
+		regmap_write(pll->clkr.regmap, pll_alpha_u(pll), a >> 32);
 	}
 
-	regmap_update_bits(pll->clkr.regmap, off + PLL_USER_CTL,
+	regmap_update_bits(pll->clkr.regmap, pll_user_ctl(pll),
 			   PLL_VCO_MASK << PLL_VCO_SHIFT,
 			   vco->val << PLL_VCO_SHIFT);
 
-	regmap_update_bits(pll->clkr.regmap, off + PLL_USER_CTL, PLL_ALPHA_EN,
+	regmap_update_bits(pll->clkr.regmap, pll_user_ctl(pll), PLL_ALPHA_EN,
 			   PLL_ALPHA_EN);
 
 	return 0;
@@ -463,7 +465,7 @@ static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 	struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
 	u32 ctl;
 
-	regmap_read(pll->clkr.regmap, pll->offset + PLL_USER_CTL, &ctl);
+	regmap_read(pll->clkr.regmap, pll_user_ctl(pll), &ctl);
 
 	ctl >>= PLL_POST_DIV_SHIFT;
 	ctl &= PLL_POST_DIV_MASK;
@@ -499,7 +501,7 @@ static int clk_alpha_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,
 	/* 16 -> 0xf, 8 -> 0x7, 4 -> 0x3, 2 -> 0x1, 1 -> 0x0 */
 	div = DIV_ROUND_UP_ULL((u64)parent_rate, rate) - 1;
 
-	return regmap_update_bits(pll->clkr.regmap, pll->offset + PLL_USER_CTL,
+	return regmap_update_bits(pll->clkr.regmap, pll_user_ctl(pll),
 				  PLL_POST_DIV_MASK << PLL_POST_DIV_SHIFT,
 				  div << PLL_POST_DIV_SHIFT);
 }
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
index 39686db..4901d92 100644
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -17,6 +17,20 @@
 #include <linux/clk-provider.h>
 #include "clk-regmap.h"
 
+enum {
+	ALPHA_PLL_MODE,
+	ALPHA_PLL_L_VAL,
+	ALPHA_PLL_ALPHA_VAL,
+	ALPHA_PLL_ALPHA_VAL_U,
+	ALPHA_PLL_USER_CTL,
+	ALPHA_PLL_USER_CTL_U,
+	ALPHA_PLL_CONFIG_CTL,
+	ALPHA_PLL_CONFIG_CTL_U,
+	ALPHA_PLL_TEST_CTL,
+	ALPHA_PLL_TEST_CTL_U,
+	ALPHA_PLL_STATUS,
+};
+
 struct pll_vco {
 	unsigned long min_freq;
 	unsigned long max_freq;
@@ -25,12 +39,14 @@ struct pll_vco {
 
 /**
  * struct clk_alpha_pll - phase locked loop (PLL)
- * @offset: base address of registers
+ * @base: base address of registers
+ * @offsets: array containing offsets of all PLL registers from base address
  * @vco_table: array of VCO settings
  * @clkr: regmap clock handle
  */
 struct clk_alpha_pll {
-	u32 offset;
+	u32 base;
+	const u8 *offsets;
 
 	const struct pll_vco *vco_table;
 	size_t num_vco;
@@ -45,12 +61,14 @@ struct clk_alpha_pll {
 
 /**
  * struct clk_alpha_pll_postdiv - phase locked loop (PLL) post-divider
- * @offset: base address of registers
+ * @base: base address of registers
+ * @offsets: array containing offsets of all PLL registers from base address
  * @width: width of post-divider
  * @clkr: regmap clock handle
  */
 struct clk_alpha_pll_postdiv {
-	u32 offset;
+	u32 base;
+	const u8 *offsets;
 	u8 width;
 
 	struct clk_regmap clkr;
@@ -76,6 +94,8 @@ struct alpha_pll_config {
 	u32 vco_mask;
 };
 
+extern const u8 clk_alpha_pll_offsets[];
+
 extern const struct clk_ops clk_alpha_pll_ops;
 extern const struct clk_ops clk_alpha_pll_hwfsm_ops;
 extern const struct clk_ops clk_alpha_pll_postdiv_ops;
diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
index 0f735d3..29380d2 100644
--- a/drivers/clk/qcom/gcc-ipq8074.c
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -51,7 +51,8 @@ enum {
 };
 
 static struct clk_alpha_pll gpll0_main = {
-	.offset = 0x21000,
+	.base = 0x21000,
+	.offsets = clk_alpha_pll_offsets,
 	.clkr = {
 		.enable_reg = 0x0b000,
 		.enable_mask = BIT(0),
@@ -81,7 +82,8 @@ enum {
 };
 
 static struct clk_alpha_pll_postdiv gpll0 = {
-	.offset = 0x21000,
+	.base = 0x21000,
+	.offsets = clk_alpha_pll_offsets,
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gpll0",
 		.parent_names = (const char *[]){
diff --git a/drivers/clk/qcom/gcc-msm8994.c b/drivers/clk/qcom/gcc-msm8994.c
index 7983288..da6b0d1 100644
--- a/drivers/clk/qcom/gcc-msm8994.c
+++ b/drivers/clk/qcom/gcc-msm8994.c
@@ -72,7 +72,8 @@ enum {
 };
 
 static struct clk_alpha_pll gpll0_early = {
-	.offset = 0x00000,
+	.base = 0x00000,
+	.offsets = clk_alpha_pll_offsets,
 	.clkr = {
 		.enable_reg = 0x1480,
 		.enable_mask = BIT(0),
@@ -87,7 +88,8 @@ enum {
 };
 
 static struct clk_alpha_pll_postdiv gpll0 = {
-	.offset = 0x00000,
+	.base = 0x00000,
+	.offsets = clk_alpha_pll_offsets,
 	.clkr.hw.init = &(struct clk_init_data)
 	{
 		.name = "gpll0",
@@ -98,7 +100,8 @@ enum {
 };
 
 static struct clk_alpha_pll gpll4_early = {
-	.offset = 0x1dc0,
+	.base = 0x1dc0,
+	.offsets = clk_alpha_pll_offsets,
 	.clkr = {
 		.enable_reg = 0x1480,
 		.enable_mask = BIT(4),
@@ -113,7 +116,8 @@ enum {
 };
 
 static struct clk_alpha_pll_postdiv gpll4 = {
-	.offset = 0x1dc0,
+	.base = 0x1dc0,
+	.offsets = clk_alpha_pll_offsets,
 	.clkr.hw.init = &(struct clk_init_data)
 	{
 		.name = "gpll4",
diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c
index 8abc200..fcf1b15 100644
--- a/drivers/clk/qcom/gcc-msm8996.c
+++ b/drivers/clk/qcom/gcc-msm8996.c
@@ -226,7 +226,8 @@ enum {
 };
 
 static struct clk_alpha_pll gpll0_early = {
-	.offset = 0x00000,
+	.base = 0x00000,
+	.offsets = clk_alpha_pll_offsets,
 	.clkr = {
 		.enable_reg = 0x52000,
 		.enable_mask = BIT(0),
@@ -251,7 +252,8 @@ enum {
 };
 
 static struct clk_alpha_pll_postdiv gpll0 = {
-	.offset = 0x00000,
+	.base = 0x00000,
+	.offsets = clk_alpha_pll_offsets,
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gpll0",
 		.parent_names = (const char *[]){ "gpll0_early" },
@@ -261,7 +263,8 @@ enum {
 };
 
 static struct clk_alpha_pll gpll4_early = {
-	.offset = 0x77000,
+	.base = 0x77000,
+	.offsets = clk_alpha_pll_offsets,
 	.clkr = {
 		.enable_reg = 0x52000,
 		.enable_mask = BIT(4),
@@ -275,7 +278,8 @@ enum {
 };
 
 static struct clk_alpha_pll_postdiv gpll4 = {
-	.offset = 0x77000,
+	.base = 0x77000,
+	.offsets = clk_alpha_pll_offsets,
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gpll4",
 		.parent_names = (const char *[]){ "gpll4_early" },
diff --git a/drivers/clk/qcom/mmcc-msm8996.c b/drivers/clk/qcom/mmcc-msm8996.c
index 352394d..2447740 100644
--- a/drivers/clk/qcom/mmcc-msm8996.c
+++ b/drivers/clk/qcom/mmcc-msm8996.c
@@ -266,7 +266,8 @@ enum {
 };
 
 static struct clk_alpha_pll mmpll0_early = {
-	.offset = 0x0,
+	.base = 0x0,
+	.offsets = clk_alpha_pll_offsets,
 	.vco_table = mmpll_p_vco,
 	.num_vco = ARRAY_SIZE(mmpll_p_vco),
 	.clkr = {
@@ -282,7 +283,8 @@ enum {
 };
 
 static struct clk_alpha_pll_postdiv mmpll0 = {
-	.offset = 0x0,
+	.base = 0x0,
+	.offsets = clk_alpha_pll_offsets,
 	.width = 4,
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "mmpll0",
@@ -294,7 +296,8 @@ enum {
 };
 
 static struct clk_alpha_pll mmpll1_early = {
-	.offset = 0x30,
+	.base = 0x30,
+	.offsets = clk_alpha_pll_offsets,
 	.vco_table = mmpll_p_vco,
 	.num_vco = ARRAY_SIZE(mmpll_p_vco),
 	.clkr = {
@@ -310,7 +313,8 @@ enum {
 };
 
 static struct clk_alpha_pll_postdiv mmpll1 = {
-	.offset = 0x30,
+	.base = 0x30,
+	.offsets = clk_alpha_pll_offsets,
 	.width = 4,
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "mmpll1",
@@ -322,7 +326,8 @@ enum {
 };
 
 static struct clk_alpha_pll mmpll2_early = {
-	.offset = 0x4100,
+	.base = 0x4100,
+	.offsets = clk_alpha_pll_offsets,
 	.vco_table = mmpll_gfx_vco,
 	.num_vco = ARRAY_SIZE(mmpll_gfx_vco),
 	.clkr.hw.init = &(struct clk_init_data){
@@ -334,7 +339,8 @@ enum {
 };
 
 static struct clk_alpha_pll_postdiv mmpll2 = {
-	.offset = 0x4100,
+	.base = 0x4100,
+	.offsets = clk_alpha_pll_offsets,
 	.width = 4,
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "mmpll2",
@@ -346,7 +352,8 @@ enum {
 };
 
 static struct clk_alpha_pll mmpll3_early = {
-	.offset = 0x60,
+	.base = 0x60,
+	.offsets = clk_alpha_pll_offsets,
 	.vco_table = mmpll_p_vco,
 	.num_vco = ARRAY_SIZE(mmpll_p_vco),
 	.clkr.hw.init = &(struct clk_init_data){
@@ -358,7 +365,8 @@ enum {
 };
 
 static struct clk_alpha_pll_postdiv mmpll3 = {
-	.offset = 0x60,
+	.base = 0x60,
+	.offsets = clk_alpha_pll_offsets,
 	.width = 4,
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "mmpll3",
@@ -370,7 +378,8 @@ enum {
 };
 
 static struct clk_alpha_pll mmpll4_early = {
-	.offset = 0x90,
+	.base = 0x90,
+	.offsets = clk_alpha_pll_offsets,
 	.vco_table = mmpll_t_vco,
 	.num_vco = ARRAY_SIZE(mmpll_t_vco),
 	.clkr.hw.init = &(struct clk_init_data){
@@ -382,7 +391,8 @@ enum {
 };
 
 static struct clk_alpha_pll_postdiv mmpll4 = {
-	.offset = 0x90,
+	.base = 0x90,
+	.offsets = clk_alpha_pll_offsets,
 	.width = 2,
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "mmpll4",
@@ -394,7 +404,8 @@ enum {
 };
 
 static struct clk_alpha_pll mmpll5_early = {
-	.offset = 0xc0,
+	.base = 0xc0,
+	.offsets = clk_alpha_pll_offsets,
 	.vco_table = mmpll_p_vco,
 	.num_vco = ARRAY_SIZE(mmpll_p_vco),
 	.clkr.hw.init = &(struct clk_init_data){
@@ -406,7 +417,8 @@ enum {
 };
 
 static struct clk_alpha_pll_postdiv mmpll5 = {
-	.offset = 0xc0,
+	.base = 0xc0,
+	.offsets = clk_alpha_pll_offsets,
 	.width = 4,
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "mmpll5",
@@ -418,7 +430,8 @@ enum {
 };
 
 static struct clk_alpha_pll mmpll8_early = {
-	.offset = 0x4130,
+	.base = 0x4130,
+	.offsets = clk_alpha_pll_offsets,
 	.vco_table = mmpll_gfx_vco,
 	.num_vco = ARRAY_SIZE(mmpll_gfx_vco),
 	.clkr.hw.init = &(struct clk_init_data){
@@ -430,7 +443,8 @@ enum {
 };
 
 static struct clk_alpha_pll_postdiv mmpll8 = {
-	.offset = 0x4130,
+	.base = 0x4130,
+	.offsets = clk_alpha_pll_offsets,
 	.width = 4,
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "mmpll8",
@@ -442,7 +456,8 @@ enum {
 };
 
 static struct clk_alpha_pll mmpll9_early = {
-	.offset = 0x4200,
+	.base = 0x4200,
+	.offsets = clk_alpha_pll_offsets,
 	.vco_table = mmpll_t_vco,
 	.num_vco = ARRAY_SIZE(mmpll_t_vco),
 	.clkr.hw.init = &(struct clk_init_data){
@@ -454,7 +469,8 @@ enum {
 };
 
 static struct clk_alpha_pll_postdiv mmpll9 = {
-	.offset = 0x4200,
+	.base = 0x4200,
+	.offsets = clk_alpha_pll_offsets,
 	.width = 2,
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "mmpll9",
-- 
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] 13+ messages in thread

* [RFC v2 04/12] clk: qcom: fix 16 bit alpha support calculation
  2017-08-08 18:24 [RFC v2 00/12] Misc patches for QCOM clocks Abhishek Sahu
                   ` (2 preceding siblings ...)
  2017-08-08 18:24 ` [RFC v2 03/12] clk: qcom: use offset from alpha pll node Abhishek Sahu
@ 2017-08-08 18:24 ` Abhishek Sahu
  2017-08-08 18:24 ` [RFC v2 05/12] clk: qcom: support for dynamic updating the PLL Abhishek Sahu
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Abhishek Sahu @ 2017-08-08 18:24 UTC (permalink / raw)
  To: sboyd, mturquette
  Cc: andy.gross, david.brown, rnayak, linux-arm-msm, linux-soc,
	linux-clk, linux-kernel, Abhishek Sahu

The alpha value calculation function has been written for 40 bit
alpha which is not coming properly for 16 bit

1. Alpha value is being calculated on the basis of
   ALPHA_BITWIDTH to make the computation easy for 40 bit alpha.
   After calculating the 32 bit alpha, It is being converted to 40
   bit alpha by making making lower bits zero. But if actual alpha
   register width is less than ALPHA_BITWIDTH, then the actual width
   can be used for calculation

2. During 40 bit alpha pll set rate, the lower alpha register is
   not being configured

Now the changes have been made to calculate the rate and register
values from alpha_width instead hardcoding it so that it can work
for all the cases.

Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---
 drivers/clk/qcom/clk-alpha-pll.c | 56 +++++++++++++++++++++++-----------------
 1 file changed, 33 insertions(+), 23 deletions(-)

diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 084fbdc..6694fd5 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -45,8 +45,11 @@
  * Even though 40 bits are present, use only 32 for ease of calculation.
  */
 #define ALPHA_REG_BITWIDTH	40
+#define ALPHA_REG_16BIT_WIDTH	16
 #define ALPHA_BITWIDTH		32
-#define ALPHA_16BIT_MASK	0xffff
+
+#define pll_alpha_width(pll)  (pll->flags & SUPPORTS_16BIT_ALPHA ?	\
+			       ALPHA_REG_16BIT_WIDTH : ALPHA_REG_BITWIDTH)
 
 #define pll_mode(pll)		(pll->base + pll->offsets[ALPHA_PLL_MODE])
 #define pll_l(pll)		(pll->base + pll->offsets[ALPHA_PLL_L_VAL])
@@ -317,13 +320,16 @@ static void clk_alpha_pll_disable(struct clk_hw *hw)
 	regmap_update_bits(pll->clkr.regmap, pll_mode(pll), mask, 0);
 }
 
-static unsigned long alpha_pll_calc_rate(u64 prate, u32 l, u32 a)
+static unsigned long
+alpha_pll_calc_rate(u64 prate, u32 l, u32 a, u32 alpha_width)
 {
-	return (prate * l) + ((prate * a) >> ALPHA_BITWIDTH);
+	return (prate * l) + ((prate * a) >>
+		(alpha_width < ALPHA_BITWIDTH ? alpha_width : ALPHA_BITWIDTH));
 }
 
 static unsigned long
-alpha_pll_round_rate(unsigned long rate, unsigned long prate, u32 *l, u64 *a)
+alpha_pll_round_rate(unsigned long rate, unsigned long prate, u32 *l, u64 *a,
+		     u32 alpha_width)
 {
 	u64 remainder;
 	u64 quotient;
@@ -338,14 +344,16 @@ static unsigned long alpha_pll_calc_rate(u64 prate, u32 l, u32 a)
 	}
 
 	/* Upper ALPHA_BITWIDTH bits of Alpha */
-	quotient = remainder << ALPHA_BITWIDTH;
+	quotient = remainder << (alpha_width < ALPHA_BITWIDTH ?
+				 alpha_width : ALPHA_BITWIDTH);
+
 	remainder = do_div(quotient, prate);
 
 	if (remainder)
 		quotient++;
 
 	*a = quotient;
-	return alpha_pll_calc_rate(prate, *l, *a);
+	return alpha_pll_calc_rate(prate, *l, *a, alpha_width);
 }
 
 static const struct pll_vco *
@@ -364,26 +372,28 @@ static unsigned long alpha_pll_calc_rate(u64 prate, u32 l, u32 a)
 static unsigned long
 clk_alpha_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
 {
-	u32 l, low, high, ctl;
-	u64 a = 0, prate = parent_rate;
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+	u32 l, low, high, ctl, alpha_width = pll_alpha_width(pll);
+	u64 a = 0, prate = parent_rate;
 
 	regmap_read(pll->clkr.regmap, pll_l(pll), &l);
 
 	regmap_read(pll->clkr.regmap, pll_user_ctl(pll), &ctl);
 	if (ctl & PLL_ALPHA_EN) {
 		regmap_read(pll->clkr.regmap, pll_alpha(pll), &low);
-		if (pll->flags & SUPPORTS_16BIT_ALPHA) {
-			a = low & ALPHA_16BIT_MASK;
-		} else {
+		if (alpha_width > 32) {
 			regmap_read(pll->clkr.regmap, pll_alpha_u(pll),
 				    &high);
 			a = (u64)high << 32 | low;
-			a >>= ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH;
+		} else {
+			a = low & GENMASK(0, alpha_width - 1);
 		}
+
+		if (alpha_width > ALPHA_BITWIDTH)
+			a >>= alpha_width - ALPHA_BITWIDTH;
 	}
 
-	return alpha_pll_calc_rate(prate, l, a);
+	return alpha_pll_calc_rate(prate, l, a, alpha_width);
 }
 
 static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -391,10 +401,10 @@ static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 {
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
 	const struct pll_vco *vco;
-	u32 l;
+	u32 l, alpha_width = pll_alpha_width(pll);
 	u64 a;
 
-	rate = alpha_pll_round_rate(rate, prate, &l, &a);
+	rate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);
 	vco = alpha_pll_find_vco(pll, rate);
 	if (!vco) {
 		pr_err("alpha pll not in a valid vco range\n");
@@ -403,13 +413,13 @@ static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 
 	regmap_write(pll->clkr.regmap, pll_l(pll), l);
 
-	if (pll->flags & SUPPORTS_16BIT_ALPHA) {
-		regmap_write(pll->clkr.regmap, pll_alpha(pll),
-			     a & ALPHA_16BIT_MASK);
-	} else {
-		a <<= (ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH);
+	if (alpha_width > ALPHA_BITWIDTH)
+		a <<= alpha_width - ALPHA_BITWIDTH;
+
+	if (alpha_width > 32)
 		regmap_write(pll->clkr.regmap, pll_alpha_u(pll), a >> 32);
-	}
+
+	regmap_write(pll->clkr.regmap, pll_alpha(pll), a);
 
 	regmap_update_bits(pll->clkr.regmap, pll_user_ctl(pll),
 			   PLL_VCO_MASK << PLL_VCO_SHIFT,
@@ -425,11 +435,11 @@ static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 				     unsigned long *prate)
 {
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
-	u32 l;
+	u32 l, alpha_width = pll_alpha_width(pll);
 	u64 a;
 	unsigned long min_freq, max_freq;
 
-	rate = alpha_pll_round_rate(rate, *prate, &l, &a);
+	rate = alpha_pll_round_rate(rate, *prate, &l, &a, alpha_width);
 	if (alpha_pll_find_vco(pll, rate))
 		return 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] 13+ messages in thread

* [RFC v2 05/12] clk: qcom: support for dynamic updating the PLL
  2017-08-08 18:24 [RFC v2 00/12] Misc patches for QCOM clocks Abhishek Sahu
                   ` (3 preceding siblings ...)
  2017-08-08 18:24 ` [RFC v2 04/12] clk: qcom: fix 16 bit alpha support calculation Abhishek Sahu
@ 2017-08-08 18:24 ` Abhishek Sahu
  2017-08-08 18:24 ` [RFC v2 06/12] clk: qcom: add flag for VCO operation Abhishek Sahu
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Abhishek Sahu @ 2017-08-08 18:24 UTC (permalink / raw)
  To: sboyd, mturquette
  Cc: andy.gross, david.brown, rnayak, linux-arm-msm, linux-soc,
	linux-clk, linux-kernel, Abhishek Sahu, Taniya Das

Some of the Alpha PLL’s support dynamic update in which the
frequency can be changed dynamically without turning off the PLL.

This dynamic update requires the following sequence

1. Write the desired values to pll_l_val and pll_alpha_val
2. Toggle pll_latch_input from low to high
3. Wait for pll_ack_latch to transition from low to high
   The new L and alpha values have been latched. It make
   take some time for the PLL to fully settle with these
   new values
4. Pull pll_latch_input low

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

diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 6694fd5..1f37bf8a 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -31,7 +31,10 @@
 # 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_UPDATE_BYPASS	BIT(23)
 # define PLL_OFFLINE_ACK	BIT(28)
+# define ALPHA_PLL_ACK_LATCH	BIT(29)
 # define PLL_ACTIVE_FLAG	BIT(30)
 # define PLL_LOCK_DET		BIT(31)
 
@@ -123,6 +126,15 @@ 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_update(pll) \
+	wait_for_pll(pll, PLL_UPDATE, 1, "update")
+
+#define wait_for_pll_update_ack_set(pll) \
+	wait_for_pll(pll, ALPHA_PLL_ACK_LATCH, 0, "update_ack_set")
+
+#define wait_for_pll_update_ack_clear(pll) \
+	wait_for_pll(pll, ALPHA_PLL_ACK_LATCH, 1, "update_ack_clear")
+
 void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
 			     const struct alpha_pll_config *config)
 {
@@ -396,6 +408,56 @@ static void clk_alpha_pll_disable(struct clk_hw *hw)
 	return alpha_pll_calc_rate(prate, l, a, alpha_width);
 }
 
+static int clk_alpha_pll_update_latch(struct clk_alpha_pll *pll)
+{
+	u32 mode;
+	int ret;
+
+	regmap_read(pll->clkr.regmap, pll_mode(pll), &mode);
+
+	/* Latch the input to the PLL */
+	regmap_update_bits(pll->clkr.regmap, pll_mode(pll), PLL_UPDATE,
+			   PLL_UPDATE);
+
+	/* Make sure PLL_UPDATE request goes through*/
+	mb();
+
+	/* Wait for 2 reference cycle before checking ACK bit */
+	udelay(1);
+
+	/*
+	 * PLL will latch the new L, Alpha and freq control word.
+	 * PLL will respond by raising PLL_ACK_LATCH output when new programming
+	 * has been latched in and PLL is being updated. When
+	 * UPDATE_LOGIC_BYPASS bit is not set, PLL_UPDATE will be cleared
+	 * automatically by hardware when PLL_ACK_LATCH is asserted by PLL.
+	 */
+	if (mode & PLL_UPDATE_BYPASS) {
+		ret = wait_for_pll_update_ack_set(pll);
+		if (ret)
+			return ret;
+
+		regmap_update_bits(pll->clkr.regmap, pll_mode(pll),
+				   PLL_UPDATE, 0);
+
+		/* Make sure PLL_UPDATE request goes through*/
+		mb();
+	} else {
+		ret = wait_for_pll_update(pll);
+		if (ret)
+			return ret;
+	}
+
+	ret = wait_for_pll_update_ack_clear(pll);
+	if (ret)
+		return ret;
+
+	/* Wait for PLL output to stabilize */
+	udelay(10);
+
+	return 0;
+}
+
 static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 				  unsigned long prate)
 {
@@ -428,7 +490,10 @@ static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 	regmap_update_bits(pll->clkr.regmap, pll_user_ctl(pll), PLL_ALPHA_EN,
 			   PLL_ALPHA_EN);
 
-	return 0;
+	if (!clk_hw_is_enabled(hw) || !(pll->flags & SUPPORTS_DYNAMIC_UPDATE))
+		return 0;
+
+	return clk_alpha_pll_update_latch(pll);
 }
 
 static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
index 4901d92..8b27c05 100644
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -54,6 +54,7 @@ struct clk_alpha_pll {
 #define SUPPORTS_16BIT_ALPHA		BIT(1)
 #define SUPPORTS_FSM_MODE		BIT(2)
 #define SUPPORTS_64BIT_CONFIG_CTL	BIT(3)
+#define SUPPORTS_DYNAMIC_UPDATE		BIT(4)
 	u8 flags;
 
 	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] 13+ messages in thread

* [RFC v2 06/12] clk: qcom: add flag for VCO operation
  2017-08-08 18:24 [RFC v2 00/12] Misc patches for QCOM clocks Abhishek Sahu
                   ` (4 preceding siblings ...)
  2017-08-08 18:24 ` [RFC v2 05/12] clk: qcom: support for dynamic updating the PLL Abhishek Sahu
@ 2017-08-08 18:24 ` Abhishek Sahu
  2017-08-08 18:24 ` [RFC v2 07/12] clk: qcom: support for Huayra PLL Abhishek Sahu
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Abhishek Sahu @ 2017-08-08 18:24 UTC (permalink / raw)
  To: sboyd, mturquette
  Cc: andy.gross, david.brown, rnayak, linux-arm-msm, linux-soc,
	linux-clk, linux-kernel, Abhishek Sahu

Some of the Alpha PLL’s does not have VCO configuration so this
patch adds the flag and does not perform VCO operation if this
flag is set.

Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---
 drivers/clk/qcom/clk-alpha-pll.c | 19 +++++++++++--------
 drivers/clk/qcom/clk-alpha-pll.h |  1 +
 2 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 1f37bf8a..c368e7c 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -467,10 +467,12 @@ static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 	u64 a;
 
 	rate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);
-	vco = alpha_pll_find_vco(pll, rate);
-	if (!vco) {
-		pr_err("alpha pll not in a valid vco range\n");
-		return -EINVAL;
+	if (!(pll->flags & SUPPORTS_NO_VCO)) {
+		vco = alpha_pll_find_vco(pll, rate);
+		if (!vco) {
+			pr_err("alpha pll not in a valid vco range\n");
+			return -EINVAL;
+		}
 	}
 
 	regmap_write(pll->clkr.regmap, pll_l(pll), l);
@@ -483,9 +485,10 @@ static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 
 	regmap_write(pll->clkr.regmap, pll_alpha(pll), a);
 
-	regmap_update_bits(pll->clkr.regmap, pll_user_ctl(pll),
-			   PLL_VCO_MASK << PLL_VCO_SHIFT,
-			   vco->val << PLL_VCO_SHIFT);
+	if (!(pll->flags & SUPPORTS_NO_VCO))
+		regmap_update_bits(pll->clkr.regmap, pll_user_ctl(pll),
+				   PLL_VCO_MASK << PLL_VCO_SHIFT,
+				   vco->val << PLL_VCO_SHIFT);
 
 	regmap_update_bits(pll->clkr.regmap, pll_user_ctl(pll), PLL_ALPHA_EN,
 			   PLL_ALPHA_EN);
@@ -505,7 +508,7 @@ 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, alpha_width);
-	if (alpha_pll_find_vco(pll, rate))
+	if ((pll->flags & SUPPORTS_NO_VCO) || alpha_pll_find_vco(pll, rate))
 		return rate;
 
 	min_freq = pll->vco_table[0].min_freq;
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
index 8b27c05..973673b 100644
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -55,6 +55,7 @@ struct clk_alpha_pll {
 #define SUPPORTS_FSM_MODE		BIT(2)
 #define SUPPORTS_64BIT_CONFIG_CTL	BIT(3)
 #define SUPPORTS_DYNAMIC_UPDATE		BIT(4)
+#define SUPPORTS_NO_VCO			BIT(5)
 	u8 flags;
 
 	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] 13+ messages in thread

* [RFC v2 07/12] clk: qcom: support for Huayra PLL
  2017-08-08 18:24 [RFC v2 00/12] Misc patches for QCOM clocks Abhishek Sahu
                   ` (5 preceding siblings ...)
  2017-08-08 18:24 ` [RFC v2 06/12] clk: qcom: add flag for VCO operation Abhishek Sahu
@ 2017-08-08 18:24 ` Abhishek Sahu
  2017-08-08 18:24 ` [RFC v2 08/12] clk: qcom: support for Brammo PLL Abhishek Sahu
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Abhishek Sahu @ 2017-08-08 18:24 UTC (permalink / raw)
  To: sboyd, mturquette
  Cc: andy.gross, david.brown, rnayak, linux-arm-msm, linux-soc,
	linux-clk, linux-kernel, Abhishek Sahu

Following are the major differences in Huayra PLL

1. PLL Alpha Value is 16 bits
2. Depending on alpha_mode, the pll_alpha_val can be treated as
   M/N value or as a two’s compliment number.
3. Huayra PLL supports PLL dynamic programming. User can change
   L_VAL, without having to go through the power on sequence.

Since the decoding of alpha val and dynamic programming are
completely different from other Alpha PLL’s so this patch
made adds separate functions for Huayra PLL.

Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---
 drivers/clk/qcom/clk-alpha-pll.c | 180 +++++++++++++++++++++++++++++++++++++++
 drivers/clk/qcom/clk-alpha-pll.h |   6 ++
 2 files changed, 186 insertions(+)

diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index c368e7c..23e2bb7 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -41,9 +41,17 @@
 # define PLL_POST_DIV_SHIFT	8
 # define PLL_POST_DIV_MASK	0xf
 # define PLL_ALPHA_EN		BIT(24)
+# define PLL_ALPHA_MODE		BIT(25)
 # define PLL_VCO_SHIFT		20
 # define PLL_VCO_MASK		0x3
 
+#define PLL_HUAYRA_M_WIDTH		8
+#define PLL_HUAYRA_M_SHIFT		8
+#define PLL_HUAYRA_M_MASK		0xff
+#define PLL_HUAYRA_N_SHIFT		0
+#define PLL_HUAYRA_N_MASK		0xff
+#define PLL_HUAYRA_ALPHA_WIDTH		16
+
 /*
  * Even though 40 bits are present, use only 32 for ease of calculation.
  */
@@ -86,6 +94,19 @@
 };
 EXPORT_SYMBOL_GPL(clk_alpha_pll_offsets);
 
+const u8 clk_alpha_huayra_pll_offsets[] = {
+	[ALPHA_PLL_MODE] = 0x00,
+	[ALPHA_PLL_L_VAL] = 0x04,
+	[ALPHA_PLL_ALPHA_VAL] = 0x08,
+	[ALPHA_PLL_USER_CTL] = 0x10,
+	[ALPHA_PLL_CONFIG_CTL] = 0x14,
+	[ALPHA_PLL_CONFIG_CTL_U] = 0x18,
+	[ALPHA_PLL_TEST_CTL] = 0x1c,
+	[ALPHA_PLL_TEST_CTL_U] = 0x20,
+	[ALPHA_PLL_STATUS] = 0x24,
+};
+EXPORT_SYMBOL_GPL(clk_alpha_huayra_pll_offsets);
+
 static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse,
 			const char *action)
 {
@@ -517,6 +538,155 @@ static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 	return clamp(rate, min_freq, max_freq);
 }
 
+static unsigned long
+alpha_huayra_pll_calc_rate(u64 prate, u32 l, u32 a)
+{
+	/*
+	 * a contains 16 bit alpha_val in two’s compliment number in the range
+	 * of [-0.5, 0.5).
+	 */
+	if (a >= BIT(PLL_HUAYRA_ALPHA_WIDTH - 1))
+		l -= 1;
+
+	return (prate * l) + (prate * a >> PLL_HUAYRA_ALPHA_WIDTH);
+}
+
+static unsigned long
+alpha_huayra_pll_round_rate(unsigned long rate, unsigned long prate,
+			    u32 *l, u32 *a)
+{
+	u64 remainder;
+	u64 quotient;
+
+	quotient = rate;
+	remainder = do_div(quotient, prate);
+	*l = quotient;
+
+	if (!remainder) {
+		*a = 0;
+		return rate;
+	}
+
+	quotient = remainder << PLL_HUAYRA_ALPHA_WIDTH;
+	remainder = do_div(quotient, prate);
+
+	if (remainder)
+		quotient++;
+
+	/*
+	 * alpha_val should be in two’s compliment number in the range
+	 * of [-0.5, 0.5) so if quotient >= 0.5 then increment the l value
+	 * since alpha value will be subtracted in this case.
+	 */
+	if (quotient >= BIT(PLL_HUAYRA_ALPHA_WIDTH - 1))
+		*l += 1;
+
+	*a = quotient;
+	return alpha_huayra_pll_calc_rate(prate, *l, *a);
+}
+
+static unsigned long
+clk_alpha_huayra_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+	u32 l, alpha = 0, ctl, alpha_m, alpha_n;
+	u64 rate = parent_rate, tmp;
+	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+
+	regmap_read(pll->clkr.regmap, pll_l(pll), &l);
+	regmap_read(pll->clkr.regmap, pll_user_ctl(pll), &ctl);
+
+	if (ctl & PLL_ALPHA_EN) {
+		regmap_read(pll->clkr.regmap, pll_alpha(pll), &alpha);
+		/*
+		 * Depending upon alpha_mode, it can be treated as M/N value or
+		 * as a two’s compliment number. When
+		 * alpha_mode=1 pll_alpha_val<15:8>=M & pll_apla_val<7:0>=N
+		 *		Fout=FIN*(L+(M/N))
+		 * M is a signed number (-128 to 127) and N is unsigned
+		 * (0 to 255). M/N has to be within +/-0.5.
+		 *
+		 * alpha_mode=0, it is a two’s compliment number in the range
+		 * of [-0.5, 0.5).
+		 *		Fout=FIN*(L+(alpha_val)/2^16),where alpha_val is
+		 * two’s compliment number.
+		 */
+		if (!(ctl & PLL_ALPHA_MODE))
+			return alpha_huayra_pll_calc_rate(rate, l, alpha);
+
+		alpha_m = alpha >> PLL_HUAYRA_M_SHIFT & PLL_HUAYRA_M_MASK;
+		alpha_n = alpha >> PLL_HUAYRA_N_SHIFT & PLL_HUAYRA_N_MASK;
+
+		rate *= l;
+		tmp = parent_rate;
+		if (alpha_m >= BIT(PLL_HUAYRA_M_WIDTH - 1)) {
+			alpha_m = BIT(PLL_HUAYRA_M_WIDTH) - alpha_m;
+			tmp *= alpha_m;
+			do_div(tmp, alpha_n);
+			rate -= tmp;
+		} else {
+			tmp *= alpha_m;
+			do_div(tmp, alpha_n);
+			rate += tmp;
+		}
+
+		return rate;
+	}
+
+	return alpha_huayra_pll_calc_rate(rate, l, alpha);
+}
+
+static int clk_alpha_huayra_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+					 unsigned long prate)
+{
+	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+	u32 l, a, ctl, cur_alpha = 0;
+
+	rate = alpha_huayra_pll_round_rate(rate, prate, &l, &a);
+
+	regmap_read(pll->clkr.regmap, pll_user_ctl(pll), &ctl);
+
+	if (ctl & PLL_ALPHA_EN)
+		regmap_read(pll->clkr.regmap, pll_alpha(pll), &cur_alpha);
+
+	/*
+	 * Huayra PLL supports PLL dynamic programming. User can change L_VAL,
+	 * without having to go through the power on sequence.
+	 */
+	if (clk_hw_is_enabled(hw)) {
+		if (cur_alpha != a) {
+			pr_err("clock needs to be gated %s\n",
+			       clk_hw_get_name(hw));
+			return -EBUSY;
+		}
+
+		regmap_write(pll->clkr.regmap, pll_l(pll), l);
+		/* Ensure that the write above goes to detect L val change. */
+		mb();
+		return wait_for_pll_enable_lock(pll);
+	}
+
+	regmap_write(pll->clkr.regmap, pll_l(pll), l);
+	regmap_write(pll->clkr.regmap, pll_alpha(pll), a);
+
+	if (a == 0)
+		regmap_update_bits(pll->clkr.regmap, pll_user_ctl(pll),
+				   PLL_ALPHA_EN, 0x0);
+	else
+		regmap_update_bits(pll->clkr.regmap, pll_user_ctl(pll),
+				   PLL_ALPHA_EN | PLL_ALPHA_MODE, PLL_ALPHA_EN);
+
+	return 0;
+}
+
+static long clk_alpha_huayra_pll_round_rate(struct clk_hw *hw,
+					    unsigned long rate,
+					    unsigned long *prate)
+{
+	u32 l, a;
+
+	return alpha_huayra_pll_round_rate(rate, *prate, &l, &a);
+}
+
 const struct clk_ops clk_alpha_pll_ops = {
 	.enable = clk_alpha_pll_enable,
 	.disable = clk_alpha_pll_disable,
@@ -537,6 +707,16 @@ static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 };
 EXPORT_SYMBOL_GPL(clk_alpha_pll_hwfsm_ops);
 
+const struct clk_ops clk_alpha_huayra_pll_ops = {
+	.enable = clk_alpha_pll_enable,
+	.disable = clk_alpha_pll_disable,
+	.is_enabled = clk_alpha_pll_is_enabled,
+	.recalc_rate = clk_alpha_huayra_pll_recalc_rate,
+	.round_rate = clk_alpha_huayra_pll_round_rate,
+	.set_rate = clk_alpha_huayra_pll_set_rate,
+};
+EXPORT_SYMBOL_GPL(clk_alpha_huayra_pll_ops);
+
 static unsigned long
 clk_alpha_pll_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
 {
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
index 973673b..af74abf 100644
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -61,6 +61,10 @@ struct clk_alpha_pll {
 	struct clk_regmap clkr;
 };
 
+#define CLK_HUAYRA_PLL_FLAGS	(SUPPORTS_NO_VCO | SUPPORTS_DYNAMIC_UPDATE | \
+				 SUPPORTS_64BIT_CONFIG_CTL |		     \
+				 SUPPORTS_16BIT_ALPHA)
+
 /**
  * struct clk_alpha_pll_postdiv - phase locked loop (PLL) post-divider
  * @base: base address of registers
@@ -97,9 +101,11 @@ struct alpha_pll_config {
 };
 
 extern const u8 clk_alpha_pll_offsets[];
+extern const u8 clk_alpha_huayra_pll_offsets[];
 
 extern const struct clk_ops clk_alpha_pll_ops;
 extern const struct clk_ops clk_alpha_pll_hwfsm_ops;
+extern const struct clk_ops clk_alpha_huayra_pll_ops;
 extern const struct clk_ops clk_alpha_pll_postdiv_ops;
 
 void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
-- 
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] 13+ messages in thread

* [RFC v2 08/12] clk: qcom: support for Brammo PLL
  2017-08-08 18:24 [RFC v2 00/12] Misc patches for QCOM clocks Abhishek Sahu
                   ` (6 preceding siblings ...)
  2017-08-08 18:24 ` [RFC v2 07/12] clk: qcom: support for Huayra PLL Abhishek Sahu
@ 2017-08-08 18:24 ` Abhishek Sahu
  2017-08-08 18:24 ` [RFC v2 09/12] clk: qcom: support for 2 bit PLL post divider Abhishek Sahu
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Abhishek Sahu @ 2017-08-08 18:24 UTC (permalink / raw)
  To: sboyd, mturquette
  Cc: andy.gross, david.brown, rnayak, linux-arm-msm, linux-soc,
	linux-clk, linux-kernel, Abhishek Sahu

1. Brammo PLL does not allow configuration of VCO
2. Supports the dynamic update in which the frequency can
   be changed dynamically without turning off the PLL
3. The register offsets are different from normal Alpha PLL

Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---
 drivers/clk/qcom/clk-alpha-pll.c | 12 ++++++++++++
 drivers/clk/qcom/clk-alpha-pll.h |  2 ++
 2 files changed, 14 insertions(+)

diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 23e2bb7..b491dbe 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -107,6 +107,18 @@
 };
 EXPORT_SYMBOL_GPL(clk_alpha_huayra_pll_offsets);
 
+const u8 clk_alpha_brammo_pll_offsets[] = {
+	[ALPHA_PLL_MODE] = 0x00,
+	[ALPHA_PLL_L_VAL] = 0x04,
+	[ALPHA_PLL_ALPHA_VAL] = 0x08,
+	[ALPHA_PLL_ALPHA_VAL_U] = 0x0c,
+	[ALPHA_PLL_USER_CTL] = 0x10,
+	[ALPHA_PLL_CONFIG_CTL] = 0x18,
+	[ALPHA_PLL_TEST_CTL] = 0x1c,
+	[ALPHA_PLL_STATUS] = 0x24,
+};
+EXPORT_SYMBOL_GPL(clk_alpha_brammo_pll_offsets);
+
 static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse,
 			const char *action)
 {
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
index af74abf..8a0dab6 100644
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -64,6 +64,7 @@ struct clk_alpha_pll {
 #define CLK_HUAYRA_PLL_FLAGS	(SUPPORTS_NO_VCO | SUPPORTS_DYNAMIC_UPDATE | \
 				 SUPPORTS_64BIT_CONFIG_CTL |		     \
 				 SUPPORTS_16BIT_ALPHA)
+#define CLK_BRAMMO_PLL_FLAGS	(SUPPORTS_NO_VCO | SUPPORTS_DYNAMIC_UPDATE)
 
 /**
  * struct clk_alpha_pll_postdiv - phase locked loop (PLL) post-divider
@@ -102,6 +103,7 @@ struct alpha_pll_config {
 
 extern const u8 clk_alpha_pll_offsets[];
 extern const u8 clk_alpha_huayra_pll_offsets[];
+extern const u8 clk_alpha_brammo_pll_offsets[];
 
 extern const struct clk_ops clk_alpha_pll_ops;
 extern const struct clk_ops clk_alpha_pll_hwfsm_ops;
-- 
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] 13+ messages in thread

* [RFC v2 09/12] clk: qcom: support for 2 bit PLL post divider
  2017-08-08 18:24 [RFC v2 00/12] Misc patches for QCOM clocks Abhishek Sahu
                   ` (7 preceding siblings ...)
  2017-08-08 18:24 ` [RFC v2 08/12] clk: qcom: support for Brammo PLL Abhishek Sahu
@ 2017-08-08 18:24 ` Abhishek Sahu
  2017-08-08 18:24 ` [RFC v2 10/12] clk: qcom: add read-only alpha pll post divider operations Abhishek Sahu
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Abhishek Sahu @ 2017-08-08 18:24 UTC (permalink / raw)
  To: sboyd, mturquette
  Cc: andy.gross, david.brown, rnayak, linux-arm-msm, linux-soc,
	linux-clk, linux-kernel, Abhishek Sahu

Current PLL driver only supports 4 bit PLL post divider so
modified the PLL divider operations to support 2 bit PLL
post divider.

Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---
 drivers/clk/qcom/clk-alpha-pll.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index b491dbe..4725f80 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -39,7 +39,6 @@
 # define PLL_LOCK_DET		BIT(31)
 
 # define PLL_POST_DIV_SHIFT	8
-# define PLL_POST_DIV_MASK	0xf
 # define PLL_ALPHA_EN		BIT(24)
 # define PLL_ALPHA_MODE		BIT(25)
 # define PLL_VCO_SHIFT		20
@@ -738,7 +737,7 @@ static long clk_alpha_huayra_pll_round_rate(struct clk_hw *hw,
 	regmap_read(pll->clkr.regmap, pll_user_ctl(pll), &ctl);
 
 	ctl >>= PLL_POST_DIV_SHIFT;
-	ctl &= PLL_POST_DIV_MASK;
+	ctl &= BIT(pll->width) - 1;
 
 	return parent_rate >> fls(ctl);
 }
@@ -752,13 +751,26 @@ static long clk_alpha_huayra_pll_round_rate(struct clk_hw *hw,
 	{ }
 };
 
+static const struct clk_div_table clk_alpha_2bit_div_table[] = {
+	{ 0x0, 1 },
+	{ 0x1, 2 },
+	{ 0x3, 4 },
+	{ }
+};
+
 static long
 clk_alpha_pll_postdiv_round_rate(struct clk_hw *hw, unsigned long rate,
 				 unsigned long *prate)
 {
 	struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
+	const struct clk_div_table *table;
+
+	if (pll->width == 2)
+		table = clk_alpha_2bit_div_table;
+	else
+		table = clk_alpha_div_table;
 
-	return divider_round_rate(hw, rate, prate, clk_alpha_div_table,
+	return divider_round_rate(hw, rate, prate, table,
 				  pll->width, CLK_DIVIDER_POWER_OF_TWO);
 }
 
@@ -772,7 +784,7 @@ static int clk_alpha_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,
 	div = DIV_ROUND_UP_ULL((u64)parent_rate, rate) - 1;
 
 	return regmap_update_bits(pll->clkr.regmap, pll_user_ctl(pll),
-				  PLL_POST_DIV_MASK << PLL_POST_DIV_SHIFT,
+				  (BIT(pll->width) - 1) << PLL_POST_DIV_SHIFT,
 				  div << PLL_POST_DIV_SHIFT);
 }
 
-- 
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] 13+ messages in thread

* [RFC v2 10/12] clk: qcom: add read-only alpha pll post divider operations
  2017-08-08 18:24 [RFC v2 00/12] Misc patches for QCOM clocks Abhishek Sahu
                   ` (8 preceding siblings ...)
  2017-08-08 18:24 ` [RFC v2 09/12] clk: qcom: support for 2 bit PLL post divider Abhishek Sahu
@ 2017-08-08 18:24 ` Abhishek Sahu
  2017-08-08 18:24 ` [RFC v2 11/12] clk: qcom: add read-only " Abhishek Sahu
  2017-08-08 18:24 ` [RFC v2 12/12] clk: qcom: add parent map for regmap mux Abhishek Sahu
  11 siblings, 0 replies; 13+ messages in thread
From: Abhishek Sahu @ 2017-08-08 18:24 UTC (permalink / raw)
  To: sboyd, mturquette
  Cc: andy.gross, david.brown, rnayak, linux-arm-msm, linux-soc,
	linux-clk, linux-kernel, Abhishek Sahu

Some of the divider settings are preconfigured and should not
be changed by the clock framework during frequency change. This
patch adds the read-only divider operation for QCOM alpha pll
post divider which is equivalent to generic divider operations in
'commit 79c6ab509558 ("clk: divider: add CLK_DIVIDER_READ_ONLY flag")'.

Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---
 drivers/clk/qcom/clk-alpha-pll.c | 25 +++++++++++++++++++++++++
 drivers/clk/qcom/clk-alpha-pll.h |  1 +
 2 files changed, 26 insertions(+)

diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 4725f80..69d069f 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -774,6 +774,25 @@ static long clk_alpha_huayra_pll_round_rate(struct clk_hw *hw,
 				  pll->width, CLK_DIVIDER_POWER_OF_TWO);
 }
 
+static long
+clk_alpha_pll_postdiv_round_ro_rate(struct clk_hw *hw, unsigned long rate,
+				    unsigned long *prate)
+{
+	struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
+	u32 ctl, div;
+
+	regmap_read(pll->clkr.regmap, pll_user_ctl(pll), &ctl);
+
+	ctl >>= PLL_POST_DIV_SHIFT;
+	ctl &= BIT(pll->width) - 1;
+	div = 1 << fls(ctl);
+
+	if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)
+		*prate = clk_hw_round_rate(clk_hw_get_parent(hw), div * rate);
+
+	return DIV_ROUND_UP_ULL((u64)*prate, div);
+}
+
 static int clk_alpha_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,
 					  unsigned long parent_rate)
 {
@@ -794,3 +813,9 @@ static int clk_alpha_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,
 	.set_rate = clk_alpha_pll_postdiv_set_rate,
 };
 EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_ops);
+
+const struct clk_ops clk_alpha_pll_postdiv_ro_ops = {
+	.round_rate = clk_alpha_pll_postdiv_round_ro_rate,
+	.recalc_rate = clk_alpha_pll_postdiv_recalc_rate,
+};
+EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_ro_ops);
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
index 8a0dab6..2b96beb 100644
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -109,6 +109,7 @@ struct alpha_pll_config {
 extern const struct clk_ops clk_alpha_pll_hwfsm_ops;
 extern const struct clk_ops clk_alpha_huayra_pll_ops;
 extern const struct clk_ops clk_alpha_pll_postdiv_ops;
+extern const struct clk_ops clk_alpha_pll_postdiv_ro_ops;
 
 void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
 			     const struct alpha_pll_config *config);
-- 
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] 13+ messages in thread

* [RFC v2 11/12] clk: qcom: add read-only divider operations
  2017-08-08 18:24 [RFC v2 00/12] Misc patches for QCOM clocks Abhishek Sahu
                   ` (9 preceding siblings ...)
  2017-08-08 18:24 ` [RFC v2 10/12] clk: qcom: add read-only alpha pll post divider operations Abhishek Sahu
@ 2017-08-08 18:24 ` Abhishek Sahu
  2017-08-08 18:24 ` [RFC v2 12/12] clk: qcom: add parent map for regmap mux Abhishek Sahu
  11 siblings, 0 replies; 13+ messages in thread
From: Abhishek Sahu @ 2017-08-08 18:24 UTC (permalink / raw)
  To: sboyd, mturquette
  Cc: andy.gross, david.brown, rnayak, linux-arm-msm, linux-soc,
	linux-clk, linux-kernel, Abhishek Sahu

Some of the divider settings are preconfigured and should not
be changed by the clock framework during frequency change. This
patch adds the read-only divider operation for QCOM dividers
which is equivalent to generic divider operations in
'commit 79c6ab509558 ("clk: divider: add CLK_DIVIDER_READ_ONLY flag")'.

Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---
 drivers/clk/qcom/clk-regmap-divider.c | 29 +++++++++++++++++++++++++++++
 drivers/clk/qcom/clk-regmap-divider.h |  1 +
 2 files changed, 30 insertions(+)

diff --git a/drivers/clk/qcom/clk-regmap-divider.c b/drivers/clk/qcom/clk-regmap-divider.c
index 5348491..6cf9005 100644
--- a/drivers/clk/qcom/clk-regmap-divider.c
+++ b/drivers/clk/qcom/clk-regmap-divider.c
@@ -23,6 +23,29 @@ static inline struct clk_regmap_div *to_clk_regmap_div(struct clk_hw *hw)
 	return container_of(to_clk_regmap(hw), struct clk_regmap_div, clkr);
 }
 
+static long div_round_ro_rate(struct clk_hw *hw, unsigned long rate,
+			      unsigned long *prate)
+{
+	struct clk_regmap_div *divider = to_clk_regmap_div(hw);
+	struct clk_regmap *clkr = &divider->clkr;
+	u32 div;
+	struct clk_hw *hw_parent = clk_hw_get_parent(hw);
+
+	regmap_read(clkr->regmap, divider->reg, &div);
+	div >>= divider->shift;
+	div &= BIT(divider->width) - 1;
+	div += 1;
+
+	if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) {
+		if (!hw_parent)
+			return -EINVAL;
+
+		*prate = clk_hw_round_rate(hw_parent, rate * div);
+	}
+
+	return DIV_ROUND_UP_ULL((u64)*prate, div);
+}
+
 static long div_round_rate(struct clk_hw *hw, unsigned long rate,
 			   unsigned long *prate)
 {
@@ -68,3 +91,9 @@ static unsigned long div_recalc_rate(struct clk_hw *hw,
 	.recalc_rate = div_recalc_rate,
 };
 EXPORT_SYMBOL_GPL(clk_regmap_div_ops);
+
+const struct clk_ops clk_regmap_div_ro_ops = {
+	.round_rate = div_round_ro_rate,
+	.recalc_rate = div_recalc_rate,
+};
+EXPORT_SYMBOL_GPL(clk_regmap_div_ro_ops);
diff --git a/drivers/clk/qcom/clk-regmap-divider.h b/drivers/clk/qcom/clk-regmap-divider.h
index fc4492e..8c39c27 100644
--- a/drivers/clk/qcom/clk-regmap-divider.h
+++ b/drivers/clk/qcom/clk-regmap-divider.h
@@ -25,5 +25,6 @@ struct clk_regmap_div {
 };
 
 extern const struct clk_ops clk_regmap_div_ops;
+extern const struct clk_ops clk_regmap_div_ro_ops;
 
 #endif
-- 
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] 13+ messages in thread

* [RFC v2 12/12] clk: qcom: add parent map for regmap mux
  2017-08-08 18:24 [RFC v2 00/12] Misc patches for QCOM clocks Abhishek Sahu
                   ` (10 preceding siblings ...)
  2017-08-08 18:24 ` [RFC v2 11/12] clk: qcom: add read-only " Abhishek Sahu
@ 2017-08-08 18:24 ` Abhishek Sahu
  11 siblings, 0 replies; 13+ messages in thread
From: Abhishek Sahu @ 2017-08-08 18:24 UTC (permalink / raw)
  To: sboyd, mturquette
  Cc: andy.gross, david.brown, rnayak, linux-arm-msm, linux-soc,
	linux-clk, linux-kernel, Abhishek Sahu

Currently the driver assumes the register configuration value
is identical to its index in the parent map. This patch adds
the parent map field in regmap mux clock node which contains
the mapping of parent index with actual register configuration
value. If regmap node contains this parent map then the
configuration value will be taken from this
parent map instead of simply writing the index value.

Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---
 drivers/clk/qcom/clk-rcg.h        | 10 ----------
 drivers/clk/qcom/clk-regmap-mux.c |  6 ++++++
 drivers/clk/qcom/clk-regmap-mux.h |  2 ++
 drivers/clk/qcom/common.h         | 11 ++++++++++-
 4 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h
index 1b3e8d2..ee66857 100644
--- a/drivers/clk/qcom/clk-rcg.h
+++ b/drivers/clk/qcom/clk-rcg.h
@@ -26,16 +26,6 @@ struct freq_tbl {
 };
 
 /**
- * struct parent_map - map table for PLL source select configuration values
- * @src: source PLL
- * @cfg: configuration value
- */
-struct parent_map {
-	u8 src;
-	u8 cfg;
-};
-
-/**
  * struct mn - M/N:D counter
  * @mnctr_en_bit: bit to enable mn counter
  * @mnctr_reset_bit: bit to assert mn counter reset
diff --git a/drivers/clk/qcom/clk-regmap-mux.c b/drivers/clk/qcom/clk-regmap-mux.c
index cae3071..0f3a1bd 100644
--- a/drivers/clk/qcom/clk-regmap-mux.c
+++ b/drivers/clk/qcom/clk-regmap-mux.c
@@ -35,6 +35,9 @@ static u8 mux_get_parent(struct clk_hw *hw)
 	val >>= mux->shift;
 	val &= mask;
 
+	if (mux->parent_map)
+		return qcom_find_src_index(hw, mux->parent_map, val);
+
 	return val;
 }
 
@@ -45,6 +48,9 @@ static int mux_set_parent(struct clk_hw *hw, u8 index)
 	unsigned int mask = GENMASK(mux->width + mux->shift - 1, mux->shift);
 	unsigned int val;
 
+	if (mux->parent_map)
+		index = mux->parent_map[index].cfg;
+
 	val = index;
 	val <<= mux->shift;
 
diff --git a/drivers/clk/qcom/clk-regmap-mux.h b/drivers/clk/qcom/clk-regmap-mux.h
index 5cec761..7797cdd 100644
--- a/drivers/clk/qcom/clk-regmap-mux.h
+++ b/drivers/clk/qcom/clk-regmap-mux.h
@@ -16,11 +16,13 @@
 
 #include <linux/clk-provider.h>
 #include "clk-regmap.h"
+#include "common.h"
 
 struct clk_regmap_mux {
 	u32			reg;
 	u32			shift;
 	u32			width;
+	const struct parent_map	*parent_map;
 	struct clk_regmap	clkr;
 };
 
diff --git a/drivers/clk/qcom/common.h b/drivers/clk/qcom/common.h
index 23c1927..00196ee 100644
--- a/drivers/clk/qcom/common.h
+++ b/drivers/clk/qcom/common.h
@@ -20,7 +20,6 @@
 struct regmap;
 struct freq_tbl;
 struct clk_hw;
-struct parent_map;
 
 #define PLL_LOCK_COUNT_SHIFT	8
 #define PLL_LOCK_COUNT_MASK	0x3f
@@ -39,6 +38,16 @@ struct qcom_cc_desc {
 	size_t num_gdscs;
 };
 
+/**
+ * struct parent_map - map table for source select configuration values
+ * @src: source
+ * @cfg: configuration value
+ */
+struct parent_map {
+	u8 src;
+	u8 cfg;
+};
+
 extern const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f,
 					     unsigned long rate);
 extern const struct freq_tbl *qcom_find_freq_floor(const struct freq_tbl *f,
-- 
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] 13+ messages in thread

end of thread, other threads:[~2017-08-08 18:24 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-08-08 18:24 [RFC v2 00/12] Misc patches for QCOM clocks Abhishek Sahu
2017-08-08 18:24 ` [RFC v2 01/12] clk: qcom: flag for 64 bit CONFIG_CTL Abhishek Sahu
2017-08-08 18:24 ` [RFC v2 02/12] clk: qcom: support for alpha mode configuration Abhishek Sahu
2017-08-08 18:24 ` [RFC v2 03/12] clk: qcom: use offset from alpha pll node Abhishek Sahu
2017-08-08 18:24 ` [RFC v2 04/12] clk: qcom: fix 16 bit alpha support calculation Abhishek Sahu
2017-08-08 18:24 ` [RFC v2 05/12] clk: qcom: support for dynamic updating the PLL Abhishek Sahu
2017-08-08 18:24 ` [RFC v2 06/12] clk: qcom: add flag for VCO operation Abhishek Sahu
2017-08-08 18:24 ` [RFC v2 07/12] clk: qcom: support for Huayra PLL Abhishek Sahu
2017-08-08 18:24 ` [RFC v2 08/12] clk: qcom: support for Brammo PLL Abhishek Sahu
2017-08-08 18:24 ` [RFC v2 09/12] clk: qcom: support for 2 bit PLL post divider Abhishek Sahu
2017-08-08 18:24 ` [RFC v2 10/12] clk: qcom: add read-only alpha pll post divider operations Abhishek Sahu
2017-08-08 18:24 ` [RFC v2 11/12] clk: qcom: add read-only " Abhishek Sahu
2017-08-08 18:24 ` [RFC v2 12/12] clk: qcom: add parent map for regmap mux Abhishek Sahu

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).