Commit 27b3bcbf authored by Frank Li's avatar Frank Li Committed by Lorenzo Pieralisi

PCI: layerscape: Add suspend/resume for ls1043a

Add suspend/resume support for Layerscape LS1043a.

In the suspend path, PME_Turn_Off message is sent to the endpoint to
transition the link to L2/L3_Ready state. In this SoC, there is no way to
check if the controller has received the PME_To_Ack from the endpoint or
not. So to be on the safer side, the driver just waits for
PCIE_PME_TO_L2_TIMEOUT_US before asserting the SoC specific PMXMTTURNOFF
bit to complete the PME_Turn_Off handshake. Then the link would enter L2/L3
state depending on the VAUX supply.

In the resume path, the link is brought back from L2 to L0 by doing a
software reset.

Link: https://lore.kernel.org/r/20231204160829.2498703-5-Frank.Li@nxp.comSigned-off-by: default avatarFrank Li <Frank.Li@nxp.com>
Signed-off-by: default avatarLorenzo Pieralisi <lpieralisi@kernel.org>
Reviewed-by: default avatarManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Acked-by: default avatarRoy Zang <Roy.Zang@nxp.com>
parent 762ef94b
......@@ -41,6 +41,15 @@
#define SCFG_PEXSFTRSTCR 0x190
#define PEXSR(idx) BIT(idx)
/* LS1043A PEX PME control register */
#define SCFG_PEXPMECR 0x144
#define PEXPME(idx) BIT(31 - (idx) * 4)
/* LS1043A PEX LUT debug register */
#define LS_PCIE_LDBG 0x7fc
#define LDBG_SR BIT(30)
#define LDBG_WE BIT(31)
#define PCIE_IATU_NUM 6
struct ls_pcie_drvdata {
......@@ -224,6 +233,45 @@ static int ls1021a_pcie_exit_from_l2(struct dw_pcie_rp *pp)
return scfg_pcie_exit_from_l2(pcie->scfg, SCFG_PEXSFTRSTCR, PEXSR(pcie->index));
}
static void ls1043a_pcie_send_turnoff_msg(struct dw_pcie_rp *pp)
{
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
struct ls_pcie *pcie = to_ls_pcie(pci);
scfg_pcie_send_turnoff_msg(pcie->scfg, SCFG_PEXPMECR, PEXPME(pcie->index));
}
static int ls1043a_pcie_exit_from_l2(struct dw_pcie_rp *pp)
{
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
struct ls_pcie *pcie = to_ls_pcie(pci);
u32 val;
/*
* Reset the PEX wrapper to bring the link out of L2.
* LDBG_WE: allows the user to have write access to the PEXDBG[SR] for both setting and
* clearing the soft reset on the PEX module.
* LDBG_SR: When SR is set to 1, the PEX module enters soft reset.
*/
val = ls_pcie_pf_lut_readl(pcie, LS_PCIE_LDBG);
val |= LDBG_WE;
ls_pcie_pf_lut_writel(pcie, LS_PCIE_LDBG, val);
val = ls_pcie_pf_lut_readl(pcie, LS_PCIE_LDBG);
val |= LDBG_SR;
ls_pcie_pf_lut_writel(pcie, LS_PCIE_LDBG, val);
val = ls_pcie_pf_lut_readl(pcie, LS_PCIE_LDBG);
val &= ~LDBG_SR;
ls_pcie_pf_lut_writel(pcie, LS_PCIE_LDBG, val);
val = ls_pcie_pf_lut_readl(pcie, LS_PCIE_LDBG);
val &= ~LDBG_WE;
ls_pcie_pf_lut_writel(pcie, LS_PCIE_LDBG, val);
return 0;
}
static const struct dw_pcie_host_ops ls_pcie_host_ops = {
.host_init = ls_pcie_host_init,
.pme_turn_off = ls_pcie_send_turnoff_msg,
......@@ -241,6 +289,19 @@ static const struct ls_pcie_drvdata ls1021a_drvdata = {
.exit_from_l2 = ls1021a_pcie_exit_from_l2,
};
static const struct dw_pcie_host_ops ls1043a_pcie_host_ops = {
.host_init = ls_pcie_host_init,
.pme_turn_off = ls1043a_pcie_send_turnoff_msg,
};
static const struct ls_pcie_drvdata ls1043a_drvdata = {
.pf_lut_off = 0x10000,
.pm_support = true,
.scfg_support = true,
.ops = &ls1043a_pcie_host_ops,
.exit_from_l2 = ls1043a_pcie_exit_from_l2,
};
static const struct ls_pcie_drvdata layerscape_drvdata = {
.pf_lut_off = 0xc0000,
.pm_support = true,
......@@ -252,7 +313,7 @@ static const struct of_device_id ls_pcie_of_match[] = {
{ .compatible = "fsl,ls1012a-pcie", .data = &layerscape_drvdata },
{ .compatible = "fsl,ls1021a-pcie", .data = &ls1021a_drvdata },
{ .compatible = "fsl,ls1028a-pcie", .data = &layerscape_drvdata },
{ .compatible = "fsl,ls1043a-pcie", .data = &ls1021a_drvdata },
{ .compatible = "fsl,ls1043a-pcie", .data = &ls1043a_drvdata },
{ .compatible = "fsl,ls1046a-pcie", .data = &layerscape_drvdata },
{ .compatible = "fsl,ls2080a-pcie", .data = &layerscape_drvdata },
{ .compatible = "fsl,ls2085a-pcie", .data = &layerscape_drvdata },
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment