aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Agarwal <jagarwal@nvidia.com>2013-08-09 10:49:24 -0400
committerStephen Warren <swarren@nvidia.com>2013-08-13 14:07:48 -0400
commit94716cddbec6602643e2c7fe10f4385d951cf2f8 (patch)
tree038b88ea028ab41c898d9309489bc71edfef5ea4
parentd1523b52bff35ea709141abac87dd701559ef290 (diff)
PCI: tegra: Add Tegra 30 PCIe support
Introduce a data structure to parameterize the driver according to SoC generation, add Tegra30 specific code and update the device tree binding document for Tegra30 support. Signed-off-by: Jay Agarwal <jagarwal@nvidia.com> Signed-off-by: Thierry Reding <treding@nvidia.com> Acked-by: Bjorn Helgaas <bhelgaas@google.com> Signed-off-by: Stephen Warren <swarren@nvidia.com>
-rw-r--r--Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt4
-rw-r--r--drivers/pci/host/pci-tegra.c209
2 files changed, 179 insertions, 34 deletions
diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
index 90c112f671da..6b7510775c50 100644
--- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
@@ -1,7 +1,7 @@
1NVIDIA Tegra PCIe controller 1NVIDIA Tegra PCIe controller
2 2
3Required properties: 3Required properties:
4- compatible: "nvidia,tegra20-pcie" 4- compatible: "nvidia,tegra20-pcie" or "nvidia,tegra30-pcie"
5- device_type: Must be "pci" 5- device_type: Must be "pci"
6- reg: A list of physical base address and length for each set of controller 6- reg: A list of physical base address and length for each set of controller
7 registers. Must contain an entry for each entry in the reg-names property. 7 registers. Must contain an entry for each entry in the reg-names property.
@@ -16,6 +16,7 @@ Required properties:
16 "msi": The Tegra interrupt that is asserted when an MSI is received 16 "msi": The Tegra interrupt that is asserted when an MSI is received
17- pex-clk-supply: Supply voltage for internal reference clock 17- pex-clk-supply: Supply voltage for internal reference clock
18- vdd-supply: Power supply for controller (1.05V) 18- vdd-supply: Power supply for controller (1.05V)
19- avdd-supply: Power supply for controller (1.05V) (not required for Tegra20)
19- bus-range: Range of bus numbers associated with this controller 20- bus-range: Range of bus numbers associated with this controller
20- #address-cells: Address representation for root ports (must be 3) 21- #address-cells: Address representation for root ports (must be 3)
21 - cell 0 specifies the bus and device numbers of the root port: 22 - cell 0 specifies the bus and device numbers of the root port:
@@ -48,6 +49,7 @@ Required properties:
48 "afi": The Tegra clock of that name 49 "afi": The Tegra clock of that name
49 "pcie_xclk": The Tegra clock of that name 50 "pcie_xclk": The Tegra clock of that name
50 "pll_e": The Tegra clock of that name 51 "pll_e": The Tegra clock of that name
52 "cml": The Tegra clock of that name (not required for Tegra20)
51 53
52Root ports are defined as subnodes of the PCIe controller node. 54Root ports are defined as subnodes of the PCIe controller node.
53 55
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index a54a01138927..75607c788ff6 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * PCIe host controller driver for TEGRA(2) SOCs 2 * PCIe host controller driver for Tegra SoCs
3 * 3 *
4 * Copyright (c) 2010, CompuLab, Ltd. 4 * Copyright (c) 2010, CompuLab, Ltd.
5 * Author: Mike Rapoport <mike@compulab.co.il> 5 * Author: Mike Rapoport <mike@compulab.co.il>
@@ -50,7 +50,6 @@
50#include <asm/mach/pci.h> 50#include <asm/mach/pci.h>
51 51
52#define INT_PCI_MSI_NR (8 * 32) 52#define INT_PCI_MSI_NR (8 * 32)
53#define TEGRA_MAX_PORTS 2
54 53
55/* register definitions */ 54/* register definitions */
56 55
@@ -142,22 +141,30 @@
142#define AFI_INTR_EN_DFPCI_DECERR (1 << 5) 141#define AFI_INTR_EN_DFPCI_DECERR (1 << 5)
143#define AFI_INTR_EN_AXI_DECERR (1 << 6) 142#define AFI_INTR_EN_AXI_DECERR (1 << 6)
144#define AFI_INTR_EN_FPCI_TIMEOUT (1 << 7) 143#define AFI_INTR_EN_FPCI_TIMEOUT (1 << 7)
144#define AFI_INTR_EN_PRSNT_SENSE (1 << 8)
145 145
146#define AFI_PCIE_CONFIG 0x0f8 146#define AFI_PCIE_CONFIG 0x0f8
147#define AFI_PCIE_CONFIG_PCIE_DISABLE(x) (1 << ((x) + 1)) 147#define AFI_PCIE_CONFIG_PCIE_DISABLE(x) (1 << ((x) + 1))
148#define AFI_PCIE_CONFIG_PCIE_DISABLE_ALL 0xe 148#define AFI_PCIE_CONFIG_PCIE_DISABLE_ALL 0xe
149#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK (0xf << 20) 149#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK (0xf << 20)
150#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_SINGLE (0x0 << 20) 150#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_SINGLE (0x0 << 20)
151#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_420 (0x0 << 20)
151#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL (0x1 << 20) 152#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL (0x1 << 20)
153#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_222 (0x1 << 20)
154#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_411 (0x2 << 20)
152 155
153#define AFI_FUSE 0x104 156#define AFI_FUSE 0x104
154#define AFI_FUSE_PCIE_T0_GEN2_DIS (1 << 2) 157#define AFI_FUSE_PCIE_T0_GEN2_DIS (1 << 2)
155 158
156#define AFI_PEX0_CTRL 0x110 159#define AFI_PEX0_CTRL 0x110
157#define AFI_PEX1_CTRL 0x118 160#define AFI_PEX1_CTRL 0x118
161#define AFI_PEX2_CTRL 0x128
158#define AFI_PEX_CTRL_RST (1 << 0) 162#define AFI_PEX_CTRL_RST (1 << 0)
163#define AFI_PEX_CTRL_CLKREQ_EN (1 << 1)
159#define AFI_PEX_CTRL_REFCLK_EN (1 << 3) 164#define AFI_PEX_CTRL_REFCLK_EN (1 << 3)
160 165
166#define AFI_PEXBIAS_CTRL_0 0x168
167
161#define RP_VEND_XP 0x00000F00 168#define RP_VEND_XP 0x00000F00
162#define RP_VEND_XP_DL_UP (1 << 30) 169#define RP_VEND_XP_DL_UP (1 << 30)
163 170
@@ -172,7 +179,8 @@
172#define PADS_CTL_TX_DATA_EN_1L (1 << 6) 179#define PADS_CTL_TX_DATA_EN_1L (1 << 6)
173#define PADS_CTL_RX_DATA_EN_1L (1 << 10) 180#define PADS_CTL_RX_DATA_EN_1L (1 << 10)
174 181
175#define PADS_PLL_CTL 0x000000B8 182#define PADS_PLL_CTL_TEGRA20 0x000000B8
183#define PADS_PLL_CTL_TEGRA30 0x000000B4
176#define PADS_PLL_CTL_RST_B4SM (1 << 1) 184#define PADS_PLL_CTL_RST_B4SM (1 << 1)
177#define PADS_PLL_CTL_LOCKDET (1 << 8) 185#define PADS_PLL_CTL_LOCKDET (1 << 8)
178#define PADS_PLL_CTL_REFCLK_MASK (0x3 << 16) 186#define PADS_PLL_CTL_REFCLK_MASK (0x3 << 16)
@@ -182,6 +190,10 @@
182#define PADS_PLL_CTL_TXCLKREF_MASK (0x1 << 20) 190#define PADS_PLL_CTL_TXCLKREF_MASK (0x1 << 20)
183#define PADS_PLL_CTL_TXCLKREF_DIV10 (0 << 20) 191#define PADS_PLL_CTL_TXCLKREF_DIV10 (0 << 20)
184#define PADS_PLL_CTL_TXCLKREF_DIV5 (1 << 20) 192#define PADS_PLL_CTL_TXCLKREF_DIV5 (1 << 20)
193#define PADS_PLL_CTL_TXCLKREF_BUF_EN (1 << 22)
194
195#define PADS_REFCLK_CFG0 0x000000C8
196#define PADS_REFCLK_CFG1 0x000000CC
185 197
186struct tegra_msi { 198struct tegra_msi {
187 struct msi_chip chip; 199 struct msi_chip chip;
@@ -192,6 +204,19 @@ struct tegra_msi {
192 int irq; 204 int irq;
193}; 205};
194 206
207/* used to differentiate between Tegra SoC generations */
208struct tegra_pcie_soc_data {
209 unsigned int num_ports;
210 unsigned int msi_base_shift;
211 u32 pads_pll_ctl;
212 u32 tx_ref_sel;
213 bool has_pex_clkreq_en;
214 bool has_pex_bias_ctrl;
215 bool has_intr_prsnt_sense;
216 bool has_avdd_supply;
217 bool has_cml_clk;
218};
219
195static inline struct tegra_msi *to_tegra_msi(struct msi_chip *chip) 220static inline struct tegra_msi *to_tegra_msi(struct msi_chip *chip)
196{ 221{
197 return container_of(chip, struct tegra_msi, chip); 222 return container_of(chip, struct tegra_msi, chip);
@@ -216,6 +241,7 @@ struct tegra_pcie {
216 struct clk *afi_clk; 241 struct clk *afi_clk;
217 struct clk *pcie_xclk; 242 struct clk *pcie_xclk;
218 struct clk *pll_e; 243 struct clk *pll_e;
244 struct clk *cml_clk;
219 245
220 struct tegra_msi msi; 246 struct tegra_msi msi;
221 247
@@ -225,6 +251,9 @@ struct tegra_pcie {
225 251
226 struct regulator *pex_clk_supply; 252 struct regulator *pex_clk_supply;
227 struct regulator *vdd_supply; 253 struct regulator *vdd_supply;
254 struct regulator *avdd_supply;
255
256 const struct tegra_pcie_soc_data *soc_data;
228}; 257};
229 258
230struct tegra_pcie_port { 259struct tegra_pcie_port {
@@ -469,6 +498,10 @@ static unsigned long tegra_pcie_port_get_pex_ctrl(struct tegra_pcie_port *port)
469 case 1: 498 case 1:
470 ret = AFI_PEX1_CTRL; 499 ret = AFI_PEX1_CTRL;
471 break; 500 break;
501
502 case 2:
503 ret = AFI_PEX2_CTRL;
504 break;
472 } 505 }
473 506
474 return ret; 507 return ret;
@@ -493,12 +526,17 @@ static void tegra_pcie_port_reset(struct tegra_pcie_port *port)
493 526
494static void tegra_pcie_port_enable(struct tegra_pcie_port *port) 527static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
495{ 528{
529 const struct tegra_pcie_soc_data *soc = port->pcie->soc_data;
496 unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port); 530 unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
497 unsigned long value; 531 unsigned long value;
498 532
499 /* enable reference clock */ 533 /* enable reference clock */
500 value = afi_readl(port->pcie, ctrl); 534 value = afi_readl(port->pcie, ctrl);
501 value |= AFI_PEX_CTRL_REFCLK_EN; 535 value |= AFI_PEX_CTRL_REFCLK_EN;
536
537 if (soc->has_pex_clkreq_en)
538 value |= AFI_PEX_CTRL_CLKREQ_EN;
539
502 afi_writel(port->pcie, value, ctrl); 540 afi_writel(port->pcie, value, ctrl);
503 541
504 tegra_pcie_port_reset(port); 542 tegra_pcie_port_reset(port);
@@ -551,6 +589,8 @@ static void tegra_pcie_fixup_class(struct pci_dev *dev)
551} 589}
552DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0bf0, tegra_pcie_fixup_class); 590DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0bf0, tegra_pcie_fixup_class);
553DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_fixup_class); 591DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_fixup_class);
592DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0e1c, tegra_pcie_fixup_class);
593DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0e1d, tegra_pcie_fixup_class);
554 594
555/* Tegra PCIE requires relaxed ordering */ 595/* Tegra PCIE requires relaxed ordering */
556static void tegra_pcie_relax_enable(struct pci_dev *dev) 596static void tegra_pcie_relax_enable(struct pci_dev *dev)
@@ -723,10 +763,15 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
723 763
724static int tegra_pcie_enable_controller(struct tegra_pcie *pcie) 764static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
725{ 765{
766 const struct tegra_pcie_soc_data *soc = pcie->soc_data;
726 struct tegra_pcie_port *port; 767 struct tegra_pcie_port *port;
727 unsigned int timeout; 768 unsigned int timeout;
728 unsigned long value; 769 unsigned long value;
729 770
771 /* power down PCIe slot clock bias pad */
772 if (soc->has_pex_bias_ctrl)
773 afi_writel(pcie, 0, AFI_PEXBIAS_CTRL_0);
774
730 /* configure mode and disable all ports */ 775 /* configure mode and disable all ports */
731 value = afi_readl(pcie, AFI_PCIE_CONFIG); 776 value = afi_readl(pcie, AFI_PCIE_CONFIG);
732 value &= ~AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK; 777 value &= ~AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK;
@@ -753,27 +798,26 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
753 * Set up PHY PLL inputs select PLLE output as refclock, 798 * Set up PHY PLL inputs select PLLE output as refclock,
754 * set TX ref sel to div10 (not div5). 799 * set TX ref sel to div10 (not div5).
755 */ 800 */
756 value = pads_readl(pcie, PADS_PLL_CTL); 801 value = pads_readl(pcie, soc->pads_pll_ctl);
757 value &= ~(PADS_PLL_CTL_REFCLK_MASK | PADS_PLL_CTL_TXCLKREF_MASK); 802 value &= ~(PADS_PLL_CTL_REFCLK_MASK | PADS_PLL_CTL_TXCLKREF_MASK);
758 value |= PADS_PLL_CTL_REFCLK_INTERNAL_CML | 803 value |= PADS_PLL_CTL_REFCLK_INTERNAL_CML | soc->tx_ref_sel;
759 PADS_PLL_CTL_TXCLKREF_DIV10; 804 pads_writel(pcie, value, soc->pads_pll_ctl);
760 pads_writel(pcie, value, PADS_PLL_CTL);
761 805
762 /* take PLL out of reset */ 806 /* take PLL out of reset */
763 value = pads_readl(pcie, PADS_PLL_CTL); 807 value = pads_readl(pcie, soc->pads_pll_ctl);
764 value |= PADS_PLL_CTL_RST_B4SM; 808 value |= PADS_PLL_CTL_RST_B4SM;
765 pads_writel(pcie, value, PADS_PLL_CTL); 809 pads_writel(pcie, value, soc->pads_pll_ctl);
766 810
767 /* 811 /*
768 * Hack, set the clock voltage to the DEFAULT provided by hw folks. 812 * Hack, set the clock voltage to the DEFAULT provided by hw folks.
769 * This doesn't exist in the documentation. 813 * This doesn't exist in the documentation.
770 */ 814 */
771 pads_writel(pcie, 0xfa5cfa5c, 0xc8); 815 pads_writel(pcie, 0xfa5cfa5c, PADS_REFCLK_CFG0);
772 816
773 /* wait for the PLL to lock */ 817 /* wait for the PLL to lock */
774 timeout = 300; 818 timeout = 300;
775 do { 819 do {
776 value = pads_readl(pcie, PADS_PLL_CTL); 820 value = pads_readl(pcie, soc->pads_pll_ctl);
777 usleep_range(1000, 2000); 821 usleep_range(1000, 2000);
778 if (--timeout == 0) { 822 if (--timeout == 0) {
779 pr_err("Tegra PCIe error: timeout waiting for PLL\n"); 823 pr_err("Tegra PCIe error: timeout waiting for PLL\n");
@@ -802,6 +846,10 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
802 value = AFI_INTR_EN_INI_SLVERR | AFI_INTR_EN_INI_DECERR | 846 value = AFI_INTR_EN_INI_SLVERR | AFI_INTR_EN_INI_DECERR |
803 AFI_INTR_EN_TGT_SLVERR | AFI_INTR_EN_TGT_DECERR | 847 AFI_INTR_EN_TGT_SLVERR | AFI_INTR_EN_TGT_DECERR |
804 AFI_INTR_EN_TGT_WRERR | AFI_INTR_EN_DFPCI_DECERR; 848 AFI_INTR_EN_TGT_WRERR | AFI_INTR_EN_DFPCI_DECERR;
849
850 if (soc->has_intr_prsnt_sense)
851 value |= AFI_INTR_EN_PRSNT_SENSE;
852
805 afi_writel(pcie, value, AFI_AFI_INTR_ENABLE); 853 afi_writel(pcie, value, AFI_AFI_INTR_ENABLE);
806 afi_writel(pcie, 0xffffffff, AFI_SM_INTR_ENABLE); 854 afi_writel(pcie, 0xffffffff, AFI_SM_INTR_ENABLE);
807 855
@@ -816,6 +864,7 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
816 864
817static void tegra_pcie_power_off(struct tegra_pcie *pcie) 865static void tegra_pcie_power_off(struct tegra_pcie *pcie)
818{ 866{
867 const struct tegra_pcie_soc_data *soc = pcie->soc_data;
819 int err; 868 int err;
820 869
821 /* TODO: disable and unprepare clocks? */ 870 /* TODO: disable and unprepare clocks? */
@@ -826,19 +875,28 @@ static void tegra_pcie_power_off(struct tegra_pcie *pcie)
826 875
827 tegra_powergate_power_off(TEGRA_POWERGATE_PCIE); 876 tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
828 877
878 if (soc->has_avdd_supply) {
879 err = regulator_disable(pcie->avdd_supply);
880 if (err < 0)
881 dev_warn(pcie->dev,
882 "failed to disable AVDD regulator: %d\n",
883 err);
884 }
885
829 err = regulator_disable(pcie->pex_clk_supply); 886 err = regulator_disable(pcie->pex_clk_supply);
830 if (err < 0) 887 if (err < 0)
831 dev_err(pcie->dev, "failed to disable pex-clk regulator: %d\n", 888 dev_warn(pcie->dev, "failed to disable pex-clk regulator: %d\n",
832 err); 889 err);
833 890
834 err = regulator_disable(pcie->vdd_supply); 891 err = regulator_disable(pcie->vdd_supply);
835 if (err < 0) 892 if (err < 0)
836 dev_err(pcie->dev, "failed to disable VDD regulator: %d\n", 893 dev_warn(pcie->dev, "failed to disable VDD regulator: %d\n",
837 err); 894 err);
838} 895}
839 896
840static int tegra_pcie_power_on(struct tegra_pcie *pcie) 897static int tegra_pcie_power_on(struct tegra_pcie *pcie)
841{ 898{
899 const struct tegra_pcie_soc_data *soc = pcie->soc_data;
842 int err; 900 int err;
843 901
844 tegra_periph_reset_assert(pcie->pcie_xclk); 902 tegra_periph_reset_assert(pcie->pcie_xclk);
@@ -861,6 +919,16 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)
861 return err; 919 return err;
862 } 920 }
863 921
922 if (soc->has_avdd_supply) {
923 err = regulator_enable(pcie->avdd_supply);
924 if (err < 0) {
925 dev_err(pcie->dev,
926 "failed to enable AVDD regulator: %d\n",
927 err);
928 return err;
929 }
930 }
931
864 err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE, 932 err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE,
865 pcie->pex_clk); 933 pcie->pex_clk);
866 if (err) { 934 if (err) {
@@ -876,6 +944,15 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)
876 return err; 944 return err;
877 } 945 }
878 946
947 if (soc->has_cml_clk) {
948 err = clk_prepare_enable(pcie->cml_clk);
949 if (err < 0) {
950 dev_err(pcie->dev, "failed to enable CML clock: %d\n",
951 err);
952 return err;
953 }
954 }
955
879 err = clk_prepare_enable(pcie->pll_e); 956 err = clk_prepare_enable(pcie->pll_e);
880 if (err < 0) { 957 if (err < 0) {
881 dev_err(pcie->dev, "failed to enable PLLE clock: %d\n", err); 958 dev_err(pcie->dev, "failed to enable PLLE clock: %d\n", err);
@@ -887,6 +964,8 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)
887 964
888static int tegra_pcie_clocks_get(struct tegra_pcie *pcie) 965static int tegra_pcie_clocks_get(struct tegra_pcie *pcie)
889{ 966{
967 const struct tegra_pcie_soc_data *soc = pcie->soc_data;
968
890 pcie->pex_clk = devm_clk_get(pcie->dev, "pex"); 969 pcie->pex_clk = devm_clk_get(pcie->dev, "pex");
891 if (IS_ERR(pcie->pex_clk)) 970 if (IS_ERR(pcie->pex_clk))
892 return PTR_ERR(pcie->pex_clk); 971 return PTR_ERR(pcie->pex_clk);
@@ -903,6 +982,12 @@ static int tegra_pcie_clocks_get(struct tegra_pcie *pcie)
903 if (IS_ERR(pcie->pll_e)) 982 if (IS_ERR(pcie->pll_e))
904 return PTR_ERR(pcie->pll_e); 983 return PTR_ERR(pcie->pll_e);
905 984
985 if (soc->has_cml_clk) {
986 pcie->cml_clk = devm_clk_get(pcie->dev, "cml");
987 if (IS_ERR(pcie->cml_clk))
988 return PTR_ERR(pcie->cml_clk);
989 }
990
906 return 0; 991 return 0;
907} 992}
908 993
@@ -1127,6 +1212,7 @@ static const struct irq_domain_ops msi_domain_ops = {
1127static int tegra_pcie_enable_msi(struct tegra_pcie *pcie) 1212static int tegra_pcie_enable_msi(struct tegra_pcie *pcie)
1128{ 1213{
1129 struct platform_device *pdev = to_platform_device(pcie->dev); 1214 struct platform_device *pdev = to_platform_device(pcie->dev);
1215 const struct tegra_pcie_soc_data *soc = pcie->soc_data;
1130 struct tegra_msi *msi = &pcie->msi; 1216 struct tegra_msi *msi = &pcie->msi;
1131 unsigned long base; 1217 unsigned long base;
1132 int err; 1218 int err;
@@ -1164,7 +1250,7 @@ static int tegra_pcie_enable_msi(struct tegra_pcie *pcie)
1164 msi->pages = __get_free_pages(GFP_KERNEL, 0); 1250 msi->pages = __get_free_pages(GFP_KERNEL, 0);
1165 base = virt_to_phys((void *)msi->pages); 1251 base = virt_to_phys((void *)msi->pages);
1166 1252
1167 afi_writel(pcie, base, AFI_MSI_FPCI_BAR_ST); 1253 afi_writel(pcie, base >> soc->msi_base_shift, AFI_MSI_FPCI_BAR_ST);
1168 afi_writel(pcie, base, AFI_MSI_AXI_BAR_ST); 1254 afi_writel(pcie, base, AFI_MSI_AXI_BAR_ST);
1169 /* this register is in 4K increments */ 1255 /* this register is in 4K increments */
1170 afi_writel(pcie, 1, AFI_MSI_BAR_SZ); 1256 afi_writel(pcie, 1, AFI_MSI_BAR_SZ);
@@ -1233,16 +1319,35 @@ static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes,
1233{ 1319{
1234 struct device_node *np = pcie->dev->of_node; 1320 struct device_node *np = pcie->dev->of_node;
1235 1321
1236 switch (lanes) { 1322 if (of_device_is_compatible(np, "nvidia,tegra30-pcie")) {
1237 case 0x00000004: 1323 switch (lanes) {
1238 dev_info(pcie->dev, "single-mode configuration\n"); 1324 case 0x00000204:
1239 *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_SINGLE; 1325 dev_info(pcie->dev, "4x1, 2x1 configuration\n");
1240 return 0; 1326 *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_420;
1241 1327 return 0;
1242 case 0x00000202: 1328
1243 dev_info(pcie->dev, "dual-mode configuration\n"); 1329 case 0x00020202:
1244 *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL; 1330 dev_info(pcie->dev, "2x3 configuration\n");
1245 return 0; 1331 *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_222;
1332 return 0;
1333
1334 case 0x00010104:
1335 dev_info(pcie->dev, "4x1, 1x2 configuration\n");
1336 *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_411;
1337 return 0;
1338 }
1339 } else if (of_device_is_compatible(np, "nvidia,tegra20-pcie")) {
1340 switch (lanes) {
1341 case 0x00000004:
1342 dev_info(pcie->dev, "single-mode configuration\n");
1343 *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_SINGLE;
1344 return 0;
1345
1346 case 0x00000202:
1347 dev_info(pcie->dev, "dual-mode configuration\n");
1348 *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL;
1349 return 0;
1350 }
1246 } 1351 }
1247 1352
1248 return -EINVAL; 1353 return -EINVAL;
@@ -1250,6 +1355,7 @@ static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes,
1250 1355
1251static int tegra_pcie_parse_dt(struct tegra_pcie *pcie) 1356static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
1252{ 1357{
1358 const struct tegra_pcie_soc_data *soc = pcie->soc_data;
1253 struct device_node *np = pcie->dev->of_node, *port; 1359 struct device_node *np = pcie->dev->of_node, *port;
1254 struct of_pci_range_parser parser; 1360 struct of_pci_range_parser parser;
1255 struct of_pci_range range; 1361 struct of_pci_range range;
@@ -1270,6 +1376,12 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
1270 if (IS_ERR(pcie->pex_clk_supply)) 1376 if (IS_ERR(pcie->pex_clk_supply))
1271 return PTR_ERR(pcie->pex_clk_supply); 1377 return PTR_ERR(pcie->pex_clk_supply);
1272 1378
1379 if (soc->has_avdd_supply) {
1380 pcie->avdd_supply = devm_regulator_get(pcie->dev, "avdd");
1381 if (IS_ERR(pcie->avdd_supply))
1382 return PTR_ERR(pcie->avdd_supply);
1383 }
1384
1273 for_each_of_pci_range(&parser, &range) { 1385 for_each_of_pci_range(&parser, &range) {
1274 of_pci_range_to_resource(&range, np, &res); 1386 of_pci_range_to_resource(&range, np, &res);
1275 1387
@@ -1316,7 +1428,7 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
1316 1428
1317 index = PCI_SLOT(err); 1429 index = PCI_SLOT(err);
1318 1430
1319 if (index < 1 || index > TEGRA_MAX_PORTS) { 1431 if (index < 1 || index > soc->num_ports) {
1320 dev_err(pcie->dev, "invalid port number: %d\n", index); 1432 dev_err(pcie->dev, "invalid port number: %d\n", index);
1321 return -EINVAL; 1433 return -EINVAL;
1322 } 1434 }
@@ -1454,17 +1566,54 @@ static int tegra_pcie_enable(struct tegra_pcie *pcie)
1454 return 0; 1566 return 0;
1455} 1567}
1456 1568
1569static const struct tegra_pcie_soc_data tegra20_pcie_data = {
1570 .num_ports = 2,
1571 .msi_base_shift = 0,
1572 .pads_pll_ctl = PADS_PLL_CTL_TEGRA20,
1573 .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_DIV10,
1574 .has_pex_clkreq_en = false,
1575 .has_pex_bias_ctrl = false,
1576 .has_intr_prsnt_sense = false,
1577 .has_avdd_supply = false,
1578 .has_cml_clk = false,
1579};
1580
1581static const struct tegra_pcie_soc_data tegra30_pcie_data = {
1582 .num_ports = 3,
1583 .msi_base_shift = 8,
1584 .pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
1585 .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
1586 .has_pex_clkreq_en = true,
1587 .has_pex_bias_ctrl = true,
1588 .has_intr_prsnt_sense = true,
1589 .has_avdd_supply = true,
1590 .has_cml_clk = true,
1591};
1592
1593static const struct of_device_id tegra_pcie_of_match[] = {
1594 { .compatible = "nvidia,tegra30-pcie", .data = &tegra30_pcie_data },
1595 { .compatible = "nvidia,tegra20-pcie", .data = &tegra20_pcie_data },
1596 { },
1597};
1598MODULE_DEVICE_TABLE(of, tegra_pcie_of_match);
1599
1457static int tegra_pcie_probe(struct platform_device *pdev) 1600static int tegra_pcie_probe(struct platform_device *pdev)
1458{ 1601{
1602 const struct of_device_id *match;
1459 struct tegra_pcie *pcie; 1603 struct tegra_pcie *pcie;
1460 int err; 1604 int err;
1461 1605
1606 match = of_match_device(tegra_pcie_of_match, &pdev->dev);
1607 if (!match)
1608 return -ENODEV;
1609
1462 pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL); 1610 pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
1463 if (!pcie) 1611 if (!pcie)
1464 return -ENOMEM; 1612 return -ENOMEM;
1465 1613
1466 INIT_LIST_HEAD(&pcie->busses); 1614 INIT_LIST_HEAD(&pcie->busses);
1467 INIT_LIST_HEAD(&pcie->ports); 1615 INIT_LIST_HEAD(&pcie->ports);
1616 pcie->soc_data = match->data;
1468 pcie->dev = &pdev->dev; 1617 pcie->dev = &pdev->dev;
1469 1618
1470 err = tegra_pcie_parse_dt(pcie); 1619 err = tegra_pcie_parse_dt(pcie);
@@ -1513,12 +1662,6 @@ put_resources:
1513 return err; 1662 return err;
1514} 1663}
1515 1664
1516static const struct of_device_id tegra_pcie_of_match[] = {
1517 { .compatible = "nvidia,tegra20-pcie", },
1518 { },
1519};
1520MODULE_DEVICE_TABLE(of, tegra_pcie_of_match);
1521
1522static struct platform_driver tegra_pcie_driver = { 1665static struct platform_driver tegra_pcie_driver = {
1523 .driver = { 1666 .driver = {
1524 .name = "tegra-pcie", 1667 .name = "tegra-pcie",