Skip to contentSkip to conversation

Updates for QCOM Alpha PLL

PATCH Applied Abhishek Sahu 2 participants 31 messages Sep 28, 2017 – Dec 14, 2017

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover Updates for QCOM Alpha PLL

This patch series does the miscellaneous changes in QCOM Alpha PLL operation and structure to support other types of Alpha PLL’s.

1. It adds the pll_type which will be used for determining all the properties of Alpha PLL.
2. It adds the support for Brammo and Huayra PLL’s for which the support is not available in existing alpha PLL code.
3. There won’t be any change in existing users of Alpha PLL’s since all the newly added code will be under flag for the default PLL operations.

The previous RFC series can be found for this in
https://www.spinics.net/lists/linux-clk/msg19305.html

Abhishek Sahu (13):
clk: qcom: remove redundant PLL_MODE macro offset
clk: qcom: minor code reorganization related with offset variable
clk: qcom: support for alpha pll properties
clk: qcom: fix 16 bit alpha support calculation
clk: qcom: add and use alpha register width from PLL properties
clk: qcom: flag for 64 bit CONFIG_CTL
clk: qcom: support for alpha mode configuration
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

 drivers/clk/qcom/clk-alpha-pll.c | 701 +++++++++++++++++++++++++++++++++------
 drivers/clk/qcom/clk-alpha-pll.h |  19 +-
 2 files changed, 609 insertions(+), 111 deletions(-)
Signature · 1 line
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
#1 lore raw

PATCH 1/13 clk: qcom: remove redundant PLL_MODE macro offset

The PLL_MODE offset macro is redundant which is defined as zero. The offset in PLL structure is the address of PLL_MODE register itself so the PLL_MODE can be removed. It will help in subsequent patches to support different PLL offset registers to reduce the code diff.

---
 drivers/clk/qcom/clk-alpha-pll.c | 33 ++++++++++++++++-----------------
 1 file changed, 16 insertions(+), 17 deletions(-)
drivers/clk/qcom/clk-alpha-pll.c +16 -17
index 47a1da3..b9be822 100644
@@ -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)
@@ -77,12 +76,12 @@ static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse,
 	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, off, &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, off, &val);
 		if (ret)
 			return ret;
 		if (inverse && !(val & mask))
@@ -139,7 +138,7 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
 	regmap_update_bits(regmap, off + PLL_USER_CTL, 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, off, 6, 0);
 }
 
 static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
@@ -149,7 +148,7 @@ static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
 	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, off, &val);
 	if (ret)
 		return ret;
 
@@ -158,7 +157,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, off, val);
 	if (ret)
 		return ret;
 
@@ -175,12 +174,12 @@ static void clk_alpha_pll_hwfsm_disable(struct clk_hw *hw)
 	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, off, &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, off,
 					 PLL_OFFLINE_REQ, PLL_OFFLINE_REQ);
 		if (ret)
 			return;
@@ -191,7 +190,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, off,
 				 PLL_FSM_ENA, 0);
 	if (ret)
 		return;
@@ -206,7 +205,7 @@ static int pll_is_enabled(struct clk_hw *hw, u32 mask)
 	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, off, &val);
 	if (ret)
 		return ret;
 
@@ -232,7 +231,7 @@ static int clk_alpha_pll_enable(struct clk_hw *hw)
 	off = pll->offset;
 
 	mask = PLL_OUTCTRL | PLL_RESET_N | PLL_BYPASSNL;
-	ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
+	ret = regmap_read(pll->clkr.regmap, off, &val);
 	if (ret)
 		return ret;
 
@@ -248,7 +247,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, off,
 				 PLL_BYPASSNL, PLL_BYPASSNL);
 	if (ret)
 		return ret;
@@ -260,7 +259,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, off,
 				 PLL_RESET_N, PLL_RESET_N);
 	if (ret)
 		return ret;
@@ -269,7 +268,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, off,
 				 PLL_OUTCTRL, PLL_OUTCTRL);
 
 	/* Ensure that the write above goes through before returning. */
@@ -285,7 +284,7 @@ static void clk_alpha_pll_disable(struct clk_hw *hw)
 
 	off = pll->offset;
 
-	ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
+	ret = regmap_read(pll->clkr.regmap, off, &val);
 	if (ret)
 		return;
 
@@ -296,14 +295,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, off, 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, off, mask, 0);
 }
 
 static unsigned long alpha_pll_calc_rate(u64 prate, u32 l, u32 a)
Signature · 1 line
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
#2 lore raw

PATCH 2/13 clk: qcom: minor code reorganization related with offset variable

In reply to Abhishek Sahu

This patch does minor code reorganization related with offset variable assignment. The offset variable can be directly defined which will help in subsequent patches to support different PLL offset registers.

---
 drivers/clk/qcom/clk-alpha-pll.c | 26 +++++++++-----------------
 1 file changed, 9 insertions(+), 17 deletions(-)
drivers/clk/qcom/clk-alpha-pll.c +9 -17
index b9be822..ab2f23c 100644
@@ -70,12 +70,11 @@
 static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse,
 			const char *action)
 {
-	u32 val, off;
+	u32 val, off = pll->offset;
 	int count;
 	int ret;
 	const char *name = clk_hw_get_name(&pll->clkr.hw);
 
-	off = pll->offset;
 	ret = regmap_read(pll->clkr.regmap, off, &val);
 	if (ret)
 		return ret;
@@ -143,11 +142,10 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
 
 static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
 {
-	int ret;
-	u32 val, off;
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+	int ret;
+	u32 val, off = pll->offset;
 
-	off = pll->offset;
 	ret = regmap_read(pll->clkr.regmap, off, &val);
 	if (ret)
 		return ret;
@@ -169,11 +167,10 @@ 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;
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+	int ret;
+	u32 val, off = pll->offset;
 
-	off = pll->offset;
 	ret = regmap_read(pll->clkr.regmap, off, &val);
 	if (ret)
 		return;
@@ -200,11 +197,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;
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+	int ret;
+	u32 val, off = pll->offset;
 
-	off = pll->offset;
 	ret = regmap_read(pll->clkr.regmap, off, &val);
 	if (ret)
 		return ret;
@@ -226,9 +222,7 @@ 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, off = pll->offset;
 
 	mask = PLL_OUTCTRL | PLL_RESET_N | PLL_BYPASSNL;
 	ret = regmap_read(pll->clkr.regmap, off, &val);
@@ -280,9 +274,7 @@ 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, off = pll->offset;
 
 	ret = regmap_read(pll->clkr.regmap, off, &val);
 	if (ret)
Signature · 1 line
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
#3 lore raw

PATCH 3/13 clk: qcom: support for alpha pll properties

In reply to Abhishek Sahu

Alpha PLL is a generic name used for QCOM PLL’s which uses L and Alpha values for configuring the integer and fractional part. QCOM SoC’s use different types of Alpha PLL’s for which basic software configuration part is common with following differences.

1. All 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.
2. PLL dynamic programming sequence will be different in some of the Alpha PLL’s
3. Some of the PLL won’t have 64 bit config control, 64 bit user control, VCO configuration etc.

Now, this patch adds the Alpha PLL type in clock node and adds alpha PLL properties structure inside clk-alpha-pll.c. This PLL property will contain everything including register offsets, clock operations and other properties since all these properties will be fixed for Alpha PLL.

This allows to support other types of Alpha PLL without addition of new flag and variable in structures of clk_alpha_pll.h. Also, we don’t have to add operation for each Alpha PLL’s and export them.

In future, we can get rid of most of the flags like following

    struct clk_alpha_pll {
            #define SUPPORTS_OFFLINE_REQ    BIT(0)
            #define SUPPORTS_16BIT_ALPHA    BIT(1)
            #define SUPPORTS_FSM_MODE       BIT(2)
            u8 flags;
    };

    struct clk_alpha_pll_postdiv {
            u8 width;
    };

Since all the above properties will be always same for different instances of same type of Alpha PLL’s.

---
 drivers/clk/qcom/clk-alpha-pll.c | 231 ++++++++++++++++++++++++++++++++-------
 drivers/clk/qcom/clk-alpha-pll.h |  10 ++
 2 files changed, 200 insertions(+), 41 deletions(-)
drivers/clk/qcom/clk-alpha-pll.c +190 -41
index ab2f23c..d5bfc52 100644
@@ -35,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.
  */
@@ -61,12 +48,90 @@
 #define ALPHA_BITWIDTH		32
 #define ALPHA_16BIT_MASK	0xffff
 
+/* Returns the alpha_pll_clk_ops for pll type */
+#define pll_clk_ops(hw)		(alpha_pll_props[to_clk_alpha_pll(hw)->	   \
+				 pll_type].ops)
+
+/* Returns the actual register offset for the reg crossponding to pll type */
+#define pll_reg(type, reg)	alpha_pll_props[type].reg_offsets[reg]
+
+/* Helpers to return the actual register offset */
+#define pll_l(type)		pll_reg(type, PLL_L_VAL)
+#define pll_alpha(type)		pll_reg(type, PLL_ALPHA_VAL)
+#define pll_alpha_u(type)	pll_reg(type, PLL_ALPHA_VAL_U)
+#define pll_user_ctl(type)	pll_reg(type, PLL_USER_CTL)
+#define pll_user_ctl_u(type)	pll_reg(type, PLL_USER_CTL_U)
+#define pll_cfg_ctl(type)	pll_reg(type, PLL_CONFIG_CTL)
+#define pll_test_ctl(type)	pll_reg(type, PLL_TEST_CTL)
+#define pll_test_ctl_u(type)	pll_reg(type, PLL_TEST_CTL_U)
+#define pll_status(type)	pll_reg(type, PLL_STATUS)
+#define pll_cfg_ctl_u(type)	pll_reg(type, 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)
 
+/**
+ * Contains the index which will be used for mapping with actual
+ * register offset in Alpha PLL
+ */
+enum {
+	PLL_L_VAL,
+	PLL_ALPHA_VAL,
+	PLL_ALPHA_VAL_U,
+	PLL_USER_CTL,
+	PLL_USER_CTL_U,
+	PLL_CONFIG_CTL,
+	PLL_CONFIG_CTL_U,
+	PLL_TEST_CTL,
+	PLL_TEST_CTL_U,
+	PLL_STATUS,
+	PLL_MAX_REGS,
+};
+
+/**
+ * struct alpha_pll_clk_ops - operations for alpha PLL
+ * @enable: enable function when HW voting FSM is disabled
+ * @disable: disable function when HW voting FSM is disabled
+ * @is_enabled: check whether PLL is enabled when HW voting FSM is disabled
+ * @hwfsm_enable: check whether PLL is enabled when HW voting FSM is enabled
+ * @hwfsm_disable: check whether PLL is disabled when HW voting FSM is enabled
+ * @hwfsm_is_enabled: check whether PLL is enabled when HW voting FSM is enabled
+ * @recalc_rate: recalculate the rate of PLL by reading mode, L and Alpha Value
+ * @round_rate: returns the closest supported rate of PLL
+ * @set_rate: change the rate of this clock by actually programming the mode, L
+ *	      and Alpha Value registers
+ */
+struct alpha_pll_clk_ops {
+	int		(*enable)(struct clk_hw *hw);
+	void		(*disable)(struct clk_hw *hw);
+	int		(*is_enabled)(struct clk_hw *hw);
+	int		(*hwfsm_enable)(struct clk_hw *hw);
+	void		(*hwfsm_disable)(struct clk_hw *hw);
+	int		(*hwfsm_is_enabled)(struct clk_hw *hw);
+	unsigned long	(*recalc_rate)(struct clk_hw *hw,
+				       unsigned long parent_rate);
+	long		(*round_rate)(struct clk_hw *hw, unsigned long rate,
+				      unsigned long *parent_rate);
+	int		(*set_rate)(struct clk_hw *hw, unsigned long rate,
+				    unsigned long parent_rate);
+};
+
+/**
+ * struct alpha_pll_props - contains the various properties which
+ *			    will be fixed for PLL type.
+ * @reg_offsets: register offsets mapping array
+ * @ops: clock operations for alpha PLL
+ */
+struct alpha_pll_props {
+	u8 reg_offsets[PLL_MAX_REGS];
+	struct alpha_pll_clk_ops ops;
+};
+
+static const struct alpha_pll_props alpha_pll_props[];
+
 static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse,
 			const char *action)
 {
@@ -112,11 +177,13 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
 {
 	u32 val, mask;
 	u32 off = pll->offset;
+	u8 type = pll->pll_type;
 
-	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);
+	regmap_write(regmap, off + pll_l(type), config->l);
+	regmap_write(regmap, off + pll_alpha(type), config->alpha);
+	regmap_write(regmap, off + pll_cfg_ctl(type), config->config_ctl_val);
+	regmap_write(regmap, off + pll_cfg_ctl_u(type),
+		     config->config_ctl_hi_val);
 
 	val = config->main_output_mask;
 	val |= config->aux_output_mask;
@@ -134,13 +201,13 @@ 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, off + pll_user_ctl(type), mask, val);
 
 	if (pll->flags & SUPPORTS_FSM_MODE)
 		qcom_pll_set_fsm_mode(regmap, off, 6, 0);
 }
 
-static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
+static int alpha_pll_default_hwfsm_enable(struct clk_hw *hw)
 {
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
 	int ret;
@@ -165,7 +232,7 @@ static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
 	return wait_for_pll_enable_active(pll);
 }
 
-static void clk_alpha_pll_hwfsm_disable(struct clk_hw *hw)
+static void alpha_pll_default_hwfsm_disable(struct clk_hw *hw)
 {
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
 	int ret;
@@ -208,17 +275,17 @@ static int pll_is_enabled(struct clk_hw *hw, u32 mask)
 	return !!(val & mask);
 }
 
-static int clk_alpha_pll_hwfsm_is_enabled(struct clk_hw *hw)
+static int alpha_pll_default_hwfsm_is_enabled(struct clk_hw *hw)
 {
 	return pll_is_enabled(hw, PLL_ACTIVE_FLAG);
 }
 
-static int clk_alpha_pll_is_enabled(struct clk_hw *hw)
+static int alpha_pll_default_is_enabled(struct clk_hw *hw)
 {
 	return pll_is_enabled(hw, PLL_LOCK_DET);
 }
 
-static int clk_alpha_pll_enable(struct clk_hw *hw)
+static int alpha_pll_default_enable(struct clk_hw *hw)
 {
 	int ret;
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
@@ -270,7 +337,7 @@ static int clk_alpha_pll_enable(struct clk_hw *hw)
 	return ret;
 }
 
-static void clk_alpha_pll_disable(struct clk_hw *hw)
+static void alpha_pll_default_disable(struct clk_hw *hw)
 {
 	int ret;
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
@@ -342,22 +409,23 @@ 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)
+alpha_pll_default_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 off = pll->offset;
+	u8 type = pll->pll_type;
 
-	regmap_read(pll->clkr.regmap, off + PLL_L_VAL, &l);
+	regmap_read(pll->clkr.regmap, off + pll_l(type), &l);
 
-	regmap_read(pll->clkr.regmap, off + PLL_USER_CTL, &ctl);
+	regmap_read(pll->clkr.regmap, off + pll_user_ctl(type), &ctl);
 	if (ctl & PLL_ALPHA_EN) {
-		regmap_read(pll->clkr.regmap, off + PLL_ALPHA_VAL, &low);
+		regmap_read(pll->clkr.regmap, off + pll_alpha(type), &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, off + pll_alpha_u(type),
 				    &high);
 			a = (u64)high << 32 | low;
 			a >>= ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH;
@@ -367,12 +435,13 @@ 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_default_set_rate(struct clk_hw *hw, unsigned long rate,
+				      unsigned long prate)
 {
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
 	const struct pll_vco *vco;
 	u32 l, off = pll->offset;
+	u8 type = pll->pll_type;
 	u64 a;
 
 	rate = alpha_pll_round_rate(rate, prate, &l, &a);
@@ -382,28 +451,29 @@ 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, off + pll_l(type), l);
 
 	if (pll->flags & SUPPORTS_16BIT_ALPHA) {
-		regmap_write(pll->clkr.regmap, off + PLL_ALPHA_VAL,
+		regmap_write(pll->clkr.regmap, off + pll_alpha(type),
 			     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, off + pll_alpha_u(type),
+			     a >> 32);
 	}
 
-	regmap_update_bits(pll->clkr.regmap, off + PLL_USER_CTL,
+	regmap_update_bits(pll->clkr.regmap, off + pll_user_ctl(type),
 			   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);
+	regmap_update_bits(pll->clkr.regmap, off + pll_user_ctl(type),
+			   PLL_ALPHA_EN, PLL_ALPHA_EN);
 
 	return 0;
 }
 
-static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
-				     unsigned long *prate)
+static long alpha_pll_default_round_rate(struct clk_hw *hw, unsigned long rate,
+					 unsigned long *prate)
 {
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
 	u32 l;
@@ -420,6 +490,54 @@ static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 	return clamp(rate, min_freq, max_freq);
 }
 
+static int clk_alpha_pll_enable(struct clk_hw *hw)
+{
+	return pll_clk_ops(hw).enable(hw);
+}
+
+static void clk_alpha_pll_disable(struct clk_hw *hw)
+{
+	pll_clk_ops(hw).disable(hw);
+}
+
+static int clk_alpha_pll_is_enabled(struct clk_hw *hw)
+{
+	return pll_clk_ops(hw).is_enabled(hw);
+}
+
+static unsigned long
+clk_alpha_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+	return pll_clk_ops(hw).recalc_rate(hw, parent_rate);
+}
+
+static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+				     unsigned long *prate)
+{
+	return pll_clk_ops(hw).round_rate(hw, rate, prate);
+}
+
+static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+				  unsigned long prate)
+{
+	return pll_clk_ops(hw).set_rate(hw, rate, prate);
+}
+
+static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
+{
+	return pll_clk_ops(hw).hwfsm_enable(hw);
+}
+
+static void clk_alpha_pll_hwfsm_disable(struct clk_hw *hw)
+{
+	pll_clk_ops(hw).hwfsm_disable(hw);
+}
+
+static int clk_alpha_pll_hwfsm_is_enabled(struct clk_hw *hw)
+{
+	return pll_clk_ops(hw).hwfsm_is_enabled(hw);
+}
+
 const struct clk_ops clk_alpha_pll_ops = {
 	.enable = clk_alpha_pll_enable,
 	.disable = clk_alpha_pll_disable,
@@ -446,7 +564,8 @@ 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->offset + pll_user_ctl(pll->pll_type),
+		    &ctl);
 
 	ctl >>= PLL_POST_DIV_SHIFT;
 	ctl &= PLL_POST_DIV_MASK;
@@ -482,7 +601,8 @@ 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->offset +
+				  pll_user_ctl(pll->pll_type),
 				  PLL_POST_DIV_MASK << PLL_POST_DIV_SHIFT,
 				  div << PLL_POST_DIV_SHIFT);
 }
@@ -493,3 +613,32 @@ 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);
+
+/* Contains actual property values for different PLL types */
+static const struct
+alpha_pll_props alpha_pll_props[CLK_ALPHA_PLL_TYPE_MAX] = {
+	[CLK_ALPHA_PLL_TYPE_DEFAULT] =  {
+		.reg_offsets = {
+			[PLL_L_VAL] = 0x04,
+			[PLL_ALPHA_VAL] = 0x08,
+			[PLL_ALPHA_VAL_U] = 0x0c,
+			[PLL_USER_CTL] = 0x10,
+			[PLL_USER_CTL_U] = 0x14,
+			[PLL_CONFIG_CTL] = 0x18,
+			[PLL_TEST_CTL] = 0x1c,
+			[PLL_TEST_CTL_U] = 0x20,
+			[PLL_STATUS] = 0x24,
+		},
+		.ops = {
+			.enable = alpha_pll_default_enable,
+			.disable = alpha_pll_default_disable,
+			.is_enabled = alpha_pll_default_is_enabled,
+			.hwfsm_enable = alpha_pll_default_hwfsm_enable,
+			.hwfsm_disable = alpha_pll_default_hwfsm_disable,
+			.hwfsm_is_enabled = alpha_pll_default_hwfsm_is_enabled,
+			.recalc_rate = alpha_pll_default_recalc_rate,
+			.round_rate = alpha_pll_default_round_rate,
+			.set_rate = alpha_pll_default_set_rate,
+		},
+	},
+};
drivers/clk/qcom/clk-alpha-pll.h +10 -0
index d6e1ee2..4c91fbc 100644
@@ -17,6 +17,12 @@
 #include <linux/clk-provider.h>
 #include "clk-regmap.h"
 
+/* Alpha PLL types */
+enum {
+	CLK_ALPHA_PLL_TYPE_DEFAULT,
+	CLK_ALPHA_PLL_TYPE_MAX,
+};
+
 struct pll_vco {
 	unsigned long min_freq;
 	unsigned long max_freq;
@@ -27,6 +33,7 @@ struct pll_vco {
  * struct clk_alpha_pll - phase locked loop (PLL)
  * @offset: base address of registers
  * @vco_table: array of VCO settings
+ * @pll_type: alpha pll type
  * @clkr: regmap clock handle
  */
 struct clk_alpha_pll {
@@ -38,6 +45,7 @@ struct clk_alpha_pll {
 #define SUPPORTS_16BIT_ALPHA	BIT(1)
 #define SUPPORTS_FSM_MODE	BIT(2)
 	u8 flags;
+	u8 pll_type;
 
 	struct clk_regmap clkr;
 };
@@ -45,11 +53,13 @@ struct clk_alpha_pll {
 /**
  * struct clk_alpha_pll_postdiv - phase locked loop (PLL) post-divider
  * @offset: base address of registers
+ * @pll_type: alpha pll type
  * @width: width of post-divider
  * @clkr: regmap clock handle
  */
 struct clk_alpha_pll_postdiv {
 	u32 offset;
+	u8 pll_type;
 	u8 width;
 
 	struct clk_regmap clkr;
Signature · 1 line
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Applied
#4 lore raw

Re: [PATCH 03/13] clk: qcom: support for alpha pll properties

Quoted 36 lines · Abhishek Sahu

Alpha PLL is a generic name used for QCOM PLL’s which uses L and Alpha values for configuring the integer and fractional part. QCOM SoC’s use different types of Alpha PLL’s for which basic software configuration part is common with following differences.

1. All 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.
2. PLL dynamic programming sequence will be different in some of the Alpha PLL’s
3. Some of the PLL won’t have 64 bit config control, 64 bit user control, VCO configuration etc.

Now, this patch adds the Alpha PLL type in clock node and adds alpha PLL properties structure inside clk-alpha-pll.c. This PLL property will contain everything including register offsets, clock operations and other properties since all these properties will be fixed for Alpha PLL.

This allows to support other types of Alpha PLL without addition of new flag and variable in structures of clk_alpha_pll.h. Also, we don’t have to add operation for each Alpha PLL’s and export them.

In future, we can get rid of most of the flags like following

    struct clk_alpha_pll {
            #define SUPPORTS_OFFLINE_REQ    BIT(0)
            #define SUPPORTS_16BIT_ALPHA    BIT(1)
            #define SUPPORTS_FSM_MODE       BIT(2)
            u8 flags;
    };

    struct clk_alpha_pll_postdiv {
            u8 width;
    };
Quoted 5 lines

Since all the above properties will be always same for different instances of same type of Alpha PLL’s.

---

Applied to clk-next

Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
#5 lore raw

PATCH 4/13 clk: qcom: fix 16 bit alpha support calculation

In reply to 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.

---
 drivers/clk/qcom/clk-alpha-pll.c | 55 ++++++++++++++++++++++++----------------
 1 file changed, 33 insertions(+), 22 deletions(-)
drivers/clk/qcom/clk-alpha-pll.c +33 -22
index d5bfc52..a12f7b4 100644
@@ -45,8 +45,12 @@
  * 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
+
+/* Returns the Alpha register width for pll */
+#define pll_alpha_width(pll)	(pll->flags & SUPPORTS_16BIT_ALPHA ?	\
+				 ALPHA_REG_16BIT_WIDTH : ALPHA_REG_BITWIDTH)
 
 /* Returns the alpha_pll_clk_ops for pll type */
 #define pll_clk_ops(hw)		(alpha_pll_props[to_clk_alpha_pll(hw)->	   \
@@ -364,13 +368,16 @@ static void alpha_pll_default_disable(struct clk_hw *hw)
 	regmap_update_bits(pll->clkr.regmap, off, 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;
@@ -385,14 +392,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 *
@@ -414,7 +423,7 @@ 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;
+	u32 off = pll->offset, alpha_width = pll_alpha_width(pll);
 	u8 type = pll->pll_type;
 
 	regmap_read(pll->clkr.regmap, off + pll_l(type), &l);
@@ -422,17 +431,19 @@ static unsigned long alpha_pll_calc_rate(u64 prate, u32 l, u32 a)
 	regmap_read(pll->clkr.regmap, off + pll_user_ctl(type), &ctl);
 	if (ctl & PLL_ALPHA_EN) {
 		regmap_read(pll->clkr.regmap, off + pll_alpha(type), &low);
-		if (pll->flags & SUPPORTS_16BIT_ALPHA) {
-			a = low & ALPHA_16BIT_MASK;
-		} else {
+		if (alpha_width > 32) {
 			regmap_read(pll->clkr.regmap, off + pll_alpha_u(type),
 				    &high);
 			a = (u64)high << 32 | low;
-			a >>= ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH;
+		} else {
+			a = low & GENMASK(alpha_width - 1, 0);
 		}
+
+		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 alpha_pll_default_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -440,11 +451,11 @@ static int alpha_pll_default_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, off = pll->offset, alpha_width = pll_alpha_width(pll);
 	u8 type = pll->pll_type;
 	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");
@@ -453,14 +464,14 @@ static int alpha_pll_default_set_rate(struct clk_hw *hw, unsigned long rate,
 
 	regmap_write(pll->clkr.regmap, off + pll_l(type), l);
 
-	if (pll->flags & SUPPORTS_16BIT_ALPHA) {
-		regmap_write(pll->clkr.regmap, off + pll_alpha(type),
-			     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, off + pll_alpha_u(type),
 			     a >> 32);
-	}
+
+	regmap_write(pll->clkr.regmap, off + pll_alpha(type), a);
 
 	regmap_update_bits(pll->clkr.regmap, off + pll_user_ctl(type),
 			   PLL_VCO_MASK << PLL_VCO_SHIFT,
@@ -476,11 +487,11 @@ static long alpha_pll_default_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;
 
Signature · 1 line
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Applied
#6 lore raw

Re: [PATCH 04/13] clk: qcom: fix 16 bit alpha support calculation

Quoted 13 lines · 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

Quoted 6 lines

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.

---

Applied to clk-next

Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
#7 lore raw

PATCH 5/13 clk: qcom: add and use alpha register width from PLL properties

In reply to Abhishek Sahu

Currently SUPPORTS_16BIT_ALPHA flag determines the PLL alpha register width. If this flag is set then the alpha register width is 16 bits otherwise it is 40 bits. The alpha width is always fixed for PLL type so it can be added in PLL properties and clock driver don’t have to specify explicitly.

The SUPPORTS_16BIT_ALPHA flag is unused in the current code so it’s safe to remove this flags.

---
 drivers/clk/qcom/clk-alpha-pll.c | 16 ++++++++--------
 drivers/clk/qcom/clk-alpha-pll.h |  3 +--
 2 files changed, 9 insertions(+), 10 deletions(-)
drivers/clk/qcom/clk-alpha-pll.c +8 -8
index a12f7b4..78eb6bf 100644
@@ -44,13 +44,10 @@
 /*
  * 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
 
-/* Returns the Alpha register width for pll */
-#define pll_alpha_width(pll)	(pll->flags & SUPPORTS_16BIT_ALPHA ?	\
-				 ALPHA_REG_16BIT_WIDTH : ALPHA_REG_BITWIDTH)
+/* Returns the Alpha register width for pll type */
+#define pll_alpha_width(type)	(alpha_pll_props[type].alpha_width)
 
 /* Returns the alpha_pll_clk_ops for pll type */
 #define pll_clk_ops(hw)		(alpha_pll_props[to_clk_alpha_pll(hw)->	   \
@@ -127,10 +124,12 @@ struct alpha_pll_clk_ops {
  * struct alpha_pll_props - contains the various properties which
  *			    will be fixed for PLL type.
  * @reg_offsets: register offsets mapping array
+ * @alpha_width: alpha value width
  * @ops: clock operations for alpha PLL
  */
 struct alpha_pll_props {
 	u8 reg_offsets[PLL_MAX_REGS];
+	u8 alpha_width;
 	struct alpha_pll_clk_ops ops;
 };
 
@@ -423,8 +422,8 @@ static void alpha_pll_default_disable(struct clk_hw *hw)
 	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, alpha_width = pll_alpha_width(pll);
 	u8 type = pll->pll_type;
+	u32 off = pll->offset, alpha_width = pll_alpha_width(type);
 
 	regmap_read(pll->clkr.regmap, off + pll_l(type), &l);
 
@@ -451,8 +450,8 @@ static int alpha_pll_default_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, alpha_width = pll_alpha_width(pll);
 	u8 type = pll->pll_type;
+	u32 l, off = pll->offset, alpha_width = pll_alpha_width(type);
 	u64 a;
 
 	rate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);
@@ -487,7 +486,7 @@ static long alpha_pll_default_round_rate(struct clk_hw *hw, unsigned long rate,
 					 unsigned long *prate)
 {
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
-	u32 l, alpha_width = pll_alpha_width(pll);
+	u32 l, alpha_width = pll_alpha_width(pll->pll_type);
 	u64 a;
 	unsigned long min_freq, max_freq;
 
@@ -640,6 +639,7 @@ static int clk_alpha_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,
 			[PLL_TEST_CTL_U] = 0x20,
 			[PLL_STATUS] = 0x24,
 		},
+		.alpha_width = 40,
 		.ops = {
 			.enable = alpha_pll_default_enable,
 			.disable = alpha_pll_default_disable,
drivers/clk/qcom/clk-alpha-pll.h +1 -2
index 4c91fbc..b9caefc 100644
@@ -42,8 +42,7 @@ 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_FSM_MODE	BIT(1)
 	u8 flags;
 	u8 pll_type;
 
Signature · 1 line
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Applied
#8 lore raw

Re: [PATCH 05/13] clk: qcom: add and use alpha register width from PLL properties

Quoted 11 lines · Abhishek Sahu

Currently SUPPORTS_16BIT_ALPHA flag determines the PLL alpha register width. If this flag is set then the alpha register width is 16 bits otherwise it is 40 bits. The alpha width is always fixed for PLL type so it can be added in PLL properties and clock driver don’t have to specify explicitly.

The SUPPORTS_16BIT_ALPHA flag is unused in the current code so it’s safe to remove this flags.

---

Applied to clk-next

Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
#9 lore raw

PATCH 6/13 clk: qcom: flag for 64 bit CONFIG_CTL

In reply to Abhishek Sahu

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

---
 drivers/clk/qcom/clk-alpha-pll.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/clk/qcom/clk-alpha-pll.c +11 -1
index 78eb6bf..b33d120 100644
@@ -49,6 +49,9 @@
 /* Returns the Alpha register width for pll type */
 #define pll_alpha_width(type)	(alpha_pll_props[type].alpha_width)
 
+/* Returns the flags for pll type */
+#define pll_flags(type)		(alpha_pll_props[type].flags)
+
 /* Returns the alpha_pll_clk_ops for pll type */
 #define pll_clk_ops(hw)		(alpha_pll_props[to_clk_alpha_pll(hw)->	   \
 				 pll_type].ops)
@@ -130,6 +133,9 @@ struct alpha_pll_clk_ops {
 struct alpha_pll_props {
 	u8 reg_offsets[PLL_MAX_REGS];
 	u8 alpha_width;
+
+#define HAVE_64BIT_CONFIG_CTL	BIT(0)
+	u8 flags;
 	struct alpha_pll_clk_ops ops;
 };
 
@@ -180,7 +186,7 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
 {
 	u32 val, mask;
 	u32 off = pll->offset;
-	u8 type = pll->pll_type;
+	u8 type = pll->pll_type, flags = pll_flags(type);
 
 	regmap_write(regmap, off + pll_l(type), config->l);
 	regmap_write(regmap, off + pll_alpha(type), config->alpha);
@@ -188,6 +194,10 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
 	regmap_write(regmap, off + pll_cfg_ctl_u(type),
 		     config->config_ctl_hi_val);
 
+	if (flags & HAVE_64BIT_CONFIG_CTL)
+		regmap_write(regmap, off + pll_cfg_ctl_u(type),
+			     config->config_ctl_hi_val);
+
 	val = config->main_output_mask;
 	val |= config->aux_output_mask;
 	val |= config->aux2_output_mask;
Signature · 1 line
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Applied
#10 lore raw

Re: [PATCH 06/13] clk: qcom: flag for 64 bit CONFIG_CTL

Quoted 7 lines · Abhishek Sahu

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

---

Applied to clk-next

Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
#11 lore raw

PATCH 7/13 clk: qcom: support for alpha mode configuration

In reply to 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.

---
 drivers/clk/qcom/clk-alpha-pll.c | 6 ++++++
 drivers/clk/qcom/clk-alpha-pll.h | 3 +++
 2 files changed, 9 insertions(+)
drivers/clk/qcom/clk-alpha-pll.c +6 -0
index b33d120..07030d3 100644
@@ -198,6 +198,10 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
 		regmap_write(regmap, off + pll_cfg_ctl_u(type),
 			     config->config_ctl_hi_val);
 
+	if (pll_alpha_width(type) > 32)
+		regmap_write(regmap, off + pll_alpha_u(type),
+			     config->alpha_hi);
+
 	val = config->main_output_mask;
 	val |= config->aux_output_mask;
 	val |= config->aux2_output_mask;
@@ -205,6 +209,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;
drivers/clk/qcom/clk-alpha-pll.h +3 -0
index b9caefc..17aa27c 100644
@@ -67,12 +67,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;
Signature · 1 line
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Applied
#12 lore raw

Re: [PATCH 07/13] clk: qcom: support for alpha mode configuration

Quoted 8 lines · 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.

---

Applied to clk-next

Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
#13 lore raw

PATCH 8/13 clk: qcom: support for dynamic updating the PLL

In reply to Abhishek Sahu

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

---
 drivers/clk/qcom/clk-alpha-pll.c | 69 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 67 insertions(+), 2 deletions(-)
drivers/clk/qcom/clk-alpha-pll.c +67 -2
index 07030d3..6f2d165 100644
@@ -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)
 
@@ -134,7 +137,8 @@ struct alpha_pll_props {
 	u8 reg_offsets[PLL_MAX_REGS];
 	u8 alpha_width;
 
-#define HAVE_64BIT_CONFIG_CTL	BIT(0)
+#define HAVE_64BIT_CONFIG_CTL		BIT(0)
+#define SUPPORTS_DYNAMIC_UPDATE		BIT(1)
 	u8 flags;
 	struct alpha_pll_clk_ops ops;
 };
@@ -181,6 +185,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)
 {
@@ -461,6 +474,54 @@ static void alpha_pll_default_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)
+{
+	int ret;
+	u32 mode, off = pll->offset;
+
+	regmap_read(pll->clkr.regmap, off, &mode);
+
+	/* Latch the input to the PLL */
+	regmap_update_bits(pll->clkr.regmap, off, 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, off, 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 alpha_pll_default_set_rate(struct clk_hw *hw, unsigned long rate,
 				      unsigned long prate)
 {
@@ -495,7 +556,11 @@ static int alpha_pll_default_set_rate(struct clk_hw *hw, unsigned long rate,
 	regmap_update_bits(pll->clkr.regmap, off + pll_user_ctl(type),
 			   PLL_ALPHA_EN, PLL_ALPHA_EN);
 
-	return 0;
+	if (!clk_hw_is_enabled(hw) ||
+	    !(pll_flags(type) & SUPPORTS_DYNAMIC_UPDATE))
+		return 0;
+
+	return clk_alpha_pll_update_latch(pll);
 }
 
 static long alpha_pll_default_round_rate(struct clk_hw *hw, unsigned long rate,
Signature · 1 line
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Applied
#14 lore raw

Re: [PATCH 08/13] clk: qcom: support for dynamic updating the PLL

Quoted 13 lines · Abhishek Sahu

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

Quoted 4 lines

---

Applied to clk-next

Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
#15 lore raw

PATCH 9/13 clk: qcom: add flag for VCO operation

In reply to 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.

---
 drivers/clk/qcom/clk-alpha-pll.c | 29 +++++++++++++++++------------
 1 file changed, 17 insertions(+), 12 deletions(-)
drivers/clk/qcom/clk-alpha-pll.c +17 -12
index 6f2d165..bb35c60 100644
@@ -139,6 +139,7 @@ struct alpha_pll_props {
 
 #define HAVE_64BIT_CONFIG_CTL		BIT(0)
 #define SUPPORTS_DYNAMIC_UPDATE		BIT(1)
+#define SUPPORTS_VCO			BIT(2)
 	u8 flags;
 	struct alpha_pll_clk_ops ops;
 };
@@ -527,15 +528,17 @@ static int alpha_pll_default_set_rate(struct clk_hw *hw, unsigned long rate,
 {
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
 	const struct pll_vco *vco;
-	u8 type = pll->pll_type;
+	u8 type = pll->pll_type, flags = pll_flags(type);
 	u32 l, off = pll->offset, alpha_width = pll_alpha_width(type);
 	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 (flags & SUPPORTS_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, off + pll_l(type), l);
@@ -549,15 +552,15 @@ static int alpha_pll_default_set_rate(struct clk_hw *hw, unsigned long rate,
 
 	regmap_write(pll->clkr.regmap, off + pll_alpha(type), a);
 
-	regmap_update_bits(pll->clkr.regmap, off + pll_user_ctl(type),
-			   PLL_VCO_MASK << PLL_VCO_SHIFT,
-			   vco->val << PLL_VCO_SHIFT);
+	if (flags & SUPPORTS_VCO)
+		regmap_update_bits(pll->clkr.regmap, off + pll_user_ctl(type),
+				   PLL_VCO_MASK << PLL_VCO_SHIFT,
+				   vco->val << PLL_VCO_SHIFT);
 
 	regmap_update_bits(pll->clkr.regmap, off + pll_user_ctl(type),
 			   PLL_ALPHA_EN, PLL_ALPHA_EN);
 
-	if (!clk_hw_is_enabled(hw) ||
-	    !(pll_flags(type) & SUPPORTS_DYNAMIC_UPDATE))
+	if (!clk_hw_is_enabled(hw) || !(flags & SUPPORTS_DYNAMIC_UPDATE))
 		return 0;
 
 	return clk_alpha_pll_update_latch(pll);
@@ -567,12 +570,13 @@ static long alpha_pll_default_round_rate(struct clk_hw *hw, unsigned long rate,
 					 unsigned long *prate)
 {
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
-	u32 l, alpha_width = pll_alpha_width(pll->pll_type);
+	u8 type = pll->pll_type;
+	u32 l, alpha_width = pll_alpha_width(type);
 	u64 a;
 	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(type) & SUPPORTS_VCO) || alpha_pll_find_vco(pll, rate))
 		return rate;
 
 	min_freq = pll->vco_table[0].min_freq;
@@ -721,6 +725,7 @@ static int clk_alpha_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,
 			[PLL_STATUS] = 0x24,
 		},
 		.alpha_width = 40,
+		.flags = SUPPORTS_VCO,
 		.ops = {
 			.enable = alpha_pll_default_enable,
 			.disable = alpha_pll_default_disable,
Signature · 1 line
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Applied
#16 lore raw

Re: [PATCH 09/13] clk: qcom: add flag for VCO operation

Quoted 6 lines · 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.

---

Applied to clk-next

Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
#17 lore raw

PATCH 10/13 clk: qcom: support for Huayra PLL

In reply to 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.

---
 drivers/clk/qcom/clk-alpha-pll.c | 184 +++++++++++++++++++++++++++++++++++++++
 drivers/clk/qcom/clk-alpha-pll.h |   1 +
 2 files changed, 185 insertions(+)
drivers/clk/qcom/clk-alpha-pll.c +184 -0
index bb35c60..4844e63 100644
@@ -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.
  */
@@ -585,6 +593,157 @@ static long alpha_pll_default_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
+alpha_pll_huayra_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+	u64 rate = parent_rate, tmp;
+	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+	u8 type = pll->pll_type;
+	u32 l, alpha = 0, ctl, alpha_m, alpha_n, off = pll->offset;
+
+	regmap_read(pll->clkr.regmap, off + pll_l(type), &l);
+	regmap_read(pll->clkr.regmap, off + pll_user_ctl(type), &ctl);
+
+	if (ctl & PLL_ALPHA_EN) {
+		regmap_read(pll->clkr.regmap, off + pll_alpha(type), &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 alpha_pll_huayra_set_rate(struct clk_hw *hw, unsigned long rate,
+				     unsigned long prate)
+{
+	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+	u8 type = pll->pll_type;
+	u32 l, a, ctl, cur_alpha = 0, off = pll->offset;
+
+	rate = alpha_huayra_pll_round_rate(rate, prate, &l, &a);
+
+	regmap_read(pll->clkr.regmap, off + pll_user_ctl(type), &ctl);
+
+	if (ctl & PLL_ALPHA_EN)
+		regmap_read(pll->clkr.regmap, off + pll_alpha(type),
+			    &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, off + pll_l(type), 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, off + pll_l(type), l);
+	regmap_write(pll->clkr.regmap, off + pll_alpha(type), a);
+
+	if (a == 0)
+		regmap_update_bits(pll->clkr.regmap, off + pll_user_ctl(type),
+				   PLL_ALPHA_EN, 0x0);
+	else
+		regmap_update_bits(pll->clkr.regmap, off + pll_user_ctl(type),
+				   PLL_ALPHA_EN | PLL_ALPHA_MODE, PLL_ALPHA_EN);
+
+	return 0;
+}
+
+static long alpha_pll_huayra_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);
+}
+
 static int clk_alpha_pll_enable(struct clk_hw *hw)
 {
 	return pll_clk_ops(hw).enable(hw);
@@ -738,4 +897,29 @@ static int clk_alpha_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,
 			.set_rate = alpha_pll_default_set_rate,
 		},
 	},
+	[CLK_ALPHA_PLL_TYPE_HUAYRA] =  {
+		.reg_offsets = {
+			[PLL_L_VAL] = 0x04,
+			[PLL_ALPHA_VAL] = 0x08,
+			[PLL_USER_CTL] = 0x10,
+			[PLL_CONFIG_CTL] = 0x14,
+			[PLL_CONFIG_CTL_U] = 0x18,
+			[PLL_TEST_CTL] = 0x1c,
+			[PLL_TEST_CTL_U] = 0x20,
+			[PLL_STATUS] = 0x24,
+		},
+		.alpha_width = 16,
+		.flags = SUPPORTS_DYNAMIC_UPDATE | HAVE_64BIT_CONFIG_CTL,
+		.ops = {
+			.enable = alpha_pll_default_enable,
+			.disable = alpha_pll_default_disable,
+			.is_enabled = alpha_pll_default_is_enabled,
+			.hwfsm_enable = alpha_pll_default_hwfsm_enable,
+			.hwfsm_disable = alpha_pll_default_hwfsm_disable,
+			.hwfsm_is_enabled = alpha_pll_default_hwfsm_is_enabled,
+			.recalc_rate = alpha_pll_huayra_recalc_rate,
+			.round_rate = alpha_pll_huayra_round_rate,
+			.set_rate = alpha_pll_huayra_set_rate,
+		},
+	},
 };
drivers/clk/qcom/clk-alpha-pll.h +1 -0
index 17aa27c..fed783e 100644
@@ -20,6 +20,7 @@
 /* Alpha PLL types */
 enum {
 	CLK_ALPHA_PLL_TYPE_DEFAULT,
+	CLK_ALPHA_PLL_TYPE_HUAYRA,
 	CLK_ALPHA_PLL_TYPE_MAX,
 };
 
Signature · 1 line
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Applied
#18 lore raw

Re: [PATCH 10/13] clk: qcom: support for Huayra PLL

Quoted 8 lines · 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.

Quoted 6 lines

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.

---

Applied to clk-next

Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
#19 lore raw

PATCH 11/13 clk: qcom: support for Brammo PLL

In reply to 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

---
 drivers/clk/qcom/clk-alpha-pll.c | 24 ++++++++++++++++++++++++
 drivers/clk/qcom/clk-alpha-pll.h |  1 +
 2 files changed, 25 insertions(+)
drivers/clk/qcom/clk-alpha-pll.c +24 -0
index 4844e63..c682387 100644
@@ -922,4 +922,28 @@ static int clk_alpha_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,
 			.set_rate = alpha_pll_huayra_set_rate,
 		},
 	},
+	[CLK_ALPHA_PLL_TYPE_BRAMMO] =  {
+		.reg_offsets = {
+			[PLL_L_VAL] = 0x04,
+			[PLL_ALPHA_VAL] = 0x08,
+			[PLL_ALPHA_VAL_U] = 0x0c,
+			[PLL_USER_CTL] = 0x10,
+			[PLL_CONFIG_CTL] = 0x18,
+			[PLL_TEST_CTL] = 0x1c,
+			[PLL_STATUS] = 0x24,
+		},
+		.alpha_width = 40,
+		.flags = SUPPORTS_DYNAMIC_UPDATE,
+		.ops = {
+			.enable = alpha_pll_default_enable,
+			.disable = alpha_pll_default_disable,
+			.is_enabled = alpha_pll_default_is_enabled,
+			.hwfsm_enable = alpha_pll_default_hwfsm_enable,
+			.hwfsm_disable = alpha_pll_default_hwfsm_disable,
+			.hwfsm_is_enabled = alpha_pll_default_hwfsm_is_enabled,
+			.recalc_rate = alpha_pll_default_recalc_rate,
+			.round_rate = alpha_pll_default_round_rate,
+			.set_rate = alpha_pll_default_set_rate,
+		},
+	},
 };
drivers/clk/qcom/clk-alpha-pll.h +1 -0
index fed783e..dee71b4 100644
@@ -21,6 +21,7 @@
 enum {
 	CLK_ALPHA_PLL_TYPE_DEFAULT,
 	CLK_ALPHA_PLL_TYPE_HUAYRA,
+	CLK_ALPHA_PLL_TYPE_BRAMMO,
 	CLK_ALPHA_PLL_TYPE_MAX,
 };
 
Signature · 1 line
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Applied
#20 lore raw

Re: [PATCH 11/13] clk: qcom: support for Brammo PLL

Quoted 7 lines · 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

---

Applied to clk-next

Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
#21 lore raw

PATCH 12/13 clk: qcom: support for 2 bit PLL post divider

In reply to 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.

---
 drivers/clk/qcom/clk-alpha-pll.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)
drivers/clk/qcom/clk-alpha-pll.c +16 -4
index c682387..62b84fa 100644
@@ -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
@@ -822,7 +821,7 @@ static int clk_alpha_pll_hwfsm_is_enabled(struct clk_hw *hw)
 		    &ctl);
 
 	ctl >>= PLL_POST_DIV_SHIFT;
-	ctl &= PLL_POST_DIV_MASK;
+	ctl &= BIT(pll->width) - 1;
 
 	return parent_rate >> fls(ctl);
 }
@@ -836,13 +835,26 @@ static int clk_alpha_pll_hwfsm_is_enabled(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;
 
-	return divider_round_rate(hw, rate, prate, clk_alpha_div_table,
+	if (pll->width == 2)
+		table = clk_alpha_2bit_div_table;
+	else
+		table = clk_alpha_div_table;
+
+	return divider_round_rate(hw, rate, prate, table,
 				  pll->width, CLK_DIVIDER_POWER_OF_TWO);
 }
 
@@ -857,7 +869,7 @@ static int clk_alpha_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,
 
 	return regmap_update_bits(pll->clkr.regmap, pll->offset +
 				  pll_user_ctl(pll->pll_type),
-				  PLL_POST_DIV_MASK << PLL_POST_DIV_SHIFT,
+				  (BIT(pll->width) - 1) << PLL_POST_DIV_SHIFT,
 				  div << PLL_POST_DIV_SHIFT);
 }
 
Signature · 1 line
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Applied
#22 lore raw

Re: [PATCH 12/13] clk: qcom: support for 2 bit PLL post divider

Quoted 6 lines · 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.

---

Applied to clk-next

Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
#23 lore raw

PATCH 13/13 clk: qcom: add read-only alpha pll post divider operations

In reply to 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")'.

---
 drivers/clk/qcom/clk-alpha-pll.c | 26 ++++++++++++++++++++++++++
 drivers/clk/qcom/clk-alpha-pll.h |  1 +
 2 files changed, 27 insertions(+)
drivers/clk/qcom/clk-alpha-pll.c +26 -0
index 62b84fa..443fd0b 100644
@@ -858,6 +858,26 @@ static int clk_alpha_pll_hwfsm_is_enabled(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->offset + pll_user_ctl(pll->pll_type),
+		    &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)
 {
@@ -880,6 +900,12 @@ static int clk_alpha_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long 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);
+
 /* Contains actual property values for different PLL types */
 static const struct
 alpha_pll_props alpha_pll_props[CLK_ALPHA_PLL_TYPE_MAX] = {
drivers/clk/qcom/clk-alpha-pll.h +1 -0
index dee71b4..a9f8751 100644
@@ -89,6 +89,7 @@ struct alpha_pll_config {
 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;
+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);
Signature · 1 line
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Applied
#24 lore raw

Re: [PATCH 13/13] clk: qcom: add read-only alpha pll post divider operations

Quoted 8 lines · 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")'.

---

Applied to clk-next

Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
#25 lore raw
In reply to Abhishek Sahu
Quoted 11 lines · Abhishek Sahu

This patch series does the miscellaneous changes in QCOM Alpha PLL operation and structure to support other types of Alpha PLL’s.

1. It adds the pll_type which will be used for determining all the properties of Alpha PLL.
2. It adds the support for Brammo and Huayra PLL’s for which the support is not available in existing alpha PLL code.
3. There won’t be any change in existing users of Alpha PLL’s since all the newly added code will be under flag for the default PLL operations.

Ok. I took a long look at this today. I rewrote a bunch of stuff. Let me know if anything looks wrong. I'm not really interested in having a type template design that causes us to jump through one clk op to another set of them. I'd rather keep it flatter. I also kept around the macros for the offsets and had it use a register map in each struct instead. Yes, we have to go modify the PLL types to point to the right register offset, but really that's fine and I don't really care. We could have a default fallback when the reg pointer is NULL, but I'm not sure that is useful. The alternative is to make a bunch of new ops structures that passes it down into the final functions but that seemed like more work for the handful of PLLs we have to worry about. You seem to agree here. All told, it got cut down by 100 lines so the patches got smaller.

---8<----

drivers/clk/qcom/clk-alpha-pll.c +165 -331
index 443fd0b85e41..ad7478bf1655 100644
@@ -20,6 +20,7 @@
 #include "clk-alpha-pll.h"
 #include "common.h"
 
+#define PLL_MODE(p)		((p)->offset + 0x0)
 # define PLL_OUTCTRL		BIT(0)
 # define PLL_BYPASSNL		BIT(1)
 # define PLL_RESET_N		BIT(2)
@@ -38,12 +39,67 @@
 # define PLL_ACTIVE_FLAG	BIT(30)
 # define PLL_LOCK_DET		BIT(31)
 
+#define PLL_L_VAL(p)		((p)->offset + (p)->regs[PLL_OFF_L_VAL])
+#define PLL_ALPHA_VAL(p)	((p)->offset + (p)->regs[PLL_OFF_ALPHA_VAL])
+#define PLL_ALPHA_VAL_U(p)	((p)->offset + (p)->regs[PLL_OFF_ALPHA_VAL_U])
+
+#define PLL_USER_CTL(p)		((p)->offset + (p)->regs[PLL_OFF_USER_CTL])
 # define PLL_POST_DIV_SHIFT	8
+# define PLL_POST_DIV_MASK(p)	GENMASK((p)->width, 0)
 # define PLL_ALPHA_EN		BIT(24)
 # define PLL_ALPHA_MODE		BIT(25)
 # define PLL_VCO_SHIFT		20
 # define PLL_VCO_MASK		0x3
 
+#define PLL_USER_CTL_U(p)	((p)->offset + (p)->regs[PLL_OFF_USER_CTL_U])
+
+#define PLL_CONFIG_CTL(p)	((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL])
+#define PLL_CONFIG_CTL_U(p)	((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL_U])
+#define PLL_TEST_CTL(p)		((p)->offset + (p)->regs[PLL_OFF_TEST_CTL])
+#define PLL_TEST_CTL_U(p)	((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U])
+#define PLL_STATUS(p)		((p)->offset + (p)->regs[PLL_OFF_STATUS])
+
+const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = {
+	[CLK_ALPHA_PLL_TYPE_DEFAULT] =  {
+		[PLL_OFF_L_VAL] = 0x04,
+		[PLL_OFF_ALPHA_VAL] = 0x08,
+		[PLL_OFF_ALPHA_VAL_U] = 0x0c,
+		[PLL_OFF_USER_CTL] = 0x10,
+		[PLL_OFF_USER_CTL_U] = 0x14,
+		[PLL_OFF_CONFIG_CTL] = 0x18,
+		[PLL_OFF_TEST_CTL] = 0x1c,
+		[PLL_OFF_TEST_CTL_U] = 0x20,
+		[PLL_OFF_STATUS] = 0x24,
+	},
+	[CLK_ALPHA_PLL_TYPE_HUAYRA] =  {
+		[PLL_OFF_L_VAL] = 0x04,
+		[PLL_OFF_ALPHA_VAL] = 0x08,
+		[PLL_OFF_USER_CTL] = 0x10,
+		[PLL_OFF_CONFIG_CTL] = 0x14,
+		[PLL_OFF_CONFIG_CTL_U] = 0x18,
+		[PLL_OFF_TEST_CTL] = 0x1c,
+		[PLL_OFF_TEST_CTL_U] = 0x20,
+		[PLL_OFF_STATUS] = 0x24,
+	},
+	[CLK_ALPHA_PLL_TYPE_BRAMMO] =  {
+		[PLL_OFF_L_VAL] = 0x04,
+		[PLL_OFF_ALPHA_VAL] = 0x08,
+		[PLL_OFF_ALPHA_VAL_U] = 0x0c,
+		[PLL_OFF_USER_CTL] = 0x10,
+		[PLL_OFF_CONFIG_CTL] = 0x18,
+		[PLL_OFF_TEST_CTL] = 0x1c,
+		[PLL_OFF_STATUS] = 0x24,
+	},
+};
+
+/*
+ * 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		32U
+#define ALPHA_SHIFT(w)		min(w, ALPHA_BITWIDTH)
+
 #define PLL_HUAYRA_M_WIDTH		8
 #define PLL_HUAYRA_M_SHIFT		8
 #define PLL_HUAYRA_M_MASK		0xff
@@ -51,35 +107,11 @@
 #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.
- */
-#define ALPHA_BITWIDTH		32
-
-/* Returns the Alpha register width for pll type */
-#define pll_alpha_width(type)	(alpha_pll_props[type].alpha_width)
-
-/* Returns the flags for pll type */
-#define pll_flags(type)		(alpha_pll_props[type].flags)
-
-/* Returns the alpha_pll_clk_ops for pll type */
-#define pll_clk_ops(hw)		(alpha_pll_props[to_clk_alpha_pll(hw)->	   \
-				 pll_type].ops)
+#define pll_alpha_width(p)					\
+		((PLL_ALPHA_VAL_U(p) - PLL_ALPHA_VAL(p) == 4) ?	\
+				 ALPHA_REG_BITWIDTH : ALPHA_REG_16BIT_WIDTH)
 
-/* Returns the actual register offset for the reg crossponding to pll type */
-#define pll_reg(type, reg)	alpha_pll_props[type].reg_offsets[reg]
-
-/* Helpers to return the actual register offset */
-#define pll_l(type)		pll_reg(type, PLL_L_VAL)
-#define pll_alpha(type)		pll_reg(type, PLL_ALPHA_VAL)
-#define pll_alpha_u(type)	pll_reg(type, PLL_ALPHA_VAL_U)
-#define pll_user_ctl(type)	pll_reg(type, PLL_USER_CTL)
-#define pll_user_ctl_u(type)	pll_reg(type, PLL_USER_CTL_U)
-#define pll_cfg_ctl(type)	pll_reg(type, PLL_CONFIG_CTL)
-#define pll_test_ctl(type)	pll_reg(type, PLL_TEST_CTL)
-#define pll_test_ctl_u(type)	pll_reg(type, PLL_TEST_CTL_U)
-#define pll_status(type)	pll_reg(type, PLL_STATUS)
-#define pll_cfg_ctl_u(type)	pll_reg(type, PLL_CONFIG_CTL_U)
+#define pll_has_64bit_config(p)	((PLL_CONFIG_CTL_U(p) - PLL_CONFIG_CTL(p)) == 4)
 
 #define to_clk_alpha_pll(_hw) container_of(to_clk_regmap(_hw), \
 					   struct clk_alpha_pll, clkr)
@@ -87,86 +119,20 @@
 #define to_clk_alpha_pll_postdiv(_hw) container_of(to_clk_regmap(_hw), \
 					   struct clk_alpha_pll_postdiv, clkr)
 
-/**
- * Contains the index which will be used for mapping with actual
- * register offset in Alpha PLL
- */
-enum {
-	PLL_L_VAL,
-	PLL_ALPHA_VAL,
-	PLL_ALPHA_VAL_U,
-	PLL_USER_CTL,
-	PLL_USER_CTL_U,
-	PLL_CONFIG_CTL,
-	PLL_CONFIG_CTL_U,
-	PLL_TEST_CTL,
-	PLL_TEST_CTL_U,
-	PLL_STATUS,
-	PLL_MAX_REGS,
-};
-
-/**
- * struct alpha_pll_clk_ops - operations for alpha PLL
- * @enable: enable function when HW voting FSM is disabled
- * @disable: disable function when HW voting FSM is disabled
- * @is_enabled: check whether PLL is enabled when HW voting FSM is disabled
- * @hwfsm_enable: check whether PLL is enabled when HW voting FSM is enabled
- * @hwfsm_disable: check whether PLL is disabled when HW voting FSM is enabled
- * @hwfsm_is_enabled: check whether PLL is enabled when HW voting FSM is enabled
- * @recalc_rate: recalculate the rate of PLL by reading mode, L and Alpha Value
- * @round_rate: returns the closest supported rate of PLL
- * @set_rate: change the rate of this clock by actually programming the mode, L
- *	      and Alpha Value registers
- */
-struct alpha_pll_clk_ops {
-	int		(*enable)(struct clk_hw *hw);
-	void		(*disable)(struct clk_hw *hw);
-	int		(*is_enabled)(struct clk_hw *hw);
-	int		(*hwfsm_enable)(struct clk_hw *hw);
-	void		(*hwfsm_disable)(struct clk_hw *hw);
-	int		(*hwfsm_is_enabled)(struct clk_hw *hw);
-	unsigned long	(*recalc_rate)(struct clk_hw *hw,
-				       unsigned long parent_rate);
-	long		(*round_rate)(struct clk_hw *hw, unsigned long rate,
-				      unsigned long *parent_rate);
-	int		(*set_rate)(struct clk_hw *hw, unsigned long rate,
-				    unsigned long parent_rate);
-};
-
-/**
- * struct alpha_pll_props - contains the various properties which
- *			    will be fixed for PLL type.
- * @reg_offsets: register offsets mapping array
- * @alpha_width: alpha value width
- * @ops: clock operations for alpha PLL
- */
-struct alpha_pll_props {
-	u8 reg_offsets[PLL_MAX_REGS];
-	u8 alpha_width;
-
-#define HAVE_64BIT_CONFIG_CTL		BIT(0)
-#define SUPPORTS_DYNAMIC_UPDATE		BIT(1)
-#define SUPPORTS_VCO			BIT(2)
-	u8 flags;
-	struct alpha_pll_clk_ops ops;
-};
-
-static const struct alpha_pll_props alpha_pll_props[];
-
 static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse,
 			const char *action)
 {
-	u32 val, off = pll->offset;
+	u32 val;
 	int count;
 	int ret;
 	const char *name = clk_hw_get_name(&pll->clkr.hw);
 
-	ret = regmap_read(pll->clkr.regmap, off, &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, &val);
+		ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
 		if (ret)
 			return ret;
 		if (inverse && !(val & mask))
@@ -206,22 +172,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;
-	u8 type = pll->pll_type, flags = pll_flags(type);
 
-	regmap_write(regmap, off + pll_l(type), config->l);
-	regmap_write(regmap, off + pll_alpha(type), config->alpha);
-	regmap_write(regmap, off + pll_cfg_ctl(type), config->config_ctl_val);
-	regmap_write(regmap, off + pll_cfg_ctl_u(type),
-		     config->config_ctl_hi_val);
+	regmap_write(regmap, PLL_L_VAL(pll), config->l);
+	regmap_write(regmap, PLL_ALPHA_VAL(pll), config->alpha);
+	regmap_write(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val);
 
-	if (flags & HAVE_64BIT_CONFIG_CTL)
-		regmap_write(regmap, off + pll_cfg_ctl_u(type),
+	if (pll_has_64bit_config(pll))
+		regmap_write(regmap, PLL_CONFIG_CTL_U(pll),
 			     config->config_ctl_hi_val);
 
-	if (pll_alpha_width(type) > 32)
-		regmap_write(regmap, off + pll_alpha_u(type),
-			     config->alpha_hi);
+	if (pll_alpha_width(pll) > 32)
+		regmap_write(regmap, PLL_ALPHA_VAL_U(pll), config->alpha_hi);
 
 	val = config->main_output_mask;
 	val |= config->aux_output_mask;
@@ -241,19 +202,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(type), 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, 6, 0);
+		qcom_pll_set_fsm_mode(regmap, PLL_MODE(pll), 6, 0);
 }
 
-static int alpha_pll_default_hwfsm_enable(struct clk_hw *hw)
+static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
 {
-	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
 	int ret;
-	u32 val, off = pll->offset;
+	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+	u32 val;
 
-	ret = regmap_read(pll->clkr.regmap, off, &val);
+	ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
 	if (ret)
 		return ret;
 
@@ -262,7 +223,7 @@ static int alpha_pll_default_hwfsm_enable(struct clk_hw *hw)
 	if (pll->flags & SUPPORTS_OFFLINE_REQ)
 		val &= ~PLL_OFFLINE_REQ;
 
-	ret = regmap_write(pll->clkr.regmap, off, val);
+	ret = regmap_write(pll->clkr.regmap, PLL_MODE(pll), val);
 	if (ret)
 		return ret;
 
@@ -272,18 +233,18 @@ static int alpha_pll_default_hwfsm_enable(struct clk_hw *hw)
 	return wait_for_pll_enable_active(pll);
 }
 
-static void alpha_pll_default_hwfsm_disable(struct clk_hw *hw)
+static void clk_alpha_pll_hwfsm_disable(struct clk_hw *hw)
 {
-	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
 	int ret;
-	u32 val, off = pll->offset;
+	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+	u32 val;
 
-	ret = regmap_read(pll->clkr.regmap, off, &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,
+		ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll),
 					 PLL_OFFLINE_REQ, PLL_OFFLINE_REQ);
 		if (ret)
 			return;
@@ -294,7 +255,7 @@ static void alpha_pll_default_hwfsm_disable(struct clk_hw *hw)
 	}
 
 	/* Disable hwfsm */
-	ret = regmap_update_bits(pll->clkr.regmap, off,
+	ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll),
 				 PLL_FSM_ENA, 0);
 	if (ret)
 		return;
@@ -304,35 +265,35 @@ static void alpha_pll_default_hwfsm_disable(struct clk_hw *hw)
 
 static int pll_is_enabled(struct clk_hw *hw, u32 mask)
 {
-	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
 	int ret;
-	u32 val, off = pll->offset;
+	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+	u32 val;
 
-	ret = regmap_read(pll->clkr.regmap, off, &val);
+	ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
 	if (ret)
 		return ret;
 
 	return !!(val & mask);
 }
 
-static int alpha_pll_default_hwfsm_is_enabled(struct clk_hw *hw)
+static int clk_alpha_pll_hwfsm_is_enabled(struct clk_hw *hw)
 {
 	return pll_is_enabled(hw, PLL_ACTIVE_FLAG);
 }
 
-static int alpha_pll_default_is_enabled(struct clk_hw *hw)
+static int clk_alpha_pll_is_enabled(struct clk_hw *hw)
 {
 	return pll_is_enabled(hw, PLL_LOCK_DET);
 }
 
-static int alpha_pll_default_enable(struct clk_hw *hw)
+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 = pll->offset;
+	u32 val, mask;
 
 	mask = PLL_OUTCTRL | PLL_RESET_N | PLL_BYPASSNL;
-	ret = regmap_read(pll->clkr.regmap, off, &val);
+	ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
 	if (ret)
 		return ret;
 
@@ -348,7 +309,7 @@ static int alpha_pll_default_enable(struct clk_hw *hw)
 	if ((val & mask) == mask)
 		return 0;
 
-	ret = regmap_update_bits(pll->clkr.regmap, off,
+	ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll),
 				 PLL_BYPASSNL, PLL_BYPASSNL);
 	if (ret)
 		return ret;
@@ -360,7 +321,7 @@ static int alpha_pll_default_enable(struct clk_hw *hw)
 	mb();
 	udelay(5);
 
-	ret = regmap_update_bits(pll->clkr.regmap, off,
+	ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll),
 				 PLL_RESET_N, PLL_RESET_N);
 	if (ret)
 		return ret;
@@ -369,7 +330,7 @@ static int alpha_pll_default_enable(struct clk_hw *hw)
 	if (ret)
 		return ret;
 
-	ret = regmap_update_bits(pll->clkr.regmap, off,
+	ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll),
 				 PLL_OUTCTRL, PLL_OUTCTRL);
 
 	/* Ensure that the write above goes through before returning. */
@@ -377,13 +338,13 @@ static int alpha_pll_default_enable(struct clk_hw *hw)
 	return ret;
 }
 
-static void alpha_pll_default_disable(struct clk_hw *hw)
+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 = pll->offset;
+	u32 val, mask;
 
-	ret = regmap_read(pll->clkr.regmap, off, &val);
+	ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
 	if (ret)
 		return;
 
@@ -394,21 +355,20 @@ static void alpha_pll_default_disable(struct clk_hw *hw)
 	}
 
 	mask = PLL_OUTCTRL;
-	regmap_update_bits(pll->clkr.regmap, off, 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, 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, u32 alpha_width)
 {
-	return (prate * l) + ((prate * a) >>
-		(alpha_width < ALPHA_BITWIDTH ? alpha_width : ALPHA_BITWIDTH));
+	return (prate * l) + ((prate * a) >> ALPHA_SHIFT(alpha_width));
 }
 
 static unsigned long
@@ -428,8 +388,7 @@ alpha_pll_round_rate(unsigned long rate, unsigned long prate, u32 *l, u64 *a,
 	}
 
 	/* Upper ALPHA_BITWIDTH bits of Alpha */
-	quotient = remainder << (alpha_width < ALPHA_BITWIDTH ?
-				 alpha_width : ALPHA_BITWIDTH);
+	quotient = remainder << ALPHA_SHIFT(alpha_width);
 
 	remainder = do_div(quotient, prate);
 
@@ -454,21 +413,20 @@ alpha_pll_find_vco(const struct clk_alpha_pll *pll, unsigned long rate)
 }
 
 static unsigned long
-alpha_pll_default_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+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);
-	u8 type = pll->pll_type;
-	u32 off = pll->offset, alpha_width = pll_alpha_width(type);
+	u32 alpha_width = pll_alpha_width(pll);
 
-	regmap_read(pll->clkr.regmap, off + pll_l(type), &l);
+	regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l);
 
-	regmap_read(pll->clkr.regmap, off + pll_user_ctl(type), &ctl);
+	regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl);
 	if (ctl & PLL_ALPHA_EN) {
-		regmap_read(pll->clkr.regmap, off + pll_alpha(type), &low);
+		regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &low);
 		if (alpha_width > 32) {
-			regmap_read(pll->clkr.regmap, off + pll_alpha_u(type),
+			regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll),
 				    &high);
 			a = (u64)high << 32 | low;
 		} else {
@@ -492,7 +450,7 @@ static int clk_alpha_pll_update_latch(struct clk_alpha_pll *pll)
 	/* Latch the input to the PLL */
 	regmap_update_bits(pll->clkr.regmap, off, PLL_UPDATE, PLL_UPDATE);
 
-	/* Make sure PLL_UPDATE request goes through*/
+	/* Make sure PLL_UPDATE request goes through */
 	mb();
 
 	/* Wait for 2 reference cycle before checking ACK bit */
@@ -512,7 +470,7 @@ static int clk_alpha_pll_update_latch(struct clk_alpha_pll *pll)
 
 		regmap_update_bits(pll->clkr.regmap, off, PLL_UPDATE, 0);
 
-		/* Make sure PLL_UPDATE request goes through*/
+		/* Make sure PLL_UPDATE request goes through */
 		mb();
 	} else {
 		ret = wait_for_pll_update(pll);
@@ -530,60 +488,56 @@ static int clk_alpha_pll_update_latch(struct clk_alpha_pll *pll)
 	return 0;
 }
 
-static int alpha_pll_default_set_rate(struct clk_hw *hw, unsigned long rate,
-				      unsigned long prate)
+static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+				  unsigned long prate)
 {
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
 	const struct pll_vco *vco;
-	u8 type = pll->pll_type, flags = pll_flags(type);
-	u32 l, off = pll->offset, alpha_width = pll_alpha_width(type);
+	u32 l, alpha_width = pll_alpha_width(pll);
 	u64 a;
 
 	rate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);
-	if (flags & SUPPORTS_VCO) {
-		vco = alpha_pll_find_vco(pll, rate);
-		if (!vco) {
-			pr_err("alpha pll not in a valid vco range\n");
-			return -EINVAL;
-		}
+	vco = alpha_pll_find_vco(pll, rate);
+	if (pll->vco_table && !vco) {
+		pr_err("alpha pll not in a valid vco range\n");
+		return -EINVAL;
 	}
 
-	regmap_write(pll->clkr.regmap, off + pll_l(type), l);
+	regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);
 
 	if (alpha_width > ALPHA_BITWIDTH)
 		a <<= alpha_width - ALPHA_BITWIDTH;
 
 	if (alpha_width > 32)
-		regmap_write(pll->clkr.regmap, off + pll_alpha_u(type),
-			     a >> 32);
+		regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll), a >> 32);
 
-	regmap_write(pll->clkr.regmap, off + pll_alpha(type), a);
+	regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);
 
-	if (flags & SUPPORTS_VCO)
-		regmap_update_bits(pll->clkr.regmap, off + pll_user_ctl(type),
+	if (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, off + pll_user_ctl(type),
+	regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll),
 			   PLL_ALPHA_EN, PLL_ALPHA_EN);
 
-	if (!clk_hw_is_enabled(hw) || !(flags & SUPPORTS_DYNAMIC_UPDATE))
+	if (!clk_hw_is_enabled(hw) || !(pll->flags & SUPPORTS_DYNAMIC_UPDATE))
 		return 0;
 
 	return clk_alpha_pll_update_latch(pll);
 }
 
-static long alpha_pll_default_round_rate(struct clk_hw *hw, unsigned long rate,
-					 unsigned long *prate)
+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);
-	u8 type = pll->pll_type;
-	u32 l, alpha_width = pll_alpha_width(type);
+	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, alpha_width);
-	if (!(pll_flags(type) & SUPPORTS_VCO) || alpha_pll_find_vco(pll, rate))
+	if (!pll->vco_table || alpha_pll_find_vco(pll, rate))
 		return rate;
 
 	min_freq = pll->vco_table[0].min_freq;
@@ -644,26 +598,29 @@ alpha_pll_huayra_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
 {
 	u64 rate = parent_rate, tmp;
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
-	u8 type = pll->pll_type;
-	u32 l, alpha = 0, ctl, alpha_m, alpha_n, off = pll->offset;
+	u32 l, alpha = 0, ctl, alpha_m, alpha_n;
 
-	regmap_read(pll->clkr.regmap, off + pll_l(type), &l);
-	regmap_read(pll->clkr.regmap, off + pll_user_ctl(type), &ctl);
+	regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l);
+	regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl);
 
 	if (ctl & PLL_ALPHA_EN) {
-		regmap_read(pll->clkr.regmap, off + pll_alpha(type), &alpha);
+		regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(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
+		 * as a two’s compliment number. When alpha_mode=1,
+		 * pll_alpha_val<15:8>=M and 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.
+		 * When alpha_mode=0, it is a two’s compliment number in the
+		 * range [-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);
@@ -694,16 +651,14 @@ static int alpha_pll_huayra_set_rate(struct clk_hw *hw, unsigned long rate,
 				     unsigned long prate)
 {
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
-	u8 type = pll->pll_type;
-	u32 l, a, ctl, cur_alpha = 0, off = pll->offset;
+	u32 l, a, ctl, cur_alpha = 0;
 
 	rate = alpha_huayra_pll_round_rate(rate, prate, &l, &a);
 
-	regmap_read(pll->clkr.regmap, off + pll_user_ctl(type), &ctl);
+	regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl);
 
 	if (ctl & PLL_ALPHA_EN)
-		regmap_read(pll->clkr.regmap, off + pll_alpha(type),
-			    &cur_alpha);
+		regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &cur_alpha);
 
 	/*
 	 * Huayra PLL supports PLL dynamic programming. User can change L_VAL,
@@ -716,20 +671,20 @@ static int alpha_pll_huayra_set_rate(struct clk_hw *hw, unsigned long rate,
 			return -EBUSY;
 		}
 
-		regmap_write(pll->clkr.regmap, off + pll_l(type), l);
+		regmap_write(pll->clkr.regmap, PLL_L_VAL(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, off + pll_l(type), l);
-	regmap_write(pll->clkr.regmap, off + pll_alpha(type), a);
+	regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);
+	regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);
 
 	if (a == 0)
-		regmap_update_bits(pll->clkr.regmap, off + pll_user_ctl(type),
+		regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll),
 				   PLL_ALPHA_EN, 0x0);
 	else
-		regmap_update_bits(pll->clkr.regmap, off + pll_user_ctl(type),
+		regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll),
 				   PLL_ALPHA_EN | PLL_ALPHA_MODE, PLL_ALPHA_EN);
 
 	return 0;
@@ -743,54 +698,6 @@ static long alpha_pll_huayra_round_rate(struct clk_hw *hw, unsigned long rate,
 	return alpha_huayra_pll_round_rate(rate, *prate, &l, &a);
 }
 
-static int clk_alpha_pll_enable(struct clk_hw *hw)
-{
-	return pll_clk_ops(hw).enable(hw);
-}
-
-static void clk_alpha_pll_disable(struct clk_hw *hw)
-{
-	pll_clk_ops(hw).disable(hw);
-}
-
-static int clk_alpha_pll_is_enabled(struct clk_hw *hw)
-{
-	return pll_clk_ops(hw).is_enabled(hw);
-}
-
-static unsigned long
-clk_alpha_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
-{
-	return pll_clk_ops(hw).recalc_rate(hw, parent_rate);
-}
-
-static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
-				     unsigned long *prate)
-{
-	return pll_clk_ops(hw).round_rate(hw, rate, prate);
-}
-
-static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate,
-				  unsigned long prate)
-{
-	return pll_clk_ops(hw).set_rate(hw, rate, prate);
-}
-
-static int clk_alpha_pll_hwfsm_enable(struct clk_hw *hw)
-{
-	return pll_clk_ops(hw).hwfsm_enable(hw);
-}
-
-static void clk_alpha_pll_hwfsm_disable(struct clk_hw *hw)
-{
-	pll_clk_ops(hw).hwfsm_disable(hw);
-}
-
-static int clk_alpha_pll_hwfsm_is_enabled(struct clk_hw *hw)
-{
-	return pll_clk_ops(hw).hwfsm_is_enabled(hw);
-}
-
 const struct clk_ops clk_alpha_pll_ops = {
 	.enable = clk_alpha_pll_enable,
 	.disable = clk_alpha_pll_disable,
@@ -801,6 +708,16 @@ const struct clk_ops clk_alpha_pll_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_alpha_pll_ops);
 
+const struct clk_ops clk_alpha_pll_huayra_ops = {
+	.enable = clk_alpha_pll_enable,
+	.disable = clk_alpha_pll_disable,
+	.is_enabled = clk_alpha_pll_is_enabled,
+	.recalc_rate = alpha_pll_huayra_recalc_rate,
+	.round_rate = alpha_pll_huayra_round_rate,
+	.set_rate = alpha_pll_huayra_set_rate,
+};
+EXPORT_SYMBOL_GPL(clk_alpha_pll_huayra_ops);
+
 const struct clk_ops clk_alpha_pll_hwfsm_ops = {
 	.enable = clk_alpha_pll_hwfsm_enable,
 	.disable = clk_alpha_pll_hwfsm_disable,
@@ -817,11 +734,10 @@ clk_alpha_pll_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_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(pll->pll_type),
-		    &ctl);
+	regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl);
 
 	ctl >>= PLL_POST_DIV_SHIFT;
-	ctl &= BIT(pll->width) - 1;
+	ctl &= PLL_POST_DIV_MASK(pll);
 
 	return parent_rate >> fls(ctl);
 }
@@ -865,8 +781,7 @@ clk_alpha_pll_postdiv_round_ro_rate(struct clk_hw *hw, unsigned long rate,
 	struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
 	u32 ctl, div;
 
-	regmap_read(pll->clkr.regmap, pll->offset + pll_user_ctl(pll->pll_type),
-		    &ctl);
+	regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl);
 
 	ctl >>= PLL_POST_DIV_SHIFT;
 	ctl &= BIT(pll->width) - 1;
@@ -887,9 +802,8 @@ 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(pll->pll_type),
-				  (BIT(pll->width) - 1) << PLL_POST_DIV_SHIFT,
+	return regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll),
+				  PLL_POST_DIV_MASK(pll) << PLL_POST_DIV_SHIFT,
 				  div << PLL_POST_DIV_SHIFT);
 }
 
@@ -905,83 +819,3 @@ const struct clk_ops clk_alpha_pll_postdiv_ro_ops = {
 	.recalc_rate = clk_alpha_pll_postdiv_recalc_rate,
 };
 EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_ro_ops);
-
-/* Contains actual property values for different PLL types */
-static const struct
-alpha_pll_props alpha_pll_props[CLK_ALPHA_PLL_TYPE_MAX] = {
-	[CLK_ALPHA_PLL_TYPE_DEFAULT] =  {
-		.reg_offsets = {
-			[PLL_L_VAL] = 0x04,
-			[PLL_ALPHA_VAL] = 0x08,
-			[PLL_ALPHA_VAL_U] = 0x0c,
-			[PLL_USER_CTL] = 0x10,
-			[PLL_USER_CTL_U] = 0x14,
-			[PLL_CONFIG_CTL] = 0x18,
-			[PLL_TEST_CTL] = 0x1c,
-			[PLL_TEST_CTL_U] = 0x20,
-			[PLL_STATUS] = 0x24,
-		},
-		.alpha_width = 40,
-		.flags = SUPPORTS_VCO,
-		.ops = {
-			.enable = alpha_pll_default_enable,
-			.disable = alpha_pll_default_disable,
-			.is_enabled = alpha_pll_default_is_enabled,
-			.hwfsm_enable = alpha_pll_default_hwfsm_enable,
-			.hwfsm_disable = alpha_pll_default_hwfsm_disable,
-			.hwfsm_is_enabled = alpha_pll_default_hwfsm_is_enabled,
-			.recalc_rate = alpha_pll_default_recalc_rate,
-			.round_rate = alpha_pll_default_round_rate,
-			.set_rate = alpha_pll_default_set_rate,
-		},
-	},
-	[CLK_ALPHA_PLL_TYPE_HUAYRA] =  {
-		.reg_offsets = {
-			[PLL_L_VAL] = 0x04,
-			[PLL_ALPHA_VAL] = 0x08,
-			[PLL_USER_CTL] = 0x10,
-			[PLL_CONFIG_CTL] = 0x14,
-			[PLL_CONFIG_CTL_U] = 0x18,
-			[PLL_TEST_CTL] = 0x1c,
-			[PLL_TEST_CTL_U] = 0x20,
-			[PLL_STATUS] = 0x24,
-		},
-		.alpha_width = 16,
-		.flags = SUPPORTS_DYNAMIC_UPDATE | HAVE_64BIT_CONFIG_CTL,
-		.ops = {
-			.enable = alpha_pll_default_enable,
-			.disable = alpha_pll_default_disable,
-			.is_enabled = alpha_pll_default_is_enabled,
-			.hwfsm_enable = alpha_pll_default_hwfsm_enable,
-			.hwfsm_disable = alpha_pll_default_hwfsm_disable,
-			.hwfsm_is_enabled = alpha_pll_default_hwfsm_is_enabled,
-			.recalc_rate = alpha_pll_huayra_recalc_rate,
-			.round_rate = alpha_pll_huayra_round_rate,
-			.set_rate = alpha_pll_huayra_set_rate,
-		},
-	},
-	[CLK_ALPHA_PLL_TYPE_BRAMMO] =  {
-		.reg_offsets = {
-			[PLL_L_VAL] = 0x04,
-			[PLL_ALPHA_VAL] = 0x08,
-			[PLL_ALPHA_VAL_U] = 0x0c,
-			[PLL_USER_CTL] = 0x10,
-			[PLL_CONFIG_CTL] = 0x18,
-			[PLL_TEST_CTL] = 0x1c,
-			[PLL_STATUS] = 0x24,
-		},
-		.alpha_width = 40,
-		.flags = SUPPORTS_DYNAMIC_UPDATE,
-		.ops = {
-			.enable = alpha_pll_default_enable,
-			.disable = alpha_pll_default_disable,
-			.is_enabled = alpha_pll_default_is_enabled,
-			.hwfsm_enable = alpha_pll_default_hwfsm_enable,
-			.hwfsm_disable = alpha_pll_default_hwfsm_disable,
-			.hwfsm_is_enabled = alpha_pll_default_hwfsm_is_enabled,
-			.recalc_rate = alpha_pll_default_recalc_rate,
-			.round_rate = alpha_pll_default_round_rate,
-			.set_rate = alpha_pll_default_set_rate,
-		},
-	},
-};
drivers/clk/qcom/clk-alpha-pll.h +23 -5
index a9f8751227f7..7593e8a56cf2 100644
@@ -25,6 +25,22 @@ enum {
 	CLK_ALPHA_PLL_TYPE_MAX,
 };
 
+enum {
+	PLL_OFF_L_VAL,
+	PLL_OFF_ALPHA_VAL,
+	PLL_OFF_ALPHA_VAL_U,
+	PLL_OFF_USER_CTL,
+	PLL_OFF_USER_CTL_U,
+	PLL_OFF_CONFIG_CTL,
+	PLL_OFF_CONFIG_CTL_U,
+	PLL_OFF_TEST_CTL,
+	PLL_OFF_TEST_CTL_U,
+	PLL_OFF_STATUS,
+	PLL_OFF_MAX_REGS
+};
+
+extern const u8 clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_MAX][PLL_OFF_MAX_REGS];
+
 struct pll_vco {
 	unsigned long min_freq;
 	unsigned long max_freq;
@@ -35,18 +51,19 @@ struct pll_vco {
  * struct clk_alpha_pll - phase locked loop (PLL)
  * @offset: base address of registers
  * @vco_table: array of VCO settings
- * @pll_type: alpha pll type
+ * @regs: alpha pll register map (see @clk_alpha_pll_regs)
  * @clkr: regmap clock handle
  */
 struct clk_alpha_pll {
 	u32 offset;
+	const u8 *regs;
 
 	const struct pll_vco *vco_table;
 	size_t num_vco;
 #define SUPPORTS_OFFLINE_REQ	BIT(0)
-#define SUPPORTS_FSM_MODE	BIT(1)
+#define SUPPORTS_FSM_MODE	BIT(2)
+#define SUPPORTS_DYNAMIC_UPDATE	BIT(3)
 	u8 flags;
-	u8 pll_type;
 
 	struct clk_regmap clkr;
 };
@@ -54,14 +71,14 @@ struct clk_alpha_pll {
 /**
  * struct clk_alpha_pll_postdiv - phase locked loop (PLL) post-divider
  * @offset: base address of registers
- * @pll_type: alpha pll type
+ * @regs: alpha pll register map (see @clk_alpha_pll_regs)
  * @width: width of post-divider
  * @clkr: regmap clock handle
  */
 struct clk_alpha_pll_postdiv {
 	u32 offset;
-	u8 pll_type;
 	u8 width;
+	const u8 *regs;
 
 	struct clk_regmap clkr;
 };
@@ -89,6 +106,7 @@ struct alpha_pll_config {
 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;
+extern const struct clk_ops clk_alpha_pll_huayra_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,
drivers/clk/qcom/gcc-ipq8074.c +2 -0
index 0f735d37690f..ed2d00f55378 100644
@@ -52,6 +52,7 @@ static const struct parent_map gcc_xo_gpll0_gpll0_out_main_div2_map[] = {
 
 static struct clk_alpha_pll gpll0_main = {
 	.offset = 0x21000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.clkr = {
 		.enable_reg = 0x0b000,
 		.enable_mask = BIT(0),
@@ -82,6 +83,7 @@ static struct clk_fixed_factor gpll0_out_main_div2 = {
 
 static struct clk_alpha_pll_postdiv gpll0 = {
 	.offset = 0x21000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gpll0",
 		.parent_names = (const char *[]){
drivers/clk/qcom/gcc-msm8994.c +4 -0
index 7983288d9141..1e38efc37180 100644
@@ -73,6 +73,7 @@ static struct clk_fixed_factor xo = {
 
 static struct clk_alpha_pll gpll0_early = {
 	.offset = 0x00000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.clkr = {
 		.enable_reg = 0x1480,
 		.enable_mask = BIT(0),
@@ -88,6 +89,7 @@ static struct clk_alpha_pll gpll0_early = {
 
 static struct clk_alpha_pll_postdiv gpll0 = {
 	.offset = 0x00000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.clkr.hw.init = &(struct clk_init_data)
 	{
 		.name = "gpll0",
@@ -99,6 +101,7 @@ static struct clk_alpha_pll_postdiv gpll0 = {
 
 static struct clk_alpha_pll gpll4_early = {
 	.offset = 0x1dc0,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.clkr = {
 		.enable_reg = 0x1480,
 		.enable_mask = BIT(4),
@@ -114,6 +117,7 @@ static struct clk_alpha_pll gpll4_early = {
 
 static struct clk_alpha_pll_postdiv gpll4 = {
 	.offset = 0x1dc0,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.clkr.hw.init = &(struct clk_init_data)
 	{
 		.name = "gpll4",
drivers/clk/qcom/gcc-msm8996.c +4 -0
index 7ddec886fcd3..5d7451209206 100644
@@ -227,6 +227,7 @@ static struct clk_fixed_factor xo = {
 
 static struct clk_alpha_pll gpll0_early = {
 	.offset = 0x00000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.clkr = {
 		.enable_reg = 0x52000,
 		.enable_mask = BIT(0),
@@ -252,6 +253,7 @@ static struct clk_fixed_factor gpll0_early_div = {
 
 static struct clk_alpha_pll_postdiv gpll0 = {
 	.offset = 0x00000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gpll0",
 		.parent_names = (const char *[]){ "gpll0_early" },
@@ -262,6 +264,7 @@ static struct clk_alpha_pll_postdiv gpll0 = {
 
 static struct clk_alpha_pll gpll4_early = {
 	.offset = 0x77000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.clkr = {
 		.enable_reg = 0x52000,
 		.enable_mask = BIT(4),
@@ -276,6 +279,7 @@ static struct clk_alpha_pll gpll4_early = {
 
 static struct clk_alpha_pll_postdiv gpll4 = {
 	.offset = 0x77000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gpll4",
 		.parent_names = (const char *[]){ "gpll4_early" },
drivers/clk/qcom/mmcc-msm8996.c +16 -0
index 352394d8fd8c..66a2fa4ec93c 100644
@@ -267,6 +267,7 @@ static struct pll_vco mmpll_t_vco[] = {
 
 static struct clk_alpha_pll mmpll0_early = {
 	.offset = 0x0,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.vco_table = mmpll_p_vco,
 	.num_vco = ARRAY_SIZE(mmpll_p_vco),
 	.clkr = {
@@ -283,6 +284,7 @@ static struct clk_alpha_pll mmpll0_early = {
 
 static struct clk_alpha_pll_postdiv mmpll0 = {
 	.offset = 0x0,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.width = 4,
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "mmpll0",
@@ -295,6 +297,7 @@ static struct clk_alpha_pll_postdiv mmpll0 = {
 
 static struct clk_alpha_pll mmpll1_early = {
 	.offset = 0x30,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.vco_table = mmpll_p_vco,
 	.num_vco = ARRAY_SIZE(mmpll_p_vco),
 	.clkr = {
@@ -311,6 +314,7 @@ static struct clk_alpha_pll mmpll1_early = {
 
 static struct clk_alpha_pll_postdiv mmpll1 = {
 	.offset = 0x30,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.width = 4,
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "mmpll1",
@@ -323,6 +327,7 @@ static struct clk_alpha_pll_postdiv mmpll1 = {
 
 static struct clk_alpha_pll mmpll2_early = {
 	.offset = 0x4100,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.vco_table = mmpll_gfx_vco,
 	.num_vco = ARRAY_SIZE(mmpll_gfx_vco),
 	.clkr.hw.init = &(struct clk_init_data){
@@ -335,6 +340,7 @@ static struct clk_alpha_pll mmpll2_early = {
 
 static struct clk_alpha_pll_postdiv mmpll2 = {
 	.offset = 0x4100,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.width = 4,
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "mmpll2",
@@ -347,6 +353,7 @@ static struct clk_alpha_pll_postdiv mmpll2 = {
 
 static struct clk_alpha_pll mmpll3_early = {
 	.offset = 0x60,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.vco_table = mmpll_p_vco,
 	.num_vco = ARRAY_SIZE(mmpll_p_vco),
 	.clkr.hw.init = &(struct clk_init_data){
@@ -359,6 +366,7 @@ static struct clk_alpha_pll mmpll3_early = {
 
 static struct clk_alpha_pll_postdiv mmpll3 = {
 	.offset = 0x60,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.width = 4,
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "mmpll3",
@@ -371,6 +379,7 @@ static struct clk_alpha_pll_postdiv mmpll3 = {
 
 static struct clk_alpha_pll mmpll4_early = {
 	.offset = 0x90,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.vco_table = mmpll_t_vco,
 	.num_vco = ARRAY_SIZE(mmpll_t_vco),
 	.clkr.hw.init = &(struct clk_init_data){
@@ -383,6 +392,7 @@ static struct clk_alpha_pll mmpll4_early = {
 
 static struct clk_alpha_pll_postdiv mmpll4 = {
 	.offset = 0x90,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.width = 2,
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "mmpll4",
@@ -395,6 +405,7 @@ static struct clk_alpha_pll_postdiv mmpll4 = {
 
 static struct clk_alpha_pll mmpll5_early = {
 	.offset = 0xc0,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.vco_table = mmpll_p_vco,
 	.num_vco = ARRAY_SIZE(mmpll_p_vco),
 	.clkr.hw.init = &(struct clk_init_data){
@@ -407,6 +418,7 @@ static struct clk_alpha_pll mmpll5_early = {
 
 static struct clk_alpha_pll_postdiv mmpll5 = {
 	.offset = 0xc0,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.width = 4,
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "mmpll5",
@@ -419,6 +431,7 @@ static struct clk_alpha_pll_postdiv mmpll5 = {
 
 static struct clk_alpha_pll mmpll8_early = {
 	.offset = 0x4130,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.vco_table = mmpll_gfx_vco,
 	.num_vco = ARRAY_SIZE(mmpll_gfx_vco),
 	.clkr.hw.init = &(struct clk_init_data){
@@ -431,6 +444,7 @@ static struct clk_alpha_pll mmpll8_early = {
 
 static struct clk_alpha_pll_postdiv mmpll8 = {
 	.offset = 0x4130,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.width = 4,
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "mmpll8",
@@ -443,6 +457,7 @@ static struct clk_alpha_pll_postdiv mmpll8 = {
 
 static struct clk_alpha_pll mmpll9_early = {
 	.offset = 0x4200,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.vco_table = mmpll_t_vco,
 	.num_vco = ARRAY_SIZE(mmpll_t_vco),
 	.clkr.hw.init = &(struct clk_init_data){
@@ -455,6 +470,7 @@ static struct clk_alpha_pll mmpll9_early = {
 
 static struct clk_alpha_pll_postdiv mmpll9 = {
 	.offset = 0x4200,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 	.width = 2,
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "mmpll9",
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
#26 lore raw
Quoted 13 lines · Stephen Boyd
Quoted 11 lines · Abhishek Sahu

This patch series does the miscellaneous changes in QCOM Alpha PLL operation and structure to support other types of Alpha PLL’s.

1. It adds the pll_type which will be used for determining all the properties of Alpha PLL.
2. It adds the support for Brammo and Huayra PLL’s for which the support is not available in existing alpha PLL code.
3. There won’t be any change in existing users of Alpha PLL’s since all the newly added code will be under flag for the default PLL operations.

Quoted 1 line

Ok. I took a long look at this today. I rewrote a bunch of stuff.

Thanks Stephen for reviewing the changes and making the code cleaner. I checked all the code changes and everything looks good. It will work for all of our requirement. I will check with other PLL users also once and then update the patch series with all your suggested code changes after complete testing.

Quoted 8 lines

Let me know if anything looks wrong. I'm not really interested in having a type template design that causes us to jump through one clk op to another set of them. I'd rather keep it flatter. I also kept around the macros for the offsets and had it use a register map in each struct instead. Yes, we have to go modify the PLL types to point to the right register offset, but really that's fine and I don't really care. We could have a default fallback when the reg pointer is NULL, but I'm not sure that is useful.

The main reason for going with type template design is due to different register offsets. Now, if passing the register offsets from pll structure is ok, then we can get rid of this function indirection approach.

Adding NULL check seems to be overhead in all our register macros since these PLL structure will be populated by QCOM clock drivers only and now, we are making this parameter mandatory.

Quoted 6 lines

The alternative is to make a bunch of new ops structures that passes it down into the final functions but that seemed like more work for the handful of PLLs we have to worry about. You seem to agree here. All told, it got cut down by 100 lines so the patches got smaller.

Passing the ops into final function will be lead to again type template design for passing the register offsets. Since, now we have very few PLL's in current upstream code so adding register offsets will be more convenient and maintainable.

Also, now the register offset is coming from our own array so always we can retrieve the PLL type from that. In future, if someone want to have code which requires PLL type then, it can be retrieved from diff of passed pll structure address and array base address.

Thanks,
Abhishek

#27 lore raw
Quoted 14 lines · Abhishek Sahu
Quoted 13 lines · Stephen Boyd
Quoted 11 lines · Abhishek Sahu

This patch series does the miscellaneous changes in QCOM Alpha PLL operation and structure to support other types of Alpha PLL’s.

1. It adds the pll_type which will be used for determining all the properties of Alpha PLL.
2. It adds the support for Brammo and Huayra PLL’s for which the support is not available in existing alpha PLL code.
3. There won’t be any change in existing users of Alpha PLL’s since all the newly added code will be under flag for the default PLL operations.

Quoted 8 lines
Quoted 1 line

Ok. I took a long look at this today. I rewrote a bunch of stuff.

Thanks Stephen for reviewing the changes and making the code cleaner. I checked all the code changes and everything looks good. It will work for all of our requirement. I will check with other PLL users also once and then update the patch series with all your suggested code changes after complete testing.

Ok. Please don't resend. I've pushed out the branch to clk-next, and it can be adjusted if needed, or dropped and rewritten if something is totally busted.

Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
#28 lore raw
Quoted 24 lines · Stephen Boyd
Quoted 14 lines · Abhishek Sahu
Quoted 13 lines · Stephen Boyd
Quoted 11 lines · Abhishek Sahu

This patch series does the miscellaneous changes in QCOM Alpha PLL operation and structure to support other types of Alpha PLL’s.

1. It adds the pll_type which will be used for determining all the properties of Alpha PLL.
2. It adds the support for Brammo and Huayra PLL’s for which the support is not available in existing alpha PLL code.
3. There won’t be any change in existing users of Alpha PLL’s since all the newly added code will be under flag for the default PLL operations.

Quoted 8 lines
Quoted 1 line

Ok. I took a long look at this today. I rewrote a bunch of stuff.

Thanks Stephen for reviewing the changes and making the code cleaner. I checked all the code changes and everything looks good. It will work for all of our requirement. I will check with other PLL users also once and then update the patch series with all your suggested code changes after complete testing.

Quoted 3 lines

Ok. Please don't resend. I've pushed out the branch to clk-next, and it can be adjusted if needed, or dropped and rewritten if something is totally busted.

Thanks Stephen for your great help and support.
It seems, we are getting the error in the following error with these patches because of missing EXPORT_SYMBOL_GPL for clk_alpha_pll_regs and clk_hw_is_enabled.

ERROR: "clk_alpha_pll_regs" [drivers/clk/qcom/mmcc-msm8996.ko] undefined!

ERROR: "clk_hw_is_enabled" [drivers/clk/qcom/clk-qcom.ko] undefined!

Caused by commits

d1506b749e92 ("clk: qcom: support for alpha pll properties") e66a4d6d0081 ("clk: qcom: support for dynamic updating the PLL") 301803e6013b ("clk: qcom: support Huayra type Alpha PLL")

#29 lore raw
Quoted 38 lines · Abhishek Sahu
Quoted 24 lines · Stephen Boyd
Quoted 14 lines · Abhishek Sahu
Quoted 13 lines · Stephen Boyd
Quoted 11 lines · Abhishek Sahu

This patch series does the miscellaneous changes in QCOM Alpha PLL operation and structure to support other types of Alpha PLL’s.

1. It adds the pll_type which will be used for determining all the properties of Alpha PLL.
2. It adds the support for Brammo and Huayra PLL’s for which the support is not available in existing alpha PLL code.
3. There won’t be any change in existing users of Alpha PLL’s since all the newly added code will be under flag for the default PLL operations.

Quoted 8 lines
Quoted 1 line

Ok. I took a long look at this today. I rewrote a bunch of stuff.

Thanks Stephen for reviewing the changes and making the code cleaner. I checked all the code changes and everything looks good. It will work for all of our requirement. I will check with other PLL users also once and then update the patch series with all your suggested code changes after complete testing.

Quoted 3 lines

Ok. Please don't resend. I've pushed out the branch to clk-next, and it can be adjusted if needed, or dropped and rewritten if something is totally busted.

Thanks Stephen for your great help and support.
It seems, we are getting the error in the following error with these patches because of missing EXPORT_SYMBOL_GPL for clk_alpha_pll_regs and clk_hw_is_enabled.

ERROR: "clk_alpha_pll_regs" [drivers/clk/qcom/mmcc-msm8996.ko] undefined!

Quoted 7 lines

ERROR: "clk_hw_is_enabled" [drivers/clk/qcom/clk-qcom.ko] undefined!

Caused by commits

d1506b749e92 ("clk: qcom: support for alpha pll properties") e66a4d6d0081 ("clk: qcom: support for dynamic updating the PLL") 301803e6013b ("clk: qcom: support Huayra type Alpha PLL")

Yep. I'll export the regs and remove the clk_hw_is_enabled() usage. Should be possible to do that inside the ops directly instead of going through the framework for it.

Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
#30 lore raw
Quoted 43 lines · Stephen Boyd
Quoted 42 lines · Abhishek Sahu
Quoted 24 lines · Stephen Boyd
Quoted 14 lines · Abhishek Sahu
Quoted 13 lines · Stephen Boyd
Quoted 11 lines · Abhishek Sahu

This patch series does the miscellaneous changes in QCOM Alpha PLL operation and structure to support other types of Alpha PLL’s.

1. It adds the pll_type which will be used for determining all the properties of Alpha PLL.
2. It adds the support for Brammo and Huayra PLL’s for which the support is not available in existing alpha PLL code.
3. There won’t be any change in existing users of Alpha PLL’s since all the newly added code will be under flag for the default PLL operations.

Quoted 8 lines
Quoted 1 line

Ok. I took a long look at this today. I rewrote a bunch of stuff.

Thanks Stephen for reviewing the changes and making the code cleaner. I checked all the code changes and everything looks good. It will work for all of our requirement. I will check with other PLL users also once and then update the patch series with all your suggested code changes after complete testing.

Quoted 3 lines

Ok. Please don't resend. I've pushed out the branch to clk-next, and it can be adjusted if needed, or dropped and rewritten if something is totally busted.

Thanks Stephen for your great help and support.
It seems, we are getting the error in the following error with these patches because of missing EXPORT_SYMBOL_GPL for clk_alpha_pll_regs and clk_hw_is_enabled.

ERROR: "clk_alpha_pll_regs" [drivers/clk/qcom/mmcc-msm8996.ko] undefined!

ERROR: "clk_hw_is_enabled" [drivers/clk/qcom/clk-qcom.ko] undefined!

Caused by commits

Quoted 7 lines
Quoted 3 lines

d1506b749e92 ("clk: qcom: support for alpha pll properties") e66a4d6d0081 ("clk: qcom: support for dynamic updating the PLL") 301803e6013b ("clk: qcom: support Huayra type Alpha PLL")

Yep. I'll export the regs and remove the clk_hw_is_enabled() usage. Should be possible to do that inside the ops directly instead of going through the framework for it.

Thanks Stephen for updating the patches :-)

Correct. clk_alpha_pll_is_enabled can do that.