aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Zhu <r65037@freescale.com>2014-05-21 02:13:13 -0400
committerRichard Zhu <r65037@freescale.com>2014-05-26 01:18:35 -0400
commit671cc6a3c1f7ce2da92bccdf00d3fa9d9fb1633b (patch)
tree0f385e67c3d7b18c9f5eacf1f635ee4d01f1356a
parentf64f01111d4fa3ec0a5fe6477be3a79ac1efef26 (diff)
ENGR00314570-2 pcie:add pcie power control on imx6sx
imx6sx pcie has standalone ldo domain, add the power control routines. - pcie pm recovery works when imx6sx pcie is used as rc. - pcie pm recovery works on both rc and ep modes. - l2 mode had been validated on imx6sx sdb(rc) and e1000e (ep) environment. - fastmix and megamix can be turn off and turn on, during system suspend/resume. - hw: - imx6sx sdb board. - intel e1000e nic - xhci pcie2usb device Signed-off-by: Richard Zhu <r65037@freescale.com>
-rw-r--r--drivers/pci/host/Kconfig4
-rw-r--r--drivers/pci/host/pci-imx6.c250
2 files changed, 200 insertions, 54 deletions
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 120714876e83..0512d1021a4f 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -20,6 +20,10 @@ config PCI_IMX6
20 select PCIEPORTBUS 20 select PCIEPORTBUS
21 select PCIE_DW 21 select PCIE_DW
22 22
23config PCI_IMX6SX_EXTREMELY_PWR_SAVE
24 bool "Freescale i.MX6SX PCIe controller extremely power save mode"
25 depends on PCI_IMX6
26
23config EP_MODE_IN_EP_RC_SYS 27config EP_MODE_IN_EP_RC_SYS
24 bool "PCI Express EP mode in the IMX6 RC/EP interconnection system" 28 bool "PCI Express EP mode in the IMX6 RC/EP interconnection system"
25 depends on PCI_IMX6 29 depends on PCI_IMX6
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
index f893c1998a9b..064d40f3ae11 100644
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -27,6 +27,7 @@
27#include <linux/regmap.h> 27#include <linux/regmap.h>
28#include <linux/resource.h> 28#include <linux/resource.h>
29#include <linux/signal.h> 29#include <linux/signal.h>
30#include <linux/syscore_ops.h>
30#include <linux/types.h> 31#include <linux/types.h>
31#include <linux/busfreq-imx6.h> 32#include <linux/busfreq-imx6.h>
32#include <linux/regulator/consumer.h> 33#include <linux/regulator/consumer.h>
@@ -71,6 +72,7 @@ struct imx6_pcie {
71 struct regulator *pcie_regulator; 72 struct regulator *pcie_regulator;
72 void __iomem *mem_base; 73 void __iomem *mem_base;
73}; 74};
75static struct imx6_pcie *imx6_pcie;
74 76
75/* PCIe Port Logic registers (memory-mapped) */ 77/* PCIe Port Logic registers (memory-mapped) */
76#define PL_OFFSET 0x700 78#define PL_OFFSET 0x700
@@ -288,12 +290,9 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp)
288 goto err_pcie_axi; 290 goto err_pcie_axi;
289 } 291 }
290 292
291 /* allow the clocks to stabilize */
292 usleep_range(200, 500);
293
294 if (gpio_is_valid(imx6_pcie->reset_gpio)) { 293 if (gpio_is_valid(imx6_pcie->reset_gpio)) {
295 gpio_set_value(imx6_pcie->reset_gpio, 0); 294 gpio_set_value(imx6_pcie->reset_gpio, 0);
296 msleep(100); 295 mdelay(1);
297 gpio_set_value(imx6_pcie->reset_gpio, 1); 296 gpio_set_value(imx6_pcie->reset_gpio, 1);
298 } 297 }
299 298
@@ -658,9 +657,198 @@ static const struct of_device_id imx6_pcie_of_match[] = {
658}; 657};
659MODULE_DEVICE_TABLE(of, imx6_pcie_of_match); 658MODULE_DEVICE_TABLE(of, imx6_pcie_of_match);
660 659
660static void imx6_pcie_setup_ep(struct pcie_port *pp)
661{
662 /* CMD reg:I/O space, MEM space, and Bus Master Enable */
663 writel(readl(pp->dbi_base + PCI_COMMAND)
664 | PCI_COMMAND_IO
665 | PCI_COMMAND_MEMORY
666 | PCI_COMMAND_MASTER,
667 pp->dbi_base + PCI_COMMAND);
668
669 /*
670 * configure the class_rev(emaluate one memory ram ep device),
671 * bar0 and bar1 of ep
672 */
673 writel(0xdeadbeaf, pp->dbi_base + PCI_VENDOR_ID);
674 writel(readl(pp->dbi_base + PCI_CLASS_REVISION)
675 | (PCI_CLASS_MEMORY_RAM << 16),
676 pp->dbi_base + PCI_CLASS_REVISION);
677 writel(0xdeadbeaf, pp->dbi_base
678 + PCI_SUBSYSTEM_VENDOR_ID);
679
680 /* 32bit none-prefetchable 8M bytes memory on bar0 */
681 writel(0x0, pp->dbi_base + PCI_BASE_ADDRESS_0);
682 writel(SZ_8M - 1, pp->dbi_base + (1 << 12)
683 + PCI_BASE_ADDRESS_0);
684
685 /* None used bar1 */
686 writel(0x0, pp->dbi_base + PCI_BASE_ADDRESS_1);
687 writel(0, pp->dbi_base + (1 << 12) + PCI_BASE_ADDRESS_1);
688
689 /* 4K bytes IO on bar2 */
690 writel(0x1, pp->dbi_base + PCI_BASE_ADDRESS_2);
691 writel(SZ_4K - 1, pp->dbi_base + (1 << 12) +
692 PCI_BASE_ADDRESS_2);
693
694 /*
695 * 32bit prefetchable 1M bytes memory on bar3
696 * FIXME BAR MASK3 is not changable, the size
697 * is fixed to 256 bytes.
698 */
699 writel(0x8, pp->dbi_base + PCI_BASE_ADDRESS_3);
700 writel(SZ_1M - 1, pp->dbi_base + (1 << 12)
701 + PCI_BASE_ADDRESS_3);
702
703 /*
704 * 64bit prefetchable 1M bytes memory on bar4-5.
705 * FIXME BAR4,5 are not enabled yet
706 */
707 writel(0xc, pp->dbi_base + PCI_BASE_ADDRESS_4);
708 writel(SZ_1M - 1, pp->dbi_base + (1 << 12)
709 + PCI_BASE_ADDRESS_4);
710 writel(0, pp->dbi_base + (1 << 12) + PCI_BASE_ADDRESS_5);
711}
712
713#ifdef CONFIG_PM_SLEEP
714static int pci_imx_suspend(void)
715{
716 int rc = 0;
717
718 if (is_imx6sx_pcie(imx6_pcie)) {
719 if (IS_ENABLED(CONFIG_PCI_IMX6SX_EXTREMELY_PWR_SAVE)) {
720 /* Disable clks and power down PCIe PHY */
721 clk_disable_unprepare(imx6_pcie->pcie_axi);
722 if (!IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS)
723 && !IS_ENABLED(CONFIG_RC_MODE_IN_EP_RC_SYS))
724 clk_disable_unprepare(imx6_pcie->lvds_gate);
725 clk_disable_unprepare(imx6_pcie->pcie_ref_125m);
726 clk_disable_unprepare(imx6_pcie->dis_axi);
727 release_bus_freq(BUS_FREQ_HIGH);
728
729 /* Put PCIe PHY to be isolation */
730 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR0,
731 BIT(6), 1 << 6);
732
733 /*
734 * Power down PCIe PHY.
735 */
736 regulator_disable(imx6_pcie->pcie_regulator);
737 } else {
738 /* PM_TURN_OFF */
739 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
740 BIT(16), 1 << 16);
741 udelay(10);
742 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
743 BIT(16), 0 << 16);
744 clk_disable_unprepare(imx6_pcie->pcie_axi);
745 if (!IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS)
746 && !IS_ENABLED(CONFIG_RC_MODE_IN_EP_RC_SYS))
747 clk_disable_unprepare(imx6_pcie->lvds_gate);
748 clk_disable_unprepare(imx6_pcie->pcie_ref_125m);
749 clk_disable_unprepare(imx6_pcie->dis_axi);
750 release_bus_freq(BUS_FREQ_HIGH);
751 }
752 }
753
754 return rc;
755}
756
757static void pci_imx_resume(void)
758{
759 struct pcie_port *pp = &imx6_pcie->pp;
760
761 if (is_imx6sx_pcie(imx6_pcie)) {
762 if (IS_ENABLED(CONFIG_PCI_IMX6SX_EXTREMELY_PWR_SAVE)) {
763 /* Power up PCIe PHY, and so on again */
764 imx6_pcie_init_phy(pp);
765 imx6_pcie_deassert_core_reset(pp);
766
767 /*
768 * iMX6SX PCIe has the stand-alone power domain.
769 * refer to the initialization for iMX6SX PCIe,
770 * release the PCIe PHY reset here,
771 * before LTSSM enable is set
772 * .
773 */
774 regmap_update_bits(imx6_pcie->iomuxc_gpr,
775 IOMUXC_GPR5, BIT(19), 0 << 19);
776
777 if (IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS)) {
778 imx6_pcie_setup_ep(pp);
779 } else {
780 /*
781 * CMD reg:I/O space, MEM space,
782 * and Bus Master
783 */
784 writel(readl(pp->dbi_base + PCI_COMMAND)
785 | PCI_COMMAND_IO
786 | PCI_COMMAND_MEMORY
787 | PCI_COMMAND_MASTER,
788 pp->dbi_base + PCI_COMMAND);
789 /*
790 * Set the CLASS_REV of RC CFG header to
791 * PCI_CLASS_BRIDGE_PCI
792 */
793 writel(readl(pp->dbi_base + PCI_CLASS_REVISION)
794 | (PCI_CLASS_BRIDGE_PCI << 16),
795 pp->dbi_base + PCI_CLASS_REVISION);
796 }
797
798 /* assert LTSSM enable */
799 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
800 IMX6Q_GPR12_PCIE_CTL_2, 1 << 10);
801 } else {
802 /* Wake up re-enable clks */
803 request_bus_freq(BUS_FREQ_HIGH);
804 clk_prepare_enable(imx6_pcie->dis_axi);
805 if (!IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS)
806 && !IS_ENABLED(CONFIG_RC_MODE_IN_EP_RC_SYS))
807 clk_prepare_enable(imx6_pcie->lvds_gate);
808 clk_prepare_enable(imx6_pcie->pcie_ref_125m);
809 clk_prepare_enable(imx6_pcie->pcie_axi);
810
811 /* reset iMX6SX PCIe */
812 regmap_update_bits(imx6_pcie->iomuxc_gpr,
813 IOMUXC_GPR5, BIT(18), 1 << 18);
814
815 regmap_update_bits(imx6_pcie->iomuxc_gpr,
816 IOMUXC_GPR5, BIT(18), 0 << 18);
817
818 /*
819 * controller maybe turn off, re-configure again
820 * Set the CLASS_REV of RC CFG header to
821 * PCI_CLASS_BRIDGE_PCI
822 */
823 writel(readl(pp->dbi_base + PCI_CLASS_REVISION)
824 | (PCI_CLASS_BRIDGE_PCI << 16),
825 pp->dbi_base + PCI_CLASS_REVISION);
826
827 dw_pcie_setup_rc(pp);
828
829 /* reset iMX6SX PCIe */
830 regmap_update_bits(imx6_pcie->iomuxc_gpr,
831 IOMUXC_GPR5, BIT(18), 1 << 18);
832
833 regmap_update_bits(imx6_pcie->iomuxc_gpr,
834 IOMUXC_GPR5, BIT(18), 0 << 18);
835
836 /* RESET EP */
837 gpio_set_value(imx6_pcie->reset_gpio, 0);
838 udelay(10);
839 gpio_set_value(imx6_pcie->reset_gpio, 1);
840 }
841 }
842}
843#endif
844
845static struct syscore_ops pci_imx_syscore_ops = {
846 .suspend = pci_imx_suspend,
847 .resume = pci_imx_resume,
848};
849
661static int __init imx6_pcie_probe(struct platform_device *pdev) 850static int __init imx6_pcie_probe(struct platform_device *pdev)
662{ 851{
663 struct imx6_pcie *imx6_pcie;
664 struct pcie_port *pp; 852 struct pcie_port *pp;
665 const struct of_device_id *of_id = 853 const struct of_device_id *of_id =
666 of_match_device(imx6_pcie_of_match, &pdev->dev); 854 of_match_device(imx6_pcie_of_match, &pdev->dev);
@@ -874,55 +1062,7 @@ static int __init imx6_pcie_probe(struct platform_device *pdev)
874 usleep_range(10, 20); 1062 usleep_range(10, 20);
875 } while ((readl(pp->dbi_base + PCIE_PHY_DEBUG_R1) & 0x10) == 0); 1063 } while ((readl(pp->dbi_base + PCIE_PHY_DEBUG_R1) & 0x10) == 0);
876 1064
877 /* CMD reg:I/O space, MEM space, and Bus Master Enable */ 1065 imx6_pcie_setup_ep(pp);
878 writel(readl(pp->dbi_base + PCI_COMMAND)
879 | PCI_COMMAND_IO
880 | PCI_COMMAND_MEMORY
881 | PCI_COMMAND_MASTER,
882 pp->dbi_base + PCI_COMMAND);
883
884 /*
885 * configure the class_rev(emaluate one memory ram ep device),
886 * bar0 and bar1 of ep
887 */
888 writel(0xdeadbeaf, pp->dbi_base + PCI_VENDOR_ID);
889 writel(readl(pp->dbi_base + PCI_CLASS_REVISION)
890 | (PCI_CLASS_MEMORY_RAM << 16),
891 pp->dbi_base + PCI_CLASS_REVISION);
892 writel(0xdeadbeaf, pp->dbi_base
893 + PCI_SUBSYSTEM_VENDOR_ID);
894
895 /* 32bit none-prefetchable 8M bytes memory on bar0 */
896 writel(0x0, pp->dbi_base + PCI_BASE_ADDRESS_0);
897 writel(SZ_8M - 1, pp->dbi_base + (1 << 12)
898 + PCI_BASE_ADDRESS_0);
899
900 /* None used bar1 */
901 writel(0x0, pp->dbi_base + PCI_BASE_ADDRESS_1);
902 writel(0, pp->dbi_base + (1 << 12) + PCI_BASE_ADDRESS_1);
903
904 /* 4K bytes IO on bar2 */
905 writel(0x1, pp->dbi_base + PCI_BASE_ADDRESS_2);
906 writel(SZ_4K - 1, pp->dbi_base + (1 << 12) +
907 PCI_BASE_ADDRESS_2);
908
909 /*
910 * 32bit prefetchable 1M bytes memory on bar3
911 * FIXME BAR MASK3 is not changable, the size
912 * is fixed to 256 bytes.
913 */
914 writel(0x8, pp->dbi_base + PCI_BASE_ADDRESS_3);
915 writel(SZ_1M - 1, pp->dbi_base + (1 << 12)
916 + PCI_BASE_ADDRESS_3);
917
918 /*
919 * 64bit prefetchable 1M bytes memory on bar4-5.
920 * FIXME BAR4,5 are not enabled yet
921 */
922 writel(0xc, pp->dbi_base + PCI_BASE_ADDRESS_4);
923 writel(SZ_1M - 1, pp->dbi_base + (1 << 12)
924 + PCI_BASE_ADDRESS_4);
925 writel(0, pp->dbi_base + (1 << 12) + PCI_BASE_ADDRESS_5);
926 1066
927 /* Re-setup the iATU */ 1067 /* Re-setup the iATU */
928 imx_pcie_regions_setup(&pdev->dev); 1068 imx_pcie_regions_setup(&pdev->dev);
@@ -978,6 +1118,8 @@ static int __init imx6_pcie_probe(struct platform_device *pdev)
978 /* Re-setup the iATU */ 1118 /* Re-setup the iATU */
979 imx_pcie_regions_setup(&pdev->dev); 1119 imx_pcie_regions_setup(&pdev->dev);
980 } 1120 }
1121
1122 register_syscore_ops(&pci_imx_syscore_ops);
981 return 0; 1123 return 0;
982 1124
983err: 1125err: