Skip to contentSkip to conversation

PCI: rockchip: Simplify clock handling by using clk_bulk*() function

PATCH Superseded Anand Moon 2 participants 9 messages Sep 1, 2024 – Sep 28, 2024 1 message not in the archive

Subsystems (5)

v5 of 11 Superseded Latest is v11 →

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

Anand Moon

author
#1 lore raw

PATCH v5 1/6 PCI: rockchip: Simplify clock handling by using clk_bulk*() function

Refactor the clock handling in the Rockchip PCIe driver, introducing a more robust and efficient method for enabling and disabling clocks using clk_bulk*() API. Using the clk_bulk APIs, the clock handling for the core clocks becomes much simpler.

---
v5: switch to use use devm_clk_bulk_get_all()? gets rid of hardcoding the
clock names in driver.
v4: use dev_err_probe for error patch.
v3: Fix typo in commit message, dropped reported by.
v2: Fix compilation error reported by Intel test robot.
---

---
 drivers/pci/controller/pcie-rockchip.c | 65 +++-----------------------
 drivers/pci/controller/pcie-rockchip.h |  7 ++-
 2 files changed, 10 insertions(+), 62 deletions(-)
drivers/pci/controller/pcie-rockchip.c +7 -58
index c07d7129f1c7..2777ef0cb599 100644
@@ -127,29 +127,9 @@ int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
 					     "failed to get ep GPIO\n");
 	}
 
-	rockchip->aclk_pcie = devm_clk_get(dev, "aclk");
-	if (IS_ERR(rockchip->aclk_pcie)) {
-		dev_err(dev, "aclk clock not found\n");
-		return PTR_ERR(rockchip->aclk_pcie);
-	}
-
-	rockchip->aclk_perf_pcie = devm_clk_get(dev, "aclk-perf");
-	if (IS_ERR(rockchip->aclk_perf_pcie)) {
-		dev_err(dev, "aclk_perf clock not found\n");
-		return PTR_ERR(rockchip->aclk_perf_pcie);
-	}
-
-	rockchip->hclk_pcie = devm_clk_get(dev, "hclk");
-	if (IS_ERR(rockchip->hclk_pcie)) {
-		dev_err(dev, "hclk clock not found\n");
-		return PTR_ERR(rockchip->hclk_pcie);
-	}
-
-	rockchip->clk_pcie_pm = devm_clk_get(dev, "pm");
-	if (IS_ERR(rockchip->clk_pcie_pm)) {
-		dev_err(dev, "pm clock not found\n");
-		return PTR_ERR(rockchip->clk_pcie_pm);
-	}
+	rockchip->num_clks = devm_clk_bulk_get_all(dev, &rockchip->clks);
+	if (rockchip->num_clks < 0)
+		return dev_err_probe(dev, err, "failed to get clocks\n");
 
 	return 0;
 }
@@ -372,39 +352,11 @@ int rockchip_pcie_enable_clocks(struct rockchip_pcie *rockchip)
 	struct device *dev = rockchip->dev;
 	int err;
 
-	err = clk_prepare_enable(rockchip->aclk_pcie);
-	if (err) {
-		dev_err(dev, "unable to enable aclk_pcie clock\n");
-		return err;
-	}
-
-	err = clk_prepare_enable(rockchip->aclk_perf_pcie);
-	if (err) {
-		dev_err(dev, "unable to enable aclk_perf_pcie clock\n");
-		goto err_aclk_perf_pcie;
-	}
-
-	err = clk_prepare_enable(rockchip->hclk_pcie);
-	if (err) {
-		dev_err(dev, "unable to enable hclk_pcie clock\n");
-		goto err_hclk_pcie;
-	}
-
-	err = clk_prepare_enable(rockchip->clk_pcie_pm);
-	if (err) {
-		dev_err(dev, "unable to enable clk_pcie_pm clock\n");
-		goto err_clk_pcie_pm;
-	}
+	err = clk_bulk_prepare_enable(rockchip->num_clks, rockchip->clks);
+	if (err)
+		return dev_err_probe(dev, err, "failed to enable clocks\n");
 
 	return 0;
-
-err_clk_pcie_pm:
-	clk_disable_unprepare(rockchip->hclk_pcie);
-err_hclk_pcie:
-	clk_disable_unprepare(rockchip->aclk_perf_pcie);
-err_aclk_perf_pcie:
-	clk_disable_unprepare(rockchip->aclk_pcie);
-	return err;
 }
 EXPORT_SYMBOL_GPL(rockchip_pcie_enable_clocks);
 
@@ -412,10 +364,7 @@ void rockchip_pcie_disable_clocks(void *data)
 {
 	struct rockchip_pcie *rockchip = data;
 
-	clk_disable_unprepare(rockchip->clk_pcie_pm);
-	clk_disable_unprepare(rockchip->hclk_pcie);
-	clk_disable_unprepare(rockchip->aclk_perf_pcie);
-	clk_disable_unprepare(rockchip->aclk_pcie);
+	clk_bulk_disable_unprepare(rockchip->num_clks, rockchip->clks);
 }
 EXPORT_SYMBOL_GPL(rockchip_pcie_disable_clocks);
 
drivers/pci/controller/pcie-rockchip.h +3 -4
index 6111de35f84c..bebab80c9553 100644
@@ -11,6 +11,7 @@
 #ifndef _PCIE_ROCKCHIP_H
 #define _PCIE_ROCKCHIP_H
 
+#include <linux/clk.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/pci-ecam.h>
@@ -299,10 +300,8 @@ struct rockchip_pcie {
 	struct	reset_control *pm_rst;
 	struct	reset_control *aclk_rst;
 	struct	reset_control *pclk_rst;
-	struct	clk *aclk_pcie;
-	struct	clk *aclk_perf_pcie;
-	struct	clk *hclk_pcie;
-	struct	clk *clk_pcie_pm;
+	struct  clk_bulk_data *clks;
+	int	num_clks;
 	struct	regulator *vpcie12v; /* 12V power supply */
 	struct	regulator *vpcie3v3; /* 3.3V power supply */
 	struct	regulator *vpcie1v8; /* 1.8V power supply */
Signature · 1 line
2.44.0
author
#2 lore raw

Hi,

Quoted 7 lines · Anand Moon

Refactor the clock handling in the Rockchip PCIe driver, introducing a more robust and efficient method for enabling and disabling clocks using clk_bulk*() API. Using the clk_bulk APIs, the clock handling for the core clocks becomes much simpler.

Do you have any review comments on this series?

Thanks
-Anand

Quoted 132 lines

---
v5: switch to use use devm_clk_bulk_get_all()? gets rid of hardcoding the
clock names in driver.
v4: use dev_err_probe for error patch.
v3: Fix typo in commit message, dropped reported by.
v2: Fix compilation error reported by Intel test robot.
---

---
 drivers/pci/controller/pcie-rockchip.c | 65 +++-----------------------
 drivers/pci/controller/pcie-rockchip.h |  7 ++-
 2 files changed, 10 insertions(+), 62 deletions(-)
drivers/pci/controller/pcie-rockchip.c +7 -58
index c07d7129f1c7..2777ef0cb599 100644
@@ -127,29 +127,9 @@ int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
                                             "failed to get ep GPIO\n");
        }
 
-       rockchip->aclk_pcie = devm_clk_get(dev, "aclk");
-       if (IS_ERR(rockchip->aclk_pcie)) {
-               dev_err(dev, "aclk clock not found\n");
-               return PTR_ERR(rockchip->aclk_pcie);
-       }
-
-       rockchip->aclk_perf_pcie = devm_clk_get(dev, "aclk-perf");
-       if (IS_ERR(rockchip->aclk_perf_pcie)) {
-               dev_err(dev, "aclk_perf clock not found\n");
-               return PTR_ERR(rockchip->aclk_perf_pcie);
-       }
-
-       rockchip->hclk_pcie = devm_clk_get(dev, "hclk");
-       if (IS_ERR(rockchip->hclk_pcie)) {
-               dev_err(dev, "hclk clock not found\n");
-               return PTR_ERR(rockchip->hclk_pcie);
-       }
-
-       rockchip->clk_pcie_pm = devm_clk_get(dev, "pm");
-       if (IS_ERR(rockchip->clk_pcie_pm)) {
-               dev_err(dev, "pm clock not found\n");
-               return PTR_ERR(rockchip->clk_pcie_pm);
-       }
+       rockchip->num_clks = devm_clk_bulk_get_all(dev, &rockchip->clks);
+       if (rockchip->num_clks < 0)
+               return dev_err_probe(dev, err, "failed to get clocks\n");
 
        return 0;
 }
@@ -372,39 +352,11 @@ int rockchip_pcie_enable_clocks(struct rockchip_pcie *rockchip)
        struct device *dev = rockchip->dev;
        int err;
 
-       err = clk_prepare_enable(rockchip->aclk_pcie);
-       if (err) {
-               dev_err(dev, "unable to enable aclk_pcie clock\n");
-               return err;
-       }
-
-       err = clk_prepare_enable(rockchip->aclk_perf_pcie);
-       if (err) {
-               dev_err(dev, "unable to enable aclk_perf_pcie clock\n");
-               goto err_aclk_perf_pcie;
-       }
-
-       err = clk_prepare_enable(rockchip->hclk_pcie);
-       if (err) {
-               dev_err(dev, "unable to enable hclk_pcie clock\n");
-               goto err_hclk_pcie;
-       }
-
-       err = clk_prepare_enable(rockchip->clk_pcie_pm);
-       if (err) {
-               dev_err(dev, "unable to enable clk_pcie_pm clock\n");
-               goto err_clk_pcie_pm;
-       }
+       err = clk_bulk_prepare_enable(rockchip->num_clks, rockchip->clks);
+       if (err)
+               return dev_err_probe(dev, err, "failed to enable clocks\n");
 
        return 0;
-
-err_clk_pcie_pm:
-       clk_disable_unprepare(rockchip->hclk_pcie);
-err_hclk_pcie:
-       clk_disable_unprepare(rockchip->aclk_perf_pcie);
-err_aclk_perf_pcie:
-       clk_disable_unprepare(rockchip->aclk_pcie);
-       return err;
 }
 EXPORT_SYMBOL_GPL(rockchip_pcie_enable_clocks);
 
@@ -412,10 +364,7 @@ void rockchip_pcie_disable_clocks(void *data)
 {
        struct rockchip_pcie *rockchip = data;
 
-       clk_disable_unprepare(rockchip->clk_pcie_pm);
-       clk_disable_unprepare(rockchip->hclk_pcie);
-       clk_disable_unprepare(rockchip->aclk_perf_pcie);
-       clk_disable_unprepare(rockchip->aclk_pcie);
+       clk_bulk_disable_unprepare(rockchip->num_clks, rockchip->clks);
 }
 EXPORT_SYMBOL_GPL(rockchip_pcie_disable_clocks);
 
drivers/pci/controller/pcie-rockchip.h +3 -5
index 6111de35f84c..bebab80c9553 100644
@@ -11,6 +11,7 @@
 #ifndef _PCIE_ROCKCHIP_H
 #define _PCIE_ROCKCHIP_H
 
+#include <linux/clk.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/pci-ecam.h>
@@ -299,10 +300,8 @@ struct rockchip_pcie {
        struct  reset_control *pm_rst;
        struct  reset_control *aclk_rst;
        struct  reset_control *pclk_rst;
-       struct  clk *aclk_pcie;
-       struct  clk *aclk_perf_pcie;
-       struct  clk *hclk_pcie;
-       struct  clk *clk_pcie_pm;
+       struct  clk_bulk_data *clks;
+       int     num_clks;
        struct  regulator *vpcie12v; /* 12V power supply */
        struct  regulator *vpcie3v3; /* 3.3V power supply */
        struct  regulator *vpcie1v8; /* 1.8V power supply */
--

2.44.0

#3 lore raw
Quoted 10 lines · Anand Moon
Quoted 7 lines · Anand Moon

Refactor the clock handling in the Rockchip PCIe driver, introducing a more robust and efficient method for enabling and disabling clocks using clk_bulk*() API. Using the clk_bulk APIs, the clock handling for the core clocks becomes much simpler.

Do you have any review comments on this series?

Looks like nice work, thanks. Minor tips below. We'll start applying PCI patches to v6.13-rc1 after it is tagged. It looks like these will apply cleanly, so no rebasing needed.

- It would be helpful if you can add a cover letter (0/n), which is a good place for the overall diffstat and series-level changelog.

- This v5 series adds drivers/phy patches, which are also related to rockchip, but will be handled by a different maintainer, so best to send them as separate series (and of course send the phy patches to the right maintainer, linux-phy, etc).

- "b4 am -o/tmp/ [email protected]" complains about something, I dunno how to fix:

Checking attestation on all messages, may take a moment...
---
✗ [PATCH v5 1/6] PCI: rockchip: Simplify clock handling by using clk_bulk*() function ✗ [PATCH v5 2/6] PCI: rockchip: Simplify reset control handling by using reset_control_bulk*() function ✗ [PATCH v5 3/6] PCI: rockchip: Refactor rockchip_pcie_disable_clocks function signature ✗ [PATCH v5 4/6] phy: rockchip-pcie: Simplify error handling with dev_err_probe()
✗ [PATCH v5 5/6] phy: rockchip-pcie: Change to use devm_clk_get_enabled() helper
✗ [PATCH v5 6/6] phy: rockchip-pcie: Use regmap_read_poll_timeout for PCIe reference clk PLL status
---
✗ BADSIG: DKIM/gmail.com

- In 3/6 and 6/6 commit logs, add parens after function names as you did elsewhere.

- Super nit: In 5/6, s/Change to use/Use/. Every patch is a change, so "Change to" doesn't add any information.

Bjorn

author
#4 lore raw

Hi Bjorn,

Thanks for your review comments.

Quoted 39 lines · Bjorn Helgaas
Quoted 10 lines · Anand Moon
Quoted 7 lines · Anand Moon

Refactor the clock handling in the Rockchip PCIe driver, introducing a more robust and efficient method for enabling and disabling clocks using clk_bulk*() API. Using the clk_bulk APIs, the clock handling for the core clocks becomes much simpler.

Do you have any review comments on this series?

Looks like nice work, thanks. Minor tips below. We'll start applying PCI patches to v6.13-rc1 after it is tagged. It looks like these will apply cleanly, so no rebasing needed.

- It would be helpful if you can add a cover letter (0/n), which is a good place for the overall diffstat and series-level changelog.

- This v5 series adds drivers/phy patches, which are also related to rockchip, but will be handled by a different maintainer, so best to send them as separate series (and of course send the phy patches to the right maintainer, linux-phy, etc).

- "b4 am -o/tmp/ [email protected]" complains about something, I dunno how to fix:

Checking attestation on all messages, may take a moment...
---
✗ [PATCH v5 1/6] PCI: rockchip: Simplify clock handling by using clk_bulk*() function ✗ [PATCH v5 2/6] PCI: rockchip: Simplify reset control handling by using reset_control_bulk*() function ✗ [PATCH v5 3/6] PCI: rockchip: Refactor rockchip_pcie_disable_clocks function signature ✗ [PATCH v5 4/6] phy: rockchip-pcie: Simplify error handling with dev_err_probe()
✗ [PATCH v5 5/6] phy: rockchip-pcie: Change to use devm_clk_get_enabled() helper
✗ [PATCH v5 6/6] phy: rockchip-pcie: Use regmap_read_poll_timeout for PCIe reference clk PLL status
---
✗ BADSIG: DKIM/gmail.com

Quoted 6 lines

- In 3/6 and 6/6 commit logs, add parens after function names as you did elsewhere.

- Super nit: In 5/6, s/Change to use/Use/. Every patch is a change, so "Change to" doesn't add any information.

Ok, I will try to fix and improve on your suggestion in the next version.

Quoted 1 line

Bjorn

Thanks
-Anand

author
#5 lore raw

PATCH v5 2/6 PCI: rockchip: Simplify reset control handling by using reset_control_bulk*() function

In reply to a message not in the archive

Refactor the reset control handling in the Rockchip PCIe driver, introducing a more robust and efficient method for assert and deassert reset controller using reset_control_bulk*() API. Using the reset_control_bulk APIs, the reset handling for the core clocks reset unit becomes much simpler.

---
v5: Fix the De-assert reset core as per the TRM
De-assert the PIPE_RESET_N/MGMT_STICKY_RESET_N/MGMT_RESET_N/RESET_N simultaneously.
v4: use dev_err_probe in error path.
v3: Fix typo in commit message, dropped reported by.
v2: Fix compilation error reported by Intel test robot
fixed checkpatch warning
---

---
 drivers/pci/controller/pcie-rockchip.c | 151 +++++--------------------
 drivers/pci/controller/pcie-rockchip.h |  26 +++--
 2 files changed, 49 insertions(+), 128 deletions(-)
drivers/pci/controller/pcie-rockchip.c +30 -121
index 2777ef0cb599..87daa3288a01 100644
@@ -30,7 +30,7 @@ int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
 	struct platform_device *pdev = to_platform_device(dev);
 	struct device_node *node = dev->of_node;
 	struct resource *regs;
-	int err;
+	int err, i;
 
 	if (rockchip->is_rc) {
 		regs = platform_get_resource_byname(pdev,
@@ -69,55 +69,23 @@ int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
 	if (rockchip->link_gen < 0 || rockchip->link_gen > 2)
 		rockchip->link_gen = 2;
 
-	rockchip->core_rst = devm_reset_control_get_exclusive(dev, "core");
-	if (IS_ERR(rockchip->core_rst)) {
-		if (PTR_ERR(rockchip->core_rst) != -EPROBE_DEFER)
-			dev_err(dev, "missing core reset property in node\n");
-		return PTR_ERR(rockchip->core_rst);
-	}
-
-	rockchip->mgmt_rst = devm_reset_control_get_exclusive(dev, "mgmt");
-	if (IS_ERR(rockchip->mgmt_rst)) {
-		if (PTR_ERR(rockchip->mgmt_rst) != -EPROBE_DEFER)
-			dev_err(dev, "missing mgmt reset property in node\n");
-		return PTR_ERR(rockchip->mgmt_rst);
-	}
-
-	rockchip->mgmt_sticky_rst = devm_reset_control_get_exclusive(dev,
-								"mgmt-sticky");
-	if (IS_ERR(rockchip->mgmt_sticky_rst)) {
-		if (PTR_ERR(rockchip->mgmt_sticky_rst) != -EPROBE_DEFER)
-			dev_err(dev, "missing mgmt-sticky reset property in node\n");
-		return PTR_ERR(rockchip->mgmt_sticky_rst);
-	}
-
-	rockchip->pipe_rst = devm_reset_control_get_exclusive(dev, "pipe");
-	if (IS_ERR(rockchip->pipe_rst)) {
-		if (PTR_ERR(rockchip->pipe_rst) != -EPROBE_DEFER)
-			dev_err(dev, "missing pipe reset property in node\n");
-		return PTR_ERR(rockchip->pipe_rst);
-	}
+	for (i = 0; i < ROCKCHIP_NUM_PM_RSTS; i++)
+		rockchip->pm_rsts[i].id = rockchip_pci_pm_rsts[i];
 
-	rockchip->pm_rst = devm_reset_control_get_exclusive(dev, "pm");
-	if (IS_ERR(rockchip->pm_rst)) {
-		if (PTR_ERR(rockchip->pm_rst) != -EPROBE_DEFER)
-			dev_err(dev, "missing pm reset property in node\n");
-		return PTR_ERR(rockchip->pm_rst);
-	}
+	err = devm_reset_control_bulk_get_optional_exclusive(dev,
+							     ROCKCHIP_NUM_PM_RSTS,
+							     rockchip->pm_rsts);
+	if (err)
+		return dev_err_probe(dev, err, "cannot get the reset control\n");
 
-	rockchip->pclk_rst = devm_reset_control_get_exclusive(dev, "pclk");
-	if (IS_ERR(rockchip->pclk_rst)) {
-		if (PTR_ERR(rockchip->pclk_rst) != -EPROBE_DEFER)
-			dev_err(dev, "missing pclk reset property in node\n");
-		return PTR_ERR(rockchip->pclk_rst);
-	}
+	for (i = 0; i < ROCKCHIP_NUM_CORE_RSTS; i++)
+		rockchip->core_rsts[i].id = rockchip_pci_core_rsts[i];
 
-	rockchip->aclk_rst = devm_reset_control_get_exclusive(dev, "aclk");
-	if (IS_ERR(rockchip->aclk_rst)) {
-		if (PTR_ERR(rockchip->aclk_rst) != -EPROBE_DEFER)
-			dev_err(dev, "missing aclk reset property in node\n");
-		return PTR_ERR(rockchip->aclk_rst);
-	}
+	err = devm_reset_control_bulk_get_optional_exclusive(dev,
+							     ROCKCHIP_NUM_CORE_RSTS,
+							     rockchip->core_rsts);
+	if (err)
+		return dev_err_probe(dev, err, "cannot get the reset control\n");
 
 	if (rockchip->is_rc) {
 		rockchip->ep_gpio = devm_gpiod_get_optional(dev, "ep",
@@ -147,23 +115,10 @@ int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
 	int err, i;
 	u32 regs;
 
-	err = reset_control_assert(rockchip->aclk_rst);
-	if (err) {
-		dev_err(dev, "assert aclk_rst err %d\n", err);
-		return err;
-	}
-
-	err = reset_control_assert(rockchip->pclk_rst);
-	if (err) {
-		dev_err(dev, "assert pclk_rst err %d\n", err);
-		return err;
-	}
-
-	err = reset_control_assert(rockchip->pm_rst);
-	if (err) {
-		dev_err(dev, "assert pm_rst err %d\n", err);
-		return err;
-	}
+	err = reset_control_bulk_assert(ROCKCHIP_NUM_PM_RSTS,
+					rockchip->pm_rsts);
+	if (err)
+		return dev_err_probe(dev, err, "reset bulk assert pm reset\n");
 
 	for (i = 0; i < MAX_LANE_NUM; i++) {
 		err = phy_init(rockchip->phys[i]);
@@ -173,47 +128,17 @@ int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
 		}
 	}
 
-	err = reset_control_assert(rockchip->core_rst);
-	if (err) {
-		dev_err(dev, "assert core_rst err %d\n", err);
-		goto err_exit_phy;
-	}
-
-	err = reset_control_assert(rockchip->mgmt_rst);
-	if (err) {
-		dev_err(dev, "assert mgmt_rst err %d\n", err);
-		goto err_exit_phy;
-	}
-
-	err = reset_control_assert(rockchip->mgmt_sticky_rst);
-	if (err) {
-		dev_err(dev, "assert mgmt_sticky_rst err %d\n", err);
-		goto err_exit_phy;
-	}
-
-	err = reset_control_assert(rockchip->pipe_rst);
-	if (err) {
-		dev_err(dev, "assert pipe_rst err %d\n", err);
-		goto err_exit_phy;
-	}
+	err = reset_control_bulk_assert(ROCKCHIP_NUM_CORE_RSTS,
+					rockchip->core_rsts);
+	if (err)
+		return dev_err_probe(dev, err, "reset bulk assert core reset\n");
 
 	udelay(10);
 
-	err = reset_control_deassert(rockchip->pm_rst);
-	if (err) {
-		dev_err(dev, "deassert pm_rst err %d\n", err);
-		goto err_exit_phy;
-	}
-
-	err = reset_control_deassert(rockchip->aclk_rst);
+	err = reset_control_bulk_deassert(ROCKCHIP_NUM_PM_RSTS,
+					  rockchip->pm_rsts);
 	if (err) {
-		dev_err(dev, "deassert aclk_rst err %d\n", err);
-		goto err_exit_phy;
-	}
-
-	err = reset_control_deassert(rockchip->pclk_rst);
-	if (err) {
-		dev_err(dev, "deassert pclk_rst err %d\n", err);
+		dev_err(dev, "reset bulk deassert pm err %d\n", err);
 		goto err_exit_phy;
 	}
 
@@ -256,31 +181,15 @@ int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
 	 * Please don't reorder the deassert sequence of the following
 	 * four reset pins.
 	 */
-	err = reset_control_deassert(rockchip->mgmt_sticky_rst);
-	if (err) {
-		dev_err(dev, "deassert mgmt_sticky_rst err %d\n", err);
-		goto err_power_off_phy;
-	}
-
-	err = reset_control_deassert(rockchip->core_rst);
+	err = reset_control_bulk_deassert(ROCKCHIP_NUM_CORE_RSTS,
+					  rockchip->core_rsts);
 	if (err) {
-		dev_err(dev, "deassert core_rst err %d\n", err);
-		goto err_power_off_phy;
-	}
-
-	err = reset_control_deassert(rockchip->mgmt_rst);
-	if (err) {
-		dev_err(dev, "deassert mgmt_rst err %d\n", err);
-		goto err_power_off_phy;
-	}
-
-	err = reset_control_deassert(rockchip->pipe_rst);
-	if (err) {
-		dev_err(dev, "deassert pipe_rst err %d\n", err);
+		dev_err(dev, "reset bulk deassert core err %d\n", err);
 		goto err_power_off_phy;
 	}
 
 	return 0;
+
 err_power_off_phy:
 	while (i--)
 		phy_power_off(rockchip->phys[i]);
drivers/pci/controller/pcie-rockchip.h +19 -7
index bebab80c9553..2761699f670b 100644
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/pci-ecam.h>
+#include <linux/reset.h>
 
 /*
  * The upper 16 bits of PCIE_CLIENT_CONFIG are a write mask for the lower 16
@@ -288,18 +289,29 @@
 		(((c) << ((b) * 8 + 5)) & \
 		 ROCKCHIP_PCIE_CORE_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b))
 
+#define ROCKCHIP_NUM_PM_RSTS   ARRAY_SIZE(rockchip_pci_pm_rsts)
+#define ROCKCHIP_NUM_CORE_RSTS ARRAY_SIZE(rockchip_pci_core_rsts)
+
+static const char * const rockchip_pci_pm_rsts[] = {
+	"pm",
+	"pclk",
+	"aclk",
+};
+
+static const char * const rockchip_pci_core_rsts[] = {
+	"mgmt-sticky",
+	"mgmt",
+	"core",
+	"pipe",
+};
+
 struct rockchip_pcie {
 	void	__iomem *reg_base;		/* DT axi-base */
 	void	__iomem *apb_base;		/* DT apb-base */
 	bool    legacy_phy;
 	struct  phy *phys[MAX_LANE_NUM];
-	struct	reset_control *core_rst;
-	struct	reset_control *mgmt_rst;
-	struct	reset_control *mgmt_sticky_rst;
-	struct	reset_control *pipe_rst;
-	struct	reset_control *pm_rst;
-	struct	reset_control *aclk_rst;
-	struct	reset_control *pclk_rst;
+	struct  reset_control_bulk_data pm_rsts[ROCKCHIP_NUM_PM_RSTS];
+	struct  reset_control_bulk_data core_rsts[ROCKCHIP_NUM_CORE_RSTS];
 	struct  clk_bulk_data *clks;
 	int	num_clks;
 	struct	regulator *vpcie12v; /* 12V power supply */
Signature · 1 line
2.44.0
author
#6 lore raw

PATCH v5 3/6 PCI: rockchip: Refactor rockchip_pcie_disable_clocks function signature

In reply to a message not in the archive

Refactor the rockchip_pcie_disable_clocks function to accept a struct rockchip_pcie pointer instead of a void pointer. This change improves type safety and code readability by explicitly specifying the expected data type.

---
v5: Fix the commit message and add r-b Manivannan.
v4: None
v3: None
v2: None

---
 drivers/pci/controller/pcie-rockchip.c | 3 +--
 drivers/pci/controller/pcie-rockchip.h | 2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)
drivers/pci/controller/pcie-rockchip.c +1 -2
index 87daa3288a01..b528d561b2de 100644
@@ -269,9 +269,8 @@ int rockchip_pcie_enable_clocks(struct rockchip_pcie *rockchip)
 }
 EXPORT_SYMBOL_GPL(rockchip_pcie_enable_clocks);
 
-void rockchip_pcie_disable_clocks(void *data)
+void rockchip_pcie_disable_clocks(struct rockchip_pcie *rockchip)
 {
-	struct rockchip_pcie *rockchip = data;
 
 	clk_bulk_disable_unprepare(rockchip->num_clks, rockchip->clks);
 }
drivers/pci/controller/pcie-rockchip.h +1 -1
index 2761699f670b..7f0f938e9195 100644
@@ -347,7 +347,7 @@ int rockchip_pcie_init_port(struct rockchip_pcie *rockchip);
 int rockchip_pcie_get_phys(struct rockchip_pcie *rockchip);
 void rockchip_pcie_deinit_phys(struct rockchip_pcie *rockchip);
 int rockchip_pcie_enable_clocks(struct rockchip_pcie *rockchip);
-void rockchip_pcie_disable_clocks(void *data);
+void rockchip_pcie_disable_clocks(struct rockchip_pcie *rockchip);
 void rockchip_pcie_cfg_configuration_accesses(
 		struct rockchip_pcie *rockchip, u32 type);
 
Signature · 1 line
2.44.0
author
#7 lore raw

PATCH v5 4/6 phy: rockchip-pcie: Simplify error handling with dev_err_probe()

In reply to a message not in the archive

Use the dev_err_probe() helper to simplify error handling during probe. This also handle scenario, when -EDEFER is returned and useless error is printed.

---
v5: New patch in this series

---
 drivers/phy/rockchip/phy-rockchip-pcie.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)
drivers/phy/rockchip/phy-rockchip-pcie.c +3 -6
index 51cc5ece0e63..51e636a1ce33 100644
@@ -371,12 +371,9 @@ static int rockchip_pcie_phy_probe(struct platform_device *pdev)
 	mutex_init(&rk_phy->pcie_mutex);
 
 	rk_phy->phy_rst = devm_reset_control_get(dev, "phy");
-	if (IS_ERR(rk_phy->phy_rst)) {
-		if (PTR_ERR(rk_phy->phy_rst) != -EPROBE_DEFER)
-			dev_err(dev,
-				"missing phy property for reset controller\n");
-		return PTR_ERR(rk_phy->phy_rst);
-	}
+	if (IS_ERR(rk_phy->phy_rst))
+		return dev_err_probe(&pdev->dev, PTR_ERR(rk_phy->phy_rst),
+				     "missing phy property for reset controller\n");
 
 	rk_phy->clk_pciephy_ref = devm_clk_get(dev, "refclk");
 	if (IS_ERR(rk_phy->clk_pciephy_ref)) {
Signature · 1 line
2.44.0
author
#8 lore raw

PATCH v5 5/6 phy: rockchip-pcie: Change to use devm_clk_get_enabled() helper

In reply to a message not in the archive

Use devm_clk_get_enabled() instead of devm_clk_get() to make the code cleaner and avoid calling clk_disable_unprepare(), as this is exactly what this function does. Use the dev_err_probe() helper to simplify error handling during probe.

--
v5: New patch in this series

---
 drivers/phy/rockchip/phy-rockchip-pcie.c | 25 ++++++------------------
 1 file changed, 6 insertions(+), 19 deletions(-)
drivers/phy/rockchip/phy-rockchip-pcie.c +6 -19
index 51e636a1ce33..a1b4b0323e9d 100644
@@ -277,26 +277,16 @@ static int rockchip_pcie_phy_init(struct phy *phy)
 	if (rk_phy->init_cnt++)
 		goto err_out;
 
-	err = clk_prepare_enable(rk_phy->clk_pciephy_ref);
-	if (err) {
-		dev_err(&phy->dev, "Fail to enable pcie ref clock.\n");
-		goto err_refclk;
-	}
-
 	err = reset_control_assert(rk_phy->phy_rst);
 	if (err) {
 		dev_err(&phy->dev, "assert phy_rst err %d\n", err);
-		goto err_reset;
+		goto err_out;
 	}
 
-err_out:
 	mutex_unlock(&rk_phy->pcie_mutex);
 	return 0;
 
-err_reset:
-
-	clk_disable_unprepare(rk_phy->clk_pciephy_ref);
-err_refclk:
+err_out:
 	rk_phy->init_cnt--;
 	mutex_unlock(&rk_phy->pcie_mutex);
 	return err;
@@ -312,8 +302,6 @@ static int rockchip_pcie_phy_exit(struct phy *phy)
 	if (--rk_phy->init_cnt)
 		goto err_init_cnt;
 
-	clk_disable_unprepare(rk_phy->clk_pciephy_ref);
-
 err_init_cnt:
 	mutex_unlock(&rk_phy->pcie_mutex);
 	return 0;
@@ -375,11 +363,10 @@ static int rockchip_pcie_phy_probe(struct platform_device *pdev)
 		return dev_err_probe(&pdev->dev, PTR_ERR(rk_phy->phy_rst),
 				     "missing phy property for reset controller\n");
 
-	rk_phy->clk_pciephy_ref = devm_clk_get(dev, "refclk");
-	if (IS_ERR(rk_phy->clk_pciephy_ref)) {
-		dev_err(dev, "refclk not found.\n");
-		return PTR_ERR(rk_phy->clk_pciephy_ref);
-	}
+	rk_phy->clk_pciephy_ref = devm_clk_get_enabled(dev, "refclk");
+	if (IS_ERR(rk_phy->clk_pciephy_ref))
+		return dev_err_probe(&pdev->dev, PTR_ERR(rk_phy->clk_pciephy_ref),
+				     "failed to get phyclk\n");
 
 	/* parse #phy-cells to see if it's legacy PHY model */
 	if (of_property_read_u32(dev->of_node, "#phy-cells", &phy_num))
Signature · 1 line
2.44.0
author
#9 lore raw

PATCH v5 6/6 phy: rockchip-pcie: Use regmap_read_poll_timeout for PCIe reference clk PLL status

In reply to a message not in the archive

Replace open-coded phy PCIe reference clk PLL status polling with regmap_read_poll_timeout API. This change simplifies the code without altering functionality.

---
v5: New patch in this seriese

---
 drivers/phy/rockchip/phy-rockchip-pcie.c | 56 +++++++-----------------
 1 file changed, 15 insertions(+), 41 deletions(-)
drivers/phy/rockchip/phy-rockchip-pcie.c +15 -41
index a1b4b0323e9d..2c4d6f68f02a 100644
@@ -162,7 +162,6 @@ static int rockchip_pcie_phy_power_on(struct phy *phy)
 	struct rockchip_pcie_phy *rk_phy = to_pcie_phy(inst);
 	int err = 0;
 	u32 status;
-	unsigned long timeout;
 
 	mutex_lock(&rk_phy->pcie_mutex);
 
@@ -191,21 +190,11 @@ static int rockchip_pcie_phy_power_on(struct phy *phy)
 	 * so we make it large enough here. And we use loop-break
 	 * method which should not be harmful.
 	 */
-	timeout = jiffies + msecs_to_jiffies(1000);
-
-	err = -EINVAL;
-	while (time_before(jiffies, timeout)) {
-		regmap_read(rk_phy->reg_base,
-			    rk_phy->phy_data->pcie_status,
-			    &status);
-		if (status & PHY_PLL_LOCKED) {
-			dev_dbg(&phy->dev, "pll locked!\n");
-			err = 0;
-			break;
-		}
-		msleep(20);
-	}
-
+	err = regmap_read_poll_timeout(rk_phy->reg_base,
+				       rk_phy->phy_data->pcie_status,
+				       status,
+				       status & PHY_PLL_LOCKED,
+				       200, 100000);
 	if (err) {
 		dev_err(&phy->dev, "pll lock timeout!\n");
 		goto err_pll_lock;
@@ -214,19 +203,11 @@ static int rockchip_pcie_phy_power_on(struct phy *phy)
 	phy_wr_cfg(rk_phy, PHY_CFG_CLK_TEST, PHY_CFG_SEPE_RATE);
 	phy_wr_cfg(rk_phy, PHY_CFG_CLK_SCC, PHY_CFG_PLL_100M);
 
-	err = -ETIMEDOUT;
-	while (time_before(jiffies, timeout)) {
-		regmap_read(rk_phy->reg_base,
-			    rk_phy->phy_data->pcie_status,
-			    &status);
-		if (!(status & PHY_PLL_OUTPUT)) {
-			dev_dbg(&phy->dev, "pll output enable done!\n");
-			err = 0;
-			break;
-		}
-		msleep(20);
-	}
-
+	err = regmap_read_poll_timeout(rk_phy->reg_base,
+				       rk_phy->phy_data->pcie_status,
+				       status,
+				       !(status & PHY_PLL_OUTPUT),
+				       200, 100000);
 	if (err) {
 		dev_err(&phy->dev, "pll output enable timeout!\n");
 		goto err_pll_lock;
@@ -236,19 +217,12 @@ static int rockchip_pcie_phy_power_on(struct phy *phy)
 		     HIWORD_UPDATE(PHY_CFG_PLL_LOCK,
 				   PHY_CFG_ADDR_MASK,
 				   PHY_CFG_ADDR_SHIFT));
-	err = -EINVAL;
-	while (time_before(jiffies, timeout)) {
-		regmap_read(rk_phy->reg_base,
-			    rk_phy->phy_data->pcie_status,
-			    &status);
-		if (status & PHY_PLL_LOCKED) {
-			dev_dbg(&phy->dev, "pll relocked!\n");
-			err = 0;
-			break;
-		}
-		msleep(20);
-	}
 
+	err = regmap_read_poll_timeout(rk_phy->reg_base,
+				       rk_phy->phy_data->pcie_status,
+				       status,
+				       status & PHY_PLL_LOCKED,
+				       200, 100000);
 	if (err) {
 		dev_err(&phy->dev, "pll relock timeout!\n");
 		goto err_pll_lock;
Signature · 1 line
2.44.0