blob: f4f53d092e00526cd4dec08e575334fd9f400c1e [file] [log] [blame]
Bjorn Helgaas736759e2018-01-26 14:22:04 -06001// SPDX-License-Identifier: GPL-2.0+
Thierry Redingd1523b52013-08-09 16:49:19 +02002/*
Jay Agarwal94716cd2013-08-09 16:49:24 +02003 * PCIe host controller driver for Tegra SoCs
Thierry Redingd1523b52013-08-09 16:49:19 +02004 *
5 * Copyright (c) 2010, CompuLab, Ltd.
6 * Author: Mike Rapoport <mike@compulab.co.il>
7 *
8 * Based on NVIDIA PCIe driver
9 * Copyright (c) 2008-2009, NVIDIA Corporation.
10 *
11 * Bits taken from arch/arm/mach-dove/pcie.c
12 *
Paul Gortmakerad183272016-07-02 19:13:31 -040013 * Author: Thierry Reding <treding@nvidia.com>
Thierry Redingd1523b52013-08-09 16:49:19 +020014 */
15
16#include <linux/clk.h>
Thierry Reding2cb989f2014-07-22 12:30:46 -060017#include <linux/debugfs.h>
Thierry Redingd1523b52013-08-09 16:49:19 +020018#include <linux/delay.h>
19#include <linux/export.h>
20#include <linux/interrupt.h>
Manikanta Maddireddy662b94c2018-02-28 15:30:33 +053021#include <linux/iopoll.h>
Thierry Redingd1523b52013-08-09 16:49:19 +020022#include <linux/irq.h>
23#include <linux/irqdomain.h>
24#include <linux/kernel.h>
Paul Gortmakerad183272016-07-02 19:13:31 -040025#include <linux/init.h>
Manikanta Maddireddy662b94c2018-02-28 15:30:33 +053026#include <linux/module.h>
Thierry Redingd1523b52013-08-09 16:49:19 +020027#include <linux/msi.h>
28#include <linux/of_address.h>
29#include <linux/of_pci.h>
30#include <linux/of_platform.h>
31#include <linux/pci.h>
Thierry Reding7f1f0542014-08-26 17:11:38 +020032#include <linux/phy/phy.h>
Thierry Redingd1523b52013-08-09 16:49:19 +020033#include <linux/platform_device.h>
Stephen Warren3127a6b2013-11-06 15:56:58 -070034#include <linux/reset.h>
Thierry Redingd1523b52013-08-09 16:49:19 +020035#include <linux/sizes.h>
36#include <linux/slab.h>
Thierry Redingd1523b52013-08-09 16:49:19 +020037#include <linux/vmalloc.h>
38#include <linux/regulator/consumer.h>
39
Thierry Reding306a7f92014-07-17 13:17:24 +020040#include <soc/tegra/cpuidle.h>
Thierry Reding72323982014-07-11 13:19:06 +020041#include <soc/tegra/pmc.h>
Thierry Reding306a7f92014-07-17 13:17:24 +020042
Rob Herring9e2aee82018-05-11 12:15:30 -050043#include "../pci.h"
44
Thierry Redingd1523b52013-08-09 16:49:19 +020045#define INT_PCI_MSI_NR (8 * 32)
Thierry Redingd1523b52013-08-09 16:49:19 +020046
47/* register definitions */
48
49#define AFI_AXI_BAR0_SZ 0x00
50#define AFI_AXI_BAR1_SZ 0x04
51#define AFI_AXI_BAR2_SZ 0x08
52#define AFI_AXI_BAR3_SZ 0x0c
53#define AFI_AXI_BAR4_SZ 0x10
54#define AFI_AXI_BAR5_SZ 0x14
55
56#define AFI_AXI_BAR0_START 0x18
57#define AFI_AXI_BAR1_START 0x1c
58#define AFI_AXI_BAR2_START 0x20
59#define AFI_AXI_BAR3_START 0x24
60#define AFI_AXI_BAR4_START 0x28
61#define AFI_AXI_BAR5_START 0x2c
62
63#define AFI_FPCI_BAR0 0x30
64#define AFI_FPCI_BAR1 0x34
65#define AFI_FPCI_BAR2 0x38
66#define AFI_FPCI_BAR3 0x3c
67#define AFI_FPCI_BAR4 0x40
68#define AFI_FPCI_BAR5 0x44
69
70#define AFI_CACHE_BAR0_SZ 0x48
71#define AFI_CACHE_BAR0_ST 0x4c
72#define AFI_CACHE_BAR1_SZ 0x50
73#define AFI_CACHE_BAR1_ST 0x54
74
75#define AFI_MSI_BAR_SZ 0x60
76#define AFI_MSI_FPCI_BAR_ST 0x64
77#define AFI_MSI_AXI_BAR_ST 0x68
78
79#define AFI_MSI_VEC0 0x6c
80#define AFI_MSI_VEC1 0x70
81#define AFI_MSI_VEC2 0x74
82#define AFI_MSI_VEC3 0x78
83#define AFI_MSI_VEC4 0x7c
84#define AFI_MSI_VEC5 0x80
85#define AFI_MSI_VEC6 0x84
86#define AFI_MSI_VEC7 0x88
87
88#define AFI_MSI_EN_VEC0 0x8c
89#define AFI_MSI_EN_VEC1 0x90
90#define AFI_MSI_EN_VEC2 0x94
91#define AFI_MSI_EN_VEC3 0x98
92#define AFI_MSI_EN_VEC4 0x9c
93#define AFI_MSI_EN_VEC5 0xa0
94#define AFI_MSI_EN_VEC6 0xa4
95#define AFI_MSI_EN_VEC7 0xa8
96
97#define AFI_CONFIGURATION 0xac
98#define AFI_CONFIGURATION_EN_FPCI (1 << 0)
99
100#define AFI_FPCI_ERROR_MASKS 0xb0
101
102#define AFI_INTR_MASK 0xb4
103#define AFI_INTR_MASK_INT_MASK (1 << 0)
104#define AFI_INTR_MASK_MSI_MASK (1 << 8)
105
106#define AFI_INTR_CODE 0xb8
107#define AFI_INTR_CODE_MASK 0xf
Thierry Reding7f1f0542014-08-26 17:11:38 +0200108#define AFI_INTR_INI_SLAVE_ERROR 1
109#define AFI_INTR_INI_DECODE_ERROR 2
Thierry Redingd1523b52013-08-09 16:49:19 +0200110#define AFI_INTR_TARGET_ABORT 3
111#define AFI_INTR_MASTER_ABORT 4
112#define AFI_INTR_INVALID_WRITE 5
113#define AFI_INTR_LEGACY 6
114#define AFI_INTR_FPCI_DECODE_ERROR 7
Thierry Reding7f1f0542014-08-26 17:11:38 +0200115#define AFI_INTR_AXI_DECODE_ERROR 8
116#define AFI_INTR_FPCI_TIMEOUT 9
117#define AFI_INTR_PE_PRSNT_SENSE 10
118#define AFI_INTR_PE_CLKREQ_SENSE 11
119#define AFI_INTR_CLKCLAMP_SENSE 12
120#define AFI_INTR_RDY4PD_SENSE 13
121#define AFI_INTR_P2P_ERROR 14
Thierry Redingd1523b52013-08-09 16:49:19 +0200122
123#define AFI_INTR_SIGNATURE 0xbc
124#define AFI_UPPER_FPCI_ADDRESS 0xc0
125#define AFI_SM_INTR_ENABLE 0xc4
126#define AFI_SM_INTR_INTA_ASSERT (1 << 0)
127#define AFI_SM_INTR_INTB_ASSERT (1 << 1)
128#define AFI_SM_INTR_INTC_ASSERT (1 << 2)
129#define AFI_SM_INTR_INTD_ASSERT (1 << 3)
130#define AFI_SM_INTR_INTA_DEASSERT (1 << 4)
131#define AFI_SM_INTR_INTB_DEASSERT (1 << 5)
132#define AFI_SM_INTR_INTC_DEASSERT (1 << 6)
133#define AFI_SM_INTR_INTD_DEASSERT (1 << 7)
134
135#define AFI_AFI_INTR_ENABLE 0xc8
136#define AFI_INTR_EN_INI_SLVERR (1 << 0)
137#define AFI_INTR_EN_INI_DECERR (1 << 1)
138#define AFI_INTR_EN_TGT_SLVERR (1 << 2)
139#define AFI_INTR_EN_TGT_DECERR (1 << 3)
140#define AFI_INTR_EN_TGT_WRERR (1 << 4)
141#define AFI_INTR_EN_DFPCI_DECERR (1 << 5)
142#define AFI_INTR_EN_AXI_DECERR (1 << 6)
143#define AFI_INTR_EN_FPCI_TIMEOUT (1 << 7)
Jay Agarwal94716cd2013-08-09 16:49:24 +0200144#define AFI_INTR_EN_PRSNT_SENSE (1 << 8)
Thierry Redingd1523b52013-08-09 16:49:19 +0200145
Manikanta Maddireddy662b94c2018-02-28 15:30:33 +0530146#define AFI_PCIE_PME 0xf0
147
Thierry Redingd1523b52013-08-09 16:49:19 +0200148#define AFI_PCIE_CONFIG 0x0f8
149#define AFI_PCIE_CONFIG_PCIE_DISABLE(x) (1 << ((x) + 1))
150#define AFI_PCIE_CONFIG_PCIE_DISABLE_ALL 0xe
151#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK (0xf << 20)
152#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_SINGLE (0x0 << 20)
Jay Agarwal94716cd2013-08-09 16:49:24 +0200153#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_420 (0x0 << 20)
Thierry Reding7f1f0542014-08-26 17:11:38 +0200154#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X2_X1 (0x0 << 20)
Manikanta Maddireddy9cea5132017-09-27 17:28:35 +0530155#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_401 (0x0 << 20)
Thierry Redingd1523b52013-08-09 16:49:19 +0200156#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL (0x1 << 20)
Jay Agarwal94716cd2013-08-09 16:49:24 +0200157#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_222 (0x1 << 20)
Thierry Reding7f1f0542014-08-26 17:11:38 +0200158#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X4_X1 (0x1 << 20)
Manikanta Maddireddy9cea5132017-09-27 17:28:35 +0530159#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_211 (0x1 << 20)
Jay Agarwal94716cd2013-08-09 16:49:24 +0200160#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_411 (0x2 << 20)
Manikanta Maddireddy9cea5132017-09-27 17:28:35 +0530161#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_111 (0x2 << 20)
Thierry Redingd1523b52013-08-09 16:49:19 +0200162
163#define AFI_FUSE 0x104
164#define AFI_FUSE_PCIE_T0_GEN2_DIS (1 << 2)
165
166#define AFI_PEX0_CTRL 0x110
167#define AFI_PEX1_CTRL 0x118
Jay Agarwal94716cd2013-08-09 16:49:24 +0200168#define AFI_PEX2_CTRL 0x128
Thierry Redingd1523b52013-08-09 16:49:19 +0200169#define AFI_PEX_CTRL_RST (1 << 0)
Jay Agarwal94716cd2013-08-09 16:49:24 +0200170#define AFI_PEX_CTRL_CLKREQ_EN (1 << 1)
Thierry Redingd1523b52013-08-09 16:49:19 +0200171#define AFI_PEX_CTRL_REFCLK_EN (1 << 3)
Thierry Reding7f1f0542014-08-26 17:11:38 +0200172#define AFI_PEX_CTRL_OVERRIDE_EN (1 << 4)
173
174#define AFI_PLLE_CONTROL 0x160
175#define AFI_PLLE_CONTROL_BYPASS_PADS2PLLE_CONTROL (1 << 9)
176#define AFI_PLLE_CONTROL_PADS2PLLE_CONTROL_EN (1 << 1)
Thierry Redingd1523b52013-08-09 16:49:19 +0200177
Jay Agarwal94716cd2013-08-09 16:49:24 +0200178#define AFI_PEXBIAS_CTRL_0 0x168
179
Thierry Redingacb341e2016-07-25 16:02:05 -0500180#define RP_VEND_XP 0x00000f00
Thierry Redingd1523b52013-08-09 16:49:19 +0200181#define RP_VEND_XP_DL_UP (1 << 30)
182
Thierry Reding76245ca2016-11-25 11:57:14 +0100183#define RP_VEND_CTL2 0x00000fa8
184#define RP_VEND_CTL2_PCA_ENABLE (1 << 7)
185
Thierry Redingacb341e2016-07-25 16:02:05 -0500186#define RP_PRIV_MISC 0x00000fe0
187#define RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT (0xe << 0)
188#define RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT (0xf << 0)
Thierry Reding7f1f0542014-08-26 17:11:38 +0200189
Thierry Redingd1523b52013-08-09 16:49:19 +0200190#define RP_LINK_CONTROL_STATUS 0x00000090
191#define RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE 0x20000000
192#define RP_LINK_CONTROL_STATUS_LINKSTAT_MASK 0x3fff0000
193
Thierry Redingacb341e2016-07-25 16:02:05 -0500194#define PADS_CTL_SEL 0x0000009c
Thierry Redingd1523b52013-08-09 16:49:19 +0200195
Thierry Redingacb341e2016-07-25 16:02:05 -0500196#define PADS_CTL 0x000000a0
Thierry Redingd1523b52013-08-09 16:49:19 +0200197#define PADS_CTL_IDDQ_1L (1 << 0)
198#define PADS_CTL_TX_DATA_EN_1L (1 << 6)
199#define PADS_CTL_RX_DATA_EN_1L (1 << 10)
200
Thierry Redingacb341e2016-07-25 16:02:05 -0500201#define PADS_PLL_CTL_TEGRA20 0x000000b8
202#define PADS_PLL_CTL_TEGRA30 0x000000b4
Thierry Redingd1523b52013-08-09 16:49:19 +0200203#define PADS_PLL_CTL_RST_B4SM (1 << 1)
204#define PADS_PLL_CTL_LOCKDET (1 << 8)
205#define PADS_PLL_CTL_REFCLK_MASK (0x3 << 16)
206#define PADS_PLL_CTL_REFCLK_INTERNAL_CML (0 << 16)
207#define PADS_PLL_CTL_REFCLK_INTERNAL_CMOS (1 << 16)
208#define PADS_PLL_CTL_REFCLK_EXTERNAL (2 << 16)
209#define PADS_PLL_CTL_TXCLKREF_MASK (0x1 << 20)
210#define PADS_PLL_CTL_TXCLKREF_DIV10 (0 << 20)
211#define PADS_PLL_CTL_TXCLKREF_DIV5 (1 << 20)
Jay Agarwal94716cd2013-08-09 16:49:24 +0200212#define PADS_PLL_CTL_TXCLKREF_BUF_EN (1 << 22)
213
Thierry Redingacb341e2016-07-25 16:02:05 -0500214#define PADS_REFCLK_CFG0 0x000000c8
215#define PADS_REFCLK_CFG1 0x000000cc
216#define PADS_REFCLK_BIAS 0x000000d0
Thierry Redingd1523b52013-08-09 16:49:19 +0200217
Stephen Warrenb02b07a2013-08-09 16:49:25 +0200218/*
219 * Fields in PADS_REFCLK_CFG*. Those registers form an array of 16-bit
220 * entries, one entry per PCIe port. These field definitions and desired
221 * values aren't in the TRM, but do come from NVIDIA.
222 */
223#define PADS_REFCLK_CFG_TERM_SHIFT 2 /* 6:2 */
224#define PADS_REFCLK_CFG_E_TERM_SHIFT 7
225#define PADS_REFCLK_CFG_PREDI_SHIFT 8 /* 11:8 */
226#define PADS_REFCLK_CFG_DRVI_SHIFT 12 /* 15:12 */
227
Manikanta Maddireddy662b94c2018-02-28 15:30:33 +0530228#define PME_ACK_TIMEOUT 10000
229
Thierry Redingd1523b52013-08-09 16:49:19 +0200230struct tegra_msi {
Yijing Wangc2791b82014-11-11 17:45:45 -0700231 struct msi_controller chip;
Thierry Redingd1523b52013-08-09 16:49:19 +0200232 DECLARE_BITMAP(used, INT_PCI_MSI_NR);
233 struct irq_domain *domain;
Thierry Reding8c2b4e32017-10-09 12:29:35 +0200234 unsigned long pages;
Thierry Redingd1523b52013-08-09 16:49:19 +0200235 struct mutex lock;
Thierry Redingc0165552017-05-04 22:10:31 +0200236 u64 phys;
Thierry Redingd1523b52013-08-09 16:49:19 +0200237 int irq;
238};
239
Jay Agarwal94716cd2013-08-09 16:49:24 +0200240/* used to differentiate between Tegra SoC generations */
Manikanta Maddireddy662b94c2018-02-28 15:30:33 +0530241struct tegra_pcie_port_soc {
242 struct {
243 u8 turnoff_bit;
244 u8 ack_bit;
245 } pme;
246};
247
Thierry Redinga7fbae22016-08-15 17:31:31 +0200248struct tegra_pcie_soc {
Jay Agarwal94716cd2013-08-09 16:49:24 +0200249 unsigned int num_ports;
Manikanta Maddireddy662b94c2018-02-28 15:30:33 +0530250 const struct tegra_pcie_port_soc *ports;
Jay Agarwal94716cd2013-08-09 16:49:24 +0200251 unsigned int msi_base_shift;
252 u32 pads_pll_ctl;
253 u32 tx_ref_sel;
Stephen Warrenf8144302016-07-25 16:02:27 -0500254 u32 pads_refclk_cfg0;
255 u32 pads_refclk_cfg1;
Jay Agarwal94716cd2013-08-09 16:49:24 +0200256 bool has_pex_clkreq_en;
257 bool has_pex_bias_ctrl;
258 bool has_intr_prsnt_sense;
Jay Agarwal94716cd2013-08-09 16:49:24 +0200259 bool has_cml_clk;
Thierry Reding7f1f0542014-08-26 17:11:38 +0200260 bool has_gen2;
Thierry Reding76245ca2016-11-25 11:57:14 +0100261 bool force_pca_enable;
Manikanta Maddireddy9cea5132017-09-27 17:28:35 +0530262 bool program_uphy;
Jay Agarwal94716cd2013-08-09 16:49:24 +0200263};
264
Yijing Wangc2791b82014-11-11 17:45:45 -0700265static inline struct tegra_msi *to_tegra_msi(struct msi_controller *chip)
Thierry Redingd1523b52013-08-09 16:49:19 +0200266{
267 return container_of(chip, struct tegra_msi, chip);
268}
269
270struct tegra_pcie {
271 struct device *dev;
272
273 void __iomem *pads;
274 void __iomem *afi;
Vidya Sagar1fd92922017-12-20 21:36:07 +0100275 void __iomem *cfg;
Thierry Redingd1523b52013-08-09 16:49:19 +0200276 int irq;
277
Vidya Sagar1fd92922017-12-20 21:36:07 +0100278 struct resource cs;
Thierry Redingd1523b52013-08-09 16:49:19 +0200279 struct resource io;
Thierry Reding51067872014-11-27 09:54:09 +0100280 struct resource pio;
Thierry Redingd1523b52013-08-09 16:49:19 +0200281 struct resource mem;
282 struct resource prefetch;
283 struct resource busn;
284
Thierry Reding56e75e22016-02-09 15:52:32 +0100285 struct {
286 resource_size_t mem;
287 resource_size_t io;
288 } offset;
289
Thierry Redingd1523b52013-08-09 16:49:19 +0200290 struct clk *pex_clk;
291 struct clk *afi_clk;
Thierry Redingd1523b52013-08-09 16:49:19 +0200292 struct clk *pll_e;
Jay Agarwal94716cd2013-08-09 16:49:24 +0200293 struct clk *cml_clk;
Thierry Redingd1523b52013-08-09 16:49:19 +0200294
Stephen Warren3127a6b2013-11-06 15:56:58 -0700295 struct reset_control *pex_rst;
296 struct reset_control *afi_rst;
297 struct reset_control *pcie_xrst;
298
Thierry Reding6fe7c182015-11-11 18:25:59 +0100299 bool legacy_phy;
Thierry Reding7f1f0542014-08-26 17:11:38 +0200300 struct phy *phy;
301
Thierry Redingd1523b52013-08-09 16:49:19 +0200302 struct tegra_msi msi;
303
304 struct list_head ports;
Thierry Redingd1523b52013-08-09 16:49:19 +0200305 u32 xbar_config;
306
Thierry Reding077fb152014-05-28 16:49:13 +0200307 struct regulator_bulk_data *supplies;
308 unsigned int num_supplies;
Jay Agarwal94716cd2013-08-09 16:49:24 +0200309
Thierry Redinga7fbae22016-08-15 17:31:31 +0200310 const struct tegra_pcie_soc *soc;
Thierry Reding2cb989f2014-07-22 12:30:46 -0600311 struct dentry *debugfs;
Thierry Redingd1523b52013-08-09 16:49:19 +0200312};
313
314struct tegra_pcie_port {
315 struct tegra_pcie *pcie;
Thierry Reding6fe7c182015-11-11 18:25:59 +0100316 struct device_node *np;
Thierry Redingd1523b52013-08-09 16:49:19 +0200317 struct list_head list;
318 struct resource regs;
319 void __iomem *base;
320 unsigned int index;
321 unsigned int lanes;
Thierry Reding6fe7c182015-11-11 18:25:59 +0100322
323 struct phy **phys;
Thierry Redingd1523b52013-08-09 16:49:19 +0200324};
325
326struct tegra_pcie_bus {
Thierry Redingd1523b52013-08-09 16:49:19 +0200327 struct list_head list;
328 unsigned int nr;
329};
330
Thierry Redingd1523b52013-08-09 16:49:19 +0200331static inline void afi_writel(struct tegra_pcie *pcie, u32 value,
332 unsigned long offset)
333{
334 writel(value, pcie->afi + offset);
335}
336
337static inline u32 afi_readl(struct tegra_pcie *pcie, unsigned long offset)
338{
339 return readl(pcie->afi + offset);
340}
341
342static inline void pads_writel(struct tegra_pcie *pcie, u32 value,
343 unsigned long offset)
344{
345 writel(value, pcie->pads + offset);
346}
347
348static inline u32 pads_readl(struct tegra_pcie *pcie, unsigned long offset)
349{
350 return readl(pcie->pads + offset);
351}
352
353/*
354 * The configuration space mapping on Tegra is somewhat similar to the ECAM
355 * defined by PCIe. However it deviates a bit in how the 4 bits for extended
356 * register accesses are mapped:
357 *
358 * [27:24] extended register number
359 * [23:16] bus number
360 * [15:11] device number
361 * [10: 8] function number
362 * [ 7: 0] register number
363 *
364 * Mapping the whole extended configuration space would require 256 MiB of
365 * virtual address space, only a small part of which will actually be used.
Thierry Redingd1523b52013-08-09 16:49:19 +0200366 *
Vidya Sagar1fd92922017-12-20 21:36:07 +0100367 * To work around this, a 4 KiB region is used to generate the required
368 * configuration transaction with relevant B:D:F and register offset values.
369 * This is achieved by dynamically programming base address and size of
370 * AFI_AXI_BAR used for end point config space mapping to make sure that the
371 * address (access to which generates correct config transaction) falls in
372 * this 4 KiB region.
Thierry Redingd1523b52013-08-09 16:49:19 +0200373 */
Vidya Sagar1fd92922017-12-20 21:36:07 +0100374static unsigned int tegra_pcie_conf_offset(u8 bus, unsigned int devfn,
375 unsigned int where)
Thierry Redingd1523b52013-08-09 16:49:19 +0200376{
Vidya Sagar1fd92922017-12-20 21:36:07 +0100377 return ((where & 0xf00) << 16) | (bus << 16) | (PCI_SLOT(devfn) << 11) |
378 (PCI_FUNC(devfn) << 8) | (where & 0xff);
Thierry Redingb4d18d72016-02-09 15:30:48 +0100379}
380
381static void __iomem *tegra_pcie_map_bus(struct pci_bus *bus,
382 unsigned int devfn,
383 int where)
Thierry Redingd1523b52013-08-09 16:49:19 +0200384{
Manikanta Maddireddy78243ff2018-01-11 11:38:03 +0530385 struct tegra_pcie *pcie = bus->sysdata;
Thierry Redingd1523b52013-08-09 16:49:19 +0200386 void __iomem *addr = NULL;
387
388 if (bus->number == 0) {
389 unsigned int slot = PCI_SLOT(devfn);
390 struct tegra_pcie_port *port;
391
392 list_for_each_entry(port, &pcie->ports, list) {
393 if (port->index + 1 == slot) {
394 addr = port->base + (where & ~3);
395 break;
396 }
397 }
398 } else {
Vidya Sagar1fd92922017-12-20 21:36:07 +0100399 unsigned int offset;
400 u32 base;
Thierry Redingb4d18d72016-02-09 15:30:48 +0100401
Vidya Sagar1fd92922017-12-20 21:36:07 +0100402 offset = tegra_pcie_conf_offset(bus->number, devfn, where);
Thierry Redingb4d18d72016-02-09 15:30:48 +0100403
Vidya Sagar1fd92922017-12-20 21:36:07 +0100404 /* move 4 KiB window to offset within the FPCI region */
405 base = 0xfe100000 + ((offset & ~(SZ_4K - 1)) >> 8);
406 afi_writel(pcie, base, AFI_FPCI_BAR0);
Thierry Redingd1523b52013-08-09 16:49:19 +0200407
Vidya Sagar1fd92922017-12-20 21:36:07 +0100408 /* move to correct offset within the 4 KiB page */
409 addr = pcie->cfg + (offset & (SZ_4K - 1));
Thierry Redingd1523b52013-08-09 16:49:19 +0200410 }
411
412 return addr;
413}
414
Thierry Redingb6cfe8b2017-09-22 23:18:41 -0700415static int tegra_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
416 int where, int size, u32 *value)
417{
418 if (bus->number == 0)
419 return pci_generic_config_read32(bus, devfn, where, size,
420 value);
421
422 return pci_generic_config_read(bus, devfn, where, size, value);
423}
424
425static int tegra_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
426 int where, int size, u32 value)
427{
428 if (bus->number == 0)
429 return pci_generic_config_write32(bus, devfn, where, size,
430 value);
431
432 return pci_generic_config_write(bus, devfn, where, size, value);
433}
434
Thierry Redingd1523b52013-08-09 16:49:19 +0200435static struct pci_ops tegra_pcie_ops = {
Thierry Redingb4d18d72016-02-09 15:30:48 +0100436 .map_bus = tegra_pcie_map_bus,
Thierry Redingb6cfe8b2017-09-22 23:18:41 -0700437 .read = tegra_pcie_config_read,
438 .write = tegra_pcie_config_write,
Thierry Redingd1523b52013-08-09 16:49:19 +0200439};
440
441static unsigned long tegra_pcie_port_get_pex_ctrl(struct tegra_pcie_port *port)
442{
443 unsigned long ret = 0;
444
445 switch (port->index) {
446 case 0:
447 ret = AFI_PEX0_CTRL;
448 break;
449
450 case 1:
451 ret = AFI_PEX1_CTRL;
452 break;
Jay Agarwal94716cd2013-08-09 16:49:24 +0200453
454 case 2:
455 ret = AFI_PEX2_CTRL;
456 break;
Thierry Redingd1523b52013-08-09 16:49:19 +0200457 }
458
459 return ret;
460}
461
462static void tegra_pcie_port_reset(struct tegra_pcie_port *port)
463{
464 unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
465 unsigned long value;
466
467 /* pulse reset signal */
468 value = afi_readl(port->pcie, ctrl);
469 value &= ~AFI_PEX_CTRL_RST;
470 afi_writel(port->pcie, value, ctrl);
471
472 usleep_range(1000, 2000);
473
474 value = afi_readl(port->pcie, ctrl);
475 value |= AFI_PEX_CTRL_RST;
476 afi_writel(port->pcie, value, ctrl);
477}
478
479static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
480{
481 unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
Thierry Redinga7fbae22016-08-15 17:31:31 +0200482 const struct tegra_pcie_soc *soc = port->pcie->soc;
Thierry Redingd1523b52013-08-09 16:49:19 +0200483 unsigned long value;
484
485 /* enable reference clock */
486 value = afi_readl(port->pcie, ctrl);
487 value |= AFI_PEX_CTRL_REFCLK_EN;
Jay Agarwal94716cd2013-08-09 16:49:24 +0200488
489 if (soc->has_pex_clkreq_en)
490 value |= AFI_PEX_CTRL_CLKREQ_EN;
491
Thierry Reding7f1f0542014-08-26 17:11:38 +0200492 value |= AFI_PEX_CTRL_OVERRIDE_EN;
493
Thierry Redingd1523b52013-08-09 16:49:19 +0200494 afi_writel(port->pcie, value, ctrl);
495
496 tegra_pcie_port_reset(port);
Thierry Reding76245ca2016-11-25 11:57:14 +0100497
498 if (soc->force_pca_enable) {
499 value = readl(port->base + RP_VEND_CTL2);
500 value |= RP_VEND_CTL2_PCA_ENABLE;
501 writel(value, port->base + RP_VEND_CTL2);
502 }
Thierry Redingd1523b52013-08-09 16:49:19 +0200503}
504
505static void tegra_pcie_port_disable(struct tegra_pcie_port *port)
506{
507 unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
Thierry Redinga7fbae22016-08-15 17:31:31 +0200508 const struct tegra_pcie_soc *soc = port->pcie->soc;
Thierry Redingd1523b52013-08-09 16:49:19 +0200509 unsigned long value;
510
511 /* assert port reset */
512 value = afi_readl(port->pcie, ctrl);
513 value &= ~AFI_PEX_CTRL_RST;
514 afi_writel(port->pcie, value, ctrl);
515
516 /* disable reference clock */
517 value = afi_readl(port->pcie, ctrl);
Thierry Reding0d20d622014-08-26 17:11:35 +0200518
519 if (soc->has_pex_clkreq_en)
520 value &= ~AFI_PEX_CTRL_CLKREQ_EN;
521
Thierry Redingd1523b52013-08-09 16:49:19 +0200522 value &= ~AFI_PEX_CTRL_REFCLK_EN;
523 afi_writel(port->pcie, value, ctrl);
524}
525
526static void tegra_pcie_port_free(struct tegra_pcie_port *port)
527{
528 struct tegra_pcie *pcie = port->pcie;
Bjorn Helgaasa581fa92016-10-06 13:43:04 -0500529 struct device *dev = pcie->dev;
Thierry Redingd1523b52013-08-09 16:49:19 +0200530
Bjorn Helgaasa581fa92016-10-06 13:43:04 -0500531 devm_iounmap(dev, port->base);
532 devm_release_mem_region(dev, port->regs.start,
Thierry Redingd1523b52013-08-09 16:49:19 +0200533 resource_size(&port->regs));
534 list_del(&port->list);
Bjorn Helgaasa581fa92016-10-06 13:43:04 -0500535 devm_kfree(dev, port);
Thierry Redingd1523b52013-08-09 16:49:19 +0200536}
537
Thierry Redingd1523b52013-08-09 16:49:19 +0200538/* Tegra PCIE root complex wrongly reports device class */
539static void tegra_pcie_fixup_class(struct pci_dev *dev)
540{
541 dev->class = PCI_CLASS_BRIDGE_PCI << 8;
542}
543DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0bf0, tegra_pcie_fixup_class);
544DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_fixup_class);
Jay Agarwal94716cd2013-08-09 16:49:24 +0200545DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0e1c, tegra_pcie_fixup_class);
546DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0e1d, tegra_pcie_fixup_class);
Thierry Redingd1523b52013-08-09 16:49:19 +0200547
548/* Tegra PCIE requires relaxed ordering */
549static void tegra_pcie_relax_enable(struct pci_dev *dev)
550{
551 pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_RELAX_EN);
552}
553DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable);
554
Arnd Bergmann76f25412016-11-25 11:57:12 +0100555static int tegra_pcie_request_resources(struct tegra_pcie *pcie)
Thierry Redingd1523b52013-08-09 16:49:19 +0200556{
Arnd Bergmann76f25412016-11-25 11:57:12 +0100557 struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
558 struct list_head *windows = &host->windows;
Bjorn Helgaasa581fa92016-10-06 13:43:04 -0500559 struct device *dev = pcie->dev;
Thierry Reding41534e52014-08-01 14:15:11 +0200560 int err;
561
Arnd Bergmann76f25412016-11-25 11:57:12 +0100562 pci_add_resource_offset(windows, &pcie->pio, pcie->offset.io);
563 pci_add_resource_offset(windows, &pcie->mem, pcie->offset.mem);
564 pci_add_resource_offset(windows, &pcie->prefetch, pcie->offset.mem);
565 pci_add_resource(windows, &pcie->busn);
Thierry Reding56e75e22016-02-09 15:52:32 +0100566
Arnd Bergmann76f25412016-11-25 11:57:12 +0100567 err = devm_request_pci_bus_resources(dev, windows);
Manikanta Maddireddy527557a2018-02-28 15:30:32 +0530568 if (err < 0) {
569 pci_free_resource_list(windows);
Thierry Reding56e75e22016-02-09 15:52:32 +0100570 return err;
Manikanta Maddireddy527557a2018-02-28 15:30:32 +0530571 }
Thierry Reding56e75e22016-02-09 15:52:32 +0100572
Arnd Bergmann76f25412016-11-25 11:57:12 +0100573 pci_remap_iospace(&pcie->pio, pcie->io.start);
Lorenzo Pieralisi13f392e2016-08-15 17:50:46 +0100574
Arnd Bergmann76f25412016-11-25 11:57:12 +0100575 return 0;
Thierry Redingd1523b52013-08-09 16:49:19 +0200576}
577
Manikanta Maddireddy527557a2018-02-28 15:30:32 +0530578static void tegra_pcie_free_resources(struct tegra_pcie *pcie)
579{
580 struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
581 struct list_head *windows = &host->windows;
582
583 pci_unmap_iospace(&pcie->pio);
584 pci_free_resource_list(windows);
585}
586
Thierry Redingd1523b52013-08-09 16:49:19 +0200587static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
588{
Manikanta Maddireddy78243ff2018-01-11 11:38:03 +0530589 struct tegra_pcie *pcie = pdev->bus->sysdata;
Lucas Stachf5d33522014-04-16 10:24:32 -0600590 int irq;
Thierry Redingd1523b52013-08-09 16:49:19 +0200591
Stephen Warrenb4f17372013-05-06 14:19:19 -0600592 tegra_cpuidle_pcie_irqs_in_use();
593
Lucas Stachf5d33522014-04-16 10:24:32 -0600594 irq = of_irq_parse_and_map_pci(pdev, slot, pin);
595 if (!irq)
596 irq = pcie->irq;
597
598 return irq;
Thierry Redingd1523b52013-08-09 16:49:19 +0200599}
600
Thierry Redingd1523b52013-08-09 16:49:19 +0200601static irqreturn_t tegra_pcie_isr(int irq, void *arg)
602{
603 const char *err_msg[] = {
604 "Unknown",
605 "AXI slave error",
606 "AXI decode error",
607 "Target abort",
608 "Master abort",
609 "Invalid write",
Thierry Reding7f1f0542014-08-26 17:11:38 +0200610 "Legacy interrupt",
Thierry Redingd1523b52013-08-09 16:49:19 +0200611 "Response decoding error",
612 "AXI response decoding error",
613 "Transaction timeout",
Thierry Reding7f1f0542014-08-26 17:11:38 +0200614 "Slot present pin change",
615 "Slot clock request change",
616 "TMS clock ramp change",
617 "TMS ready for power down",
618 "Peer2Peer error",
Thierry Redingd1523b52013-08-09 16:49:19 +0200619 };
620 struct tegra_pcie *pcie = arg;
Bjorn Helgaasa581fa92016-10-06 13:43:04 -0500621 struct device *dev = pcie->dev;
Thierry Redingd1523b52013-08-09 16:49:19 +0200622 u32 code, signature;
623
624 code = afi_readl(pcie, AFI_INTR_CODE) & AFI_INTR_CODE_MASK;
625 signature = afi_readl(pcie, AFI_INTR_SIGNATURE);
626 afi_writel(pcie, 0, AFI_INTR_CODE);
627
628 if (code == AFI_INTR_LEGACY)
629 return IRQ_NONE;
630
631 if (code >= ARRAY_SIZE(err_msg))
632 code = 0;
633
634 /*
635 * do not pollute kernel log with master abort reports since they
636 * happen a lot during enumeration
637 */
638 if (code == AFI_INTR_MASTER_ABORT)
Bjorn Helgaasa581fa92016-10-06 13:43:04 -0500639 dev_dbg(dev, "%s, signature: %08x\n", err_msg[code], signature);
Thierry Redingd1523b52013-08-09 16:49:19 +0200640 else
Bjorn Helgaasa581fa92016-10-06 13:43:04 -0500641 dev_err(dev, "%s, signature: %08x\n", err_msg[code], signature);
Thierry Redingd1523b52013-08-09 16:49:19 +0200642
643 if (code == AFI_INTR_TARGET_ABORT || code == AFI_INTR_MASTER_ABORT ||
644 code == AFI_INTR_FPCI_DECODE_ERROR) {
645 u32 fpci = afi_readl(pcie, AFI_UPPER_FPCI_ADDRESS) & 0xff;
646 u64 address = (u64)fpci << 32 | (signature & 0xfffffffc);
647
648 if (code == AFI_INTR_MASTER_ABORT)
Bjorn Helgaasa581fa92016-10-06 13:43:04 -0500649 dev_dbg(dev, " FPCI address: %10llx\n", address);
Thierry Redingd1523b52013-08-09 16:49:19 +0200650 else
Bjorn Helgaasa581fa92016-10-06 13:43:04 -0500651 dev_err(dev, " FPCI address: %10llx\n", address);
Thierry Redingd1523b52013-08-09 16:49:19 +0200652 }
653
654 return IRQ_HANDLED;
655}
656
657/*
658 * FPCI map is as follows:
659 * - 0xfdfc000000: I/O space
660 * - 0xfdfe000000: type 0 configuration space
661 * - 0xfdff000000: type 1 configuration space
662 * - 0xfe00000000: type 0 extended configuration space
663 * - 0xfe10000000: type 1 extended configuration space
664 */
665static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
666{
667 u32 fpci_bar, size, axi_address;
668
669 /* Bar 0: type 1 extended configuration space */
Vidya Sagar1fd92922017-12-20 21:36:07 +0100670 size = resource_size(&pcie->cs);
671 afi_writel(pcie, pcie->cs.start, AFI_AXI_BAR0_START);
Thierry Redingd1523b52013-08-09 16:49:19 +0200672 afi_writel(pcie, size >> 12, AFI_AXI_BAR0_SZ);
Thierry Redingd1523b52013-08-09 16:49:19 +0200673
674 /* Bar 1: downstream IO bar */
675 fpci_bar = 0xfdfc0000;
676 size = resource_size(&pcie->io);
Thierry Reding51067872014-11-27 09:54:09 +0100677 axi_address = pcie->io.start;
Thierry Redingd1523b52013-08-09 16:49:19 +0200678 afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
679 afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
680 afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
681
682 /* Bar 2: prefetchable memory BAR */
683 fpci_bar = (((pcie->prefetch.start >> 12) & 0x0fffffff) << 4) | 0x1;
684 size = resource_size(&pcie->prefetch);
685 axi_address = pcie->prefetch.start;
686 afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
687 afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
688 afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
689
690 /* Bar 3: non prefetchable memory BAR */
691 fpci_bar = (((pcie->mem.start >> 12) & 0x0fffffff) << 4) | 0x1;
692 size = resource_size(&pcie->mem);
693 axi_address = pcie->mem.start;
694 afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
695 afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
696 afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
697
698 /* NULL out the remaining BARs as they are not used */
699 afi_writel(pcie, 0, AFI_AXI_BAR4_START);
700 afi_writel(pcie, 0, AFI_AXI_BAR4_SZ);
701 afi_writel(pcie, 0, AFI_FPCI_BAR4);
702
703 afi_writel(pcie, 0, AFI_AXI_BAR5_START);
704 afi_writel(pcie, 0, AFI_AXI_BAR5_SZ);
705 afi_writel(pcie, 0, AFI_FPCI_BAR5);
706
707 /* map all upstream transactions as uncached */
Thierry Redinge32faa32016-02-09 15:52:33 +0100708 afi_writel(pcie, 0, AFI_CACHE_BAR0_ST);
Thierry Redingd1523b52013-08-09 16:49:19 +0200709 afi_writel(pcie, 0, AFI_CACHE_BAR0_SZ);
710 afi_writel(pcie, 0, AFI_CACHE_BAR1_ST);
711 afi_writel(pcie, 0, AFI_CACHE_BAR1_SZ);
712
713 /* MSI translations are setup only when needed */
714 afi_writel(pcie, 0, AFI_MSI_FPCI_BAR_ST);
715 afi_writel(pcie, 0, AFI_MSI_BAR_SZ);
716 afi_writel(pcie, 0, AFI_MSI_AXI_BAR_ST);
717 afi_writel(pcie, 0, AFI_MSI_BAR_SZ);
718}
719
Thierry Reding7f1f0542014-08-26 17:11:38 +0200720static int tegra_pcie_pll_wait(struct tegra_pcie *pcie, unsigned long timeout)
Thierry Redingd1523b52013-08-09 16:49:19 +0200721{
Thierry Redinga7fbae22016-08-15 17:31:31 +0200722 const struct tegra_pcie_soc *soc = pcie->soc;
Thierry Reding7f1f0542014-08-26 17:11:38 +0200723 u32 value;
Thierry Redingd1523b52013-08-09 16:49:19 +0200724
Thierry Reding7f1f0542014-08-26 17:11:38 +0200725 timeout = jiffies + msecs_to_jiffies(timeout);
Jay Agarwal94716cd2013-08-09 16:49:24 +0200726
Thierry Reding7f1f0542014-08-26 17:11:38 +0200727 while (time_before(jiffies, timeout)) {
728 value = pads_readl(pcie, soc->pads_pll_ctl);
729 if (value & PADS_PLL_CTL_LOCKDET)
730 return 0;
731 }
Thierry Redingd1523b52013-08-09 16:49:19 +0200732
Thierry Reding7f1f0542014-08-26 17:11:38 +0200733 return -ETIMEDOUT;
734}
Thierry Redingd1523b52013-08-09 16:49:19 +0200735
Thierry Reding7f1f0542014-08-26 17:11:38 +0200736static int tegra_pcie_phy_enable(struct tegra_pcie *pcie)
737{
Bjorn Helgaasa581fa92016-10-06 13:43:04 -0500738 struct device *dev = pcie->dev;
Thierry Redinga7fbae22016-08-15 17:31:31 +0200739 const struct tegra_pcie_soc *soc = pcie->soc;
Thierry Reding7f1f0542014-08-26 17:11:38 +0200740 u32 value;
741 int err;
Thierry Redingd1523b52013-08-09 16:49:19 +0200742
Bjorn Helgaasf7625982013-11-14 11:28:18 -0700743 /* initialize internal PHY, enable up to 16 PCIE lanes */
Thierry Redingd1523b52013-08-09 16:49:19 +0200744 pads_writel(pcie, 0x0, PADS_CTL_SEL);
745
746 /* override IDDQ to 1 on all 4 lanes */
747 value = pads_readl(pcie, PADS_CTL);
748 value |= PADS_CTL_IDDQ_1L;
749 pads_writel(pcie, value, PADS_CTL);
750
751 /*
752 * Set up PHY PLL inputs select PLLE output as refclock,
753 * set TX ref sel to div10 (not div5).
754 */
Jay Agarwal94716cd2013-08-09 16:49:24 +0200755 value = pads_readl(pcie, soc->pads_pll_ctl);
Thierry Redingd1523b52013-08-09 16:49:19 +0200756 value &= ~(PADS_PLL_CTL_REFCLK_MASK | PADS_PLL_CTL_TXCLKREF_MASK);
Jay Agarwal94716cd2013-08-09 16:49:24 +0200757 value |= PADS_PLL_CTL_REFCLK_INTERNAL_CML | soc->tx_ref_sel;
758 pads_writel(pcie, value, soc->pads_pll_ctl);
Thierry Redingd1523b52013-08-09 16:49:19 +0200759
Eric Yuenec732762014-08-26 17:11:37 +0200760 /* reset PLL */
761 value = pads_readl(pcie, soc->pads_pll_ctl);
762 value &= ~PADS_PLL_CTL_RST_B4SM;
763 pads_writel(pcie, value, soc->pads_pll_ctl);
764
765 usleep_range(20, 100);
766
Thierry Redingd1523b52013-08-09 16:49:19 +0200767 /* take PLL out of reset */
Jay Agarwal94716cd2013-08-09 16:49:24 +0200768 value = pads_readl(pcie, soc->pads_pll_ctl);
Thierry Redingd1523b52013-08-09 16:49:19 +0200769 value |= PADS_PLL_CTL_RST_B4SM;
Jay Agarwal94716cd2013-08-09 16:49:24 +0200770 pads_writel(pcie, value, soc->pads_pll_ctl);
Thierry Redingd1523b52013-08-09 16:49:19 +0200771
Thierry Redingd1523b52013-08-09 16:49:19 +0200772 /* wait for the PLL to lock */
Thierry Reding7f1f0542014-08-26 17:11:38 +0200773 err = tegra_pcie_pll_wait(pcie, 500);
774 if (err < 0) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -0500775 dev_err(dev, "PLL failed to lock: %d\n", err);
Thierry Reding7f1f0542014-08-26 17:11:38 +0200776 return err;
777 }
Thierry Redingd1523b52013-08-09 16:49:19 +0200778
779 /* turn off IDDQ override */
780 value = pads_readl(pcie, PADS_CTL);
781 value &= ~PADS_CTL_IDDQ_1L;
782 pads_writel(pcie, value, PADS_CTL);
783
784 /* enable TX/RX data */
785 value = pads_readl(pcie, PADS_CTL);
786 value |= PADS_CTL_TX_DATA_EN_1L | PADS_CTL_RX_DATA_EN_1L;
787 pads_writel(pcie, value, PADS_CTL);
788
Thierry Reding7f1f0542014-08-26 17:11:38 +0200789 return 0;
790}
791
Thierry Reding6fe7c182015-11-11 18:25:59 +0100792static int tegra_pcie_phy_disable(struct tegra_pcie *pcie)
793{
Thierry Redinga7fbae22016-08-15 17:31:31 +0200794 const struct tegra_pcie_soc *soc = pcie->soc;
Thierry Reding6fe7c182015-11-11 18:25:59 +0100795 u32 value;
796
797 /* disable TX/RX data */
798 value = pads_readl(pcie, PADS_CTL);
799 value &= ~(PADS_CTL_TX_DATA_EN_1L | PADS_CTL_RX_DATA_EN_1L);
800 pads_writel(pcie, value, PADS_CTL);
801
802 /* override IDDQ */
803 value = pads_readl(pcie, PADS_CTL);
804 value |= PADS_CTL_IDDQ_1L;
Bjorn Helgaas8dd99bc2016-10-05 16:04:13 -0500805 pads_writel(pcie, value, PADS_CTL);
Thierry Reding6fe7c182015-11-11 18:25:59 +0100806
807 /* reset PLL */
808 value = pads_readl(pcie, soc->pads_pll_ctl);
809 value &= ~PADS_PLL_CTL_RST_B4SM;
810 pads_writel(pcie, value, soc->pads_pll_ctl);
811
812 usleep_range(20, 100);
813
814 return 0;
815}
816
817static int tegra_pcie_port_phy_power_on(struct tegra_pcie_port *port)
818{
819 struct device *dev = port->pcie->dev;
820 unsigned int i;
821 int err;
822
823 for (i = 0; i < port->lanes; i++) {
824 err = phy_power_on(port->phys[i]);
825 if (err < 0) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -0500826 dev_err(dev, "failed to power on PHY#%u: %d\n", i, err);
Thierry Reding6fe7c182015-11-11 18:25:59 +0100827 return err;
828 }
829 }
830
831 return 0;
832}
833
834static int tegra_pcie_port_phy_power_off(struct tegra_pcie_port *port)
835{
836 struct device *dev = port->pcie->dev;
837 unsigned int i;
838 int err;
839
840 for (i = 0; i < port->lanes; i++) {
841 err = phy_power_off(port->phys[i]);
842 if (err < 0) {
843 dev_err(dev, "failed to power off PHY#%u: %d\n", i,
844 err);
845 return err;
846 }
847 }
848
849 return 0;
850}
851
852static int tegra_pcie_phy_power_on(struct tegra_pcie *pcie)
853{
Bjorn Helgaasa581fa92016-10-06 13:43:04 -0500854 struct device *dev = pcie->dev;
Thierry Redinga7fbae22016-08-15 17:31:31 +0200855 const struct tegra_pcie_soc *soc = pcie->soc;
Thierry Reding6fe7c182015-11-11 18:25:59 +0100856 struct tegra_pcie_port *port;
857 int err;
858
859 if (pcie->legacy_phy) {
860 if (pcie->phy)
861 err = phy_power_on(pcie->phy);
862 else
863 err = tegra_pcie_phy_enable(pcie);
864
865 if (err < 0)
Bjorn Helgaasa581fa92016-10-06 13:43:04 -0500866 dev_err(dev, "failed to power on PHY: %d\n", err);
Thierry Reding6fe7c182015-11-11 18:25:59 +0100867
868 return err;
869 }
870
871 list_for_each_entry(port, &pcie->ports, list) {
872 err = tegra_pcie_port_phy_power_on(port);
873 if (err < 0) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -0500874 dev_err(dev,
Thierry Reding6fe7c182015-11-11 18:25:59 +0100875 "failed to power on PCIe port %u PHY: %d\n",
876 port->index, err);
877 return err;
878 }
879 }
880
Stephen Warrencf5d31802016-07-25 16:02:21 -0500881 /* Configure the reference clock driver */
Stephen Warrenf8144302016-07-25 16:02:27 -0500882 pads_writel(pcie, soc->pads_refclk_cfg0, PADS_REFCLK_CFG0);
Stephen Warrencf5d31802016-07-25 16:02:21 -0500883
884 if (soc->num_ports > 2)
Stephen Warrenf8144302016-07-25 16:02:27 -0500885 pads_writel(pcie, soc->pads_refclk_cfg1, PADS_REFCLK_CFG1);
Stephen Warrencf5d31802016-07-25 16:02:21 -0500886
Thierry Reding6fe7c182015-11-11 18:25:59 +0100887 return 0;
888}
889
890static int tegra_pcie_phy_power_off(struct tegra_pcie *pcie)
891{
Bjorn Helgaasa581fa92016-10-06 13:43:04 -0500892 struct device *dev = pcie->dev;
Thierry Reding6fe7c182015-11-11 18:25:59 +0100893 struct tegra_pcie_port *port;
894 int err;
895
896 if (pcie->legacy_phy) {
897 if (pcie->phy)
898 err = phy_power_off(pcie->phy);
899 else
900 err = tegra_pcie_phy_disable(pcie);
901
902 if (err < 0)
Bjorn Helgaasa581fa92016-10-06 13:43:04 -0500903 dev_err(dev, "failed to power off PHY: %d\n", err);
Thierry Reding6fe7c182015-11-11 18:25:59 +0100904
905 return err;
906 }
907
908 list_for_each_entry(port, &pcie->ports, list) {
909 err = tegra_pcie_port_phy_power_off(port);
910 if (err < 0) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -0500911 dev_err(dev,
Thierry Reding6fe7c182015-11-11 18:25:59 +0100912 "failed to power off PCIe port %u PHY: %d\n",
913 port->index, err);
914 return err;
915 }
916 }
917
918 return 0;
919}
920
Thierry Reding7f1f0542014-08-26 17:11:38 +0200921static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
922{
Bjorn Helgaasa581fa92016-10-06 13:43:04 -0500923 struct device *dev = pcie->dev;
Thierry Redinga7fbae22016-08-15 17:31:31 +0200924 const struct tegra_pcie_soc *soc = pcie->soc;
Thierry Reding7f1f0542014-08-26 17:11:38 +0200925 struct tegra_pcie_port *port;
926 unsigned long value;
927 int err;
928
929 /* enable PLL power down */
930 if (pcie->phy) {
931 value = afi_readl(pcie, AFI_PLLE_CONTROL);
932 value &= ~AFI_PLLE_CONTROL_BYPASS_PADS2PLLE_CONTROL;
933 value |= AFI_PLLE_CONTROL_PADS2PLLE_CONTROL_EN;
934 afi_writel(pcie, value, AFI_PLLE_CONTROL);
935 }
936
937 /* power down PCIe slot clock bias pad */
938 if (soc->has_pex_bias_ctrl)
939 afi_writel(pcie, 0, AFI_PEXBIAS_CTRL_0);
940
941 /* configure mode and disable all ports */
942 value = afi_readl(pcie, AFI_PCIE_CONFIG);
943 value &= ~AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK;
944 value |= AFI_PCIE_CONFIG_PCIE_DISABLE_ALL | pcie->xbar_config;
945
946 list_for_each_entry(port, &pcie->ports, list)
947 value &= ~AFI_PCIE_CONFIG_PCIE_DISABLE(port->index);
948
949 afi_writel(pcie, value, AFI_PCIE_CONFIG);
950
951 if (soc->has_gen2) {
952 value = afi_readl(pcie, AFI_FUSE);
953 value &= ~AFI_FUSE_PCIE_T0_GEN2_DIS;
954 afi_writel(pcie, value, AFI_FUSE);
955 } else {
956 value = afi_readl(pcie, AFI_FUSE);
957 value |= AFI_FUSE_PCIE_T0_GEN2_DIS;
958 afi_writel(pcie, value, AFI_FUSE);
959 }
960
Manikanta Maddireddy9cea5132017-09-27 17:28:35 +0530961 if (soc->program_uphy) {
962 err = tegra_pcie_phy_power_on(pcie);
963 if (err < 0) {
964 dev_err(dev, "failed to power on PHY(s): %d\n", err);
965 return err;
966 }
Thierry Reding7f1f0542014-08-26 17:11:38 +0200967 }
968
Thierry Redingd1523b52013-08-09 16:49:19 +0200969 /* take the PCIe interface module out of reset */
Stephen Warren3127a6b2013-11-06 15:56:58 -0700970 reset_control_deassert(pcie->pcie_xrst);
Thierry Redingd1523b52013-08-09 16:49:19 +0200971
972 /* finally enable PCIe */
973 value = afi_readl(pcie, AFI_CONFIGURATION);
974 value |= AFI_CONFIGURATION_EN_FPCI;
975 afi_writel(pcie, value, AFI_CONFIGURATION);
976
977 value = AFI_INTR_EN_INI_SLVERR | AFI_INTR_EN_INI_DECERR |
978 AFI_INTR_EN_TGT_SLVERR | AFI_INTR_EN_TGT_DECERR |
979 AFI_INTR_EN_TGT_WRERR | AFI_INTR_EN_DFPCI_DECERR;
Jay Agarwal94716cd2013-08-09 16:49:24 +0200980
981 if (soc->has_intr_prsnt_sense)
982 value |= AFI_INTR_EN_PRSNT_SENSE;
983
Thierry Redingd1523b52013-08-09 16:49:19 +0200984 afi_writel(pcie, value, AFI_AFI_INTR_ENABLE);
985 afi_writel(pcie, 0xffffffff, AFI_SM_INTR_ENABLE);
986
987 /* don't enable MSI for now, only when needed */
988 afi_writel(pcie, AFI_INTR_MASK_INT_MASK, AFI_INTR_MASK);
989
990 /* disable all exceptions */
991 afi_writel(pcie, 0, AFI_FPCI_ERROR_MASKS);
992
993 return 0;
994}
995
Manikanta Maddireddy527557a2018-02-28 15:30:32 +0530996static void tegra_pcie_disable_controller(struct tegra_pcie *pcie)
997{
998 int err;
999
1000 reset_control_assert(pcie->pcie_xrst);
1001
1002 if (pcie->soc->program_uphy) {
1003 err = tegra_pcie_phy_power_off(pcie);
1004 if (err < 0)
1005 dev_err(pcie->dev, "failed to power off PHY(s): %d\n",
1006 err);
1007 }
1008}
1009
Thierry Redingd1523b52013-08-09 16:49:19 +02001010static void tegra_pcie_power_off(struct tegra_pcie *pcie)
1011{
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001012 struct device *dev = pcie->dev;
Manikanta Maddireddy9cea5132017-09-27 17:28:35 +05301013 const struct tegra_pcie_soc *soc = pcie->soc;
Thierry Redingd1523b52013-08-09 16:49:19 +02001014 int err;
1015
Stephen Warren3127a6b2013-11-06 15:56:58 -07001016 reset_control_assert(pcie->afi_rst);
1017 reset_control_assert(pcie->pex_rst);
Thierry Redingd1523b52013-08-09 16:49:19 +02001018
Manikanta Maddireddy527557a2018-02-28 15:30:32 +05301019 clk_disable_unprepare(pcie->pll_e);
1020 if (soc->has_cml_clk)
1021 clk_disable_unprepare(pcie->cml_clk);
1022 clk_disable_unprepare(pcie->afi_clk);
1023 clk_disable_unprepare(pcie->pex_clk);
1024
Manikanta Maddireddy9cea5132017-09-27 17:28:35 +05301025 if (!dev->pm_domain)
1026 tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
Thierry Redingd1523b52013-08-09 16:49:19 +02001027
Thierry Reding077fb152014-05-28 16:49:13 +02001028 err = regulator_bulk_disable(pcie->num_supplies, pcie->supplies);
Thierry Redingd1523b52013-08-09 16:49:19 +02001029 if (err < 0)
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001030 dev_warn(dev, "failed to disable regulators: %d\n", err);
Thierry Redingd1523b52013-08-09 16:49:19 +02001031}
1032
1033static int tegra_pcie_power_on(struct tegra_pcie *pcie)
1034{
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001035 struct device *dev = pcie->dev;
Thierry Redinga7fbae22016-08-15 17:31:31 +02001036 const struct tegra_pcie_soc *soc = pcie->soc;
Thierry Redingd1523b52013-08-09 16:49:19 +02001037 int err;
1038
Stephen Warren3127a6b2013-11-06 15:56:58 -07001039 reset_control_assert(pcie->pcie_xrst);
1040 reset_control_assert(pcie->afi_rst);
1041 reset_control_assert(pcie->pex_rst);
Thierry Redingd1523b52013-08-09 16:49:19 +02001042
Manikanta Maddireddy9cea5132017-09-27 17:28:35 +05301043 if (!dev->pm_domain)
1044 tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
Thierry Redingd1523b52013-08-09 16:49:19 +02001045
1046 /* enable regulators */
Thierry Reding077fb152014-05-28 16:49:13 +02001047 err = regulator_bulk_enable(pcie->num_supplies, pcie->supplies);
1048 if (err < 0)
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001049 dev_err(dev, "failed to enable regulators: %d\n", err);
Jay Agarwal94716cd2013-08-09 16:49:24 +02001050
Manikanta Maddireddy9cea5132017-09-27 17:28:35 +05301051 if (dev->pm_domain) {
1052 err = clk_prepare_enable(pcie->pex_clk);
1053 if (err) {
1054 dev_err(dev, "failed to enable PEX clock: %d\n", err);
1055 return err;
1056 }
1057 reset_control_deassert(pcie->pex_rst);
1058 } else {
1059 err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE,
1060 pcie->pex_clk,
1061 pcie->pex_rst);
1062 if (err) {
1063 dev_err(dev, "powerup sequence failed: %d\n", err);
1064 return err;
1065 }
Thierry Redingd1523b52013-08-09 16:49:19 +02001066 }
1067
Stephen Warren3127a6b2013-11-06 15:56:58 -07001068 reset_control_deassert(pcie->afi_rst);
Thierry Redingd1523b52013-08-09 16:49:19 +02001069
1070 err = clk_prepare_enable(pcie->afi_clk);
1071 if (err < 0) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001072 dev_err(dev, "failed to enable AFI clock: %d\n", err);
Thierry Redingd1523b52013-08-09 16:49:19 +02001073 return err;
1074 }
1075
Jay Agarwal94716cd2013-08-09 16:49:24 +02001076 if (soc->has_cml_clk) {
1077 err = clk_prepare_enable(pcie->cml_clk);
1078 if (err < 0) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001079 dev_err(dev, "failed to enable CML clock: %d\n", err);
Jay Agarwal94716cd2013-08-09 16:49:24 +02001080 return err;
1081 }
1082 }
1083
Thierry Redingd1523b52013-08-09 16:49:19 +02001084 err = clk_prepare_enable(pcie->pll_e);
1085 if (err < 0) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001086 dev_err(dev, "failed to enable PLLE clock: %d\n", err);
Thierry Redingd1523b52013-08-09 16:49:19 +02001087 return err;
1088 }
1089
1090 return 0;
1091}
1092
1093static int tegra_pcie_clocks_get(struct tegra_pcie *pcie)
1094{
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001095 struct device *dev = pcie->dev;
Thierry Redinga7fbae22016-08-15 17:31:31 +02001096 const struct tegra_pcie_soc *soc = pcie->soc;
Jay Agarwal94716cd2013-08-09 16:49:24 +02001097
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001098 pcie->pex_clk = devm_clk_get(dev, "pex");
Thierry Redingd1523b52013-08-09 16:49:19 +02001099 if (IS_ERR(pcie->pex_clk))
1100 return PTR_ERR(pcie->pex_clk);
1101
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001102 pcie->afi_clk = devm_clk_get(dev, "afi");
Thierry Redingd1523b52013-08-09 16:49:19 +02001103 if (IS_ERR(pcie->afi_clk))
1104 return PTR_ERR(pcie->afi_clk);
1105
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001106 pcie->pll_e = devm_clk_get(dev, "pll_e");
Thierry Redingd1523b52013-08-09 16:49:19 +02001107 if (IS_ERR(pcie->pll_e))
1108 return PTR_ERR(pcie->pll_e);
1109
Jay Agarwal94716cd2013-08-09 16:49:24 +02001110 if (soc->has_cml_clk) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001111 pcie->cml_clk = devm_clk_get(dev, "cml");
Jay Agarwal94716cd2013-08-09 16:49:24 +02001112 if (IS_ERR(pcie->cml_clk))
1113 return PTR_ERR(pcie->cml_clk);
1114 }
1115
Thierry Redingd1523b52013-08-09 16:49:19 +02001116 return 0;
1117}
1118
Stephen Warren3127a6b2013-11-06 15:56:58 -07001119static int tegra_pcie_resets_get(struct tegra_pcie *pcie)
1120{
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001121 struct device *dev = pcie->dev;
1122
Philipp Zabel4b9cc2c2017-07-19 17:25:57 +02001123 pcie->pex_rst = devm_reset_control_get_exclusive(dev, "pex");
Stephen Warren3127a6b2013-11-06 15:56:58 -07001124 if (IS_ERR(pcie->pex_rst))
1125 return PTR_ERR(pcie->pex_rst);
1126
Philipp Zabel4b9cc2c2017-07-19 17:25:57 +02001127 pcie->afi_rst = devm_reset_control_get_exclusive(dev, "afi");
Stephen Warren3127a6b2013-11-06 15:56:58 -07001128 if (IS_ERR(pcie->afi_rst))
1129 return PTR_ERR(pcie->afi_rst);
1130
Philipp Zabel4b9cc2c2017-07-19 17:25:57 +02001131 pcie->pcie_xrst = devm_reset_control_get_exclusive(dev, "pcie_x");
Stephen Warren3127a6b2013-11-06 15:56:58 -07001132 if (IS_ERR(pcie->pcie_xrst))
1133 return PTR_ERR(pcie->pcie_xrst);
1134
1135 return 0;
1136}
1137
Thierry Reding6fe7c182015-11-11 18:25:59 +01001138static int tegra_pcie_phys_get_legacy(struct tegra_pcie *pcie)
1139{
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001140 struct device *dev = pcie->dev;
Thierry Reding6fe7c182015-11-11 18:25:59 +01001141 int err;
1142
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001143 pcie->phy = devm_phy_optional_get(dev, "pcie");
Thierry Reding6fe7c182015-11-11 18:25:59 +01001144 if (IS_ERR(pcie->phy)) {
1145 err = PTR_ERR(pcie->phy);
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001146 dev_err(dev, "failed to get PHY: %d\n", err);
Thierry Reding6fe7c182015-11-11 18:25:59 +01001147 return err;
1148 }
1149
1150 err = phy_init(pcie->phy);
1151 if (err < 0) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001152 dev_err(dev, "failed to initialize PHY: %d\n", err);
Thierry Reding6fe7c182015-11-11 18:25:59 +01001153 return err;
1154 }
1155
1156 pcie->legacy_phy = true;
1157
1158 return 0;
1159}
1160
1161static struct phy *devm_of_phy_optional_get_index(struct device *dev,
1162 struct device_node *np,
1163 const char *consumer,
1164 unsigned int index)
1165{
1166 struct phy *phy;
1167 char *name;
1168
1169 name = kasprintf(GFP_KERNEL, "%s-%u", consumer, index);
1170 if (!name)
1171 return ERR_PTR(-ENOMEM);
1172
1173 phy = devm_of_phy_get(dev, np, name);
1174 kfree(name);
1175
1176 if (IS_ERR(phy) && PTR_ERR(phy) == -ENODEV)
1177 phy = NULL;
1178
1179 return phy;
1180}
1181
1182static int tegra_pcie_port_get_phys(struct tegra_pcie_port *port)
1183{
1184 struct device *dev = port->pcie->dev;
1185 struct phy *phy;
1186 unsigned int i;
1187 int err;
1188
1189 port->phys = devm_kcalloc(dev, sizeof(phy), port->lanes, GFP_KERNEL);
1190 if (!port->phys)
1191 return -ENOMEM;
1192
1193 for (i = 0; i < port->lanes; i++) {
1194 phy = devm_of_phy_optional_get_index(dev, port->np, "pcie", i);
1195 if (IS_ERR(phy)) {
1196 dev_err(dev, "failed to get PHY#%u: %ld\n", i,
1197 PTR_ERR(phy));
1198 return PTR_ERR(phy);
1199 }
1200
1201 err = phy_init(phy);
1202 if (err < 0) {
1203 dev_err(dev, "failed to initialize PHY#%u: %d\n", i,
1204 err);
1205 return err;
1206 }
1207
1208 port->phys[i] = phy;
1209 }
1210
1211 return 0;
1212}
1213
1214static int tegra_pcie_phys_get(struct tegra_pcie *pcie)
1215{
Thierry Redinga7fbae22016-08-15 17:31:31 +02001216 const struct tegra_pcie_soc *soc = pcie->soc;
Thierry Reding6fe7c182015-11-11 18:25:59 +01001217 struct device_node *np = pcie->dev->of_node;
1218 struct tegra_pcie_port *port;
1219 int err;
1220
1221 if (!soc->has_gen2 || of_find_property(np, "phys", NULL) != NULL)
1222 return tegra_pcie_phys_get_legacy(pcie);
1223
1224 list_for_each_entry(port, &pcie->ports, list) {
1225 err = tegra_pcie_port_get_phys(port);
1226 if (err < 0)
1227 return err;
1228 }
1229
1230 return 0;
1231}
1232
Manikanta Maddireddy527557a2018-02-28 15:30:32 +05301233static void tegra_pcie_phys_put(struct tegra_pcie *pcie)
1234{
1235 struct tegra_pcie_port *port;
1236 struct device *dev = pcie->dev;
1237 int err, i;
1238
1239 if (pcie->legacy_phy) {
1240 err = phy_exit(pcie->phy);
1241 if (err < 0)
1242 dev_err(dev, "failed to teardown PHY: %d\n", err);
1243 return;
1244 }
1245
1246 list_for_each_entry(port, &pcie->ports, list) {
1247 for (i = 0; i < port->lanes; i++) {
1248 err = phy_exit(port->phys[i]);
1249 if (err < 0)
1250 dev_err(dev, "failed to teardown PHY#%u: %d\n",
1251 i, err);
1252 }
1253 }
1254}
1255
1256
Thierry Redingd1523b52013-08-09 16:49:19 +02001257static int tegra_pcie_get_resources(struct tegra_pcie *pcie)
1258{
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001259 struct device *dev = pcie->dev;
1260 struct platform_device *pdev = to_platform_device(dev);
Thierry Redingd1523b52013-08-09 16:49:19 +02001261 struct resource *pads, *afi, *res;
Manikanta Maddireddy9cea5132017-09-27 17:28:35 +05301262 const struct tegra_pcie_soc *soc = pcie->soc;
Thierry Redingd1523b52013-08-09 16:49:19 +02001263 int err;
1264
1265 err = tegra_pcie_clocks_get(pcie);
1266 if (err) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001267 dev_err(dev, "failed to get clocks: %d\n", err);
Thierry Redingd1523b52013-08-09 16:49:19 +02001268 return err;
1269 }
1270
Stephen Warren3127a6b2013-11-06 15:56:58 -07001271 err = tegra_pcie_resets_get(pcie);
1272 if (err) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001273 dev_err(dev, "failed to get resets: %d\n", err);
Stephen Warren3127a6b2013-11-06 15:56:58 -07001274 return err;
1275 }
1276
Manikanta Maddireddy9cea5132017-09-27 17:28:35 +05301277 if (soc->program_uphy) {
1278 err = tegra_pcie_phys_get(pcie);
1279 if (err < 0) {
1280 dev_err(dev, "failed to get PHYs: %d\n", err);
1281 return err;
1282 }
Thierry Reding7f1f0542014-08-26 17:11:38 +02001283 }
1284
Thierry Redingd1523b52013-08-09 16:49:19 +02001285 pads = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pads");
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001286 pcie->pads = devm_ioremap_resource(dev, pads);
Julia Lawalldc05ee32013-08-26 11:11:09 +02001287 if (IS_ERR(pcie->pads)) {
1288 err = PTR_ERR(pcie->pads);
Manikanta Maddireddyda76ba52018-02-28 15:30:34 +05301289 goto phys_put;
Thierry Redingd1523b52013-08-09 16:49:19 +02001290 }
1291
1292 afi = platform_get_resource_byname(pdev, IORESOURCE_MEM, "afi");
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001293 pcie->afi = devm_ioremap_resource(dev, afi);
Julia Lawalldc05ee32013-08-26 11:11:09 +02001294 if (IS_ERR(pcie->afi)) {
1295 err = PTR_ERR(pcie->afi);
Manikanta Maddireddyda76ba52018-02-28 15:30:34 +05301296 goto phys_put;
Thierry Redingd1523b52013-08-09 16:49:19 +02001297 }
1298
Julia Lawalldc05ee32013-08-26 11:11:09 +02001299 /* request configuration space, but remap later, on demand */
Thierry Redingd1523b52013-08-09 16:49:19 +02001300 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cs");
1301 if (!res) {
1302 err = -EADDRNOTAVAIL;
Manikanta Maddireddyda76ba52018-02-28 15:30:34 +05301303 goto phys_put;
Thierry Redingd1523b52013-08-09 16:49:19 +02001304 }
1305
Vidya Sagar1fd92922017-12-20 21:36:07 +01001306 pcie->cs = *res;
1307
1308 /* constrain configuration space to 4 KiB */
1309 pcie->cs.end = pcie->cs.start + SZ_4K - 1;
1310
1311 pcie->cfg = devm_ioremap_resource(dev, &pcie->cs);
1312 if (IS_ERR(pcie->cfg)) {
1313 err = PTR_ERR(pcie->cfg);
Manikanta Maddireddyda76ba52018-02-28 15:30:34 +05301314 goto phys_put;
Thierry Redingd1523b52013-08-09 16:49:19 +02001315 }
1316
1317 /* request interrupt */
1318 err = platform_get_irq_byname(pdev, "intr");
1319 if (err < 0) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001320 dev_err(dev, "failed to get IRQ: %d\n", err);
Manikanta Maddireddyda76ba52018-02-28 15:30:34 +05301321 goto phys_put;
Thierry Redingd1523b52013-08-09 16:49:19 +02001322 }
1323
1324 pcie->irq = err;
1325
1326 err = request_irq(pcie->irq, tegra_pcie_isr, IRQF_SHARED, "PCIE", pcie);
1327 if (err) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001328 dev_err(dev, "failed to register IRQ: %d\n", err);
Manikanta Maddireddyda76ba52018-02-28 15:30:34 +05301329 goto phys_put;
Thierry Redingd1523b52013-08-09 16:49:19 +02001330 }
1331
1332 return 0;
1333
Manikanta Maddireddy527557a2018-02-28 15:30:32 +05301334phys_put:
1335 if (soc->program_uphy)
1336 tegra_pcie_phys_put(pcie);
Thierry Redingd1523b52013-08-09 16:49:19 +02001337 return err;
1338}
1339
1340static int tegra_pcie_put_resources(struct tegra_pcie *pcie)
1341{
Manikanta Maddireddy9cea5132017-09-27 17:28:35 +05301342 const struct tegra_pcie_soc *soc = pcie->soc;
Thierry Reding7f1f0542014-08-26 17:11:38 +02001343
Thierry Redingd1523b52013-08-09 16:49:19 +02001344 if (pcie->irq > 0)
1345 free_irq(pcie->irq, pcie);
1346
Manikanta Maddireddy527557a2018-02-28 15:30:32 +05301347 if (soc->program_uphy)
1348 tegra_pcie_phys_put(pcie);
Thierry Reding7f1f0542014-08-26 17:11:38 +02001349
Thierry Redingd1523b52013-08-09 16:49:19 +02001350 return 0;
1351}
1352
Manikanta Maddireddy662b94c2018-02-28 15:30:33 +05301353static void tegra_pcie_pme_turnoff(struct tegra_pcie_port *port)
1354{
1355 struct tegra_pcie *pcie = port->pcie;
1356 const struct tegra_pcie_soc *soc = pcie->soc;
1357 int err;
1358 u32 val;
1359 u8 ack_bit;
1360
1361 val = afi_readl(pcie, AFI_PCIE_PME);
1362 val |= (0x1 << soc->ports[port->index].pme.turnoff_bit);
1363 afi_writel(pcie, val, AFI_PCIE_PME);
1364
1365 ack_bit = soc->ports[port->index].pme.ack_bit;
1366 err = readl_poll_timeout(pcie->afi + AFI_PCIE_PME, val,
1367 val & (0x1 << ack_bit), 1, PME_ACK_TIMEOUT);
1368 if (err)
1369 dev_err(pcie->dev, "PME Ack is not received on port: %d\n",
1370 port->index);
1371
1372 usleep_range(10000, 11000);
1373
1374 val = afi_readl(pcie, AFI_PCIE_PME);
1375 val &= ~(0x1 << soc->ports[port->index].pme.turnoff_bit);
1376 afi_writel(pcie, val, AFI_PCIE_PME);
1377}
1378
Thierry Redingd1523b52013-08-09 16:49:19 +02001379static int tegra_msi_alloc(struct tegra_msi *chip)
1380{
1381 int msi;
1382
1383 mutex_lock(&chip->lock);
1384
1385 msi = find_first_zero_bit(chip->used, INT_PCI_MSI_NR);
1386 if (msi < INT_PCI_MSI_NR)
1387 set_bit(msi, chip->used);
1388 else
1389 msi = -ENOSPC;
1390
1391 mutex_unlock(&chip->lock);
1392
1393 return msi;
1394}
1395
1396static void tegra_msi_free(struct tegra_msi *chip, unsigned long irq)
1397{
1398 struct device *dev = chip->chip.dev;
1399
1400 mutex_lock(&chip->lock);
1401
1402 if (!test_bit(irq, chip->used))
1403 dev_err(dev, "trying to free unused MSI#%lu\n", irq);
1404 else
1405 clear_bit(irq, chip->used);
1406
1407 mutex_unlock(&chip->lock);
1408}
1409
1410static irqreturn_t tegra_pcie_msi_irq(int irq, void *data)
1411{
1412 struct tegra_pcie *pcie = data;
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001413 struct device *dev = pcie->dev;
Thierry Redingd1523b52013-08-09 16:49:19 +02001414 struct tegra_msi *msi = &pcie->msi;
1415 unsigned int i, processed = 0;
1416
1417 for (i = 0; i < 8; i++) {
1418 unsigned long reg = afi_readl(pcie, AFI_MSI_VEC0 + i * 4);
1419
1420 while (reg) {
1421 unsigned int offset = find_first_bit(&reg, 32);
1422 unsigned int index = i * 32 + offset;
1423 unsigned int irq;
1424
1425 /* clear the interrupt */
1426 afi_writel(pcie, 1 << offset, AFI_MSI_VEC0 + i * 4);
1427
1428 irq = irq_find_mapping(msi->domain, index);
1429 if (irq) {
1430 if (test_bit(index, msi->used))
1431 generic_handle_irq(irq);
1432 else
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001433 dev_info(dev, "unhandled MSI\n");
Thierry Redingd1523b52013-08-09 16:49:19 +02001434 } else {
1435 /*
1436 * that's weird who triggered this?
1437 * just clear it
1438 */
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001439 dev_info(dev, "unexpected MSI\n");
Thierry Redingd1523b52013-08-09 16:49:19 +02001440 }
1441
1442 /* see if there's any more pending in this vector */
1443 reg = afi_readl(pcie, AFI_MSI_VEC0 + i * 4);
1444
1445 processed++;
1446 }
1447 }
1448
1449 return processed > 0 ? IRQ_HANDLED : IRQ_NONE;
1450}
1451
Yijing Wangc2791b82014-11-11 17:45:45 -07001452static int tegra_msi_setup_irq(struct msi_controller *chip,
1453 struct pci_dev *pdev, struct msi_desc *desc)
Thierry Redingd1523b52013-08-09 16:49:19 +02001454{
1455 struct tegra_msi *msi = to_tegra_msi(chip);
1456 struct msi_msg msg;
1457 unsigned int irq;
1458 int hwirq;
1459
1460 hwirq = tegra_msi_alloc(msi);
1461 if (hwirq < 0)
1462 return hwirq;
1463
1464 irq = irq_create_mapping(msi->domain, hwirq);
Jisheng Zhang019fa462014-07-29 09:33:30 +08001465 if (!irq) {
1466 tegra_msi_free(msi, hwirq);
Thierry Redingd1523b52013-08-09 16:49:19 +02001467 return -EINVAL;
Jisheng Zhang019fa462014-07-29 09:33:30 +08001468 }
Thierry Redingd1523b52013-08-09 16:49:19 +02001469
1470 irq_set_msi_desc(irq, desc);
1471
Thierry Redingc0165552017-05-04 22:10:31 +02001472 msg.address_lo = lower_32_bits(msi->phys);
1473 msg.address_hi = upper_32_bits(msi->phys);
Thierry Redingd1523b52013-08-09 16:49:19 +02001474 msg.data = hwirq;
1475
Jiang Liu83a18912014-11-09 23:10:34 +08001476 pci_write_msi_msg(irq, &msg);
Thierry Redingd1523b52013-08-09 16:49:19 +02001477
1478 return 0;
1479}
1480
Yijing Wangc2791b82014-11-11 17:45:45 -07001481static void tegra_msi_teardown_irq(struct msi_controller *chip,
1482 unsigned int irq)
Thierry Redingd1523b52013-08-09 16:49:19 +02001483{
1484 struct tegra_msi *msi = to_tegra_msi(chip);
1485 struct irq_data *d = irq_get_irq_data(irq);
Jisheng Zhang019fa462014-07-29 09:33:30 +08001486 irq_hw_number_t hwirq = irqd_to_hwirq(d);
Thierry Redingd1523b52013-08-09 16:49:19 +02001487
Jisheng Zhang019fa462014-07-29 09:33:30 +08001488 irq_dispose_mapping(irq);
1489 tegra_msi_free(msi, hwirq);
Thierry Redingd1523b52013-08-09 16:49:19 +02001490}
1491
1492static struct irq_chip tegra_msi_irq_chip = {
1493 .name = "Tegra PCIe MSI",
Thomas Gleixner280510f2014-11-23 12:23:20 +01001494 .irq_enable = pci_msi_unmask_irq,
1495 .irq_disable = pci_msi_mask_irq,
1496 .irq_mask = pci_msi_mask_irq,
1497 .irq_unmask = pci_msi_unmask_irq,
Thierry Redingd1523b52013-08-09 16:49:19 +02001498};
1499
1500static int tegra_msi_map(struct irq_domain *domain, unsigned int irq,
1501 irq_hw_number_t hwirq)
1502{
1503 irq_set_chip_and_handler(irq, &tegra_msi_irq_chip, handle_simple_irq);
1504 irq_set_chip_data(irq, domain->host_data);
Thierry Redingd1523b52013-08-09 16:49:19 +02001505
Stephen Warrenb4f17372013-05-06 14:19:19 -06001506 tegra_cpuidle_pcie_irqs_in_use();
1507
Thierry Redingd1523b52013-08-09 16:49:19 +02001508 return 0;
1509}
1510
1511static const struct irq_domain_ops msi_domain_ops = {
1512 .map = tegra_msi_map,
1513};
1514
Manikanta Maddireddyda76ba52018-02-28 15:30:34 +05301515static int tegra_pcie_msi_setup(struct tegra_pcie *pcie)
Thierry Redingd1523b52013-08-09 16:49:19 +02001516{
Arnd Bergmann76f25412016-11-25 11:57:12 +01001517 struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
1518 struct platform_device *pdev = to_platform_device(pcie->dev);
Thierry Redingd1523b52013-08-09 16:49:19 +02001519 struct tegra_msi *msi = &pcie->msi;
Arnd Bergmann76f25412016-11-25 11:57:12 +01001520 struct device *dev = pcie->dev;
Thierry Redingd1523b52013-08-09 16:49:19 +02001521 int err;
Thierry Redingd1523b52013-08-09 16:49:19 +02001522
1523 mutex_init(&msi->lock);
1524
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001525 msi->chip.dev = dev;
Thierry Redingd1523b52013-08-09 16:49:19 +02001526 msi->chip.setup_irq = tegra_msi_setup_irq;
1527 msi->chip.teardown_irq = tegra_msi_teardown_irq;
1528
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001529 msi->domain = irq_domain_add_linear(dev->of_node, INT_PCI_MSI_NR,
Thierry Redingd1523b52013-08-09 16:49:19 +02001530 &msi_domain_ops, &msi->chip);
1531 if (!msi->domain) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001532 dev_err(dev, "failed to create IRQ domain\n");
Thierry Redingd1523b52013-08-09 16:49:19 +02001533 return -ENOMEM;
1534 }
1535
1536 err = platform_get_irq_byname(pdev, "msi");
1537 if (err < 0) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001538 dev_err(dev, "failed to get IRQ: %d\n", err);
Thierry Redingd1523b52013-08-09 16:49:19 +02001539 goto err;
1540 }
1541
1542 msi->irq = err;
1543
Grygorii Strashko8ff0ef92015-12-10 21:18:20 +02001544 err = request_irq(msi->irq, tegra_pcie_msi_irq, IRQF_NO_THREAD,
Thierry Redingd1523b52013-08-09 16:49:19 +02001545 tegra_msi_irq_chip.name, pcie);
1546 if (err < 0) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001547 dev_err(dev, "failed to request IRQ: %d\n", err);
Thierry Redingd1523b52013-08-09 16:49:19 +02001548 goto err;
1549 }
1550
Thierry Reding8c2b4e32017-10-09 12:29:35 +02001551 /* setup AFI/FPCI range */
1552 msi->pages = __get_free_pages(GFP_KERNEL, 0);
1553 msi->phys = virt_to_phys((void *)msi->pages);
Manikanta Maddireddyda76ba52018-02-28 15:30:34 +05301554 host->msi = &msi->chip;
1555
1556 return 0;
1557
1558err:
1559 irq_domain_remove(msi->domain);
1560 return err;
1561}
1562
1563static void tegra_pcie_enable_msi(struct tegra_pcie *pcie)
1564{
1565 const struct tegra_pcie_soc *soc = pcie->soc;
1566 struct tegra_msi *msi = &pcie->msi;
1567 u32 reg;
Thierry Redingd1523b52013-08-09 16:49:19 +02001568
Thierry Redingc0165552017-05-04 22:10:31 +02001569 afi_writel(pcie, msi->phys >> soc->msi_base_shift, AFI_MSI_FPCI_BAR_ST);
1570 afi_writel(pcie, msi->phys, AFI_MSI_AXI_BAR_ST);
Thierry Redingd1523b52013-08-09 16:49:19 +02001571 /* this register is in 4K increments */
1572 afi_writel(pcie, 1, AFI_MSI_BAR_SZ);
1573
1574 /* enable all MSI vectors */
1575 afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC0);
1576 afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC1);
1577 afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC2);
1578 afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC3);
1579 afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC4);
1580 afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC5);
1581 afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC6);
1582 afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC7);
1583
1584 /* and unmask the MSI interrupt */
1585 reg = afi_readl(pcie, AFI_INTR_MASK);
1586 reg |= AFI_INTR_MASK_MSI_MASK;
1587 afi_writel(pcie, reg, AFI_INTR_MASK);
Manikanta Maddireddyda76ba52018-02-28 15:30:34 +05301588}
Thierry Redingd1523b52013-08-09 16:49:19 +02001589
Manikanta Maddireddyda76ba52018-02-28 15:30:34 +05301590static void tegra_pcie_msi_teardown(struct tegra_pcie *pcie)
1591{
1592 struct tegra_msi *msi = &pcie->msi;
1593 unsigned int i, irq;
Arnd Bergmann76f25412016-11-25 11:57:12 +01001594
Manikanta Maddireddyda76ba52018-02-28 15:30:34 +05301595 free_pages(msi->pages, 0);
Thierry Redingd1523b52013-08-09 16:49:19 +02001596
Manikanta Maddireddyda76ba52018-02-28 15:30:34 +05301597 if (msi->irq > 0)
1598 free_irq(msi->irq, pcie);
1599
1600 for (i = 0; i < INT_PCI_MSI_NR; i++) {
1601 irq = irq_find_mapping(msi->domain, i);
1602 if (irq > 0)
1603 irq_dispose_mapping(irq);
1604 }
1605
Thierry Redingd1523b52013-08-09 16:49:19 +02001606 irq_domain_remove(msi->domain);
Thierry Redingd1523b52013-08-09 16:49:19 +02001607}
1608
1609static int tegra_pcie_disable_msi(struct tegra_pcie *pcie)
1610{
Thierry Redingd1523b52013-08-09 16:49:19 +02001611 u32 value;
1612
1613 /* mask the MSI interrupt */
1614 value = afi_readl(pcie, AFI_INTR_MASK);
1615 value &= ~AFI_INTR_MASK_MSI_MASK;
1616 afi_writel(pcie, value, AFI_INTR_MASK);
1617
1618 /* disable all MSI vectors */
1619 afi_writel(pcie, 0, AFI_MSI_EN_VEC0);
1620 afi_writel(pcie, 0, AFI_MSI_EN_VEC1);
1621 afi_writel(pcie, 0, AFI_MSI_EN_VEC2);
1622 afi_writel(pcie, 0, AFI_MSI_EN_VEC3);
1623 afi_writel(pcie, 0, AFI_MSI_EN_VEC4);
1624 afi_writel(pcie, 0, AFI_MSI_EN_VEC5);
1625 afi_writel(pcie, 0, AFI_MSI_EN_VEC6);
1626 afi_writel(pcie, 0, AFI_MSI_EN_VEC7);
1627
Thierry Redingd1523b52013-08-09 16:49:19 +02001628 return 0;
1629}
1630
1631static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes,
1632 u32 *xbar)
1633{
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001634 struct device *dev = pcie->dev;
1635 struct device_node *np = dev->of_node;
Thierry Redingd1523b52013-08-09 16:49:19 +02001636
Manikanta Maddireddy9cea5132017-09-27 17:28:35 +05301637 if (of_device_is_compatible(np, "nvidia,tegra186-pcie")) {
1638 switch (lanes) {
1639 case 0x010004:
1640 dev_info(dev, "4x1, 1x1 configuration\n");
1641 *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_401;
1642 return 0;
1643
1644 case 0x010102:
1645 dev_info(dev, "2x1, 1X1, 1x1 configuration\n");
1646 *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_211;
1647 return 0;
1648
1649 case 0x010101:
1650 dev_info(dev, "1x1, 1x1, 1x1 configuration\n");
1651 *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_111;
1652 return 0;
1653
1654 default:
1655 dev_info(dev, "wrong configuration updated in DT, "
1656 "switching to default 2x1, 1x1, 1x1 "
1657 "configuration\n");
1658 *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_211;
1659 return 0;
1660 }
1661 } else if (of_device_is_compatible(np, "nvidia,tegra124-pcie") ||
1662 of_device_is_compatible(np, "nvidia,tegra210-pcie")) {
Thierry Reding7f1f0542014-08-26 17:11:38 +02001663 switch (lanes) {
1664 case 0x0000104:
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001665 dev_info(dev, "4x1, 1x1 configuration\n");
Thierry Reding7f1f0542014-08-26 17:11:38 +02001666 *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X4_X1;
1667 return 0;
1668
1669 case 0x0000102:
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001670 dev_info(dev, "2x1, 1x1 configuration\n");
Thierry Reding7f1f0542014-08-26 17:11:38 +02001671 *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X2_X1;
1672 return 0;
1673 }
1674 } else if (of_device_is_compatible(np, "nvidia,tegra30-pcie")) {
Jay Agarwal94716cd2013-08-09 16:49:24 +02001675 switch (lanes) {
1676 case 0x00000204:
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001677 dev_info(dev, "4x1, 2x1 configuration\n");
Jay Agarwal94716cd2013-08-09 16:49:24 +02001678 *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_420;
1679 return 0;
Thierry Redingd1523b52013-08-09 16:49:19 +02001680
Jay Agarwal94716cd2013-08-09 16:49:24 +02001681 case 0x00020202:
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001682 dev_info(dev, "2x3 configuration\n");
Jay Agarwal94716cd2013-08-09 16:49:24 +02001683 *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_222;
1684 return 0;
1685
1686 case 0x00010104:
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001687 dev_info(dev, "4x1, 1x2 configuration\n");
Jay Agarwal94716cd2013-08-09 16:49:24 +02001688 *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_411;
1689 return 0;
1690 }
1691 } else if (of_device_is_compatible(np, "nvidia,tegra20-pcie")) {
1692 switch (lanes) {
1693 case 0x00000004:
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001694 dev_info(dev, "single-mode configuration\n");
Jay Agarwal94716cd2013-08-09 16:49:24 +02001695 *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_SINGLE;
1696 return 0;
1697
1698 case 0x00000202:
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001699 dev_info(dev, "dual-mode configuration\n");
Jay Agarwal94716cd2013-08-09 16:49:24 +02001700 *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL;
1701 return 0;
1702 }
Thierry Redingd1523b52013-08-09 16:49:19 +02001703 }
1704
1705 return -EINVAL;
1706}
1707
Thierry Reding077fb152014-05-28 16:49:13 +02001708/*
1709 * Check whether a given set of supplies is available in a device tree node.
1710 * This is used to check whether the new or the legacy device tree bindings
1711 * should be used.
1712 */
1713static bool of_regulator_bulk_available(struct device_node *np,
1714 struct regulator_bulk_data *supplies,
1715 unsigned int num_supplies)
1716{
1717 char property[32];
1718 unsigned int i;
1719
1720 for (i = 0; i < num_supplies; i++) {
1721 snprintf(property, 32, "%s-supply", supplies[i].supply);
1722
1723 if (of_find_property(np, property, NULL) == NULL)
1724 return false;
1725 }
1726
1727 return true;
1728}
1729
1730/*
1731 * Old versions of the device tree binding for this device used a set of power
1732 * supplies that didn't match the hardware inputs. This happened to work for a
1733 * number of cases but is not future proof. However to preserve backwards-
1734 * compatibility with old device trees, this function will try to use the old
1735 * set of supplies.
1736 */
1737static int tegra_pcie_get_legacy_regulators(struct tegra_pcie *pcie)
1738{
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001739 struct device *dev = pcie->dev;
1740 struct device_node *np = dev->of_node;
Thierry Reding077fb152014-05-28 16:49:13 +02001741
1742 if (of_device_is_compatible(np, "nvidia,tegra30-pcie"))
1743 pcie->num_supplies = 3;
1744 else if (of_device_is_compatible(np, "nvidia,tegra20-pcie"))
1745 pcie->num_supplies = 2;
1746
1747 if (pcie->num_supplies == 0) {
Rob Herringb63773a2017-07-18 16:43:21 -05001748 dev_err(dev, "device %pOF not supported in legacy mode\n", np);
Thierry Reding077fb152014-05-28 16:49:13 +02001749 return -ENODEV;
1750 }
1751
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001752 pcie->supplies = devm_kcalloc(dev, pcie->num_supplies,
Thierry Reding077fb152014-05-28 16:49:13 +02001753 sizeof(*pcie->supplies),
1754 GFP_KERNEL);
1755 if (!pcie->supplies)
1756 return -ENOMEM;
1757
1758 pcie->supplies[0].supply = "pex-clk";
1759 pcie->supplies[1].supply = "vdd";
1760
1761 if (pcie->num_supplies > 2)
1762 pcie->supplies[2].supply = "avdd";
1763
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001764 return devm_regulator_bulk_get(dev, pcie->num_supplies, pcie->supplies);
Thierry Reding077fb152014-05-28 16:49:13 +02001765}
1766
1767/*
1768 * Obtains the list of regulators required for a particular generation of the
1769 * IP block.
1770 *
1771 * This would've been nice to do simply by providing static tables for use
1772 * with the regulator_bulk_*() API, but unfortunately Tegra30 is a bit quirky
1773 * in that it has two pairs or AVDD_PEX and VDD_PEX supplies (PEXA and PEXB)
1774 * and either seems to be optional depending on which ports are being used.
1775 */
1776static int tegra_pcie_get_regulators(struct tegra_pcie *pcie, u32 lane_mask)
1777{
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001778 struct device *dev = pcie->dev;
1779 struct device_node *np = dev->of_node;
Thierry Reding077fb152014-05-28 16:49:13 +02001780 unsigned int i = 0;
1781
Manikanta Maddireddy9cea5132017-09-27 17:28:35 +05301782 if (of_device_is_compatible(np, "nvidia,tegra186-pcie")) {
1783 pcie->num_supplies = 4;
1784
1785 pcie->supplies = devm_kcalloc(pcie->dev, pcie->num_supplies,
1786 sizeof(*pcie->supplies),
1787 GFP_KERNEL);
1788 if (!pcie->supplies)
1789 return -ENOMEM;
1790
1791 pcie->supplies[i++].supply = "dvdd-pex";
1792 pcie->supplies[i++].supply = "hvdd-pex-pll";
1793 pcie->supplies[i++].supply = "hvdd-pex";
1794 pcie->supplies[i++].supply = "vddio-pexctl-aud";
1795 } else if (of_device_is_compatible(np, "nvidia,tegra210-pcie")) {
Thierry Redingc7a091c2016-11-25 11:57:15 +01001796 pcie->num_supplies = 6;
1797
1798 pcie->supplies = devm_kcalloc(pcie->dev, pcie->num_supplies,
1799 sizeof(*pcie->supplies),
1800 GFP_KERNEL);
1801 if (!pcie->supplies)
1802 return -ENOMEM;
1803
1804 pcie->supplies[i++].supply = "avdd-pll-uerefe";
1805 pcie->supplies[i++].supply = "hvddio-pex";
1806 pcie->supplies[i++].supply = "dvddio-pex";
1807 pcie->supplies[i++].supply = "dvdd-pex-pll";
1808 pcie->supplies[i++].supply = "hvdd-pex-pll-e";
1809 pcie->supplies[i++].supply = "vddio-pex-ctl";
1810 } else if (of_device_is_compatible(np, "nvidia,tegra124-pcie")) {
Thierry Reding7f1f0542014-08-26 17:11:38 +02001811 pcie->num_supplies = 7;
1812
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001813 pcie->supplies = devm_kcalloc(dev, pcie->num_supplies,
Thierry Reding7f1f0542014-08-26 17:11:38 +02001814 sizeof(*pcie->supplies),
1815 GFP_KERNEL);
1816 if (!pcie->supplies)
1817 return -ENOMEM;
1818
1819 pcie->supplies[i++].supply = "avddio-pex";
1820 pcie->supplies[i++].supply = "dvddio-pex";
1821 pcie->supplies[i++].supply = "avdd-pex-pll";
1822 pcie->supplies[i++].supply = "hvdd-pex";
1823 pcie->supplies[i++].supply = "hvdd-pex-pll-e";
1824 pcie->supplies[i++].supply = "vddio-pex-ctl";
1825 pcie->supplies[i++].supply = "avdd-pll-erefe";
1826 } else if (of_device_is_compatible(np, "nvidia,tegra30-pcie")) {
Thierry Reding077fb152014-05-28 16:49:13 +02001827 bool need_pexa = false, need_pexb = false;
1828
1829 /* VDD_PEXA and AVDD_PEXA supply lanes 0 to 3 */
1830 if (lane_mask & 0x0f)
1831 need_pexa = true;
1832
1833 /* VDD_PEXB and AVDD_PEXB supply lanes 4 to 5 */
1834 if (lane_mask & 0x30)
1835 need_pexb = true;
1836
1837 pcie->num_supplies = 4 + (need_pexa ? 2 : 0) +
1838 (need_pexb ? 2 : 0);
1839
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001840 pcie->supplies = devm_kcalloc(dev, pcie->num_supplies,
Thierry Reding077fb152014-05-28 16:49:13 +02001841 sizeof(*pcie->supplies),
1842 GFP_KERNEL);
1843 if (!pcie->supplies)
1844 return -ENOMEM;
1845
1846 pcie->supplies[i++].supply = "avdd-pex-pll";
1847 pcie->supplies[i++].supply = "hvdd-pex";
1848 pcie->supplies[i++].supply = "vddio-pex-ctl";
1849 pcie->supplies[i++].supply = "avdd-plle";
1850
1851 if (need_pexa) {
1852 pcie->supplies[i++].supply = "avdd-pexa";
1853 pcie->supplies[i++].supply = "vdd-pexa";
1854 }
1855
1856 if (need_pexb) {
1857 pcie->supplies[i++].supply = "avdd-pexb";
1858 pcie->supplies[i++].supply = "vdd-pexb";
1859 }
1860 } else if (of_device_is_compatible(np, "nvidia,tegra20-pcie")) {
1861 pcie->num_supplies = 5;
1862
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001863 pcie->supplies = devm_kcalloc(dev, pcie->num_supplies,
Thierry Reding077fb152014-05-28 16:49:13 +02001864 sizeof(*pcie->supplies),
1865 GFP_KERNEL);
1866 if (!pcie->supplies)
1867 return -ENOMEM;
1868
1869 pcie->supplies[0].supply = "avdd-pex";
1870 pcie->supplies[1].supply = "vdd-pex";
1871 pcie->supplies[2].supply = "avdd-pex-pll";
1872 pcie->supplies[3].supply = "avdd-plle";
1873 pcie->supplies[4].supply = "vddio-pex-clk";
1874 }
1875
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001876 if (of_regulator_bulk_available(dev->of_node, pcie->supplies,
Thierry Reding077fb152014-05-28 16:49:13 +02001877 pcie->num_supplies))
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001878 return devm_regulator_bulk_get(dev, pcie->num_supplies,
Thierry Reding077fb152014-05-28 16:49:13 +02001879 pcie->supplies);
1880
1881 /*
1882 * If not all regulators are available for this new scheme, assume
1883 * that the device tree complies with an older version of the device
1884 * tree binding.
1885 */
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001886 dev_info(dev, "using legacy DT binding for power supplies\n");
Thierry Reding077fb152014-05-28 16:49:13 +02001887
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001888 devm_kfree(dev, pcie->supplies);
Thierry Reding077fb152014-05-28 16:49:13 +02001889 pcie->num_supplies = 0;
1890
1891 return tegra_pcie_get_legacy_regulators(pcie);
1892}
1893
Thierry Redingd1523b52013-08-09 16:49:19 +02001894static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
1895{
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001896 struct device *dev = pcie->dev;
1897 struct device_node *np = dev->of_node, *port;
Thierry Redinga7fbae22016-08-15 17:31:31 +02001898 const struct tegra_pcie_soc *soc = pcie->soc;
Thierry Redingd1523b52013-08-09 16:49:19 +02001899 struct of_pci_range_parser parser;
1900 struct of_pci_range range;
Thierry Reding077fb152014-05-28 16:49:13 +02001901 u32 lanes = 0, mask = 0;
1902 unsigned int lane = 0;
Thierry Redingd1523b52013-08-09 16:49:19 +02001903 struct resource res;
Thierry Redingd1523b52013-08-09 16:49:19 +02001904 int err;
1905
1906 if (of_pci_range_parser_init(&parser, np)) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001907 dev_err(dev, "missing \"ranges\" property\n");
Thierry Redingd1523b52013-08-09 16:49:19 +02001908 return -EINVAL;
1909 }
1910
Thierry Redingd1523b52013-08-09 16:49:19 +02001911 for_each_of_pci_range(&parser, &range) {
Liviu Dudau0b0b0892014-09-29 15:29:25 +01001912 err = of_pci_range_to_resource(&range, np, &res);
1913 if (err < 0)
1914 return err;
Thierry Redingd1523b52013-08-09 16:49:19 +02001915
1916 switch (res.flags & IORESOURCE_TYPE_BITS) {
1917 case IORESOURCE_IO:
Thierry Reding56e75e22016-02-09 15:52:32 +01001918 /* Track the bus -> CPU I/O mapping offset. */
1919 pcie->offset.io = res.start - range.pci_addr;
1920
Thierry Reding51067872014-11-27 09:54:09 +01001921 memcpy(&pcie->pio, &res, sizeof(res));
1922 pcie->pio.name = np->full_name;
1923
1924 /*
1925 * The Tegra PCIe host bridge uses this to program the
1926 * mapping of the I/O space to the physical address,
1927 * so we override the .start and .end fields here that
1928 * of_pci_range_to_resource() converted to I/O space.
1929 * We also set the IORESOURCE_MEM type to clarify that
1930 * the resource is in the physical memory space.
1931 */
1932 pcie->io.start = range.cpu_addr;
1933 pcie->io.end = range.cpu_addr + range.size - 1;
1934 pcie->io.flags = IORESOURCE_MEM;
1935 pcie->io.name = "I/O";
1936
1937 memcpy(&res, &pcie->io, sizeof(res));
Thierry Redingd1523b52013-08-09 16:49:19 +02001938 break;
1939
1940 case IORESOURCE_MEM:
Thierry Reding56e75e22016-02-09 15:52:32 +01001941 /*
1942 * Track the bus -> CPU memory mapping offset. This
1943 * assumes that the prefetchable and non-prefetchable
1944 * regions will be the last of type IORESOURCE_MEM in
1945 * the ranges property.
1946 * */
1947 pcie->offset.mem = res.start - range.pci_addr;
1948
Thierry Redingd1523b52013-08-09 16:49:19 +02001949 if (res.flags & IORESOURCE_PREFETCH) {
1950 memcpy(&pcie->prefetch, &res, sizeof(res));
Thierry Reding41534e52014-08-01 14:15:11 +02001951 pcie->prefetch.name = "prefetchable";
Thierry Redingd1523b52013-08-09 16:49:19 +02001952 } else {
1953 memcpy(&pcie->mem, &res, sizeof(res));
Thierry Reding41534e52014-08-01 14:15:11 +02001954 pcie->mem.name = "non-prefetchable";
Thierry Redingd1523b52013-08-09 16:49:19 +02001955 }
1956 break;
1957 }
1958 }
1959
1960 err = of_pci_parse_bus_range(np, &pcie->busn);
1961 if (err < 0) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001962 dev_err(dev, "failed to parse ranges property: %d\n", err);
Thierry Redingd1523b52013-08-09 16:49:19 +02001963 pcie->busn.name = np->name;
1964 pcie->busn.start = 0;
1965 pcie->busn.end = 0xff;
1966 pcie->busn.flags = IORESOURCE_BUS;
1967 }
1968
1969 /* parse root ports */
1970 for_each_child_of_node(np, port) {
1971 struct tegra_pcie_port *rp;
1972 unsigned int index;
1973 u32 value;
1974
1975 err = of_pci_get_devfn(port);
1976 if (err < 0) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001977 dev_err(dev, "failed to parse address: %d\n", err);
Thierry Redingd1523b52013-08-09 16:49:19 +02001978 return err;
1979 }
1980
1981 index = PCI_SLOT(err);
1982
Jay Agarwal94716cd2013-08-09 16:49:24 +02001983 if (index < 1 || index > soc->num_ports) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001984 dev_err(dev, "invalid port number: %d\n", index);
Thierry Redingd1523b52013-08-09 16:49:19 +02001985 return -EINVAL;
1986 }
1987
1988 index--;
1989
1990 err = of_property_read_u32(port, "nvidia,num-lanes", &value);
1991 if (err < 0) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001992 dev_err(dev, "failed to parse # of lanes: %d\n",
Thierry Redingd1523b52013-08-09 16:49:19 +02001993 err);
1994 return err;
1995 }
1996
1997 if (value > 16) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05001998 dev_err(dev, "invalid # of lanes: %u\n", value);
Thierry Redingd1523b52013-08-09 16:49:19 +02001999 return -EINVAL;
2000 }
2001
2002 lanes |= value << (index << 3);
2003
Thierry Reding077fb152014-05-28 16:49:13 +02002004 if (!of_device_is_available(port)) {
2005 lane += value;
Thierry Redingd1523b52013-08-09 16:49:19 +02002006 continue;
Thierry Reding077fb152014-05-28 16:49:13 +02002007 }
2008
2009 mask |= ((1 << value) - 1) << lane;
2010 lane += value;
Thierry Redingd1523b52013-08-09 16:49:19 +02002011
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05002012 rp = devm_kzalloc(dev, sizeof(*rp), GFP_KERNEL);
Thierry Redingd1523b52013-08-09 16:49:19 +02002013 if (!rp)
2014 return -ENOMEM;
2015
2016 err = of_address_to_resource(port, 0, &rp->regs);
2017 if (err < 0) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05002018 dev_err(dev, "failed to parse address: %d\n", err);
Thierry Redingd1523b52013-08-09 16:49:19 +02002019 return err;
2020 }
2021
2022 INIT_LIST_HEAD(&rp->list);
2023 rp->index = index;
2024 rp->lanes = value;
2025 rp->pcie = pcie;
Thierry Reding6fe7c182015-11-11 18:25:59 +01002026 rp->np = port;
Thierry Redingd1523b52013-08-09 16:49:19 +02002027
Lorenzo Pieralisi3e02dc42017-04-19 17:49:06 +01002028 rp->base = devm_pci_remap_cfg_resource(dev, &rp->regs);
Julia Lawalldc05ee32013-08-26 11:11:09 +02002029 if (IS_ERR(rp->base))
2030 return PTR_ERR(rp->base);
Thierry Redingd1523b52013-08-09 16:49:19 +02002031
2032 list_add_tail(&rp->list, &pcie->ports);
2033 }
2034
2035 err = tegra_pcie_get_xbar_config(pcie, lanes, &pcie->xbar_config);
2036 if (err < 0) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05002037 dev_err(dev, "invalid lane configuration\n");
Thierry Redingd1523b52013-08-09 16:49:19 +02002038 return err;
2039 }
2040
Thierry Reding077fb152014-05-28 16:49:13 +02002041 err = tegra_pcie_get_regulators(pcie, mask);
2042 if (err < 0)
2043 return err;
2044
Thierry Redingd1523b52013-08-09 16:49:19 +02002045 return 0;
2046}
2047
2048/*
2049 * FIXME: If there are no PCIe cards attached, then calling this function
2050 * can result in the increase of the bootup time as there are big timeout
2051 * loops.
2052 */
2053#define TEGRA_PCIE_LINKUP_TIMEOUT 200 /* up to 1.2 seconds */
2054static bool tegra_pcie_port_check_link(struct tegra_pcie_port *port)
2055{
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05002056 struct device *dev = port->pcie->dev;
Thierry Redingd1523b52013-08-09 16:49:19 +02002057 unsigned int retries = 3;
2058 unsigned long value;
2059
Thierry Reding7f1f0542014-08-26 17:11:38 +02002060 /* override presence detection */
2061 value = readl(port->base + RP_PRIV_MISC);
2062 value &= ~RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT;
2063 value |= RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT;
2064 writel(value, port->base + RP_PRIV_MISC);
2065
Thierry Redingd1523b52013-08-09 16:49:19 +02002066 do {
2067 unsigned int timeout = TEGRA_PCIE_LINKUP_TIMEOUT;
2068
2069 do {
2070 value = readl(port->base + RP_VEND_XP);
2071
2072 if (value & RP_VEND_XP_DL_UP)
2073 break;
2074
2075 usleep_range(1000, 2000);
2076 } while (--timeout);
2077
2078 if (!timeout) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05002079 dev_err(dev, "link %u down, retrying\n", port->index);
Thierry Redingd1523b52013-08-09 16:49:19 +02002080 goto retry;
2081 }
2082
2083 timeout = TEGRA_PCIE_LINKUP_TIMEOUT;
2084
2085 do {
2086 value = readl(port->base + RP_LINK_CONTROL_STATUS);
2087
2088 if (value & RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE)
2089 return true;
2090
2091 usleep_range(1000, 2000);
2092 } while (--timeout);
2093
2094retry:
2095 tegra_pcie_port_reset(port);
2096 } while (--retries);
2097
2098 return false;
2099}
2100
Arnd Bergmann76f25412016-11-25 11:57:12 +01002101static void tegra_pcie_enable_ports(struct tegra_pcie *pcie)
Thierry Redingd1523b52013-08-09 16:49:19 +02002102{
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05002103 struct device *dev = pcie->dev;
Thierry Redingd1523b52013-08-09 16:49:19 +02002104 struct tegra_pcie_port *port, *tmp;
Thierry Redingd1523b52013-08-09 16:49:19 +02002105
2106 list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05002107 dev_info(dev, "probing port %u, using %u lanes\n",
Thierry Redingd1523b52013-08-09 16:49:19 +02002108 port->index, port->lanes);
2109
2110 tegra_pcie_port_enable(port);
2111
2112 if (tegra_pcie_port_check_link(port))
2113 continue;
2114
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05002115 dev_info(dev, "link %u down, ignoring\n", port->index);
Thierry Redingd1523b52013-08-09 16:49:19 +02002116
2117 tegra_pcie_port_disable(port);
2118 tegra_pcie_port_free(port);
2119 }
Thierry Redingd1523b52013-08-09 16:49:19 +02002120}
2121
Manikanta Maddireddy527557a2018-02-28 15:30:32 +05302122static void tegra_pcie_disable_ports(struct tegra_pcie *pcie)
2123{
2124 struct tegra_pcie_port *port, *tmp;
2125
Manikanta Maddireddyda76ba52018-02-28 15:30:34 +05302126 list_for_each_entry_safe(port, tmp, &pcie->ports, list)
Manikanta Maddireddy527557a2018-02-28 15:30:32 +05302127 tegra_pcie_port_disable(port);
Manikanta Maddireddy527557a2018-02-28 15:30:32 +05302128}
2129
Manikanta Maddireddy662b94c2018-02-28 15:30:33 +05302130static const struct tegra_pcie_port_soc tegra20_pcie_ports[] = {
2131 { .pme.turnoff_bit = 0, .pme.ack_bit = 5 },
2132 { .pme.turnoff_bit = 8, .pme.ack_bit = 10 },
2133};
2134
Thierry Redinga7fbae22016-08-15 17:31:31 +02002135static const struct tegra_pcie_soc tegra20_pcie = {
Jay Agarwal94716cd2013-08-09 16:49:24 +02002136 .num_ports = 2,
Manikanta Maddireddy662b94c2018-02-28 15:30:33 +05302137 .ports = tegra20_pcie_ports,
Jay Agarwal94716cd2013-08-09 16:49:24 +02002138 .msi_base_shift = 0,
2139 .pads_pll_ctl = PADS_PLL_CTL_TEGRA20,
2140 .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_DIV10,
Stephen Warrenf8144302016-07-25 16:02:27 -05002141 .pads_refclk_cfg0 = 0xfa5cfa5c,
Jay Agarwal94716cd2013-08-09 16:49:24 +02002142 .has_pex_clkreq_en = false,
2143 .has_pex_bias_ctrl = false,
2144 .has_intr_prsnt_sense = false,
Jay Agarwal94716cd2013-08-09 16:49:24 +02002145 .has_cml_clk = false,
Thierry Reding7f1f0542014-08-26 17:11:38 +02002146 .has_gen2 = false,
Thierry Reding76245ca2016-11-25 11:57:14 +01002147 .force_pca_enable = false,
Manikanta Maddireddy9cea5132017-09-27 17:28:35 +05302148 .program_uphy = true,
Jay Agarwal94716cd2013-08-09 16:49:24 +02002149};
2150
Manikanta Maddireddy662b94c2018-02-28 15:30:33 +05302151static const struct tegra_pcie_port_soc tegra30_pcie_ports[] = {
2152 { .pme.turnoff_bit = 0, .pme.ack_bit = 5 },
2153 { .pme.turnoff_bit = 8, .pme.ack_bit = 10 },
2154 { .pme.turnoff_bit = 16, .pme.ack_bit = 18 },
2155};
2156
Thierry Redinga7fbae22016-08-15 17:31:31 +02002157static const struct tegra_pcie_soc tegra30_pcie = {
Jay Agarwal94716cd2013-08-09 16:49:24 +02002158 .num_ports = 3,
Manikanta Maddireddy662b94c2018-02-28 15:30:33 +05302159 .ports = tegra30_pcie_ports,
Jay Agarwal94716cd2013-08-09 16:49:24 +02002160 .msi_base_shift = 8,
2161 .pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
2162 .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
Stephen Warrenf8144302016-07-25 16:02:27 -05002163 .pads_refclk_cfg0 = 0xfa5cfa5c,
2164 .pads_refclk_cfg1 = 0xfa5cfa5c,
Jay Agarwal94716cd2013-08-09 16:49:24 +02002165 .has_pex_clkreq_en = true,
2166 .has_pex_bias_ctrl = true,
2167 .has_intr_prsnt_sense = true,
Jay Agarwal94716cd2013-08-09 16:49:24 +02002168 .has_cml_clk = true,
Thierry Reding7f1f0542014-08-26 17:11:38 +02002169 .has_gen2 = false,
Thierry Reding76245ca2016-11-25 11:57:14 +01002170 .force_pca_enable = false,
Manikanta Maddireddy9cea5132017-09-27 17:28:35 +05302171 .program_uphy = true,
Thierry Reding7f1f0542014-08-26 17:11:38 +02002172};
2173
Thierry Redinga7fbae22016-08-15 17:31:31 +02002174static const struct tegra_pcie_soc tegra124_pcie = {
Thierry Reding7f1f0542014-08-26 17:11:38 +02002175 .num_ports = 2,
Manikanta Maddireddy662b94c2018-02-28 15:30:33 +05302176 .ports = tegra20_pcie_ports,
Thierry Reding7f1f0542014-08-26 17:11:38 +02002177 .msi_base_shift = 8,
2178 .pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
2179 .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
Stephen Warrenf8144302016-07-25 16:02:27 -05002180 .pads_refclk_cfg0 = 0x44ac44ac,
Thierry Reding7f1f0542014-08-26 17:11:38 +02002181 .has_pex_clkreq_en = true,
2182 .has_pex_bias_ctrl = true,
2183 .has_intr_prsnt_sense = true,
2184 .has_cml_clk = true,
2185 .has_gen2 = true,
Thierry Reding76245ca2016-11-25 11:57:14 +01002186 .force_pca_enable = false,
Manikanta Maddireddy9cea5132017-09-27 17:28:35 +05302187 .program_uphy = true,
Jay Agarwal94716cd2013-08-09 16:49:24 +02002188};
2189
Thierry Redingc7a091c2016-11-25 11:57:15 +01002190static const struct tegra_pcie_soc tegra210_pcie = {
2191 .num_ports = 2,
Manikanta Maddireddy662b94c2018-02-28 15:30:33 +05302192 .ports = tegra20_pcie_ports,
Thierry Redingc7a091c2016-11-25 11:57:15 +01002193 .msi_base_shift = 8,
2194 .pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
2195 .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
2196 .pads_refclk_cfg0 = 0x90b890b8,
2197 .has_pex_clkreq_en = true,
2198 .has_pex_bias_ctrl = true,
2199 .has_intr_prsnt_sense = true,
2200 .has_cml_clk = true,
2201 .has_gen2 = true,
2202 .force_pca_enable = true,
Manikanta Maddireddy9cea5132017-09-27 17:28:35 +05302203 .program_uphy = true,
2204};
2205
Manikanta Maddireddy662b94c2018-02-28 15:30:33 +05302206static const struct tegra_pcie_port_soc tegra186_pcie_ports[] = {
2207 { .pme.turnoff_bit = 0, .pme.ack_bit = 5 },
2208 { .pme.turnoff_bit = 8, .pme.ack_bit = 10 },
2209 { .pme.turnoff_bit = 12, .pme.ack_bit = 14 },
2210};
2211
Manikanta Maddireddy9cea5132017-09-27 17:28:35 +05302212static const struct tegra_pcie_soc tegra186_pcie = {
2213 .num_ports = 3,
Manikanta Maddireddy662b94c2018-02-28 15:30:33 +05302214 .ports = tegra186_pcie_ports,
Manikanta Maddireddy9cea5132017-09-27 17:28:35 +05302215 .msi_base_shift = 8,
2216 .pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
2217 .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
2218 .pads_refclk_cfg0 = 0x80b880b8,
2219 .pads_refclk_cfg1 = 0x000480b8,
2220 .has_pex_clkreq_en = true,
2221 .has_pex_bias_ctrl = true,
2222 .has_intr_prsnt_sense = true,
2223 .has_cml_clk = false,
2224 .has_gen2 = true,
2225 .force_pca_enable = false,
2226 .program_uphy = false,
Thierry Redingc7a091c2016-11-25 11:57:15 +01002227};
2228
Jay Agarwal94716cd2013-08-09 16:49:24 +02002229static const struct of_device_id tegra_pcie_of_match[] = {
Manikanta Maddireddy9cea5132017-09-27 17:28:35 +05302230 { .compatible = "nvidia,tegra186-pcie", .data = &tegra186_pcie },
Thierry Redingc7a091c2016-11-25 11:57:15 +01002231 { .compatible = "nvidia,tegra210-pcie", .data = &tegra210_pcie },
Thierry Redinga7fbae22016-08-15 17:31:31 +02002232 { .compatible = "nvidia,tegra124-pcie", .data = &tegra124_pcie },
2233 { .compatible = "nvidia,tegra30-pcie", .data = &tegra30_pcie },
2234 { .compatible = "nvidia,tegra20-pcie", .data = &tegra20_pcie },
Jay Agarwal94716cd2013-08-09 16:49:24 +02002235 { },
2236};
Jay Agarwal94716cd2013-08-09 16:49:24 +02002237
Thierry Reding2cb989f2014-07-22 12:30:46 -06002238static void *tegra_pcie_ports_seq_start(struct seq_file *s, loff_t *pos)
2239{
2240 struct tegra_pcie *pcie = s->private;
2241
2242 if (list_empty(&pcie->ports))
2243 return NULL;
2244
2245 seq_printf(s, "Index Status\n");
2246
2247 return seq_list_start(&pcie->ports, *pos);
2248}
2249
2250static void *tegra_pcie_ports_seq_next(struct seq_file *s, void *v, loff_t *pos)
2251{
2252 struct tegra_pcie *pcie = s->private;
2253
2254 return seq_list_next(v, &pcie->ports, pos);
2255}
2256
2257static void tegra_pcie_ports_seq_stop(struct seq_file *s, void *v)
2258{
2259}
2260
2261static int tegra_pcie_ports_seq_show(struct seq_file *s, void *v)
2262{
2263 bool up = false, active = false;
2264 struct tegra_pcie_port *port;
2265 unsigned int value;
2266
2267 port = list_entry(v, struct tegra_pcie_port, list);
2268
2269 value = readl(port->base + RP_VEND_XP);
2270
2271 if (value & RP_VEND_XP_DL_UP)
2272 up = true;
2273
2274 value = readl(port->base + RP_LINK_CONTROL_STATUS);
2275
2276 if (value & RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE)
2277 active = true;
2278
2279 seq_printf(s, "%2u ", port->index);
2280
2281 if (up)
2282 seq_printf(s, "up");
2283
2284 if (active) {
2285 if (up)
2286 seq_printf(s, ", ");
2287
2288 seq_printf(s, "active");
2289 }
2290
2291 seq_printf(s, "\n");
2292 return 0;
2293}
2294
2295static const struct seq_operations tegra_pcie_ports_seq_ops = {
2296 .start = tegra_pcie_ports_seq_start,
2297 .next = tegra_pcie_ports_seq_next,
2298 .stop = tegra_pcie_ports_seq_stop,
2299 .show = tegra_pcie_ports_seq_show,
2300};
2301
2302static int tegra_pcie_ports_open(struct inode *inode, struct file *file)
2303{
2304 struct tegra_pcie *pcie = inode->i_private;
2305 struct seq_file *s;
2306 int err;
2307
2308 err = seq_open(file, &tegra_pcie_ports_seq_ops);
2309 if (err)
2310 return err;
2311
2312 s = file->private_data;
2313 s->private = pcie;
2314
2315 return 0;
2316}
2317
2318static const struct file_operations tegra_pcie_ports_ops = {
2319 .owner = THIS_MODULE,
2320 .open = tegra_pcie_ports_open,
2321 .read = seq_read,
2322 .llseek = seq_lseek,
2323 .release = seq_release,
2324};
2325
Manikanta Maddireddy662b94c2018-02-28 15:30:33 +05302326static void tegra_pcie_debugfs_exit(struct tegra_pcie *pcie)
2327{
2328 debugfs_remove_recursive(pcie->debugfs);
2329 pcie->debugfs = NULL;
2330}
2331
Thierry Reding2cb989f2014-07-22 12:30:46 -06002332static int tegra_pcie_debugfs_init(struct tegra_pcie *pcie)
2333{
2334 struct dentry *file;
2335
2336 pcie->debugfs = debugfs_create_dir("pcie", NULL);
2337 if (!pcie->debugfs)
2338 return -ENOMEM;
2339
2340 file = debugfs_create_file("ports", S_IFREG | S_IRUGO, pcie->debugfs,
2341 pcie, &tegra_pcie_ports_ops);
2342 if (!file)
2343 goto remove;
2344
2345 return 0;
2346
2347remove:
Manikanta Maddireddy662b94c2018-02-28 15:30:33 +05302348 tegra_pcie_debugfs_exit(pcie);
Thierry Reding2cb989f2014-07-22 12:30:46 -06002349 return -ENOMEM;
2350}
2351
Thierry Redingd1523b52013-08-09 16:49:19 +02002352static int tegra_pcie_probe(struct platform_device *pdev)
2353{
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05002354 struct device *dev = &pdev->dev;
Arnd Bergmann76f25412016-11-25 11:57:12 +01002355 struct pci_host_bridge *host;
Thierry Redingd1523b52013-08-09 16:49:19 +02002356 struct tegra_pcie *pcie;
Arnd Bergmann76f25412016-11-25 11:57:12 +01002357 struct pci_bus *child;
Thierry Redingd1523b52013-08-09 16:49:19 +02002358 int err;
2359
Lorenzo Pieralisi792abc62017-06-28 15:13:54 -05002360 host = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
Arnd Bergmann76f25412016-11-25 11:57:12 +01002361 if (!host)
Thierry Redingd1523b52013-08-09 16:49:19 +02002362 return -ENOMEM;
2363
Arnd Bergmann76f25412016-11-25 11:57:12 +01002364 pcie = pci_host_bridge_priv(host);
Manikanta Maddireddy78243ff2018-01-11 11:38:03 +05302365 host->sysdata = pcie;
Manikanta Maddireddy662b94c2018-02-28 15:30:33 +05302366 platform_set_drvdata(pdev, pcie);
Arnd Bergmann76f25412016-11-25 11:57:12 +01002367
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05002368 pcie->soc = of_device_get_match_data(dev);
Thierry Redingd1523b52013-08-09 16:49:19 +02002369 INIT_LIST_HEAD(&pcie->ports);
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05002370 pcie->dev = dev;
Thierry Redingd1523b52013-08-09 16:49:19 +02002371
2372 err = tegra_pcie_parse_dt(pcie);
2373 if (err < 0)
2374 return err;
2375
Thierry Redingd1523b52013-08-09 16:49:19 +02002376 err = tegra_pcie_get_resources(pcie);
2377 if (err < 0) {
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05002378 dev_err(dev, "failed to request resources: %d\n", err);
Thierry Redingd1523b52013-08-09 16:49:19 +02002379 return err;
2380 }
2381
Manikanta Maddireddyda76ba52018-02-28 15:30:34 +05302382 err = tegra_pcie_msi_setup(pcie);
2383 if (err < 0) {
2384 dev_err(dev, "failed to enable MSI support: %d\n", err);
Thierry Redingd1523b52013-08-09 16:49:19 +02002385 goto put_resources;
Manikanta Maddireddyda76ba52018-02-28 15:30:34 +05302386 }
2387
2388 pm_runtime_enable(pcie->dev);
2389 err = pm_runtime_get_sync(pcie->dev);
2390 if (err) {
2391 dev_err(dev, "fail to enable pcie controller: %d\n", err);
2392 goto teardown_msi;
2393 }
Thierry Redingd1523b52013-08-09 16:49:19 +02002394
Arnd Bergmann76f25412016-11-25 11:57:12 +01002395 err = tegra_pcie_request_resources(pcie);
2396 if (err)
Manikanta Maddireddyda76ba52018-02-28 15:30:34 +05302397 goto pm_runtime_put;
Arnd Bergmann76f25412016-11-25 11:57:12 +01002398
Arnd Bergmann76f25412016-11-25 11:57:12 +01002399 host->busnr = pcie->busn.start;
2400 host->dev.parent = &pdev->dev;
2401 host->ops = &tegra_pcie_ops;
Lorenzo Pieralisidd5fcce2017-06-28 15:14:05 -05002402 host->map_irq = tegra_pcie_map_irq;
2403 host->swizzle_irq = pci_common_swizzle;
Arnd Bergmann76f25412016-11-25 11:57:12 +01002404
Lorenzo Pieralisicea9bc02017-06-28 15:13:55 -05002405 err = pci_scan_root_bus_bridge(host);
Thierry Redingd1523b52013-08-09 16:49:19 +02002406 if (err < 0) {
Arnd Bergmann76f25412016-11-25 11:57:12 +01002407 dev_err(dev, "failed to register host: %d\n", err);
Manikanta Maddireddyda76ba52018-02-28 15:30:34 +05302408 goto free_resources;
Thierry Redingd1523b52013-08-09 16:49:19 +02002409 }
2410
Arnd Bergmann76f25412016-11-25 11:57:12 +01002411 pci_bus_size_bridges(host->bus);
2412 pci_bus_assign_resources(host->bus);
2413
2414 list_for_each_entry(child, &host->bus->children, node)
2415 pcie_bus_configure_settings(child);
2416
2417 pci_bus_add_devices(host->bus);
2418
Thierry Reding2cb989f2014-07-22 12:30:46 -06002419 if (IS_ENABLED(CONFIG_DEBUG_FS)) {
2420 err = tegra_pcie_debugfs_init(pcie);
2421 if (err < 0)
Bjorn Helgaasa581fa92016-10-06 13:43:04 -05002422 dev_err(dev, "failed to setup debugfs: %d\n", err);
Thierry Reding2cb989f2014-07-22 12:30:46 -06002423 }
2424
Thierry Redingd1523b52013-08-09 16:49:19 +02002425 return 0;
2426
Manikanta Maddireddy527557a2018-02-28 15:30:32 +05302427free_resources:
2428 tegra_pcie_free_resources(pcie);
Manikanta Maddireddyda76ba52018-02-28 15:30:34 +05302429pm_runtime_put:
2430 pm_runtime_put_sync(pcie->dev);
2431 pm_runtime_disable(pcie->dev);
2432teardown_msi:
2433 tegra_pcie_msi_teardown(pcie);
Thierry Redingd1523b52013-08-09 16:49:19 +02002434put_resources:
2435 tegra_pcie_put_resources(pcie);
2436 return err;
2437}
2438
Manikanta Maddireddy662b94c2018-02-28 15:30:33 +05302439static int tegra_pcie_remove(struct platform_device *pdev)
2440{
2441 struct tegra_pcie *pcie = platform_get_drvdata(pdev);
2442 struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
Manikanta Maddireddyda76ba52018-02-28 15:30:34 +05302443 struct tegra_pcie_port *port, *tmp;
Manikanta Maddireddy662b94c2018-02-28 15:30:33 +05302444
2445 if (IS_ENABLED(CONFIG_DEBUG_FS))
2446 tegra_pcie_debugfs_exit(pcie);
2447
2448 pci_stop_root_bus(host->bus);
2449 pci_remove_root_bus(host->bus);
Manikanta Maddireddyda76ba52018-02-28 15:30:34 +05302450 tegra_pcie_free_resources(pcie);
2451 pm_runtime_put_sync(pcie->dev);
2452 pm_runtime_disable(pcie->dev);
2453
2454 if (IS_ENABLED(CONFIG_PCI_MSI))
2455 tegra_pcie_msi_teardown(pcie);
2456
2457 tegra_pcie_put_resources(pcie);
2458
2459 list_for_each_entry_safe(port, tmp, &pcie->ports, list)
2460 tegra_pcie_port_free(port);
2461
2462 return 0;
2463}
2464
2465static int __maybe_unused tegra_pcie_pm_suspend(struct device *dev)
2466{
2467 struct tegra_pcie *pcie = dev_get_drvdata(dev);
2468 struct tegra_pcie_port *port;
Manikanta Maddireddy662b94c2018-02-28 15:30:33 +05302469
2470 list_for_each_entry(port, &pcie->ports, list)
2471 tegra_pcie_pme_turnoff(port);
2472
2473 tegra_pcie_disable_ports(pcie);
2474
2475 if (IS_ENABLED(CONFIG_PCI_MSI))
2476 tegra_pcie_disable_msi(pcie);
2477
Manikanta Maddireddy662b94c2018-02-28 15:30:33 +05302478 tegra_pcie_disable_controller(pcie);
Manikanta Maddireddyda76ba52018-02-28 15:30:34 +05302479 tegra_pcie_power_off(pcie);
Manikanta Maddireddy662b94c2018-02-28 15:30:33 +05302480
2481 return 0;
2482}
2483
Manikanta Maddireddyda76ba52018-02-28 15:30:34 +05302484static int __maybe_unused tegra_pcie_pm_resume(struct device *dev)
2485{
2486 struct tegra_pcie *pcie = dev_get_drvdata(dev);
2487 int err;
2488
2489 err = tegra_pcie_power_on(pcie);
2490 if (err) {
2491 dev_err(dev, "tegra pcie power on fail: %d\n", err);
2492 return err;
2493 }
2494 err = tegra_pcie_enable_controller(pcie);
2495 if (err) {
2496 dev_err(dev, "tegra pcie controller enable fail: %d\n", err);
2497 goto poweroff;
2498 }
2499 tegra_pcie_setup_translations(pcie);
2500
2501 if (IS_ENABLED(CONFIG_PCI_MSI))
2502 tegra_pcie_enable_msi(pcie);
2503
2504 tegra_pcie_enable_ports(pcie);
2505
2506 return 0;
2507
2508poweroff:
2509 tegra_pcie_power_off(pcie);
2510
2511 return err;
2512}
2513
2514static const struct dev_pm_ops tegra_pcie_pm_ops = {
2515 SET_RUNTIME_PM_OPS(tegra_pcie_pm_suspend, tegra_pcie_pm_resume, NULL)
2516 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(tegra_pcie_pm_suspend,
2517 tegra_pcie_pm_resume)
2518};
2519
Thierry Redingd1523b52013-08-09 16:49:19 +02002520static struct platform_driver tegra_pcie_driver = {
2521 .driver = {
2522 .name = "tegra-pcie",
Thierry Redingd1523b52013-08-09 16:49:19 +02002523 .of_match_table = tegra_pcie_of_match,
2524 .suppress_bind_attrs = true,
Manikanta Maddireddyda76ba52018-02-28 15:30:34 +05302525 .pm = &tegra_pcie_pm_ops,
Thierry Redingd1523b52013-08-09 16:49:19 +02002526 },
2527 .probe = tegra_pcie_probe,
Manikanta Maddireddy662b94c2018-02-28 15:30:33 +05302528 .remove = tegra_pcie_remove,
Thierry Redingd1523b52013-08-09 16:49:19 +02002529};
Manikanta Maddireddy662b94c2018-02-28 15:30:33 +05302530module_platform_driver(tegra_pcie_driver);
2531MODULE_LICENSE("GPL");