mirror of
https://github.com/torvalds/linux.git
synced 2026-05-25 07:33:19 +02:00
Merge branch 'pci/controller/imx6'
- Fix suspend/resume support on i.MX6QDL, which has a hardware erratum that prevents use of L2 (Stefan Eichenberger) * pci/controller/imx6: PCI: imx6: Fix suspend/resume support on i.MX6QDL
This commit is contained in:
commit
7b86e0a589
|
|
@ -82,6 +82,11 @@ enum imx_pcie_variants {
|
|||
#define IMX_PCIE_FLAG_HAS_SERDES BIT(6)
|
||||
#define IMX_PCIE_FLAG_SUPPORT_64BIT BIT(7)
|
||||
#define IMX_PCIE_FLAG_CPU_ADDR_FIXUP BIT(8)
|
||||
/*
|
||||
* Because of ERR005723 (PCIe does not support L2 power down) we need to
|
||||
* workaround suspend resume on some devices which are affected by this errata.
|
||||
*/
|
||||
#define IMX_PCIE_FLAG_BROKEN_SUSPEND BIT(9)
|
||||
|
||||
#define imx_check_flag(pci, val) (pci->drvdata->flags & val)
|
||||
|
||||
|
|
@ -1237,9 +1242,19 @@ static int imx_pcie_suspend_noirq(struct device *dev)
|
|||
return 0;
|
||||
|
||||
imx_pcie_msi_save_restore(imx_pcie, true);
|
||||
imx_pcie_pm_turnoff(imx_pcie);
|
||||
imx_pcie_stop_link(imx_pcie->pci);
|
||||
imx_pcie_host_exit(pp);
|
||||
if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_BROKEN_SUSPEND)) {
|
||||
/*
|
||||
* The minimum for a workaround would be to set PERST# and to
|
||||
* set the PCIE_TEST_PD flag. However, we can also disable the
|
||||
* clock which saves some power.
|
||||
*/
|
||||
imx_pcie_assert_core_reset(imx_pcie);
|
||||
imx_pcie->drvdata->enable_ref_clk(imx_pcie, false);
|
||||
} else {
|
||||
imx_pcie_pm_turnoff(imx_pcie);
|
||||
imx_pcie_stop_link(imx_pcie->pci);
|
||||
imx_pcie_host_exit(pp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1253,14 +1268,32 @@ static int imx_pcie_resume_noirq(struct device *dev)
|
|||
if (!(imx_pcie->drvdata->flags & IMX_PCIE_FLAG_SUPPORTS_SUSPEND))
|
||||
return 0;
|
||||
|
||||
ret = imx_pcie_host_init(pp);
|
||||
if (ret)
|
||||
return ret;
|
||||
imx_pcie_msi_save_restore(imx_pcie, false);
|
||||
dw_pcie_setup_rc(pp);
|
||||
if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_BROKEN_SUSPEND)) {
|
||||
ret = imx_pcie->drvdata->enable_ref_clk(imx_pcie, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = imx_pcie_deassert_core_reset(imx_pcie);
|
||||
if (ret)
|
||||
return ret;
|
||||
/*
|
||||
* Using PCIE_TEST_PD seems to disable MSI and powers down the
|
||||
* root complex. This is why we have to setup the rc again and
|
||||
* why we have to restore the MSI register.
|
||||
*/
|
||||
ret = dw_pcie_setup_rc(&imx_pcie->pci->pp);
|
||||
if (ret)
|
||||
return ret;
|
||||
imx_pcie_msi_save_restore(imx_pcie, false);
|
||||
} else {
|
||||
ret = imx_pcie_host_init(pp);
|
||||
if (ret)
|
||||
return ret;
|
||||
imx_pcie_msi_save_restore(imx_pcie, false);
|
||||
dw_pcie_setup_rc(pp);
|
||||
|
||||
if (imx_pcie->link_is_up)
|
||||
imx_pcie_start_link(imx_pcie->pci);
|
||||
if (imx_pcie->link_is_up)
|
||||
imx_pcie_start_link(imx_pcie->pci);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1485,7 +1518,9 @@ static const struct imx_pcie_drvdata drvdata[] = {
|
|||
[IMX6Q] = {
|
||||
.variant = IMX6Q,
|
||||
.flags = IMX_PCIE_FLAG_IMX_PHY |
|
||||
IMX_PCIE_FLAG_IMX_SPEED_CHANGE,
|
||||
IMX_PCIE_FLAG_IMX_SPEED_CHANGE |
|
||||
IMX_PCIE_FLAG_BROKEN_SUSPEND |
|
||||
IMX_PCIE_FLAG_SUPPORTS_SUSPEND,
|
||||
.dbi_length = 0x200,
|
||||
.gpr = "fsl,imx6q-iomuxc-gpr",
|
||||
.clk_names = imx6q_clks,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user