Skip to contentSkip to conversation

PHY: Add support in Sierra to use external clock

PATCH Applied Kishon Vijay Abraham I 3 participants 16 messages Mar 19, 2021 – Mar 31, 2021

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

v7 cover PHY: Add support in Sierra to use external clock

Patch series adds support in Sierra driver to use external clock.

v1 of the patch series can be found @ [1]
v2 of the patch series can be found @ [2]
v3 of the patch series can be found @ [3]
v4 of the patch series can be found @ [5]
v5 of the patch series can be found @ [6]
v6 of the patch series can be found @ [7]

Changes from v6:
1) Fixed $subject of patches to just have Sierra
2) Added Reviewed-by Tags
3) Fixed dt-binding example which included phy-cadence-torrent.h

Changes from v5:
1) Added Rob's Reviewed-by for the DT binding
2) Fixed another error handling case pointed out by Swapnil
3) Fixed few checkpatch errors.

Changes from v4:
1) Fixed couple of error handling cases
2) Added reviewed by from Philipp Zabel
3) Fixed couple of patch commit subjects to be uniform with other patches.

Changes from v3:
1) Instead of adding separate subnodes for each clock, just add #clock-cells in Sierra SERDES nodes and model the clocks. This is
in alignment with Rob's comment for a different series [4]
2) Removed device tree changes from the series.

Changes from v2:
1) Add depends on COMMON_CLK in Sierra
2) Add modelling PLL_CMNLC and PLL_CMNLC1 as clocks into a separate patch
3) Disable clocks in Sierra driver remove

Changes from v1:
1) Remove the part that prevents configuration if the SERDES is already configured and focus only on using external clock and the associated cleanups
2) Change patch ordering
3) Use exclusive reset control APIs
4) Fix error handling code
5) Include DT patches in this series (I can send this separately to DT MAINTAINER once the driver patches are merged)

[1] -> http://lore.kernel.org/r/[email protected]
[2] -> http://lore.kernel.org/r/[email protected]
[3] -> http://lore.kernel.org/r/[email protected]
[4] -> http://lore.kernel.org/r/[email protected]
[5] -> https://lore.kernel.org/r/[email protected]
[6] -> https://lore.kernel.org/r/[email protected]
[7] -> http://lore.kernel.org/r/[email protected]

Kishon Vijay Abraham I (13):
phy: cadence: Sierra: Fix PHY power_on sequence
phy: ti: j721e-wiz: Invoke wiz_init() before
of_platform_device_create()
phy: cadence: Sierra: Create PHY only for "phy" or "link" sub-nodes
phy: ti: j721e-wiz: Get PHY properties only for "phy" or "link"
subnode
phy: cadence: Sierra: Move all clk_get_*() to a separate function
phy: cadence: Sierra: Move all reset_control_get*() to a separate
function
phy: cadence: Sierra: Explicitly request exclusive reset control
phy: cadence-torrent: Use a common header file for Cadence SERDES
phy: cadence: Sierra: Add array of input clocks in "struct
cdns_sierra_phy"
phy: cadence: Sierra: Add missing clk_disable_unprepare() in .remove
callback
dt-bindings: phy: phy-cadence-sierra: Add binding to model Sierra as
clock provider
phy: cadence: Sierra: Model PLL_CMNLC and PLL_CMNLC1 as clocks (mux
clocks)
phy: cadence: Sierra: Enable pll_cmnlc and pll_cmnlc1 clocks

 .../bindings/phy/phy-cadence-sierra.yaml      |  17 +-
 .../bindings/phy/phy-cadence-torrent.yaml     |   2 +-
 drivers/phy/cadence/Kconfig                   |   1 +
 drivers/phy/cadence/phy-cadence-sierra.c      | 419 ++++++++++++++++--
 drivers/phy/cadence/phy-cadence-torrent.c     |   2 +-
 drivers/phy/ti/phy-j721e-wiz.c                |  21 +-
 include/dt-bindings/phy/phy-cadence-torrent.h |  15 -
 include/dt-bindings/phy/phy-cadence.h         |  20 +
 8 files changed, 429 insertions(+), 68 deletions(-)
 delete mode 100644 include/dt-bindings/phy/phy-cadence-torrent.h
 create mode 100644 include/dt-bindings/phy/phy-cadence.h
Signature · 7 lines
2.17.1


-- 
linux-phy mailing list
[email protected]
https://lists.infradead.org/mailman/listinfo/linux-phy
#1 lore raw

PATCH v7 1/13 phy: cadence: Sierra: Fix PHY power_on sequence

Commit 44d30d622821d ("phy: cadence: Add driver for Sierra PHY") de-asserts PHY_RESET even before the configurations are loaded in phy_init(). However PHY_RESET should be de-asserted only after all the configurations has been initialized, instead of de-asserting in probe. Fix it here.

Fixes 44d30d622821d ("phy: cadence: Add driver for Sierra PHY")
Cc <[email protected]> # v5.4+
---
 drivers/phy/cadence/phy-cadence-sierra.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/phy/cadence/phy-cadence-sierra.c +6 -1
index 26a0badabe38..19f32ae877b9 100644
@@ -319,6 +319,12 @@ static int cdns_sierra_phy_on(struct phy *gphy)
 	u32 val;
 	int ret;
 
+	ret = reset_control_deassert(sp->phy_rst);
+	if (ret) {
+		dev_err(dev, "Failed to take the PHY out of reset\n");
+		return ret;
+	}
+
 	/* Take the PHY lane group out of reset */
 	ret = reset_control_deassert(ins->lnk_rst);
 	if (ret) {
@@ -616,7 +622,6 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
 
 	pm_runtime_enable(dev);
 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
-	reset_control_deassert(sp->phy_rst);
 	return PTR_ERR_OR_ZERO(phy_provider);
 
 put_child:
Signature · 7 lines
2.17.1


-- 
linux-phy mailing list
[email protected]
https://lists.infradead.org/mailman/listinfo/linux-phy
#2 lore raw

PATCH v7 2/13 phy: ti: j721e-wiz: Invoke wiz_init() before of_platform_device_create()

In reply to Kishon Vijay Abraham I

Invoke wiz_init() before configuring anything else in Sierra/Torrent (invoked as part of of_platform_device_create()). wiz_init() resets the SERDES device and any configuration done in the probe() of Sierra/Torrent will be lost. In order to prevent SERDES configuration from getting reset, invoke wiz_init() immediately before invoking of_platform_device_create().

Fixes 091876cc355d ("phy: ti: j721e-wiz: Add support for WIZ module present in TI J721E SoC")
Cc <[email protected]> # v5.10
---
 drivers/phy/ti/phy-j721e-wiz.c | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)
drivers/phy/ti/phy-j721e-wiz.c +7 -10
index 995c7dbec77b..1bb73822f44a 100644
@@ -1262,27 +1262,24 @@ static int wiz_probe(struct platform_device *pdev)
 		goto err_get_sync;
 	}
 
+	ret = wiz_init(wiz);
+	if (ret) {
+		dev_err(dev, "WIZ initialization failed\n");
+		goto err_wiz_init;
+	}
+
 	serdes_pdev = of_platform_device_create(child_node, NULL, dev);
 	if (!serdes_pdev) {
 		dev_WARN(dev, "Unable to create SERDES platform device\n");
 		ret = -ENOMEM;
-		goto err_pdev_create;
-	}
-	wiz->serdes_pdev = serdes_pdev;
-
-	ret = wiz_init(wiz);
-	if (ret) {
-		dev_err(dev, "WIZ initialization failed\n");
 		goto err_wiz_init;
 	}
+	wiz->serdes_pdev = serdes_pdev;
 
 	of_node_put(child_node);
 	return 0;
 
 err_wiz_init:
-	of_platform_device_destroy(&serdes_pdev->dev, NULL);
-
-err_pdev_create:
 	wiz_clock_cleanup(wiz, node);
 
 err_get_sync:
Signature · 7 lines
2.17.1


-- 
linux-phy mailing list
[email protected]
https://lists.infradead.org/mailman/listinfo/linux-phy
#3 lore raw

PATCH v7 3/13 phy: cadence: Sierra: Create PHY only for "phy" or "link" sub-nodes

In reply to Kishon Vijay Abraham I

Cadence Sierra PHY driver registers PHY using devm_phy_create() for all sub-nodes of Sierra device tree node. However Sierra device tree node can have sub-nodes for the various clocks in addtion to the PHY. Use devm_phy_create() only for nodes with name "phy" (or "link" for old device tree) which represent the actual PHY.

---
 drivers/phy/cadence/phy-cadence-sierra.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/phy/cadence/phy-cadence-sierra.c +4 -0
index 19f32ae877b9..f7ba0ed416bc 100644
@@ -577,6 +577,10 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
 	for_each_available_child_of_node(dn, child) {
 		struct phy *gphy;
 
+		if (!(of_node_name_eq(child, "phy") ||
+		      of_node_name_eq(child, "link")))
+			continue;
+
 		sp->phys[node].lnk_rst =
 			of_reset_control_array_get_exclusive(child);
 
Signature · 7 lines
2.17.1


-- 
linux-phy mailing list
[email protected]
https://lists.infradead.org/mailman/listinfo/linux-phy
#4 lore raw

PATCH v7 4/13 phy: ti: j721e-wiz: Get PHY properties only for "phy" or "link" subnode

In reply to Kishon Vijay Abraham I

"serdes" node (child node of WIZ) can have sub-nodes for representing links or it can have sub-nodes for representing the various clocks within the serdes. Instead of trying to read "reg" from every child node used for assigning "lane_phy_type", read only if the child node's name is "phy" or "link" subnode.
Ideally all PHY dt nodes should have node name as "phy", however existing devicetree used "link" as subnode. So in order to maintain old DT compatibility get PHY properties for "phy" or "link" subnode.

---
 drivers/phy/ti/phy-j721e-wiz.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/phy/ti/phy-j721e-wiz.c +4 -0
index 1bb73822f44a..659597645201 100644
@@ -1102,6 +1102,10 @@ static int wiz_get_lane_phy_types(struct device *dev, struct wiz *wiz)
 		u32 reg, num_lanes = 1, phy_type = PHY_NONE;
 		int ret, i;
 
+		if (!(of_node_name_eq(subnode, "phy") ||
+		      of_node_name_eq(subnode, "link")))
+			continue;
+
 		ret = of_property_read_u32(subnode, "reg", &reg);
 		if (ret) {
 			dev_err(dev,
Signature · 7 lines
2.17.1


-- 
linux-phy mailing list
[email protected]
https://lists.infradead.org/mailman/listinfo/linux-phy
#5 lore raw

PATCH v7 5/13 phy: cadence: Sierra: Move all clk_get_*() to a separate function

In reply to Kishon Vijay Abraham I

No functional change. Group all devm_clk_get_optional() to a separate function.

---
 drivers/phy/cadence/phy-cadence-sierra.c | 57 +++++++++++++++---------
 1 file changed, 35 insertions(+), 22 deletions(-)
drivers/phy/cadence/phy-cadence-sierra.c +35 -22
index f7ba0ed416bc..7bf1b4c7774a 100644
@@ -477,6 +477,38 @@ static int cdns_regmap_init_blocks(struct cdns_sierra_phy *sp,
 	return 0;
 }
 
+static int cdns_sierra_phy_get_clocks(struct cdns_sierra_phy *sp,
+				      struct device *dev)
+{
+	struct clk *clk;
+	int ret;
+
+	clk = devm_clk_get_optional(dev, "phy_clk");
+	if (IS_ERR(clk)) {
+		dev_err(dev, "failed to get clock phy_clk\n");
+		return PTR_ERR(clk);
+	}
+	sp->clk = clk;
+
+	clk = devm_clk_get_optional(dev, "cmn_refclk_dig_div");
+	if (IS_ERR(clk)) {
+		dev_err(dev, "cmn_refclk_dig_div clock not found\n");
+		ret = PTR_ERR(clk);
+		return ret;
+	}
+	sp->cmn_refclk_dig_div = clk;
+
+	clk = devm_clk_get_optional(dev, "cmn_refclk1_dig_div");
+	if (IS_ERR(clk)) {
+		dev_err(dev, "cmn_refclk1_dig_div clock not found\n");
+		ret = PTR_ERR(clk);
+		return ret;
+	}
+	sp->cmn_refclk1_dig_div = clk;
+
+	return 0;
+}
+
 static int cdns_sierra_phy_probe(struct platform_device *pdev)
 {
 	struct cdns_sierra_phy *sp;
@@ -487,7 +519,6 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
 	unsigned int id_value;
 	int i, ret, node = 0;
 	void __iomem *base;
-	struct clk *clk;
 	struct device_node *dn = dev->of_node, *child;
 
 	if (of_get_child_count(dn) == 0)
@@ -524,11 +555,9 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, sp);
 
-	sp->clk = devm_clk_get_optional(dev, "phy_clk");
-	if (IS_ERR(sp->clk)) {
-		dev_err(dev, "failed to get clock phy_clk\n");
-		return PTR_ERR(sp->clk);
-	}
+	ret = cdns_sierra_phy_get_clocks(sp, dev);
+	if (ret)
+		return ret;
 
 	sp->phy_rst = devm_reset_control_get(dev, "sierra_reset");
 	if (IS_ERR(sp->phy_rst)) {
@@ -542,22 +571,6 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
 		return PTR_ERR(sp->apb_rst);
 	}
 
-	clk = devm_clk_get_optional(dev, "cmn_refclk_dig_div");
-	if (IS_ERR(clk)) {
-		dev_err(dev, "cmn_refclk_dig_div clock not found\n");
-		ret = PTR_ERR(clk);
-		return ret;
-	}
-	sp->cmn_refclk_dig_div = clk;
-
-	clk = devm_clk_get_optional(dev, "cmn_refclk1_dig_div");
-	if (IS_ERR(clk)) {
-		dev_err(dev, "cmn_refclk1_dig_div clock not found\n");
-		ret = PTR_ERR(clk);
-		return ret;
-	}
-	sp->cmn_refclk1_dig_div = clk;
-
 	ret = clk_prepare_enable(sp->clk);
 	if (ret)
 		return ret;
Signature · 7 lines
2.17.1


-- 
linux-phy mailing list
[email protected]
https://lists.infradead.org/mailman/listinfo/linux-phy
#6 lore raw

PATCH v7 6/13 phy: cadence: Sierra: Move all reset_control_get*() to a separate function

In reply to Kishon Vijay Abraham I

No functional change. Group devm_reset_control_get() and devm_reset_control_get_optional() to a separate function.

---
 drivers/phy/cadence/phy-cadence-sierra.c | 36 ++++++++++++++++--------
 1 file changed, 25 insertions(+), 11 deletions(-)
drivers/phy/cadence/phy-cadence-sierra.c +25 -11
index 7bf1b4c7774a..935f165404e4 100644
@@ -509,6 +509,28 @@ static int cdns_sierra_phy_get_clocks(struct cdns_sierra_phy *sp,
 	return 0;
 }
 
+static int cdns_sierra_phy_get_resets(struct cdns_sierra_phy *sp,
+				      struct device *dev)
+{
+	struct reset_control *rst;
+
+	rst = devm_reset_control_get(dev, "sierra_reset");
+	if (IS_ERR(rst)) {
+		dev_err(dev, "failed to get reset\n");
+		return PTR_ERR(rst);
+	}
+	sp->phy_rst = rst;
+
+	rst = devm_reset_control_get_optional(dev, "sierra_apb");
+	if (IS_ERR(rst)) {
+		dev_err(dev, "failed to get apb reset\n");
+		return PTR_ERR(rst);
+	}
+	sp->apb_rst = rst;
+
+	return 0;
+}
+
 static int cdns_sierra_phy_probe(struct platform_device *pdev)
 {
 	struct cdns_sierra_phy *sp;
@@ -559,17 +581,9 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	sp->phy_rst = devm_reset_control_get(dev, "sierra_reset");
-	if (IS_ERR(sp->phy_rst)) {
-		dev_err(dev, "failed to get reset\n");
-		return PTR_ERR(sp->phy_rst);
-	}
-
-	sp->apb_rst = devm_reset_control_get_optional(dev, "sierra_apb");
-	if (IS_ERR(sp->apb_rst)) {
-		dev_err(dev, "failed to get apb reset\n");
-		return PTR_ERR(sp->apb_rst);
-	}
+	ret = cdns_sierra_phy_get_resets(sp, dev);
+	if (ret)
+		return ret;
 
 	ret = clk_prepare_enable(sp->clk);
 	if (ret)
Signature · 7 lines
2.17.1


-- 
linux-phy mailing list
[email protected]
https://lists.infradead.org/mailman/listinfo/linux-phy
#7 lore raw

PATCH v7 7/13 phy: cadence: Sierra: Explicitly request exclusive reset control

In reply to Kishon Vijay Abraham I

No functional change. Since the reset controls obtained in Sierra is exclusively used by the Sierra device, use exclusive reset control request API calls.

---
 drivers/phy/cadence/phy-cadence-sierra.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/phy/cadence/phy-cadence-sierra.c +2 -2
index 935f165404e4..44c52a0842dc 100644
@@ -514,14 +514,14 @@ static int cdns_sierra_phy_get_resets(struct cdns_sierra_phy *sp,
 {
 	struct reset_control *rst;
 
-	rst = devm_reset_control_get(dev, "sierra_reset");
+	rst = devm_reset_control_get_exclusive(dev, "sierra_reset");
 	if (IS_ERR(rst)) {
 		dev_err(dev, "failed to get reset\n");
 		return PTR_ERR(rst);
 	}
 	sp->phy_rst = rst;
 
-	rst = devm_reset_control_get_optional(dev, "sierra_apb");
+	rst = devm_reset_control_get_optional_exclusive(dev, "sierra_apb");
 	if (IS_ERR(rst)) {
 		dev_err(dev, "failed to get apb reset\n");
 		return PTR_ERR(rst);
Signature · 7 lines
2.17.1


-- 
linux-phy mailing list
[email protected]
https://lists.infradead.org/mailman/listinfo/linux-phy
#8 lore raw

PATCH v7 8/13 phy: cadence-torrent: Use a common header file for Cadence SERDES

In reply to Kishon Vijay Abraham I

No functional change. In order to have a single header file for all Cadence SERDES move phy-cadence-torrent.h to phy-cadence.h. This is in preparation for adding Cadence Sierra SERDES specific macros.

---
 .../devicetree/bindings/phy/phy-cadence-torrent.yaml     | 2 +-
 drivers/phy/cadence/phy-cadence-torrent.c                | 2 +-
 .../phy/{phy-cadence-torrent.h => phy-cadence.h}         | 9 +++++----
 3 files changed, 7 insertions(+), 6 deletions(-)
 rename include/dt-bindings/phy/{phy-cadence-torrent.h => phy-cadence.h} (51%)
Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml +1 -1
index 4608599a31d8..01dcd14e7b2a 100644
@@ -184,7 +184,7 @@ examples:
     };
   - |
     #include <dt-bindings/phy/phy.h>
-    #include <dt-bindings/phy/phy-cadence-torrent.h>
+    #include <dt-bindings/phy/phy-cadence.h>
 
     bus {
         #address-cells = <2>;
drivers/phy/cadence/phy-cadence-torrent.c +1 -1
index 95160da3e667..3fdab0d288c4 100644
@@ -7,7 +7,7 @@
  */
 
 #include <dt-bindings/phy/phy.h>
-#include <dt-bindings/phy/phy-cadence-torrent.h>
+#include <dt-bindings/phy/phy-cadence.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/delay.h>
include/dt-bindings/phy/phy-cadence.h renamed from include/dt-bindings/phy/phy-cadence-torrent.h +5 -4
similarity index 51%
rename from include/dt-bindings/phy/phy-cadence-torrent.h
rename to include/dt-bindings/phy/phy-cadence.h
index 3c92c6192493..4a5ea52a856f 100644
@@ -1,15 +1,16 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * This header provides constants for Cadence Torrent SERDES.
+ * This header provides constants for Cadence SERDES.
  */
 
-#ifndef _DT_BINDINGS_TORRENT_SERDES_H
-#define _DT_BINDINGS_TORRENT_SERDES_H
+#ifndef _DT_BINDINGS_CADENCE_SERDES_H
+#define _DT_BINDINGS_CADENCE_SERDES_H
 
+/* Torrent */
 #define TORRENT_SERDES_NO_SSC		0
 #define TORRENT_SERDES_EXTERNAL_SSC	1
 #define TORRENT_SERDES_INTERNAL_SSC	2
 
 #define CDNS_TORRENT_REFCLK_DRIVER      0
 
-#endif /* _DT_BINDINGS_TORRENT_SERDES_H */
+#endif /* _DT_BINDINGS_CADENCE_SERDES_H */
Signature · 7 lines
2.17.1


-- 
linux-phy mailing list
[email protected]
https://lists.infradead.org/mailman/listinfo/linux-phy
maintainer Acked-by on v7 8/13
#9 lore raw

Re: [PATCH v7 08/13] phy: cadence-torrent: Use a common header file for Cadence SERDES

Quoted 4 lines · Kishon Vijay Abraham I

No functional change. In order to have a single header file for all Cadence SERDES move phy-cadence-torrent.h to phy-cadence.h. This is in preparation for adding Cadence Sierra SERDES specific macros.

Quoted 9 lines
---
 .../devicetree/bindings/phy/phy-cadence-torrent.yaml     | 2 +-
 drivers/phy/cadence/phy-cadence-torrent.c                | 2 +-
 .../phy/{phy-cadence-torrent.h => phy-cadence.h}         | 9 +++++----
 3 files changed, 7 insertions(+), 6 deletions(-)
 rename include/dt-bindings/phy/{phy-cadence-torrent.h => phy-cadence.h} (51%)
Signature · 3 lines
linux-phy mailing list
[email protected]
https://lists.infradead.org/mailman/listinfo/linux-phy
#10 lore raw

PATCH v7 9/13 phy: cadence: Sierra: Add array of input clocks in "struct cdns_sierra_phy"

In reply to Kishon Vijay Abraham I

Instead of having separate structure members for each input clock, add an array for the input clocks within "struct cdns_sierra_phy". This is in preparation for adding more input clocks required for supporting additional clock combination.

---
 drivers/phy/cadence/phy-cadence-sierra.c | 25 ++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)
drivers/phy/cadence/phy-cadence-sierra.c +15 -10
index 44c52a0842dc..a45278c30948 100644
@@ -144,6 +144,13 @@
 #define SIERRA_MAX_LANES				16
 #define PLL_LOCK_TIME					100000
 
+#define CDNS_SIERRA_INPUT_CLOCKS			3
+enum cdns_sierra_clock_input {
+	PHY_CLK,
+	CMN_REFCLK_DIG_DIV,
+	CMN_REFCLK1_DIG_DIV,
+};
+
 static const struct reg_field macro_id_type =
 				REG_FIELD(SIERRA_MACRO_ID_REG, 0, 15);
 static const struct reg_field phy_pll_cfg_1 =
@@ -197,9 +204,7 @@ struct cdns_sierra_phy {
 	struct regmap_field *macro_id_type;
 	struct regmap_field *phy_pll_cfg_1;
 	struct regmap_field *pllctrl_lock[SIERRA_MAX_LANES];
-	struct clk *clk;
-	struct clk *cmn_refclk_dig_div;
-	struct clk *cmn_refclk1_dig_div;
+	struct clk *input_clks[CDNS_SIERRA_INPUT_CLOCKS];
 	int nsubnodes;
 	u32 num_lanes;
 	bool autoconf;
@@ -281,8 +286,8 @@ static int cdns_sierra_phy_init(struct phy *gphy)
 	if (phy->autoconf)
 		return 0;
 
-	clk_set_rate(phy->cmn_refclk_dig_div, 25000000);
-	clk_set_rate(phy->cmn_refclk1_dig_div, 25000000);
+	clk_set_rate(phy->input_clks[CMN_REFCLK_DIG_DIV], 25000000);
+	clk_set_rate(phy->input_clks[CMN_REFCLK1_DIG_DIV], 25000000);
 	if (ins->phy_type == PHY_TYPE_PCIE) {
 		num_cmn_regs = phy->init_data->pcie_cmn_regs;
 		num_ln_regs = phy->init_data->pcie_ln_regs;
@@ -488,7 +493,7 @@ static int cdns_sierra_phy_get_clocks(struct cdns_sierra_phy *sp,
 		dev_err(dev, "failed to get clock phy_clk\n");
 		return PTR_ERR(clk);
 	}
-	sp->clk = clk;
+	sp->input_clks[PHY_CLK] = clk;
 
 	clk = devm_clk_get_optional(dev, "cmn_refclk_dig_div");
 	if (IS_ERR(clk)) {
@@ -496,7 +501,7 @@ static int cdns_sierra_phy_get_clocks(struct cdns_sierra_phy *sp,
 		ret = PTR_ERR(clk);
 		return ret;
 	}
-	sp->cmn_refclk_dig_div = clk;
+	sp->input_clks[CMN_REFCLK_DIG_DIV] = clk;
 
 	clk = devm_clk_get_optional(dev, "cmn_refclk1_dig_div");
 	if (IS_ERR(clk)) {
@@ -504,7 +509,7 @@ static int cdns_sierra_phy_get_clocks(struct cdns_sierra_phy *sp,
 		ret = PTR_ERR(clk);
 		return ret;
 	}
-	sp->cmn_refclk1_dig_div = clk;
+	sp->input_clks[CMN_REFCLK1_DIG_DIV] = clk;
 
 	return 0;
 }
@@ -585,7 +590,7 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	ret = clk_prepare_enable(sp->clk);
+	ret = clk_prepare_enable(sp->input_clks[PHY_CLK]);
 	if (ret)
 		return ret;
 
@@ -662,7 +667,7 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
 		reset_control_put(sp->phys[i].lnk_rst);
 	of_node_put(child);
 clk_disable:
-	clk_disable_unprepare(sp->clk);
+	clk_disable_unprepare(sp->input_clks[PHY_CLK]);
 	reset_control_assert(sp->apb_rst);
 	return ret;
 }
Signature · 7 lines
2.17.1


-- 
linux-phy mailing list
[email protected]
https://lists.infradead.org/mailman/listinfo/linux-phy
#11 lore raw

PATCH v7 10/13 phy: cadence: Sierra: Add missing clk_disable_unprepare() in .remove callback

In reply to Kishon Vijay Abraham I

commit 44d30d622821 ("phy: cadence: Add driver for Sierra PHY") enabled the clock in probe and failed to disable in remove callback. Add missing clk_disable_unprepare() in cdns_sierra_phy_remove().

Fixes 44d30d622821 ("phy: cadence: Add driver for Sierra PHY")
---
 drivers/phy/cadence/phy-cadence-sierra.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/phy/cadence/phy-cadence-sierra.c +3 -0
index a45278c30948..ac32b7b0289f 100644
@@ -689,6 +689,9 @@ static int cdns_sierra_phy_remove(struct platform_device *pdev)
 		reset_control_assert(phy->phys[i].lnk_rst);
 		reset_control_put(phy->phys[i].lnk_rst);
 	}
+
+	clk_disable_unprepare(phy->input_clks[PHY_CLK]);
+
 	return 0;
 }
 
Signature · 7 lines
2.17.1


-- 
linux-phy mailing list
[email protected]
https://lists.infradead.org/mailman/listinfo/linux-phy
#12 lore raw

PATCH v7 11/13 dt-bindings: phy: phy-cadence-sierra: Add binding to model Sierra as clock provider

In reply to Kishon Vijay Abraham I

Add #clock-cells binding to model Sierra as clock provider and include clock IDs for PLL_CMNLC and PLL_CMNLC1.

---
 .../bindings/phy/phy-cadence-sierra.yaml        | 17 ++++++++++++++++-
 include/dt-bindings/phy/phy-cadence.h           |  4 ++++
 2 files changed, 20 insertions(+), 1 deletion(-)
Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml +16 -1
index d210843863df..84383e2e0b34 100644
@@ -26,6 +26,9 @@ properties:
   '#size-cells':
     const: 0
 
+  '#clock-cells':
+    const: 1
+
   resets:
     minItems: 1
     maxItems: 2
@@ -49,12 +52,24 @@ properties:
     const: serdes
 
   clocks:
-    maxItems: 2
+    minItems: 2
+    maxItems: 4
 
   clock-names:
+    minItems: 2
     items:
       - const: cmn_refclk_dig_div
       - const: cmn_refclk1_dig_div
+      - const: pll0_refclk
+      - const: pll1_refclk
+
+  assigned-clocks:
+    minItems: 1
+    maxItems: 2
+
+  assigned-clock-parents:
+    minItems: 1
+    maxItems: 2
 
   cdns,autoconf:
     type: boolean
include/dt-bindings/phy/phy-cadence.h +4 -0
index 4a5ea52a856f..4652bcb86265 100644
@@ -13,4 +13,8 @@
 
 #define CDNS_TORRENT_REFCLK_DRIVER      0
 
+/* Sierra */
+#define CDNS_SIERRA_PLL_CMNLC		0
+#define CDNS_SIERRA_PLL_CMNLC1		1
+
 #endif /* _DT_BINDINGS_CADENCE_SERDES_H */
Signature · 7 lines
2.17.1


-- 
linux-phy mailing list
[email protected]
https://lists.infradead.org/mailman/listinfo/linux-phy
#13 lore raw

PATCH v7 12/13 phy: cadence: Sierra: Model PLL_CMNLC and PLL_CMNLC1 as clocks (mux clocks)

In reply to Kishon Vijay Abraham I

Sierra has two PLLs, PLL_CMNLC and PLL_CMNLC1 and each of these PLLs has two inputs, plllc_refclk (input from pll0_refclk) and refrcv (input from pll1_refclk). Model PLL_CMNLC and PLL_CMNLC1 as clocks so that it's possible to select one of these two inputs from device tree.

---
 drivers/phy/cadence/Kconfig              |   1 +
 drivers/phy/cadence/phy-cadence-sierra.c | 267 ++++++++++++++++++++++-
 2 files changed, 265 insertions(+), 3 deletions(-)
drivers/phy/cadence/Kconfig +1 -0
index 27e9d6c377e5..a62910ff5591 100644
@@ -25,6 +25,7 @@ config PHY_CADENCE_DPHY
 config PHY_CADENCE_SIERRA
 	tristate "Cadence Sierra PHY Driver"
 	depends on OF && HAS_IOMEM && RESET_CONTROLLER
+	depends on COMMON_CLK
 	select GENERIC_PHY
 	help
 	  Enable this to support the Cadence Sierra PHY driver
drivers/phy/cadence/phy-cadence-sierra.c +264 -3

364 lines not on this page · raw message

Signature · 7 lines
2.17.1


-- 
linux-phy mailing list
[email protected]
https://lists.infradead.org/mailman/listinfo/linux-phy
#14 lore raw

PATCH v7 13/13 phy: cadence: Sierra: Enable pll_cmnlc and pll_cmnlc1 clocks

In reply to Kishon Vijay Abraham I

Get pll_cmnlc and pll_cmnlc1 optional clocks and enable them. This will enable REFRCV/1 in case the pll_cmnlc/1 takes input from REFRCV/1 respectively.

---
 drivers/phy/cadence/phy-cadence-sierra.c | 40 ++++++++++++++++++++++--
 1 file changed, 37 insertions(+), 3 deletions(-)
drivers/phy/cadence/phy-cadence-sierra.c +37 -3
index 039ca10db59d..5c68e31c5939 100644
@@ -768,6 +768,40 @@ static int cdns_sierra_phy_get_clocks(struct cdns_sierra_phy *sp,
 	return 0;
 }
 
+static int cdns_sierra_phy_enable_clocks(struct cdns_sierra_phy *sp)
+{
+	int ret;
+
+	ret = clk_prepare_enable(sp->input_clks[PHY_CLK]);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(sp->output_clks[CDNS_SIERRA_PLL_CMNLC]);
+	if (ret)
+		goto err_pll_cmnlc;
+
+	ret = clk_prepare_enable(sp->output_clks[CDNS_SIERRA_PLL_CMNLC1]);
+	if (ret)
+		goto err_pll_cmnlc1;
+
+	return 0;
+
+err_pll_cmnlc1:
+	clk_disable_unprepare(sp->output_clks[CDNS_SIERRA_PLL_CMNLC]);
+
+err_pll_cmnlc:
+	clk_disable_unprepare(sp->input_clks[PHY_CLK]);
+
+	return ret;
+}
+
+static void cdns_sierra_phy_disable_clocks(struct cdns_sierra_phy *sp)
+{
+	clk_disable_unprepare(sp->output_clks[CDNS_SIERRA_PLL_CMNLC1]);
+	clk_disable_unprepare(sp->output_clks[CDNS_SIERRA_PLL_CMNLC]);
+	clk_disable_unprepare(sp->input_clks[PHY_CLK]);
+}
+
 static int cdns_sierra_phy_get_resets(struct cdns_sierra_phy *sp,
 				      struct device *dev)
 {
@@ -848,7 +882,7 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
 	if (ret)
 		goto unregister_clk;
 
-	ret = clk_prepare_enable(sp->input_clks[PHY_CLK]);
+	ret = cdns_sierra_phy_enable_clocks(sp);
 	if (ret)
 		goto unregister_clk;
 
@@ -925,7 +959,7 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
 		reset_control_put(sp->phys[i].lnk_rst);
 	of_node_put(child);
 clk_disable:
-	clk_disable_unprepare(sp->input_clks[PHY_CLK]);
+	cdns_sierra_phy_disable_clocks(sp);
 	reset_control_assert(sp->apb_rst);
 unregister_clk:
 	cdns_sierra_clk_unregister(sp);
@@ -941,6 +975,7 @@ static int cdns_sierra_phy_remove(struct platform_device *pdev)
 	reset_control_assert(phy->apb_rst);
 	pm_runtime_disable(&pdev->dev);
 
+	cdns_sierra_phy_disable_clocks(phy);
 	/*
 	 * The device level resets will be put automatically.
 	 * Need to put the subnode resets here though.
@@ -950,7 +985,6 @@ static int cdns_sierra_phy_remove(struct platform_device *pdev)
 		reset_control_put(phy->phys[i].lnk_rst);
 	}
 
-	clk_disable_unprepare(phy->input_clks[PHY_CLK]);
 	cdns_sierra_clk_unregister(phy);
 
 	return 0;
Signature · 1 line
2.17.1
maintainer Applied
#15 lore raw
In reply to Kishon Vijay Abraham I
Quoted 8 lines · Kishon Vijay Abraham I

Patch series adds support in Sierra driver to use external clock.

v1 of the patch series can be found @ [1] v2 of the patch series can be found @ [2] v3 of the patch series can be found @ [3] v4 of the patch series can be found @ [5] v5 of the patch series can be found @ [6] v6 of the patch series can be found @ [7]

Applied, thanks. I was able to resolve the conflict on patch 4, please check it was fine

Signature · 1 line
~Vinod