@@ -82,6 +82,11 @@ enum imx_pcie_variants {
8282#define IMX_PCIE_FLAG_HAS_SERDES BIT(6)
8383#define IMX_PCIE_FLAG_SUPPORT_64BIT BIT(7)
8484#define IMX_PCIE_FLAG_CPU_ADDR_FIXUP BIT(8)
85+ /*
86+ * Because of ERR005723 (PCIe does not support L2 power down) we need to
87+ * workaround suspend resume on some devices which are affected by this errata.
88+ */
89+ #define IMX_PCIE_FLAG_BROKEN_SUSPEND BIT(9)
8590
8691#define imx_check_flag (pci , val ) (pci->drvdata->flags & val)
8792
@@ -1237,9 +1242,19 @@ static int imx_pcie_suspend_noirq(struct device *dev)
12371242 return 0 ;
12381243
12391244 imx_pcie_msi_save_restore (imx_pcie , true);
1240- imx_pcie_pm_turnoff (imx_pcie );
1241- imx_pcie_stop_link (imx_pcie -> pci );
1242- imx_pcie_host_exit (pp );
1245+ if (imx_check_flag (imx_pcie , IMX_PCIE_FLAG_BROKEN_SUSPEND )) {
1246+ /*
1247+ * The minimum for a workaround would be to set PERST# and to
1248+ * set the PCIE_TEST_PD flag. However, we can also disable the
1249+ * clock which saves some power.
1250+ */
1251+ imx_pcie_assert_core_reset (imx_pcie );
1252+ imx_pcie -> drvdata -> enable_ref_clk (imx_pcie , false);
1253+ } else {
1254+ imx_pcie_pm_turnoff (imx_pcie );
1255+ imx_pcie_stop_link (imx_pcie -> pci );
1256+ imx_pcie_host_exit (pp );
1257+ }
12431258
12441259 return 0 ;
12451260}
@@ -1253,14 +1268,32 @@ static int imx_pcie_resume_noirq(struct device *dev)
12531268 if (!(imx_pcie -> drvdata -> flags & IMX_PCIE_FLAG_SUPPORTS_SUSPEND ))
12541269 return 0 ;
12551270
1256- ret = imx_pcie_host_init (pp );
1257- if (ret )
1258- return ret ;
1259- imx_pcie_msi_save_restore (imx_pcie , false);
1260- dw_pcie_setup_rc (pp );
1271+ if (imx_check_flag (imx_pcie , IMX_PCIE_FLAG_BROKEN_SUSPEND )) {
1272+ ret = imx_pcie -> drvdata -> enable_ref_clk (imx_pcie , true);
1273+ if (ret )
1274+ return ret ;
1275+ ret = imx_pcie_deassert_core_reset (imx_pcie );
1276+ if (ret )
1277+ return ret ;
1278+ /*
1279+ * Using PCIE_TEST_PD seems to disable MSI and powers down the
1280+ * root complex. This is why we have to setup the rc again and
1281+ * why we have to restore the MSI register.
1282+ */
1283+ ret = dw_pcie_setup_rc (& imx_pcie -> pci -> pp );
1284+ if (ret )
1285+ return ret ;
1286+ imx_pcie_msi_save_restore (imx_pcie , false);
1287+ } else {
1288+ ret = imx_pcie_host_init (pp );
1289+ if (ret )
1290+ return ret ;
1291+ imx_pcie_msi_save_restore (imx_pcie , false);
1292+ dw_pcie_setup_rc (pp );
12611293
1262- if (imx_pcie -> link_is_up )
1263- imx_pcie_start_link (imx_pcie -> pci );
1294+ if (imx_pcie -> link_is_up )
1295+ imx_pcie_start_link (imx_pcie -> pci );
1296+ }
12641297
12651298 return 0 ;
12661299}
@@ -1485,7 +1518,9 @@ static const struct imx_pcie_drvdata drvdata[] = {
14851518 [IMX6Q ] = {
14861519 .variant = IMX6Q ,
14871520 .flags = IMX_PCIE_FLAG_IMX_PHY |
1488- IMX_PCIE_FLAG_IMX_SPEED_CHANGE ,
1521+ IMX_PCIE_FLAG_IMX_SPEED_CHANGE |
1522+ IMX_PCIE_FLAG_BROKEN_SUSPEND |
1523+ IMX_PCIE_FLAG_SUPPORTS_SUSPEND ,
14891524 .dbi_length = 0x200 ,
14901525 .gpr = "fsl,imx6q-iomuxc-gpr" ,
14911526 .clk_names = imx6q_clks ,
0 commit comments