lkml.org 
[lkml]   [2024]   [Jan]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH v2 15/15] PCI: j721e: add suspend and resume support
    From: Théo Lebrun <theo.lebrun@bootlin.com>

    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 <theo.lebrun@bootlin.com>
    Signed-off-by: Thomas Richard <thomas.richard@bootlin.com>
    ---
    drivers/pci/controller/cadence/pci-j721e.c | 79 ++++++++++++++++++++++++++++++
    1 file changed, 79 insertions(+)

    diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
    index 477275d72257..668d98422c4d 100644
    --- a/drivers/pci/controller/cadence/pci-j721e.c
    +++ b/drivers/pci/controller/cadence/pci-j721e.c
    @@ -6,6 +6,7 @@
    * Author: Kishon Vijay Abraham I <kishon@ti.com>
    */

    +#include <linux/clk-provider.h>
    #include <linux/clk.h>
    #include <linux/delay.h>
    #include <linux/gpio/consumer.h>
    @@ -18,10 +19,13 @@
    #include <linux/platform_device.h>
    #include <linux/pm_runtime.h>
    #include <linux/regmap.h>
    +#include <linux/container_of.h>

    #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
    @@ -554,6 +558,80 @@ 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) {
    + dev_err(dev, "j721e_pcie_ctrl_init failed\n");
    + 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) {
    + dev_err(dev, "cdns_pcie_enable_phy failed\n");
    + return -ENODEV;
    + }
    +
    + 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) {
    + dev_err(dev, "clk_prepare_enable failed\n");
    + return -ENODEV;
    + }
    +
    + /*
    + * "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.
    + */
    + if (pcie->reset_gpio) {
    + usleep_range(100, 200);
    + gpiod_set_value_cansleep(pcie->reset_gpio, 1);
    + }
    +
    + ret = cdns_pcie_host_setup(rc, false);
    + if (ret < 0) {
    + 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,
    @@ -561,6 +639,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


    \
     
     \ /
      Last update: 2024-05-27 14:35    [W:5.772 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site