4545#define PCIE_PE_RSTB BIT(3)
4646
4747#define PCIE_LTSSM_STATUS_REG 0x150
48+ #define PCIE_LTSSM_STATE_MASK GENMASK(28, 24)
49+ #define PCIE_LTSSM_STATE (val ) ((val & PCIE_LTSSM_STATE_MASK) >> 24)
50+ #define PCIE_LTSSM_STATE_L2_IDLE 0x14
4851
4952#define PCIE_LINK_STATUS_REG 0x154
5053#define PCIE_PORT_LINKUP BIT(8)
7376#define PCIE_MSI_SET_ADDR_HI_BASE 0xc80
7477#define PCIE_MSI_SET_ADDR_HI_OFFSET 0x04
7578
79+ #define PCIE_ICMD_PM_REG 0x198
80+ #define PCIE_TURN_OFF_LINK BIT(4)
81+
7682#define PCIE_TRANS_TABLE_BASE_REG 0x800
7783#define PCIE_ATR_SRC_ADDR_MSB_OFFSET 0x4
7884#define PCIE_ATR_TRSL_ADDR_LSB_OFFSET 0x8
95101 * struct mtk_msi_set - MSI information for each set
96102 * @base: IO mapped register base
97103 * @msg_addr: MSI message address
104+ * @saved_irq_state: IRQ enable state saved at suspend time
98105 */
99106struct mtk_msi_set {
100107 void __iomem * base ;
101108 phys_addr_t msg_addr ;
109+ u32 saved_irq_state ;
102110};
103111
104112/**
@@ -112,6 +120,7 @@ struct mtk_msi_set {
112120 * @clks: PCIe clocks
113121 * @num_clks: PCIe clocks count for this port
114122 * @irq: PCIe controller interrupt number
123+ * @saved_irq_state: IRQ enable state saved at suspend time
115124 * @irq_lock: lock protecting IRQ register access
116125 * @intx_domain: legacy INTx IRQ domain
117126 * @msi_domain: MSI IRQ domain
@@ -131,6 +140,7 @@ struct mtk_pcie_port {
131140 int num_clks ;
132141
133142 int irq ;
143+ u32 saved_irq_state ;
134144 raw_spinlock_t irq_lock ;
135145 struct irq_domain * intx_domain ;
136146 struct irq_domain * msi_domain ;
@@ -896,6 +906,108 @@ static int mtk_pcie_remove(struct platform_device *pdev)
896906 return 0 ;
897907}
898908
909+ static void __maybe_unused mtk_pcie_irq_save (struct mtk_pcie_port * port )
910+ {
911+ int i ;
912+
913+ raw_spin_lock (& port -> irq_lock );
914+
915+ port -> saved_irq_state = readl_relaxed (port -> base + PCIE_INT_ENABLE_REG );
916+
917+ for (i = 0 ; i < PCIE_MSI_SET_NUM ; i ++ ) {
918+ struct mtk_msi_set * msi_set = & port -> msi_sets [i ];
919+
920+ msi_set -> saved_irq_state = readl_relaxed (msi_set -> base +
921+ PCIE_MSI_SET_ENABLE_OFFSET );
922+ }
923+
924+ raw_spin_unlock (& port -> irq_lock );
925+ }
926+
927+ static void __maybe_unused mtk_pcie_irq_restore (struct mtk_pcie_port * port )
928+ {
929+ int i ;
930+
931+ raw_spin_lock (& port -> irq_lock );
932+
933+ writel_relaxed (port -> saved_irq_state , port -> base + PCIE_INT_ENABLE_REG );
934+
935+ for (i = 0 ; i < PCIE_MSI_SET_NUM ; i ++ ) {
936+ struct mtk_msi_set * msi_set = & port -> msi_sets [i ];
937+
938+ writel_relaxed (msi_set -> saved_irq_state ,
939+ msi_set -> base + PCIE_MSI_SET_ENABLE_OFFSET );
940+ }
941+
942+ raw_spin_unlock (& port -> irq_lock );
943+ }
944+
945+ static int __maybe_unused mtk_pcie_turn_off_link (struct mtk_pcie_port * port )
946+ {
947+ u32 val ;
948+
949+ val = readl_relaxed (port -> base + PCIE_ICMD_PM_REG );
950+ val |= PCIE_TURN_OFF_LINK ;
951+ writel_relaxed (val , port -> base + PCIE_ICMD_PM_REG );
952+
953+ /* Check the link is L2 */
954+ return readl_poll_timeout (port -> base + PCIE_LTSSM_STATUS_REG , val ,
955+ (PCIE_LTSSM_STATE (val ) ==
956+ PCIE_LTSSM_STATE_L2_IDLE ), 20 ,
957+ 50 * USEC_PER_MSEC );
958+ }
959+
960+ static int __maybe_unused mtk_pcie_suspend_noirq (struct device * dev )
961+ {
962+ struct mtk_pcie_port * port = dev_get_drvdata (dev );
963+ int err ;
964+ u32 val ;
965+
966+ /* Trigger link to L2 state */
967+ err = mtk_pcie_turn_off_link (port );
968+ if (err ) {
969+ dev_err (port -> dev , "cannot enter L2 state\n" );
970+ return err ;
971+ }
972+
973+ /* Pull down the PERST# pin */
974+ val = readl_relaxed (port -> base + PCIE_RST_CTRL_REG );
975+ val |= PCIE_PE_RSTB ;
976+ writel_relaxed (val , port -> base + PCIE_RST_CTRL_REG );
977+
978+ dev_dbg (port -> dev , "entered L2 states successfully" );
979+
980+ mtk_pcie_irq_save (port );
981+ mtk_pcie_power_down (port );
982+
983+ return 0 ;
984+ }
985+
986+ static int __maybe_unused mtk_pcie_resume_noirq (struct device * dev )
987+ {
988+ struct mtk_pcie_port * port = dev_get_drvdata (dev );
989+ int err ;
990+
991+ err = mtk_pcie_power_up (port );
992+ if (err )
993+ return err ;
994+
995+ err = mtk_pcie_startup_port (port );
996+ if (err ) {
997+ mtk_pcie_power_down (port );
998+ return err ;
999+ }
1000+
1001+ mtk_pcie_irq_restore (port );
1002+
1003+ return 0 ;
1004+ }
1005+
1006+ static const struct dev_pm_ops mtk_pcie_pm_ops = {
1007+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS (mtk_pcie_suspend_noirq ,
1008+ mtk_pcie_resume_noirq )
1009+ };
1010+
8991011static const struct of_device_id mtk_pcie_of_match [] = {
9001012 { .compatible = "mediatek,mt8192-pcie" },
9011013 {},
@@ -907,6 +1019,7 @@ static struct platform_driver mtk_pcie_driver = {
9071019 .driver = {
9081020 .name = "mtk-pcie" ,
9091021 .of_match_table = mtk_pcie_of_match ,
1022+ .pm = & mtk_pcie_pm_ops ,
9101023 },
9111024};
9121025
0 commit comments