aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHonghui Zhang <honghui.zhang@mediatek.com>2018-10-15 04:08:58 -0400
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2018-10-17 10:37:05 -0400
commit97d2932fee4b0607bad4f71a8d2c0938f596b1c3 (patch)
tree4e09f994f88cc09447a21c9ea1aad2315c2a480f
parent3828d60fd2ef99f97a677c1f95af2ab3e65e2576 (diff)
PCI: mediatek: Add system PM support for MT2712 and MT7622
In order to reduce the PCIe power consumption in system suspend, the PCI bus physical layer should be gated. On system resume, the PCIe link should be re-established and the related control register values should be restored. Define suspend_noirq & resume_noirq callback functions to implement PM system syspend hooks for the PCI host controller. Signed-off-by: Honghui Zhang <honghui.zhang@mediatek.com> [lorenzo.pieralisi@arm.com: updated commit log] Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Acked-by: Ryder Lee <ryder.lee@mediatek.com>
-rw-r--r--drivers/pci/controller/pcie-mediatek.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
index aa900b0f0a40..5f042316c3a8 100644
--- a/drivers/pci/controller/pcie-mediatek.c
+++ b/drivers/pci/controller/pcie-mediatek.c
@@ -1168,6 +1168,55 @@ put_resources:
1168 return err; 1168 return err;
1169} 1169}
1170 1170
1171static int __maybe_unused mtk_pcie_suspend_noirq(struct device *dev)
1172{
1173 struct mtk_pcie *pcie = dev_get_drvdata(dev);
1174 struct mtk_pcie_port *port;
1175
1176 if (list_empty(&pcie->ports))
1177 return 0;
1178
1179 list_for_each_entry(port, &pcie->ports, list) {
1180 clk_disable_unprepare(port->pipe_ck);
1181 clk_disable_unprepare(port->obff_ck);
1182 clk_disable_unprepare(port->axi_ck);
1183 clk_disable_unprepare(port->aux_ck);
1184 clk_disable_unprepare(port->ahb_ck);
1185 clk_disable_unprepare(port->sys_ck);
1186 phy_power_off(port->phy);
1187 phy_exit(port->phy);
1188 }
1189
1190 clk_disable_unprepare(pcie->free_ck);
1191
1192 return 0;
1193}
1194
1195static int __maybe_unused mtk_pcie_resume_noirq(struct device *dev)
1196{
1197 struct mtk_pcie *pcie = dev_get_drvdata(dev);
1198 struct mtk_pcie_port *port, *tmp;
1199
1200 if (list_empty(&pcie->ports))
1201 return 0;
1202
1203 clk_prepare_enable(pcie->free_ck);
1204
1205 list_for_each_entry_safe(port, tmp, &pcie->ports, list)
1206 mtk_pcie_enable_port(port);
1207
1208 /* In case of EP was removed while system suspend. */
1209 if (list_empty(&pcie->ports))
1210 clk_disable_unprepare(pcie->free_ck);
1211
1212 return 0;
1213}
1214
1215static const struct dev_pm_ops mtk_pcie_pm_ops = {
1216 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mtk_pcie_suspend_noirq,
1217 mtk_pcie_resume_noirq)
1218};
1219
1171static const struct mtk_pcie_soc mtk_pcie_soc_v1 = { 1220static const struct mtk_pcie_soc mtk_pcie_soc_v1 = {
1172 .ops = &mtk_pcie_ops, 1221 .ops = &mtk_pcie_ops,
1173 .startup = mtk_pcie_startup_port, 1222 .startup = mtk_pcie_startup_port,
@@ -1200,6 +1249,7 @@ static struct platform_driver mtk_pcie_driver = {
1200 .name = "mtk-pcie", 1249 .name = "mtk-pcie",
1201 .of_match_table = mtk_pcie_ids, 1250 .of_match_table = mtk_pcie_ids,
1202 .suppress_bind_attrs = true, 1251 .suppress_bind_attrs = true,
1252 .pm = &mtk_pcie_pm_ops,
1203 }, 1253 },
1204}; 1254};
1205builtin_platform_driver(mtk_pcie_driver); 1255builtin_platform_driver(mtk_pcie_driver);