LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH 0/5] PHY: Add support to output derived and received reference clock from Torrent
@ 2021-09-08 18:26 Swapnil Jakhade
  2021-09-08 18:26 ` [PATCH 1/5] phy: cadence-torrent: Migrate to clk_hw based registration and OF APIs Swapnil Jakhade
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Swapnil Jakhade @ 2021-09-08 18:26 UTC (permalink / raw)
  To: vkoul, kishon, robh+dt, linux-phy, linux-kernel, devicetree
  Cc: mparab, sjakhade, lokeshvutla, a-govindraju

This patch series updates reference clock driver implementation for Torrent
by adding support to output derived as well as received reference clock.
When reference clock driver is enabled, either derived or received refclk
is output on cmn_refclk_p/m.

In derived reference clock mode, cmn_refclk_p/m outputs the refclk derived
from internal PLLs while when received refclk is selected to output on
cmn_refclk_p/m, this is the internal reference clock driven on the
pma_cmn_refclk_int.

Swapnil Jakhade (5):
  phy: cadence-torrent: Migrate to clk_hw based registration and OF APIs
  dt-bindings: phy: cadence-torrent: Add clock IDs for derived and
    received refclk
  phy: cadence-torrent: Add support for derived reference clock output
  phy: cadence-torrent: Add support for received reference clock output
  phy: cadence-torrent: Model reference clock driver as a gate and mux
    clock

 drivers/phy/cadence/phy-cadence-torrent.c | 316 +++++++++++++++++++---
 include/dt-bindings/phy/phy-cadence.h     |   2 +
 2 files changed, 286 insertions(+), 32 deletions(-)

-- 
2.26.1


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

* [PATCH 1/5] phy: cadence-torrent: Migrate to clk_hw based registration and OF APIs
  2021-09-08 18:26 [PATCH 0/5] PHY: Add support to output derived and received reference clock from Torrent Swapnil Jakhade
@ 2021-09-08 18:26 ` Swapnil Jakhade
  2021-09-15  3:51   ` Kishon Vijay Abraham I
  2021-09-08 18:26 ` [PATCH 2/5] dt-bindings: phy: cadence-torrent: Add clock IDs for derived and received refclk Swapnil Jakhade
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Swapnil Jakhade @ 2021-09-08 18:26 UTC (permalink / raw)
  To: vkoul, kishon, robh+dt, linux-phy, linux-kernel, devicetree
  Cc: mparab, sjakhade, lokeshvutla, a-govindraju

Use clk_hw based provider APIs to register clks.

Signed-off-by: Swapnil Jakhade <sjakhade@cadence.com>
---
 drivers/phy/cadence/phy-cadence-torrent.c | 30 ++++++++++++++---------
 1 file changed, 19 insertions(+), 11 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c
index 415ace64adc5..ecb1aa883c05 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -235,6 +235,8 @@
 #define PHY_PMA_CMN_CTRL2		0x0001U
 #define PHY_PMA_PLL_RAW_CTRL		0x0003U
 
+#define CDNS_TORRENT_OUTPUT_CLOCKS	1
+
 static const char * const clk_names[] = {
 	[CDNS_TORRENT_REFCLK_DRIVER] = "refclk-driver",
 };
@@ -333,8 +335,7 @@ struct cdns_torrent_phy {
 	struct regmap_field *phy_pma_pll_raw_ctrl;
 	struct regmap_field *phy_reset_ctrl;
 	struct regmap_field *phy_pcs_iso_link_ctrl_1[MAX_NUM_LANES];
-	struct clk *clks[CDNS_TORRENT_REFCLK_DRIVER + 1];
-	struct clk_onecell_data clk_data;
+	struct clk_hw_onecell_data *clk_hw_data;
 };
 
 enum phy_powerstate {
@@ -1659,8 +1660,9 @@ static int cdns_torrent_derived_refclk_register(struct cdns_torrent_phy *cdns_ph
 	const char *parent_name;
 	struct regmap *regmap;
 	char clk_name[100];
+	struct clk_hw *hw;
 	struct clk *clk;
-	int i;
+	int i, ret;
 
 	derived_refclk = devm_kzalloc(dev, sizeof(*derived_refclk), GFP_KERNEL);
 	if (!derived_refclk)
@@ -1706,11 +1708,12 @@ static int cdns_torrent_derived_refclk_register(struct cdns_torrent_phy *cdns_ph
 
 	derived_refclk->hw.init = init;
 
-	clk = devm_clk_register(dev, &derived_refclk->hw);
-	if (IS_ERR(clk))
-		return PTR_ERR(clk);
+	hw = &derived_refclk->hw;
+	ret = devm_clk_hw_register(dev, hw);
+	if (ret)
+		return ret;
 
-	cdns_phy->clks[CDNS_TORRENT_REFCLK_DRIVER] = clk;
+	cdns_phy->clk_hw_data->hws[CDNS_TORRENT_REFCLK_DRIVER] = hw;
 
 	return 0;
 }
@@ -2188,18 +2191,23 @@ static int cdns_torrent_clk_register(struct cdns_torrent_phy *cdns_phy)
 {
 	struct device *dev = cdns_phy->dev;
 	struct device_node *node = dev->of_node;
+	struct clk_hw_onecell_data *data;
 	int ret;
 
+	data = devm_kzalloc(dev, struct_size(data, hws, CDNS_TORRENT_OUTPUT_CLOCKS), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->num = CDNS_TORRENT_OUTPUT_CLOCKS;
+	cdns_phy->clk_hw_data = data;
+
 	ret = cdns_torrent_derived_refclk_register(cdns_phy);
 	if (ret) {
 		dev_err(dev, "failed to register derived refclk\n");
 		return ret;
 	}
 
-	cdns_phy->clk_data.clks = cdns_phy->clks;
-	cdns_phy->clk_data.clk_num = CDNS_TORRENT_REFCLK_DRIVER + 1;
-
-	ret = of_clk_add_provider(node, of_clk_src_onecell_get, &cdns_phy->clk_data);
+	ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, data);
 	if (ret) {
 		dev_err(dev, "Failed to add clock provider: %s\n", node->name);
 		return ret;
-- 
2.26.1


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

* [PATCH 2/5] dt-bindings: phy: cadence-torrent: Add clock IDs for derived and received refclk
  2021-09-08 18:26 [PATCH 0/5] PHY: Add support to output derived and received reference clock from Torrent Swapnil Jakhade
  2021-09-08 18:26 ` [PATCH 1/5] phy: cadence-torrent: Migrate to clk_hw based registration and OF APIs Swapnil Jakhade
@ 2021-09-08 18:26 ` Swapnil Jakhade
  2021-09-21 17:10   ` Rob Herring
  2021-09-08 18:26 ` [PATCH 3/5] phy: cadence-torrent: Add support for derived reference clock output Swapnil Jakhade
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Swapnil Jakhade @ 2021-09-08 18:26 UTC (permalink / raw)
  To: vkoul, kishon, robh+dt, linux-phy, linux-kernel, devicetree
  Cc: mparab, sjakhade, lokeshvutla, a-govindraju

Add clock IDs for derived and received reference clock output.

Signed-off-by: Swapnil Jakhade <sjakhade@cadence.com>
---
 include/dt-bindings/phy/phy-cadence.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/dt-bindings/phy/phy-cadence.h b/include/dt-bindings/phy/phy-cadence.h
index 4652bcb86265..24fdc9e11bd6 100644
--- a/include/dt-bindings/phy/phy-cadence.h
+++ b/include/dt-bindings/phy/phy-cadence.h
@@ -12,6 +12,8 @@
 #define TORRENT_SERDES_INTERNAL_SSC	2
 
 #define CDNS_TORRENT_REFCLK_DRIVER      0
+#define CDNS_TORRENT_DERIVED_REFCLK	1
+#define CDNS_TORRENT_RECEIVED_REFCLK	2
 
 /* Sierra */
 #define CDNS_SIERRA_PLL_CMNLC		0
-- 
2.26.1


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

* [PATCH 3/5] phy: cadence-torrent: Add support for derived reference clock output
  2021-09-08 18:26 [PATCH 0/5] PHY: Add support to output derived and received reference clock from Torrent Swapnil Jakhade
  2021-09-08 18:26 ` [PATCH 1/5] phy: cadence-torrent: Migrate to clk_hw based registration and OF APIs Swapnil Jakhade
  2021-09-08 18:26 ` [PATCH 2/5] dt-bindings: phy: cadence-torrent: Add clock IDs for derived and received refclk Swapnil Jakhade
@ 2021-09-08 18:26 ` Swapnil Jakhade
  2021-09-15  3:55   ` Kishon Vijay Abraham I
  2021-09-08 18:26 ` [PATCH 4/5] phy: cadence-torrent: Add support for received " Swapnil Jakhade
  2021-09-08 18:26 ` [PATCH 5/5] phy: cadence-torrent: Model reference clock driver as a gate and mux clock Swapnil Jakhade
  4 siblings, 1 reply; 9+ messages in thread
From: Swapnil Jakhade @ 2021-09-08 18:26 UTC (permalink / raw)
  To: vkoul, kishon, robh+dt, linux-phy, linux-kernel, devicetree
  Cc: mparab, sjakhade, lokeshvutla, a-govindraju

Update the reference clock driver implementation where cmn_refclk_<p/m>
is configured to output the reference clock. cmn_refclk_p/m will output
either derived or received reference clock based on the selection. So,
all these clocks should be modelled separately. Model the derived
reference clock here as a first step to support reference clock driver.

Signed-off-by: Swapnil Jakhade <sjakhade@cadence.com>
---
 drivers/phy/cadence/phy-cadence-torrent.c | 78 +++++++++--------------
 1 file changed, 31 insertions(+), 47 deletions(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c
index ecb1aa883c05..6dceb12e88c4 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -235,10 +235,11 @@
 #define PHY_PMA_CMN_CTRL2		0x0001U
 #define PHY_PMA_PLL_RAW_CTRL		0x0003U
 
-#define CDNS_TORRENT_OUTPUT_CLOCKS	1
+#define CDNS_TORRENT_OUTPUT_CLOCKS	2
 
 static const char * const clk_names[] = {
 	[CDNS_TORRENT_REFCLK_DRIVER] = "refclk-driver",
+	[CDNS_TORRENT_DERIVED_REFCLK] = "refclk-der",
 };
 
 static const struct reg_field phy_pll_cfg =
@@ -261,23 +262,8 @@ static const struct reg_field phy_pcs_iso_link_ctrl_1 =
 
 static const struct reg_field phy_pipe_cmn_ctrl1_0 = REG_FIELD(PHY_PIPE_CMN_CTRL1, 0, 0);
 
-#define REFCLK_OUT_NUM_CMN_CONFIG	5
-
-enum cdns_torrent_refclk_out_cmn {
-	CMN_CDIAG_REFCLK_OVRD_4,
-	CMN_CDIAG_REFCLK_DRV0_CTRL_1,
-	CMN_CDIAG_REFCLK_DRV0_CTRL_4,
-	CMN_CDIAG_REFCLK_DRV0_CTRL_5,
-	CMN_CDIAG_REFCLK_DRV0_CTRL_6,
-};
-
-static const struct reg_field refclk_out_cmn_cfg[] = {
-	[CMN_CDIAG_REFCLK_OVRD_4]	= REG_FIELD(CMN_CDIAG_REFCLK_OVRD, 4, 4),
-	[CMN_CDIAG_REFCLK_DRV0_CTRL_1]	= REG_FIELD(CMN_CDIAG_REFCLK_DRV0_CTRL, 1, 1),
-	[CMN_CDIAG_REFCLK_DRV0_CTRL_4]	= REG_FIELD(CMN_CDIAG_REFCLK_DRV0_CTRL, 4, 4),
-	[CMN_CDIAG_REFCLK_DRV0_CTRL_5]  = REG_FIELD(CMN_CDIAG_REFCLK_DRV0_CTRL, 5, 5),
-	[CMN_CDIAG_REFCLK_DRV0_CTRL_6]	= REG_FIELD(CMN_CDIAG_REFCLK_DRV0_CTRL, 6, 6),
-};
+static const struct reg_field cmn_cdiag_refclk_ovrd_4 =
+				REG_FIELD(CMN_CDIAG_REFCLK_OVRD, 4, 4);
 
 enum cdns_torrent_phy_type {
 	TYPE_NONE,
@@ -330,6 +316,8 @@ struct cdns_torrent_phy {
 	struct regmap *regmap_phy_pcs_lane_cdb[MAX_NUM_LANES];
 	struct regmap *regmap_dptx_phy_reg;
 	struct regmap_field *phy_pll_cfg;
+	struct regmap_field *phy_pipe_cmn_ctrl1_0;
+	struct regmap_field *cmn_cdiag_refclk_ovrd_4;
 	struct regmap_field *phy_pma_cmn_ctrl_1;
 	struct regmap_field *phy_pma_cmn_ctrl_2;
 	struct regmap_field *phy_pma_pll_raw_ctrl;
@@ -348,7 +336,7 @@ enum phy_powerstate {
 struct cdns_torrent_derived_refclk {
 	struct clk_hw		hw;
 	struct regmap_field	*phy_pipe_cmn_ctrl1_0;
-	struct regmap_field	*cmn_fields[REFCLK_OUT_NUM_CMN_CONFIG];
+	struct regmap_field	*cmn_cdiag_refclk_ovrd_4;
 	struct clk_init_data	clk_data;
 };
 
@@ -1618,11 +1606,7 @@ static int cdns_torrent_derived_refclk_enable(struct clk_hw *hw)
 {
 	struct cdns_torrent_derived_refclk *derived_refclk = to_cdns_torrent_derived_refclk(hw);
 
-	regmap_field_write(derived_refclk->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_6], 0);
-	regmap_field_write(derived_refclk->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_4], 1);
-	regmap_field_write(derived_refclk->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_5], 1);
-	regmap_field_write(derived_refclk->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_1], 0);
-	regmap_field_write(derived_refclk->cmn_fields[CMN_CDIAG_REFCLK_OVRD_4], 1);
+	regmap_field_write(derived_refclk->cmn_cdiag_refclk_ovrd_4, 1);
 	regmap_field_write(derived_refclk->phy_pipe_cmn_ctrl1_0, 1);
 
 	return 0;
@@ -1633,6 +1617,7 @@ static void cdns_torrent_derived_refclk_disable(struct clk_hw *hw)
 	struct cdns_torrent_derived_refclk *derived_refclk = to_cdns_torrent_derived_refclk(hw);
 
 	regmap_field_write(derived_refclk->phy_pipe_cmn_ctrl1_0, 0);
+	regmap_field_write(derived_refclk->cmn_cdiag_refclk_ovrd_4, 0);
 }
 
 static int cdns_torrent_derived_refclk_is_enabled(struct clk_hw *hw)
@@ -1640,7 +1625,7 @@ static int cdns_torrent_derived_refclk_is_enabled(struct clk_hw *hw)
 	struct cdns_torrent_derived_refclk *derived_refclk = to_cdns_torrent_derived_refclk(hw);
 	int val;
 
-	regmap_field_read(derived_refclk->phy_pipe_cmn_ctrl1_0, &val);
+	regmap_field_read(derived_refclk->cmn_cdiag_refclk_ovrd_4, &val);
 
 	return !!val;
 }
@@ -1655,21 +1640,19 @@ static int cdns_torrent_derived_refclk_register(struct cdns_torrent_phy *cdns_ph
 {
 	struct cdns_torrent_derived_refclk *derived_refclk;
 	struct device *dev = cdns_phy->dev;
-	struct regmap_field *field;
 	struct clk_init_data *init;
 	const char *parent_name;
-	struct regmap *regmap;
 	char clk_name[100];
 	struct clk_hw *hw;
 	struct clk *clk;
-	int i, ret;
+	int ret;
 
 	derived_refclk = devm_kzalloc(dev, sizeof(*derived_refclk), GFP_KERNEL);
 	if (!derived_refclk)
 		return -ENOMEM;
 
 	snprintf(clk_name, sizeof(clk_name), "%s_%s", dev_name(dev),
-		 clk_names[CDNS_TORRENT_REFCLK_DRIVER]);
+		 clk_names[CDNS_TORRENT_DERIVED_REFCLK]);
 
 	clk = devm_clk_get_optional(dev, "phy_en_refclk");
 	if (IS_ERR(clk)) {
@@ -1688,23 +1671,8 @@ static int cdns_torrent_derived_refclk_register(struct cdns_torrent_phy *cdns_ph
 	init->flags = 0;
 	init->name = clk_name;
 
-	regmap = cdns_phy->regmap_phy_pcs_common_cdb;
-	field = devm_regmap_field_alloc(dev, regmap, phy_pipe_cmn_ctrl1_0);
-	if (IS_ERR(field)) {
-		dev_err(dev, "phy_pipe_cmn_ctrl1_0 reg field init failed\n");
-		return PTR_ERR(field);
-	}
-	derived_refclk->phy_pipe_cmn_ctrl1_0 = field;
-
-	regmap = cdns_phy->regmap_common_cdb;
-	for (i = 0; i < REFCLK_OUT_NUM_CMN_CONFIG; i++) {
-		field = devm_regmap_field_alloc(dev, regmap, refclk_out_cmn_cfg[i]);
-		if (IS_ERR(field)) {
-			dev_err(dev, "CMN reg field init failed\n");
-			return PTR_ERR(field);
-		}
-		derived_refclk->cmn_fields[i] = field;
-	}
+	derived_refclk->phy_pipe_cmn_ctrl1_0 = cdns_phy->phy_pipe_cmn_ctrl1_0;
+	derived_refclk->cmn_cdiag_refclk_ovrd_4 = cdns_phy->cmn_cdiag_refclk_ovrd_4;
 
 	derived_refclk->hw.init = init;
 
@@ -1713,7 +1681,7 @@ static int cdns_torrent_derived_refclk_register(struct cdns_torrent_phy *cdns_ph
 	if (ret)
 		return ret;
 
-	cdns_phy->clk_hw_data->hws[CDNS_TORRENT_REFCLK_DRIVER] = hw;
+	cdns_phy->clk_hw_data->hws[CDNS_TORRENT_DERIVED_REFCLK] = hw;
 
 	return 0;
 }
@@ -1768,6 +1736,22 @@ static int cdns_torrent_regfield_init(struct cdns_torrent_phy *cdns_phy)
 	}
 	cdns_phy->phy_pll_cfg = field;
 
+	regmap = cdns_phy->regmap_phy_pcs_common_cdb;
+	field = devm_regmap_field_alloc(dev, regmap, phy_pipe_cmn_ctrl1_0);
+	if (IS_ERR(field)) {
+		dev_err(dev, "phy_pipe_cmn_ctrl1_0 reg field init failed\n");
+		return PTR_ERR(field);
+	}
+	cdns_phy->phy_pipe_cmn_ctrl1_0 = field;
+
+	regmap = cdns_phy->regmap_common_cdb;
+	field = devm_regmap_field_alloc(dev, regmap, cmn_cdiag_refclk_ovrd_4);
+	if (IS_ERR(field)) {
+		dev_err(dev, "cmn_cdiag_refclk_ovrd_4 reg field init failed\n");
+		return PTR_ERR(field);
+	}
+	cdns_phy->cmn_cdiag_refclk_ovrd_4 = field;
+
 	regmap = cdns_phy->regmap_phy_pma_common_cdb;
 	field = devm_regmap_field_alloc(dev, regmap, phy_pma_cmn_ctrl_1);
 	if (IS_ERR(field)) {
-- 
2.26.1


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

* [PATCH 4/5] phy: cadence-torrent: Add support for received reference clock output
  2021-09-08 18:26 [PATCH 0/5] PHY: Add support to output derived and received reference clock from Torrent Swapnil Jakhade
                   ` (2 preceding siblings ...)
  2021-09-08 18:26 ` [PATCH 3/5] phy: cadence-torrent: Add support for derived reference clock output Swapnil Jakhade
@ 2021-09-08 18:26 ` Swapnil Jakhade
  2021-09-08 18:26 ` [PATCH 5/5] phy: cadence-torrent: Model reference clock driver as a gate and mux clock Swapnil Jakhade
  4 siblings, 0 replies; 9+ messages in thread
From: Swapnil Jakhade @ 2021-09-08 18:26 UTC (permalink / raw)
  To: vkoul, kishon, robh+dt, linux-phy, linux-kernel, devicetree
  Cc: mparab, sjakhade, lokeshvutla, a-govindraju

Model the received reference clock as a next step to support reference
clock driver. When received refclk is selected to output on
cmn_refclk_p/m, this is the internal reference clock driven on the
pma_cmn_refclk_int.

Signed-off-by: Swapnil Jakhade <sjakhade@cadence.com>
---
 drivers/phy/cadence/phy-cadence-torrent.c | 102 +++++++++++++++++++++-
 1 file changed, 101 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c
index 6dceb12e88c4..2c42a6690632 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -235,11 +235,12 @@
 #define PHY_PMA_CMN_CTRL2		0x0001U
 #define PHY_PMA_PLL_RAW_CTRL		0x0003U
 
-#define CDNS_TORRENT_OUTPUT_CLOCKS	2
+#define CDNS_TORRENT_OUTPUT_CLOCKS	3
 
 static const char * const clk_names[] = {
 	[CDNS_TORRENT_REFCLK_DRIVER] = "refclk-driver",
 	[CDNS_TORRENT_DERIVED_REFCLK] = "refclk-der",
+	[CDNS_TORRENT_RECEIVED_REFCLK] = "refclk-rec",
 };
 
 static const struct reg_field phy_pll_cfg =
@@ -343,6 +344,16 @@ struct cdns_torrent_derived_refclk {
 #define to_cdns_torrent_derived_refclk(_hw)	\
 			container_of(_hw, struct cdns_torrent_derived_refclk, hw)
 
+struct cdns_torrent_received_refclk {
+	struct clk_hw		hw;
+	struct regmap_field	*phy_pipe_cmn_ctrl1_0;
+	struct regmap_field	*cmn_cdiag_refclk_ovrd_4;
+	struct clk_init_data	clk_data;
+};
+
+#define to_cdns_torrent_received_refclk(_hw)	\
+			container_of(_hw, struct cdns_torrent_received_refclk, hw)
+
 struct cdns_reg_pairs {
 	u32 val;
 	u32 off;
@@ -1686,6 +1697,89 @@ static int cdns_torrent_derived_refclk_register(struct cdns_torrent_phy *cdns_ph
 	return 0;
 }
 
+static int cdns_torrent_received_refclk_enable(struct clk_hw *hw)
+{
+	struct cdns_torrent_received_refclk *received_refclk = to_cdns_torrent_received_refclk(hw);
+
+	regmap_field_write(received_refclk->phy_pipe_cmn_ctrl1_0, 1);
+
+	return 0;
+}
+
+static void cdns_torrent_received_refclk_disable(struct clk_hw *hw)
+{
+	struct cdns_torrent_received_refclk *received_refclk = to_cdns_torrent_received_refclk(hw);
+
+	regmap_field_write(received_refclk->phy_pipe_cmn_ctrl1_0, 0);
+}
+
+static int cdns_torrent_received_refclk_is_enabled(struct clk_hw *hw)
+{
+	struct cdns_torrent_received_refclk *received_refclk = to_cdns_torrent_received_refclk(hw);
+	int val, cmn_val;
+
+	regmap_field_read(received_refclk->phy_pipe_cmn_ctrl1_0, &val);
+	regmap_field_read(received_refclk->cmn_cdiag_refclk_ovrd_4, &cmn_val);
+
+	return val && !cmn_val;
+}
+
+static const struct clk_ops cdns_torrent_received_refclk_ops = {
+	.enable = cdns_torrent_received_refclk_enable,
+	.disable = cdns_torrent_received_refclk_disable,
+	.is_enabled = cdns_torrent_received_refclk_is_enabled,
+};
+
+static int cdns_torrent_received_refclk_register(struct cdns_torrent_phy *cdns_phy)
+{
+	struct cdns_torrent_received_refclk *received_refclk;
+	struct device *dev = cdns_phy->dev;
+	struct clk_init_data *init;
+	const char *parent_name;
+	char clk_name[100];
+	struct clk_hw *hw;
+	struct clk *clk;
+	int ret;
+
+	received_refclk = devm_kzalloc(dev, sizeof(*received_refclk), GFP_KERNEL);
+	if (!received_refclk)
+		return -ENOMEM;
+
+	snprintf(clk_name, sizeof(clk_name), "%s_%s", dev_name(dev),
+		 clk_names[CDNS_TORRENT_RECEIVED_REFCLK]);
+
+	clk = devm_clk_get_optional(dev, "phy_en_refclk");
+	if (IS_ERR(clk)) {
+		dev_err(dev, "No parent clock for received_refclk\n");
+		return PTR_ERR(clk);
+	}
+
+	init = &received_refclk->clk_data;
+
+	if (clk) {
+		parent_name = __clk_get_name(clk);
+		init->parent_names = &parent_name;
+		init->num_parents = 1;
+	}
+	init->ops = &cdns_torrent_received_refclk_ops;
+	init->flags = 0;
+	init->name = clk_name;
+
+	received_refclk->phy_pipe_cmn_ctrl1_0 = cdns_phy->phy_pipe_cmn_ctrl1_0;
+	received_refclk->cmn_cdiag_refclk_ovrd_4 = cdns_phy->cmn_cdiag_refclk_ovrd_4;
+
+	received_refclk->hw.init = init;
+
+	hw = &received_refclk->hw;
+	ret = devm_clk_hw_register(dev, hw);
+	if (ret)
+		return ret;
+
+	cdns_phy->clk_hw_data->hws[CDNS_TORRENT_RECEIVED_REFCLK] = hw;
+
+	return 0;
+}
+
 static struct regmap *cdns_regmap_init(struct device *dev, void __iomem *base,
 				       u32 block_offset,
 				       u8 reg_offset_shift,
@@ -2191,6 +2285,12 @@ static int cdns_torrent_clk_register(struct cdns_torrent_phy *cdns_phy)
 		return ret;
 	}
 
+	ret = cdns_torrent_received_refclk_register(cdns_phy);
+	if (ret) {
+		dev_err(dev, "failed to register received refclk\n");
+		return ret;
+	}
+
 	ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, data);
 	if (ret) {
 		dev_err(dev, "Failed to add clock provider: %s\n", node->name);
-- 
2.26.1


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

* [PATCH 5/5] phy: cadence-torrent: Model reference clock driver as a gate and mux clock
  2021-09-08 18:26 [PATCH 0/5] PHY: Add support to output derived and received reference clock from Torrent Swapnil Jakhade
                   ` (3 preceding siblings ...)
  2021-09-08 18:26 ` [PATCH 4/5] phy: cadence-torrent: Add support for received " Swapnil Jakhade
@ 2021-09-08 18:26 ` Swapnil Jakhade
  4 siblings, 0 replies; 9+ messages in thread
From: Swapnil Jakhade @ 2021-09-08 18:26 UTC (permalink / raw)
  To: vkoul, kishon, robh+dt, linux-phy, linux-kernel, devicetree
  Cc: mparab, sjakhade, lokeshvutla, a-govindraju

When reference clock driver is enabled, either derived or received refclk
is output on cmn_refclk_p/m. Model reference clock driver as a "clock"
with gate and mux clock operations.

Signed-off-by: Swapnil Jakhade <sjakhade@cadence.com>
---
 drivers/phy/cadence/phy-cadence-torrent.c | 160 ++++++++++++++++++++++
 1 file changed, 160 insertions(+)

diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c
index 2c42a6690632..5786166133d3 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -266,6 +266,29 @@ static const struct reg_field phy_pipe_cmn_ctrl1_0 = REG_FIELD(PHY_PIPE_CMN_CTRL
 static const struct reg_field cmn_cdiag_refclk_ovrd_4 =
 				REG_FIELD(CMN_CDIAG_REFCLK_OVRD, 4, 4);
 
+#define REFCLK_OUT_NUM_CMN_CONFIG	4
+
+enum cdns_torrent_refclk_out_cmn {
+	CMN_CDIAG_REFCLK_DRV0_CTRL_1,
+	CMN_CDIAG_REFCLK_DRV0_CTRL_4,
+	CMN_CDIAG_REFCLK_DRV0_CTRL_5,
+	CMN_CDIAG_REFCLK_DRV0_CTRL_6,
+};
+
+static const struct reg_field refclk_out_cmn_cfg[] = {
+	[CMN_CDIAG_REFCLK_DRV0_CTRL_1]	= REG_FIELD(CMN_CDIAG_REFCLK_DRV0_CTRL, 1, 1),
+	[CMN_CDIAG_REFCLK_DRV0_CTRL_4]	= REG_FIELD(CMN_CDIAG_REFCLK_DRV0_CTRL, 4, 4),
+	[CMN_CDIAG_REFCLK_DRV0_CTRL_5]  = REG_FIELD(CMN_CDIAG_REFCLK_DRV0_CTRL, 5, 5),
+	[CMN_CDIAG_REFCLK_DRV0_CTRL_6]	= REG_FIELD(CMN_CDIAG_REFCLK_DRV0_CTRL, 6, 6),
+};
+
+static const int refclk_driver_parent_index[] = {
+	CDNS_TORRENT_DERIVED_REFCLK,
+	CDNS_TORRENT_RECEIVED_REFCLK
+};
+
+static u32 cdns_torrent_refclk_driver_mux_table[] = { 1, 0 };
+
 enum cdns_torrent_phy_type {
 	TYPE_NONE,
 	TYPE_DP,
@@ -334,6 +357,15 @@ enum phy_powerstate {
 	POWERSTATE_A3 = 3,
 };
 
+struct cdns_torrent_refclk_driver {
+	struct clk_hw		hw;
+	struct regmap_field	*cmn_fields[REFCLK_OUT_NUM_CMN_CONFIG];
+	struct clk_init_data	clk_data;
+};
+
+#define to_cdns_torrent_refclk_driver(_hw)	\
+			container_of(_hw, struct cdns_torrent_refclk_driver, hw)
+
 struct cdns_torrent_derived_refclk {
 	struct clk_hw		hw;
 	struct regmap_field	*phy_pipe_cmn_ctrl1_0;
@@ -1780,6 +1812,128 @@ static int cdns_torrent_received_refclk_register(struct cdns_torrent_phy *cdns_p
 	return 0;
 }
 
+static int cdns_torrent_refclk_driver_enable(struct clk_hw *hw)
+{
+	struct cdns_torrent_refclk_driver *refclk_driver = to_cdns_torrent_refclk_driver(hw);
+
+	regmap_field_write(refclk_driver->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_6], 0);
+	regmap_field_write(refclk_driver->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_5], 1);
+	regmap_field_write(refclk_driver->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_1], 0);
+
+	return 0;
+}
+
+static void cdns_torrent_refclk_driver_disable(struct clk_hw *hw)
+{
+	struct cdns_torrent_refclk_driver *refclk_driver = to_cdns_torrent_refclk_driver(hw);
+
+	regmap_field_write(refclk_driver->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_1], 1);
+}
+
+static int cdns_torrent_refclk_driver_is_enabled(struct clk_hw *hw)
+{
+	struct cdns_torrent_refclk_driver *refclk_driver = to_cdns_torrent_refclk_driver(hw);
+	int val;
+
+	regmap_field_read(refclk_driver->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_1], &val);
+
+	return !val;
+}
+
+static u8 cdns_torrent_refclk_driver_get_parent(struct clk_hw *hw)
+{
+	struct cdns_torrent_refclk_driver *refclk_driver = to_cdns_torrent_refclk_driver(hw);
+	unsigned int val;
+
+	regmap_field_read(refclk_driver->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_4], &val);
+	return clk_mux_val_to_index(hw, cdns_torrent_refclk_driver_mux_table, 0, val);
+}
+
+static int cdns_torrent_refclk_driver_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct cdns_torrent_refclk_driver *refclk_driver = to_cdns_torrent_refclk_driver(hw);
+	unsigned int val;
+
+	val = cdns_torrent_refclk_driver_mux_table[index];
+	return regmap_field_write(refclk_driver->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_4], val);
+}
+
+static const struct clk_ops cdns_torrent_refclk_driver_ops = {
+	.enable = cdns_torrent_refclk_driver_enable,
+	.disable = cdns_torrent_refclk_driver_disable,
+	.is_enabled = cdns_torrent_refclk_driver_is_enabled,
+	.set_parent = cdns_torrent_refclk_driver_set_parent,
+	.get_parent = cdns_torrent_refclk_driver_get_parent,
+};
+
+static int cdns_torrent_refclk_driver_register(struct cdns_torrent_phy *cdns_phy)
+{
+	struct cdns_torrent_refclk_driver *refclk_driver;
+	struct device *dev = cdns_phy->dev;
+	struct regmap_field *field;
+	struct clk_init_data *init;
+	const char **parent_names;
+	unsigned int num_parents;
+	struct regmap *regmap;
+	char clk_name[100];
+	struct clk_hw *hw;
+	int i, ret;
+
+	refclk_driver = devm_kzalloc(dev, sizeof(*refclk_driver), GFP_KERNEL);
+	if (!refclk_driver)
+		return -ENOMEM;
+
+	num_parents = ARRAY_SIZE(refclk_driver_parent_index);
+	parent_names = devm_kzalloc(dev, (sizeof(char *) * num_parents), GFP_KERNEL);
+	if (!parent_names)
+		return -ENOMEM;
+
+	for (i = 0; i < num_parents; i++) {
+		hw = cdns_phy->clk_hw_data->hws[refclk_driver_parent_index[i]];
+		if (IS_ERR_OR_NULL(hw)) {
+			dev_err(dev, "No parent clock for refclk driver clock\n");
+			return IS_ERR(hw) ? PTR_ERR(hw) : -ENOENT;
+		}
+		parent_names[i] = clk_hw_get_name(hw);
+	}
+
+	snprintf(clk_name, sizeof(clk_name), "%s_%s", dev_name(dev),
+		 clk_names[CDNS_TORRENT_REFCLK_DRIVER]);
+
+	init = &refclk_driver->clk_data;
+
+	init->ops = &cdns_torrent_refclk_driver_ops;
+	init->flags = CLK_SET_RATE_NO_REPARENT;
+	init->parent_names = parent_names;
+	init->num_parents = num_parents;
+	init->name = clk_name;
+
+	regmap = cdns_phy->regmap_common_cdb;
+
+	for (i = 0; i < REFCLK_OUT_NUM_CMN_CONFIG; i++) {
+		field = devm_regmap_field_alloc(dev, regmap, refclk_out_cmn_cfg[i]);
+		if (IS_ERR(field)) {
+			dev_err(dev, "Refclk driver CMN reg field init failed\n");
+			return PTR_ERR(field);
+		}
+		refclk_driver->cmn_fields[i] = field;
+	}
+
+	/* Enable Derived reference clock as default */
+	regmap_field_write(refclk_driver->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_4], 1);
+
+	refclk_driver->hw.init = init;
+
+	hw = &refclk_driver->hw;
+	ret = devm_clk_hw_register(dev, hw);
+	if (ret)
+		return ret;
+
+	cdns_phy->clk_hw_data->hws[CDNS_TORRENT_REFCLK_DRIVER] = hw;
+
+	return 0;
+}
+
 static struct regmap *cdns_regmap_init(struct device *dev, void __iomem *base,
 				       u32 block_offset,
 				       u8 reg_offset_shift,
@@ -2291,6 +2445,12 @@ static int cdns_torrent_clk_register(struct cdns_torrent_phy *cdns_phy)
 		return ret;
 	}
 
+	ret = cdns_torrent_refclk_driver_register(cdns_phy);
+	if (ret) {
+		dev_err(dev, "failed to register refclk driver\n");
+		return ret;
+	}
+
 	ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, data);
 	if (ret) {
 		dev_err(dev, "Failed to add clock provider: %s\n", node->name);
-- 
2.26.1


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

* Re: [PATCH 1/5] phy: cadence-torrent: Migrate to clk_hw based registration and OF APIs
  2021-09-08 18:26 ` [PATCH 1/5] phy: cadence-torrent: Migrate to clk_hw based registration and OF APIs Swapnil Jakhade
@ 2021-09-15  3:51   ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 9+ messages in thread
From: Kishon Vijay Abraham I @ 2021-09-15  3:51 UTC (permalink / raw)
  To: Swapnil Jakhade, vkoul, robh+dt, linux-phy, linux-kernel, devicetree
  Cc: mparab, lokeshvutla, a-govindraju

Hi Swapnil,

On 08/09/21 11:56 pm, Swapnil Jakhade wrote:
> Use clk_hw based provider APIs to register clks.

Please explain the reasoning for moving to clk_hw based API.

Thanks,
Kishon
> 
> Signed-off-by: Swapnil Jakhade <sjakhade@cadence.com>
> ---
>  drivers/phy/cadence/phy-cadence-torrent.c | 30 ++++++++++++++---------
>  1 file changed, 19 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c
> index 415ace64adc5..ecb1aa883c05 100644
> --- a/drivers/phy/cadence/phy-cadence-torrent.c
> +++ b/drivers/phy/cadence/phy-cadence-torrent.c
> @@ -235,6 +235,8 @@
>  #define PHY_PMA_CMN_CTRL2		0x0001U
>  #define PHY_PMA_PLL_RAW_CTRL		0x0003U
>  
> +#define CDNS_TORRENT_OUTPUT_CLOCKS	1
> +
>  static const char * const clk_names[] = {
>  	[CDNS_TORRENT_REFCLK_DRIVER] = "refclk-driver",
>  };
> @@ -333,8 +335,7 @@ struct cdns_torrent_phy {
>  	struct regmap_field *phy_pma_pll_raw_ctrl;
>  	struct regmap_field *phy_reset_ctrl;
>  	struct regmap_field *phy_pcs_iso_link_ctrl_1[MAX_NUM_LANES];
> -	struct clk *clks[CDNS_TORRENT_REFCLK_DRIVER + 1];
> -	struct clk_onecell_data clk_data;
> +	struct clk_hw_onecell_data *clk_hw_data;
>  };
>  
>  enum phy_powerstate {
> @@ -1659,8 +1660,9 @@ static int cdns_torrent_derived_refclk_register(struct cdns_torrent_phy *cdns_ph
>  	const char *parent_name;
>  	struct regmap *regmap;
>  	char clk_name[100];
> +	struct clk_hw *hw;
>  	struct clk *clk;
> -	int i;
> +	int i, ret;
>  
>  	derived_refclk = devm_kzalloc(dev, sizeof(*derived_refclk), GFP_KERNEL);
>  	if (!derived_refclk)
> @@ -1706,11 +1708,12 @@ static int cdns_torrent_derived_refclk_register(struct cdns_torrent_phy *cdns_ph
>  
>  	derived_refclk->hw.init = init;
>  
> -	clk = devm_clk_register(dev, &derived_refclk->hw);
> -	if (IS_ERR(clk))
> -		return PTR_ERR(clk);
> +	hw = &derived_refclk->hw;
> +	ret = devm_clk_hw_register(dev, hw);
> +	if (ret)
> +		return ret;
>  
> -	cdns_phy->clks[CDNS_TORRENT_REFCLK_DRIVER] = clk;
> +	cdns_phy->clk_hw_data->hws[CDNS_TORRENT_REFCLK_DRIVER] = hw;
>  
>  	return 0;
>  }
> @@ -2188,18 +2191,23 @@ static int cdns_torrent_clk_register(struct cdns_torrent_phy *cdns_phy)
>  {
>  	struct device *dev = cdns_phy->dev;
>  	struct device_node *node = dev->of_node;
> +	struct clk_hw_onecell_data *data;
>  	int ret;
>  
> +	data = devm_kzalloc(dev, struct_size(data, hws, CDNS_TORRENT_OUTPUT_CLOCKS), GFP_KERNEL);
> +	if (!data)
> +		return -ENOMEM;
> +
> +	data->num = CDNS_TORRENT_OUTPUT_CLOCKS;
> +	cdns_phy->clk_hw_data = data;
> +
>  	ret = cdns_torrent_derived_refclk_register(cdns_phy);
>  	if (ret) {
>  		dev_err(dev, "failed to register derived refclk\n");
>  		return ret;
>  	}
>  
> -	cdns_phy->clk_data.clks = cdns_phy->clks;
> -	cdns_phy->clk_data.clk_num = CDNS_TORRENT_REFCLK_DRIVER + 1;
> -
> -	ret = of_clk_add_provider(node, of_clk_src_onecell_get, &cdns_phy->clk_data);
> +	ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, data);
>  	if (ret) {
>  		dev_err(dev, "Failed to add clock provider: %s\n", node->name);
>  		return ret;
> 

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

* Re: [PATCH 3/5] phy: cadence-torrent: Add support for derived reference clock output
  2021-09-08 18:26 ` [PATCH 3/5] phy: cadence-torrent: Add support for derived reference clock output Swapnil Jakhade
@ 2021-09-15  3:55   ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 9+ messages in thread
From: Kishon Vijay Abraham I @ 2021-09-15  3:55 UTC (permalink / raw)
  To: Swapnil Jakhade, vkoul, robh+dt, linux-phy, linux-kernel, devicetree
  Cc: mparab, lokeshvutla, a-govindraju

Hi Swapnil,

On 08/09/21 11:56 pm, Swapnil Jakhade wrote:
> Update the reference clock driver implementation where cmn_refclk_<p/m>
> is configured to output the reference clock. cmn_refclk_p/m will output
> either derived or received reference clock based on the selection. So,
> all these clocks should be modelled separately. Model the derived
> reference clock here as a first step to support reference clock driver.
> 

Will AM64 work after this patch? Since you are removing bunch of configurations
here, would it affect git bisectability?

Thanks
Kishon

> Signed-off-by: Swapnil Jakhade <sjakhade@cadence.com>
> ---
>  drivers/phy/cadence/phy-cadence-torrent.c | 78 +++++++++--------------
>  1 file changed, 31 insertions(+), 47 deletions(-)
> 
> diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c
> index ecb1aa883c05..6dceb12e88c4 100644
> --- a/drivers/phy/cadence/phy-cadence-torrent.c
> +++ b/drivers/phy/cadence/phy-cadence-torrent.c
> @@ -235,10 +235,11 @@
>  #define PHY_PMA_CMN_CTRL2		0x0001U
>  #define PHY_PMA_PLL_RAW_CTRL		0x0003U
>  
> -#define CDNS_TORRENT_OUTPUT_CLOCKS	1
> +#define CDNS_TORRENT_OUTPUT_CLOCKS	2
>  
>  static const char * const clk_names[] = {
>  	[CDNS_TORRENT_REFCLK_DRIVER] = "refclk-driver",
> +	[CDNS_TORRENT_DERIVED_REFCLK] = "refclk-der",
>  };
>  
>  static const struct reg_field phy_pll_cfg =
> @@ -261,23 +262,8 @@ static const struct reg_field phy_pcs_iso_link_ctrl_1 =
>  
>  static const struct reg_field phy_pipe_cmn_ctrl1_0 = REG_FIELD(PHY_PIPE_CMN_CTRL1, 0, 0);
>  
> -#define REFCLK_OUT_NUM_CMN_CONFIG	5
> -
> -enum cdns_torrent_refclk_out_cmn {
> -	CMN_CDIAG_REFCLK_OVRD_4,
> -	CMN_CDIAG_REFCLK_DRV0_CTRL_1,
> -	CMN_CDIAG_REFCLK_DRV0_CTRL_4,
> -	CMN_CDIAG_REFCLK_DRV0_CTRL_5,
> -	CMN_CDIAG_REFCLK_DRV0_CTRL_6,
> -};
> -
> -static const struct reg_field refclk_out_cmn_cfg[] = {
> -	[CMN_CDIAG_REFCLK_OVRD_4]	= REG_FIELD(CMN_CDIAG_REFCLK_OVRD, 4, 4),
> -	[CMN_CDIAG_REFCLK_DRV0_CTRL_1]	= REG_FIELD(CMN_CDIAG_REFCLK_DRV0_CTRL, 1, 1),
> -	[CMN_CDIAG_REFCLK_DRV0_CTRL_4]	= REG_FIELD(CMN_CDIAG_REFCLK_DRV0_CTRL, 4, 4),
> -	[CMN_CDIAG_REFCLK_DRV0_CTRL_5]  = REG_FIELD(CMN_CDIAG_REFCLK_DRV0_CTRL, 5, 5),
> -	[CMN_CDIAG_REFCLK_DRV0_CTRL_6]	= REG_FIELD(CMN_CDIAG_REFCLK_DRV0_CTRL, 6, 6),
> -};
> +static const struct reg_field cmn_cdiag_refclk_ovrd_4 =
> +				REG_FIELD(CMN_CDIAG_REFCLK_OVRD, 4, 4);
>  
>  enum cdns_torrent_phy_type {
>  	TYPE_NONE,
> @@ -330,6 +316,8 @@ struct cdns_torrent_phy {
>  	struct regmap *regmap_phy_pcs_lane_cdb[MAX_NUM_LANES];
>  	struct regmap *regmap_dptx_phy_reg;
>  	struct regmap_field *phy_pll_cfg;
> +	struct regmap_field *phy_pipe_cmn_ctrl1_0;
> +	struct regmap_field *cmn_cdiag_refclk_ovrd_4;
>  	struct regmap_field *phy_pma_cmn_ctrl_1;
>  	struct regmap_field *phy_pma_cmn_ctrl_2;
>  	struct regmap_field *phy_pma_pll_raw_ctrl;
> @@ -348,7 +336,7 @@ enum phy_powerstate {
>  struct cdns_torrent_derived_refclk {
>  	struct clk_hw		hw;
>  	struct regmap_field	*phy_pipe_cmn_ctrl1_0;
> -	struct regmap_field	*cmn_fields[REFCLK_OUT_NUM_CMN_CONFIG];
> +	struct regmap_field	*cmn_cdiag_refclk_ovrd_4;
>  	struct clk_init_data	clk_data;
>  };
>  
> @@ -1618,11 +1606,7 @@ static int cdns_torrent_derived_refclk_enable(struct clk_hw *hw)
>  {
>  	struct cdns_torrent_derived_refclk *derived_refclk = to_cdns_torrent_derived_refclk(hw);
>  
> -	regmap_field_write(derived_refclk->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_6], 0);
> -	regmap_field_write(derived_refclk->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_4], 1);
> -	regmap_field_write(derived_refclk->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_5], 1);
> -	regmap_field_write(derived_refclk->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_1], 0);
> -	regmap_field_write(derived_refclk->cmn_fields[CMN_CDIAG_REFCLK_OVRD_4], 1);
> +	regmap_field_write(derived_refclk->cmn_cdiag_refclk_ovrd_4, 1);
>  	regmap_field_write(derived_refclk->phy_pipe_cmn_ctrl1_0, 1);
>  
>  	return 0;
> @@ -1633,6 +1617,7 @@ static void cdns_torrent_derived_refclk_disable(struct clk_hw *hw)
>  	struct cdns_torrent_derived_refclk *derived_refclk = to_cdns_torrent_derived_refclk(hw);
>  
>  	regmap_field_write(derived_refclk->phy_pipe_cmn_ctrl1_0, 0);
> +	regmap_field_write(derived_refclk->cmn_cdiag_refclk_ovrd_4, 0);
>  }
>  
>  static int cdns_torrent_derived_refclk_is_enabled(struct clk_hw *hw)
> @@ -1640,7 +1625,7 @@ static int cdns_torrent_derived_refclk_is_enabled(struct clk_hw *hw)
>  	struct cdns_torrent_derived_refclk *derived_refclk = to_cdns_torrent_derived_refclk(hw);
>  	int val;
>  
> -	regmap_field_read(derived_refclk->phy_pipe_cmn_ctrl1_0, &val);
> +	regmap_field_read(derived_refclk->cmn_cdiag_refclk_ovrd_4, &val);
>  
>  	return !!val;
>  }
> @@ -1655,21 +1640,19 @@ static int cdns_torrent_derived_refclk_register(struct cdns_torrent_phy *cdns_ph
>  {
>  	struct cdns_torrent_derived_refclk *derived_refclk;
>  	struct device *dev = cdns_phy->dev;
> -	struct regmap_field *field;
>  	struct clk_init_data *init;
>  	const char *parent_name;
> -	struct regmap *regmap;
>  	char clk_name[100];
>  	struct clk_hw *hw;
>  	struct clk *clk;
> -	int i, ret;
> +	int ret;
>  
>  	derived_refclk = devm_kzalloc(dev, sizeof(*derived_refclk), GFP_KERNEL);
>  	if (!derived_refclk)
>  		return -ENOMEM;
>  
>  	snprintf(clk_name, sizeof(clk_name), "%s_%s", dev_name(dev),
> -		 clk_names[CDNS_TORRENT_REFCLK_DRIVER]);
> +		 clk_names[CDNS_TORRENT_DERIVED_REFCLK]);
>  
>  	clk = devm_clk_get_optional(dev, "phy_en_refclk");
>  	if (IS_ERR(clk)) {
> @@ -1688,23 +1671,8 @@ static int cdns_torrent_derived_refclk_register(struct cdns_torrent_phy *cdns_ph
>  	init->flags = 0;
>  	init->name = clk_name;
>  
> -	regmap = cdns_phy->regmap_phy_pcs_common_cdb;
> -	field = devm_regmap_field_alloc(dev, regmap, phy_pipe_cmn_ctrl1_0);
> -	if (IS_ERR(field)) {
> -		dev_err(dev, "phy_pipe_cmn_ctrl1_0 reg field init failed\n");
> -		return PTR_ERR(field);
> -	}
> -	derived_refclk->phy_pipe_cmn_ctrl1_0 = field;
> -
> -	regmap = cdns_phy->regmap_common_cdb;
> -	for (i = 0; i < REFCLK_OUT_NUM_CMN_CONFIG; i++) {
> -		field = devm_regmap_field_alloc(dev, regmap, refclk_out_cmn_cfg[i]);
> -		if (IS_ERR(field)) {
> -			dev_err(dev, "CMN reg field init failed\n");
> -			return PTR_ERR(field);
> -		}
> -		derived_refclk->cmn_fields[i] = field;
> -	}
> +	derived_refclk->phy_pipe_cmn_ctrl1_0 = cdns_phy->phy_pipe_cmn_ctrl1_0;
> +	derived_refclk->cmn_cdiag_refclk_ovrd_4 = cdns_phy->cmn_cdiag_refclk_ovrd_4;
>  
>  	derived_refclk->hw.init = init;
>  
> @@ -1713,7 +1681,7 @@ static int cdns_torrent_derived_refclk_register(struct cdns_torrent_phy *cdns_ph
>  	if (ret)
>  		return ret;
>  
> -	cdns_phy->clk_hw_data->hws[CDNS_TORRENT_REFCLK_DRIVER] = hw;
> +	cdns_phy->clk_hw_data->hws[CDNS_TORRENT_DERIVED_REFCLK] = hw;
>  
>  	return 0;
>  }
> @@ -1768,6 +1736,22 @@ static int cdns_torrent_regfield_init(struct cdns_torrent_phy *cdns_phy)
>  	}
>  	cdns_phy->phy_pll_cfg = field;
>  
> +	regmap = cdns_phy->regmap_phy_pcs_common_cdb;
> +	field = devm_regmap_field_alloc(dev, regmap, phy_pipe_cmn_ctrl1_0);
> +	if (IS_ERR(field)) {
> +		dev_err(dev, "phy_pipe_cmn_ctrl1_0 reg field init failed\n");
> +		return PTR_ERR(field);
> +	}
> +	cdns_phy->phy_pipe_cmn_ctrl1_0 = field;
> +
> +	regmap = cdns_phy->regmap_common_cdb;
> +	field = devm_regmap_field_alloc(dev, regmap, cmn_cdiag_refclk_ovrd_4);
> +	if (IS_ERR(field)) {
> +		dev_err(dev, "cmn_cdiag_refclk_ovrd_4 reg field init failed\n");
> +		return PTR_ERR(field);
> +	}
> +	cdns_phy->cmn_cdiag_refclk_ovrd_4 = field;
> +
>  	regmap = cdns_phy->regmap_phy_pma_common_cdb;
>  	field = devm_regmap_field_alloc(dev, regmap, phy_pma_cmn_ctrl_1);
>  	if (IS_ERR(field)) {
> 

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

* Re: [PATCH 2/5] dt-bindings: phy: cadence-torrent: Add clock IDs for derived and received refclk
  2021-09-08 18:26 ` [PATCH 2/5] dt-bindings: phy: cadence-torrent: Add clock IDs for derived and received refclk Swapnil Jakhade
@ 2021-09-21 17:10   ` Rob Herring
  0 siblings, 0 replies; 9+ messages in thread
From: Rob Herring @ 2021-09-21 17:10 UTC (permalink / raw)
  To: Swapnil Jakhade
  Cc: devicetree, linux-phy, robh+dt, vkoul, lokeshvutla, a-govindraju,
	linux-kernel, kishon, mparab

On Wed, 08 Sep 2021 20:26:25 +0200, Swapnil Jakhade wrote:
> Add clock IDs for derived and received reference clock output.
> 
> Signed-off-by: Swapnil Jakhade <sjakhade@cadence.com>
> ---
>  include/dt-bindings/phy/phy-cadence.h | 2 ++
>  1 file changed, 2 insertions(+)
> 

Acked-by: Rob Herring <robh@kernel.org>

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

end of thread, other threads:[~2021-09-21 17:10 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-08 18:26 [PATCH 0/5] PHY: Add support to output derived and received reference clock from Torrent Swapnil Jakhade
2021-09-08 18:26 ` [PATCH 1/5] phy: cadence-torrent: Migrate to clk_hw based registration and OF APIs Swapnil Jakhade
2021-09-15  3:51   ` Kishon Vijay Abraham I
2021-09-08 18:26 ` [PATCH 2/5] dt-bindings: phy: cadence-torrent: Add clock IDs for derived and received refclk Swapnil Jakhade
2021-09-21 17:10   ` Rob Herring
2021-09-08 18:26 ` [PATCH 3/5] phy: cadence-torrent: Add support for derived reference clock output Swapnil Jakhade
2021-09-15  3:55   ` Kishon Vijay Abraham I
2021-09-08 18:26 ` [PATCH 4/5] phy: cadence-torrent: Add support for received " Swapnil Jakhade
2021-09-08 18:26 ` [PATCH 5/5] phy: cadence-torrent: Model reference clock driver as a gate and mux clock Swapnil Jakhade

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).