2024-05-15 10:07:20

by Thomas Richard

[permalink] [raw]
Subject: [PATCH v6 00/12] Add suspend to ram support for PCIe on J7200

This adds suspend to ram support for the PCIe (RC mode) on J7200 platform.

This 6th iteration fixes a compile issue in the i2c-omap driver if
CONFIG_PM_SLEEP is not set.
A new patch was added to remove the __maybe_unused attribute of
omap_i2c_runtime_suspend() and omap_i2c_runtime_resume().

Regards,

Thomas

Signed-off-by: Thomas Richard <[email protected]>
---
Changes in v6:
- i2c-omap: add a patch to remove __maybe_unused attribute of
omap_i2c_runtime_suspend() and omap_i2c_runtime_resume()
- i2c-omap: fix compile issue if CONFIG_PM_SLEEP is not set
- Link to v5: https://lore.kernel.org/r/[email protected]

Changes in v5:
- all: series rebased on Linux 6.9-rc1
- pinctrl-single: patch removed (already applied to the pinctrl tree)
- phy: patches moved to a dedicated series.
- pci: add T_PERST_CLK_US macro.
- pci-j721e: update the comments about T_PERST_CLK_US.
- Link to v4: https://lore.kernel.org/r/[email protected]

Changes in v4:
- all: use SoB/Co-developed-by for patches initially developed by Théo
Lebrun.
- pinctrl-single: squash the two commits.
- i2c-omap: fix line lenghts of the comment in omap_i2c_suspend().
- mux: mux_chip_resume() return 0 or at the first error.
- phy-j721e-wiz: clean code around dev_err_probe().
- phy-j721e-wiz: use REF_CLK_100MHZ macros.
- pci: fix subject line for all PCI patches.
- pci-cadence: use fsleep() instead of usleep_range().
- pci-cadence: remove cdns_torrent_clk_cleanup() call in
cdns_torrent_phy_resume_noirq().
- pci-j721e: add a patch to use dev_err_probe() instead of dev_err() in the probe().
- pci-j721e: fix unordered header files.
- pci-j721e: remove some log spammers.
- pci-j721e: add a missing clock disable in j721e_pcie_resume_noirq().
- pci-j721e: simplify the patch "Add reset GPIO to struct j721e_pcie"
- Link to v3: https://lore.kernel.org/r/[email protected]

Changes in v3:
- pinctrl-single: split patch in two parts, a first patch to remove the
dead code, a second to move suspend()/resume() callbacks to noirq.
- i2c-omap: add a comments above the suspend_noirq() callback.
- mux: now mux_chip_resume() try to restores all muxes, then return 0 if
all is ok or the first failure.
- mmio: fix commit message.
- phy-j721e-wiz: add a patch to use dev_err_probe() instead of dev_err() in
the wiz_clock_init() function.
- phy-j721e-wiz: remove probe boolean for the wiz_clock_init(), rename the
function to wiz_clock_probe(), extract hardware configuration part in a
new function wiz_clock_init().
- phy-cadence-torrent: use dev_err_probe() and fix commit messages
- pcie-cadence-host: remove probe boolean for the cdns_pcie_host_setup()
function and extract the link setup part in a new function
cdns_pcie_host_link_setup().
- pcie-cadence-host: make cdns_pcie_host_init() global.
- pci-j721e: use the cdns_pcie_host_link_setup() cdns_pcie_host_init()
functions in the resume_noirq() callback.
- Link to v2: https://lore.kernel.org/r/[email protected]

Changes in v2:
- all: fix commits messages.
- all: use DEFINE_NOIRQ_DEV_PM_OPS and pm_sleep_ptr macros.
- all: remove useless #ifdef CONFIG_PM.
- pinctrl-single: drop dead code
- mux: add mux_chip_resume() function in mux core.
- mmio: resume sequence is now a call to mux_chip_resume().
- phy-cadence-torrent: fix typo in resume sequence (reset_control_assert()
instead of reset_control_put()).
- phy-cadence-torrent: use PHY instead of phy.
- pci-j721e: do not shadow cdns_pcie_host_setup return code in resume
sequence.
- pci-j721e: drop dead code.
- Link to v1: https://lore.kernel.org/r/[email protected]

---
Thomas Richard (9):
gpio: pca953x: move suspend()/resume() to suspend_noirq()/resume_noirq()
i2c: omap: switch to NOIRQ_SYSTEM_SLEEP_PM_OPS() and RUNTIME_PM_OPS()
i2c: omap: wakeup the controller during suspend() callback
mux: add mux_chip_resume() function
PCI: cadence: Extract link setup sequence from cdns_pcie_host_setup()
PCI: cadence: Set cdns_pcie_host_init() global
PCI: j721e: Use dev_err_probe() in the probe() function
PCI: Add T_PERST_CLK_US macro
PCI: j721e: Use T_PERST_CLK_US macro

Théo Lebrun (3):
mux: mmio: add resume support
PCI: j721e: Add reset GPIO to struct j721e_pcie
PCI: j721e: Add suspend and resume support

drivers/gpio/gpio-pca953x.c | 7 +-
drivers/i2c/busses/i2c-omap.c | 36 ++++--
drivers/mux/core.c | 29 +++++
drivers/mux/mmio.c | 12 ++
drivers/pci/controller/cadence/pci-j721e.c | 121 ++++++++++++++++++---
drivers/pci/controller/cadence/pcie-cadence-host.c | 44 +++++---
drivers/pci/controller/cadence/pcie-cadence.h | 12 ++
drivers/pci/pci.h | 3 +
include/linux/mux/driver.h | 1 +
9 files changed, 221 insertions(+), 44 deletions(-)
---
base-commit: cebffb4fba6177b15e60e28e1ac17fc4efb2f86f
change-id: 20240102-j7200-pcie-s2r-ecb1a979e357

Best regards,
--
Thomas Richard <[email protected]>



2024-05-15 10:10:25

by Thomas Richard

[permalink] [raw]
Subject: [PATCH v6 08/12] PCI: j721e: Use dev_err_probe() in the probe() function

Use dev_err_probe() instead of dev_err() in the probe() function to
simplify the code and standardize the error output.

Reviewed-by: Francesco Dolcini <[email protected]>
Signed-off-by: Thomas Richard <[email protected]>
---
drivers/pci/controller/cadence/pci-j721e.c | 19 ++++++++-----------
1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
index 85718246016b..98484f001562 100644
--- a/drivers/pci/controller/cadence/pci-j721e.c
+++ b/drivers/pci/controller/cadence/pci-j721e.c
@@ -482,20 +482,20 @@ static int j721e_pcie_probe(struct platform_device *pdev)
pm_runtime_enable(dev);
ret = pm_runtime_get_sync(dev);
if (ret < 0) {
- dev_err(dev, "pm_runtime_get_sync failed\n");
+ dev_err_probe(dev, ret, "pm_runtime_get_sync failed\n");
goto err_get_sync;
}

ret = j721e_pcie_ctrl_init(pcie);
if (ret < 0) {
- dev_err(dev, "pm_runtime_get_sync failed\n");
+ dev_err_probe(dev, ret, "pm_runtime_get_sync failed\n");
goto err_get_sync;
}

ret = devm_request_irq(dev, irq, j721e_pcie_link_irq_handler, 0,
"j721e-pcie-link-down-irq", pcie);
if (ret < 0) {
- dev_err(dev, "failed to request link state IRQ %d\n", irq);
+ dev_err_probe(dev, ret, "failed to request link state IRQ %d\n", irq);
goto err_get_sync;
}

@@ -505,28 +505,25 @@ static int j721e_pcie_probe(struct platform_device *pdev)
case PCI_MODE_RC:
gpiod = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
if (IS_ERR(gpiod)) {
- ret = PTR_ERR(gpiod);
- if (ret != -EPROBE_DEFER)
- dev_err(dev, "Failed to get reset GPIO\n");
+ ret = dev_err_probe(dev, PTR_ERR(gpiod), "Failed to get reset GPIO\n");
goto err_get_sync;
}

ret = cdns_pcie_init_phy(dev, cdns_pcie);
if (ret) {
- dev_err(dev, "Failed to init phy\n");
+ dev_err_probe(dev, ret, "Failed to init phy\n");
goto err_get_sync;
}

clk = devm_clk_get_optional(dev, "pcie_refclk");
if (IS_ERR(clk)) {
- ret = PTR_ERR(clk);
- dev_err(dev, "failed to get pcie_refclk\n");
+ ret = dev_err_probe(dev, PTR_ERR(clk), "failed to get pcie_refclk\n");
goto err_pcie_setup;
}

ret = clk_prepare_enable(clk);
if (ret) {
- dev_err(dev, "failed to enable pcie_refclk\n");
+ dev_err_probe(dev, ret, "failed to enable pcie_refclk\n");
goto err_pcie_setup;
}
pcie->refclk = clk;
@@ -554,7 +551,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)
case PCI_MODE_EP:
ret = cdns_pcie_init_phy(dev, cdns_pcie);
if (ret) {
- dev_err(dev, "Failed to init phy\n");
+ dev_err_probe(dev, ret, "Failed to init phy\n");
goto err_get_sync;
}


--
2.39.2


2024-05-15 10:10:50

by Thomas Richard

[permalink] [raw]
Subject: [PATCH v6 09/12] PCI: j721e: Add reset GPIO to struct j721e_pcie

From: Théo Lebrun <[email protected]>

Add reset GPIO to struct j721e_pcie, so it can be used at suspend and
resume stages.

Signed-off-by: Théo Lebrun <[email protected]>
Signed-off-by: Thomas Richard <[email protected]>
---
drivers/pci/controller/cadence/pci-j721e.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
index 98484f001562..9af4fd64c1f9 100644
--- a/drivers/pci/controller/cadence/pci-j721e.c
+++ b/drivers/pci/controller/cadence/pci-j721e.c
@@ -52,6 +52,7 @@ struct j721e_pcie {
u32 mode;
u32 num_lanes;
u32 max_lanes;
+ struct gpio_desc *reset_gpio;
void __iomem *user_cfg_base;
void __iomem *intd_cfg_base;
u32 linkdown_irq_regfield;
@@ -508,6 +509,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)
ret = dev_err_probe(dev, PTR_ERR(gpiod), "Failed to get reset GPIO\n");
goto err_get_sync;
}
+ pcie->reset_gpio = gpiod;

ret = cdns_pcie_init_phy(dev, cdns_pcie);
if (ret) {

--
2.39.2


2024-05-15 10:11:22

by Thomas Richard

[permalink] [raw]
Subject: [PATCH v6 10/12] PCI: Add T_PERST_CLK_US macro

"Power Sequencing and Reset Signal Timings" table (section 2.9.2) in PCI
EXPRESS CARD ELECTROMECHANICAL SPECIFICATION, REV. 5.1 indicates PERST#
should be deasserted after minimum of 100us once REFCLK is stable (symbol
T_PERST-CLK).

Add a macro so that PCIe controller drivers can use it.

Signed-off-by: Thomas Richard <[email protected]>
---
drivers/pci/pci.h | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 17fed1846847..c47b1d3b5887 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -16,6 +16,9 @@
/* Power stable to PERST# inactive from PCIe card Electromechanical Spec */
#define PCIE_T_PVPERL_MS 100

+/* REFCLK stable before PERST# inactive from PCIe card Electromechanical Spec */
+#define PCIE_T_PERST_CLK_US 100
+
/*
* PCIe r6.0, sec 5.3.3.2.1 <PME Synchronization>
* Recommends 1ms to 10ms timeout to check L2 ready.

--
2.39.2


2024-05-15 10:12:16

by Thomas Richard

[permalink] [raw]
Subject: [PATCH v6 12/12] PCI: j721e: Add suspend and resume support

From: Théo Lebrun <[email protected]>

Add suspend and resume support. Only the rc mode is supported.

During the suspend stage PERST# is asserted, then deasserted during the
resume stage.

Signed-off-by: Théo Lebrun <[email protected]>
Reviewed-by: Siddharth Vadapalli <[email protected]>
Signed-off-by: Thomas Richard <[email protected]>
---
drivers/pci/controller/cadence/pci-j721e.c | 98 ++++++++++++++++++++++++++++--
1 file changed, 92 insertions(+), 6 deletions(-)

diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
index 967a5bf38e26..96316a79ab8a 100644
--- a/drivers/pci/controller/cadence/pci-j721e.c
+++ b/drivers/pci/controller/cadence/pci-j721e.c
@@ -7,6 +7,8 @@
*/

#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/container_of.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/io.h>
@@ -22,6 +24,8 @@
#include "../../pci.h"
#include "pcie-cadence.h"

+#define cdns_pcie_to_rc(p) container_of(p, struct cdns_pcie_rc, pcie)
+
#define ENABLE_REG_SYS_2 0x108
#define STATUS_REG_SYS_2 0x508
#define STATUS_CLR_REG_SYS_2 0x708
@@ -531,12 +535,12 @@ static int j721e_pcie_probe(struct platform_device *pdev)
pcie->refclk = clk;

/*
- * "Power Sequencing and Reset Signal Timings" table in
- * PCI EXPRESS CARD ELECTROMECHANICAL SPECIFICATION, REV. 3.0
- * indicates PERST# should be deasserted after minimum of 100us
- * once REFCLK is stable. The REFCLK to the connector in RC
- * mode is selected while enabling the PHY. So deassert PERST#
- * after 100 us.
+ * "Power Sequencing and Reset Signal Timings" table (section
+ * 2.9.2) in PCI EXPRESS CARD ELECTROMECHANICAL SPECIFICATION,
+ * REV. 5.1 indicates PERST# should be deasserted after minimum
+ * of 100us once REFCLK is stable (symbol T_PERST-CLK).
+ * The REFCLK to the connector in RC mode is selected while
+ * enabling the PHY. So deassert PERST# after 100 us.
*/
if (gpiod) {
fsleep(PCIE_T_PERST_CLK_US);
@@ -588,6 +592,87 @@ static void j721e_pcie_remove(struct platform_device *pdev)
pm_runtime_disable(dev);
}

+static int j721e_pcie_suspend_noirq(struct device *dev)
+{
+ struct j721e_pcie *pcie = dev_get_drvdata(dev);
+
+ if (pcie->mode == PCI_MODE_RC) {
+ gpiod_set_value_cansleep(pcie->reset_gpio, 0);
+ clk_disable_unprepare(pcie->refclk);
+ }
+
+ cdns_pcie_disable_phy(pcie->cdns_pcie);
+
+ return 0;
+}
+
+static int j721e_pcie_resume_noirq(struct device *dev)
+{
+ struct j721e_pcie *pcie = dev_get_drvdata(dev);
+ struct cdns_pcie *cdns_pcie = pcie->cdns_pcie;
+ int ret;
+
+ ret = j721e_pcie_ctrl_init(pcie);
+ if (ret < 0)
+ return ret;
+
+ j721e_pcie_config_link_irq(pcie);
+
+ /*
+ * This is not called explicitly in the probe, it is called by
+ * cdns_pcie_init_phy().
+ */
+ ret = cdns_pcie_enable_phy(pcie->cdns_pcie);
+ if (ret < 0)
+ return ret;
+
+ if (pcie->mode == PCI_MODE_RC) {
+ struct cdns_pcie_rc *rc = cdns_pcie_to_rc(cdns_pcie);
+
+ ret = clk_prepare_enable(pcie->refclk);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * "Power Sequencing and Reset Signal Timings" table (section
+ * 2.9.2) in PCI EXPRESS CARD ELECTROMECHANICAL SPECIFICATION,
+ * REV. 5.1 indicates PERST# should be deasserted after minimum
+ * of 100us once REFCLK is stable (symbol T_PERST-CLK).
+ * The REFCLK to the connector in RC mode is selected while
+ * enabling the PHY. So deassert PERST# after 100 us.
+ */
+ if (pcie->reset_gpio) {
+ fsleep(PCIE_T_PERST_CLK_US);
+ gpiod_set_value_cansleep(pcie->reset_gpio, 1);
+ }
+
+ ret = cdns_pcie_host_link_setup(rc);
+ if (ret < 0) {
+ clk_disable_unprepare(pcie->refclk);
+ return ret;
+ }
+
+ /*
+ * Reset internal status of BARs to force reinitialization in
+ * cdns_pcie_host_init().
+ */
+ for (enum cdns_pcie_rp_bar bar = RP_BAR0; bar <= RP_NO_BAR; bar++)
+ rc->avail_ib_bar[bar] = true;
+
+ ret = cdns_pcie_host_init(rc);
+ if (ret) {
+ clk_disable_unprepare(pcie->refclk);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static DEFINE_NOIRQ_DEV_PM_OPS(j721e_pcie_pm_ops,
+ j721e_pcie_suspend_noirq,
+ j721e_pcie_resume_noirq);
+
static struct platform_driver j721e_pcie_driver = {
.probe = j721e_pcie_probe,
.remove_new = j721e_pcie_remove,
@@ -595,6 +680,7 @@ static struct platform_driver j721e_pcie_driver = {
.name = "j721e-pcie",
.of_match_table = of_j721e_pcie_match,
.suppress_bind_attrs = true,
+ .pm = pm_sleep_ptr(&j721e_pcie_pm_ops),
},
};
builtin_platform_driver(j721e_pcie_driver);

--
2.39.2


2024-05-31 16:55:34

by Thomas Richard

[permalink] [raw]
Subject: Re: [PATCH v6 00/12] Add suspend to ram support for PCIe on J7200

On 5/15/24 12:01, Thomas Richard wrote:
> This adds suspend to ram support for the PCIe (RC mode) on J7200 platform.
>

Hello,

Gentle ping.
No merge conflict with 6.10-rc1.
I know the patch for the gpio-pca953x driver causes a regression for one
other platform.
But most of the patches could be applied.

Best Regards,

Thomas

--
Thomas Richard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


2024-06-03 09:53:13

by Bartosz Golaszewski

[permalink] [raw]
Subject: Re: [PATCH v6 00/12] Add suspend to ram support for PCIe on J7200

On Fri, May 31, 2024 at 6:55 PM Thomas Richard
<[email protected]> wrote:
>
> On 5/15/24 12:01, Thomas Richard wrote:
> > This adds suspend to ram support for the PCIe (RC mode) on J7200 platform.
> >
>
> Hello,
>
> Gentle ping.
> No merge conflict with 6.10-rc1.
> I know the patch for the gpio-pca953x driver causes a regression for one
> other platform.
> But most of the patches could be applied.
>
> Best Regards,
>
> Thomas
>

If the patches targeting different subsystems don't depend on each
other then you'd have more chance of getting them picked up by
splitting the series up and sending individual bits and pieces to
appropriate maintainers separately.

Bart