Skip to content

Commit e4d6613

Browse files
Richard ZhuMani-Sadhasivam
authored andcommitted
PCI: imx6: Save and restore the LUT setting during suspend/resume for i.MX95 SoC
The look up table (LUT) setting would be lost during the PCIe suspend on i.MX95 SoC. So to ensure proper functionality after resume, save it during suspend and restore it while resuming. Fixes: 9d6b1bd ("PCI: imx6: Add i.MX8MQ, i.MX8Q and i.MX95 PM support") Signed-off-by: Richard Zhu <[email protected]> [mani: subject and description rewording] Signed-off-by: Manivannan Sadhasivam <[email protected]> Reviewed-by: Frank Li <[email protected]> Reviewed-by: Manivannan Sadhasivam <[email protected]> Link: https://patch.msgid.link/[email protected]
1 parent 047e8b6 commit e4d6613

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed

drivers/pci/controller/dwc/pci-imx6.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,11 @@ struct imx_pcie_drvdata {
139139
const struct dw_pcie_host_ops *ops;
140140
};
141141

142+
struct imx_lut_data {
143+
u32 data1;
144+
u32 data2;
145+
};
146+
142147
struct imx_pcie {
143148
struct dw_pcie *pci;
144149
struct gpio_desc *reset_gpiod;
@@ -158,6 +163,8 @@ struct imx_pcie {
158163
struct regulator *vph;
159164
void __iomem *phy_base;
160165

166+
/* LUT data for pcie */
167+
struct imx_lut_data luts[IMX95_MAX_LUT];
161168
/* power domain for pcie */
162169
struct device *pd_pcie;
163170
/* power domain for pcie phy */
@@ -1484,6 +1491,42 @@ static void imx_pcie_msi_save_restore(struct imx_pcie *imx_pcie, bool save)
14841491
}
14851492
}
14861493

1494+
static void imx_pcie_lut_save(struct imx_pcie *imx_pcie)
1495+
{
1496+
u32 data1, data2;
1497+
int i;
1498+
1499+
for (i = 0; i < IMX95_MAX_LUT; i++) {
1500+
regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL,
1501+
IMX95_PEO_LUT_RWA | i);
1502+
regmap_read(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1, &data1);
1503+
regmap_read(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, &data2);
1504+
if (data1 & IMX95_PE0_LUT_VLD) {
1505+
imx_pcie->luts[i].data1 = data1;
1506+
imx_pcie->luts[i].data2 = data2;
1507+
} else {
1508+
imx_pcie->luts[i].data1 = 0;
1509+
imx_pcie->luts[i].data2 = 0;
1510+
}
1511+
}
1512+
}
1513+
1514+
static void imx_pcie_lut_restore(struct imx_pcie *imx_pcie)
1515+
{
1516+
int i;
1517+
1518+
for (i = 0; i < IMX95_MAX_LUT; i++) {
1519+
if ((imx_pcie->luts[i].data1 & IMX95_PE0_LUT_VLD) == 0)
1520+
continue;
1521+
1522+
regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1,
1523+
imx_pcie->luts[i].data1);
1524+
regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2,
1525+
imx_pcie->luts[i].data2);
1526+
regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, i);
1527+
}
1528+
}
1529+
14871530
static int imx_pcie_suspend_noirq(struct device *dev)
14881531
{
14891532
struct imx_pcie *imx_pcie = dev_get_drvdata(dev);
@@ -1492,6 +1535,8 @@ static int imx_pcie_suspend_noirq(struct device *dev)
14921535
return 0;
14931536

14941537
imx_pcie_msi_save_restore(imx_pcie, true);
1538+
if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_LUT))
1539+
imx_pcie_lut_save(imx_pcie);
14951540
if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_BROKEN_SUSPEND)) {
14961541
/*
14971542
* The minimum for a workaround would be to set PERST# and to
@@ -1536,6 +1581,8 @@ static int imx_pcie_resume_noirq(struct device *dev)
15361581
if (ret)
15371582
return ret;
15381583
}
1584+
if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_LUT))
1585+
imx_pcie_lut_restore(imx_pcie);
15391586
imx_pcie_msi_save_restore(imx_pcie, false);
15401587

15411588
return 0;

0 commit comments

Comments
 (0)