aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/controller/dwc/pci-imx6.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/controller/dwc/pci-imx6.c')
-rw-r--r--drivers/pci/controller/dwc/pci-imx6.c102
1 files changed, 97 insertions, 5 deletions
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 88af6bff945f..52e47dac028f 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -27,6 +27,8 @@
27#include <linux/types.h> 27#include <linux/types.h>
28#include <linux/interrupt.h> 28#include <linux/interrupt.h>
29#include <linux/reset.h> 29#include <linux/reset.h>
30#include <linux/pm_domain.h>
31#include <linux/pm_runtime.h>
30 32
31#include "pcie-designware.h" 33#include "pcie-designware.h"
32 34
@@ -59,6 +61,11 @@ struct imx6_pcie {
59 u32 tx_swing_low; 61 u32 tx_swing_low;
60 int link_gen; 62 int link_gen;
61 struct regulator *vpcie; 63 struct regulator *vpcie;
64
65 /* power domain for pcie */
66 struct device *pd_pcie;
67 /* power domain for pcie phy */
68 struct device *pd_pcie_phy;
62}; 69};
63 70
64/* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */ 71/* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */
@@ -67,6 +74,7 @@ struct imx6_pcie {
67#define PHY_PLL_LOCK_WAIT_USLEEP_MAX 200 74#define PHY_PLL_LOCK_WAIT_USLEEP_MAX 200
68 75
69/* PCIe Root Complex registers (memory-mapped) */ 76/* PCIe Root Complex registers (memory-mapped) */
77#define PCIE_RC_IMX6_MSI_CAP 0x50
70#define PCIE_RC_LCR 0x7c 78#define PCIE_RC_LCR 0x7c
71#define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1 0x1 79#define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1 0x1
72#define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2 0x2 80#define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2 0x2
@@ -290,6 +298,43 @@ static int imx6q_pcie_abort_handler(unsigned long addr,
290 return 1; 298 return 1;
291} 299}
292 300
301static int imx6_pcie_attach_pd(struct device *dev)
302{
303 struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
304 struct device_link *link;
305
306 /* Do nothing when in a single power domain */
307 if (dev->pm_domain)
308 return 0;
309
310 imx6_pcie->pd_pcie = dev_pm_domain_attach_by_name(dev, "pcie");
311 if (IS_ERR(imx6_pcie->pd_pcie))
312 return PTR_ERR(imx6_pcie->pd_pcie);
313 link = device_link_add(dev, imx6_pcie->pd_pcie,
314 DL_FLAG_STATELESS |
315 DL_FLAG_PM_RUNTIME |
316 DL_FLAG_RPM_ACTIVE);
317 if (!link) {
318 dev_err(dev, "Failed to add device_link to pcie pd.\n");
319 return -EINVAL;
320 }
321
322 imx6_pcie->pd_pcie_phy = dev_pm_domain_attach_by_name(dev, "pcie_phy");
323 if (IS_ERR(imx6_pcie->pd_pcie_phy))
324 return PTR_ERR(imx6_pcie->pd_pcie_phy);
325
326 device_link_add(dev, imx6_pcie->pd_pcie_phy,
327 DL_FLAG_STATELESS |
328 DL_FLAG_PM_RUNTIME |
329 DL_FLAG_RPM_ACTIVE);
330 if (IS_ERR(link)) {
331 dev_err(dev, "Failed to add device_link to pcie_phy pd: %ld\n", PTR_ERR(link));
332 return PTR_ERR(link);
333 }
334
335 return 0;
336}
337
293static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie) 338static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
294{ 339{
295 struct device *dev = imx6_pcie->pci->dev; 340 struct device *dev = imx6_pcie->pci->dev;
@@ -765,8 +810,28 @@ static void imx6_pcie_ltssm_disable(struct device *dev)
765 810
766static void imx6_pcie_pm_turnoff(struct imx6_pcie *imx6_pcie) 811static void imx6_pcie_pm_turnoff(struct imx6_pcie *imx6_pcie)
767{ 812{
768 reset_control_assert(imx6_pcie->turnoff_reset); 813 struct device *dev = imx6_pcie->pci->dev;
769 reset_control_deassert(imx6_pcie->turnoff_reset); 814
815 /* Some variants have a turnoff reset in DT */
816 if (imx6_pcie->turnoff_reset) {
817 reset_control_assert(imx6_pcie->turnoff_reset);
818 reset_control_deassert(imx6_pcie->turnoff_reset);
819 goto pm_turnoff_sleep;
820 }
821
822 /* Others poke directly at IOMUXC registers */
823 switch (imx6_pcie->variant) {
824 case IMX6SX:
825 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
826 IMX6SX_GPR12_PCIE_PM_TURN_OFF,
827 IMX6SX_GPR12_PCIE_PM_TURN_OFF);
828 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
829 IMX6SX_GPR12_PCIE_PM_TURN_OFF, 0);
830 break;
831 default:
832 dev_err(dev, "PME_Turn_Off not implemented\n");
833 return;
834 }
770 835
771 /* 836 /*
772 * Components with an upstream port must respond to 837 * Components with an upstream port must respond to
@@ -775,6 +840,7 @@ static void imx6_pcie_pm_turnoff(struct imx6_pcie *imx6_pcie)
775 * The standard recommends a 1-10ms timeout after which to 840 * The standard recommends a 1-10ms timeout after which to
776 * proceed anyway as if acks were received. 841 * proceed anyway as if acks were received.
777 */ 842 */
843pm_turnoff_sleep:
778 usleep_range(1000, 10000); 844 usleep_range(1000, 10000);
779} 845}
780 846
@@ -784,18 +850,31 @@ static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie)
784 clk_disable_unprepare(imx6_pcie->pcie_phy); 850 clk_disable_unprepare(imx6_pcie->pcie_phy);
785 clk_disable_unprepare(imx6_pcie->pcie_bus); 851 clk_disable_unprepare(imx6_pcie->pcie_bus);
786 852
787 if (imx6_pcie->variant == IMX7D) { 853 switch (imx6_pcie->variant) {
854 case IMX6SX:
855 clk_disable_unprepare(imx6_pcie->pcie_inbound_axi);
856 break;
857 case IMX7D:
788 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, 858 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
789 IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, 859 IMX7D_GPR12_PCIE_PHY_REFCLK_SEL,
790 IMX7D_GPR12_PCIE_PHY_REFCLK_SEL); 860 IMX7D_GPR12_PCIE_PHY_REFCLK_SEL);
861 break;
862 default:
863 break;
791 } 864 }
792} 865}
793 866
867static inline bool imx6_pcie_supports_suspend(struct imx6_pcie *imx6_pcie)
868{
869 return (imx6_pcie->variant == IMX7D ||
870 imx6_pcie->variant == IMX6SX);
871}
872
794static int imx6_pcie_suspend_noirq(struct device *dev) 873static int imx6_pcie_suspend_noirq(struct device *dev)
795{ 874{
796 struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); 875 struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
797 876
798 if (imx6_pcie->variant != IMX7D) 877 if (!imx6_pcie_supports_suspend(imx6_pcie))
799 return 0; 878 return 0;
800 879
801 imx6_pcie_pm_turnoff(imx6_pcie); 880 imx6_pcie_pm_turnoff(imx6_pcie);
@@ -811,7 +890,7 @@ static int imx6_pcie_resume_noirq(struct device *dev)
811 struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); 890 struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
812 struct pcie_port *pp = &imx6_pcie->pci->pp; 891 struct pcie_port *pp = &imx6_pcie->pci->pp;
813 892
814 if (imx6_pcie->variant != IMX7D) 893 if (!imx6_pcie_supports_suspend(imx6_pcie))
815 return 0; 894 return 0;
816 895
817 imx6_pcie_assert_core_reset(imx6_pcie); 896 imx6_pcie_assert_core_reset(imx6_pcie);
@@ -840,6 +919,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
840 struct resource *dbi_base; 919 struct resource *dbi_base;
841 struct device_node *node = dev->of_node; 920 struct device_node *node = dev->of_node;
842 int ret; 921 int ret;
922 u16 val;
843 923
844 imx6_pcie = devm_kzalloc(dev, sizeof(*imx6_pcie), GFP_KERNEL); 924 imx6_pcie = devm_kzalloc(dev, sizeof(*imx6_pcie), GFP_KERNEL);
845 if (!imx6_pcie) 925 if (!imx6_pcie)
@@ -977,10 +1057,22 @@ static int imx6_pcie_probe(struct platform_device *pdev)
977 1057
978 platform_set_drvdata(pdev, imx6_pcie); 1058 platform_set_drvdata(pdev, imx6_pcie);
979 1059
1060 ret = imx6_pcie_attach_pd(dev);
1061 if (ret)
1062 return ret;
1063
980 ret = imx6_add_pcie_port(imx6_pcie, pdev); 1064 ret = imx6_add_pcie_port(imx6_pcie, pdev);
981 if (ret < 0) 1065 if (ret < 0)
982 return ret; 1066 return ret;
983 1067
1068 if (pci_msi_enabled()) {
1069 val = dw_pcie_readw_dbi(pci, PCIE_RC_IMX6_MSI_CAP +
1070 PCI_MSI_FLAGS);
1071 val |= PCI_MSI_FLAGS_ENABLE;
1072 dw_pcie_writew_dbi(pci, PCIE_RC_IMX6_MSI_CAP + PCI_MSI_FLAGS,
1073 val);
1074 }
1075
984 return 0; 1076 return 0;
985} 1077}
986 1078