mirror of
https://github.com/torvalds/linux.git
synced 2026-05-24 15:12:13 +02:00
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.com Signed-off-by: Frank Li <Frank.Li@nxp.com> Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Acked-by: Roy Zang <Roy.Zang@nxp.com>
This commit is contained in:
parent
762ef94b45
commit
27b3bcbf8a
|
|
@ -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 },
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user