blob: d4ba1f2f4e39570ab3697fdc579404c73ed01d2a [file] [log] [blame]
Ray Jui1fb37a82015-04-08 11:21:35 -07001/*
2 * Copyright (C) 2014 Hauke Mehrtens <hauke@hauke-m.de>
Florian Fainellibe908d22015-10-16 12:04:04 -07003 * Copyright (C) 2015 Broadcom Corporation
Ray Jui1fb37a82015-04-08 11:21:35 -07004 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation version 2.
8 *
9 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
10 * kind, whether express or implied; without even the implied warranty
11 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include <linux/kernel.h>
16#include <linux/pci.h>
17#include <linux/msi.h>
18#include <linux/clk.h>
19#include <linux/module.h>
20#include <linux/mbus.h>
21#include <linux/slab.h>
22#include <linux/delay.h>
23#include <linux/interrupt.h>
Ray Jui787b3c42016-10-31 17:38:35 -070024#include <linux/irqchip/arm-gic-v3.h>
Ray Jui1fb37a82015-04-08 11:21:35 -070025#include <linux/platform_device.h>
26#include <linux/of_address.h>
27#include <linux/of_pci.h>
28#include <linux/of_irq.h>
29#include <linux/of_platform.h>
30#include <linux/phy/phy.h>
31
32#include "pcie-iproc.h"
33
Ray Jui199ff142015-09-15 17:39:18 -070034#define EP_PERST_SOURCE_SELECT_SHIFT 2
35#define EP_PERST_SOURCE_SELECT BIT(EP_PERST_SOURCE_SELECT_SHIFT)
Ray Jui1fb37a82015-04-08 11:21:35 -070036#define EP_MODE_SURVIVE_PERST_SHIFT 1
37#define EP_MODE_SURVIVE_PERST BIT(EP_MODE_SURVIVE_PERST_SHIFT)
38#define RC_PCIE_RST_OUTPUT_SHIFT 0
39#define RC_PCIE_RST_OUTPUT BIT(RC_PCIE_RST_OUTPUT_SHIFT)
Ray Jui943ebae2015-12-04 09:34:59 -080040#define PAXC_RESET_MASK 0x7f
Ray Jui1fb37a82015-04-08 11:21:35 -070041
Ray Jui787b3c42016-10-31 17:38:35 -070042#define GIC_V3_CFG_SHIFT 0
43#define GIC_V3_CFG BIT(GIC_V3_CFG_SHIFT)
44
45#define MSI_ENABLE_CFG_SHIFT 0
46#define MSI_ENABLE_CFG BIT(MSI_ENABLE_CFG_SHIFT)
47
Ray Jui1fb37a82015-04-08 11:21:35 -070048#define CFG_IND_ADDR_MASK 0x00001ffc
49
Ray Jui1fb37a82015-04-08 11:21:35 -070050#define CFG_ADDR_BUS_NUM_SHIFT 20
51#define CFG_ADDR_BUS_NUM_MASK 0x0ff00000
52#define CFG_ADDR_DEV_NUM_SHIFT 15
53#define CFG_ADDR_DEV_NUM_MASK 0x000f8000
54#define CFG_ADDR_FUNC_NUM_SHIFT 12
55#define CFG_ADDR_FUNC_NUM_MASK 0x00007000
56#define CFG_ADDR_REG_NUM_SHIFT 2
57#define CFG_ADDR_REG_NUM_MASK 0x00000ffc
58#define CFG_ADDR_CFG_TYPE_SHIFT 0
59#define CFG_ADDR_CFG_TYPE_MASK 0x00000003
60
Ray Jui1fb37a82015-04-08 11:21:35 -070061#define SYS_RC_INTX_MASK 0xf
62
Ray Juiaaf22ab2015-09-15 17:39:19 -070063#define PCIE_PHYLINKUP_SHIFT 3
64#define PCIE_PHYLINKUP BIT(PCIE_PHYLINKUP_SHIFT)
65#define PCIE_DL_ACTIVE_SHIFT 2
66#define PCIE_DL_ACTIVE BIT(PCIE_DL_ACTIVE_SHIFT)
67
Ray Jui538928f2016-10-31 17:38:33 -070068#define APB_ERR_EN_SHIFT 0
69#define APB_ERR_EN BIT(APB_ERR_EN_SHIFT)
70
Ray Juie99a1872015-10-16 08:18:24 -050071#define OARR_VALID_SHIFT 0
72#define OARR_VALID BIT(OARR_VALID_SHIFT)
73#define OARR_SIZE_CFG_SHIFT 1
74#define OARR_SIZE_CFG BIT(OARR_SIZE_CFG_SHIFT)
75
Bjorn Helgaase3a16982016-10-06 13:36:07 -050076#define PCI_EXP_CAP 0xac
77
Ray Juie99a1872015-10-16 08:18:24 -050078#define MAX_NUM_OB_WINDOWS 2
Ray Jui943ebae2015-12-04 09:34:59 -080079
80#define IPROC_PCIE_REG_INVALID 0xffff
81
Ray Jui06324ed2016-10-31 17:38:30 -070082/*
83 * iProc PCIe host registers
84 */
Ray Jui943ebae2015-12-04 09:34:59 -080085enum iproc_pcie_reg {
Ray Jui06324ed2016-10-31 17:38:30 -070086 /* clock/reset signal control */
Ray Jui943ebae2015-12-04 09:34:59 -080087 IPROC_PCIE_CLK_CTRL = 0,
Ray Jui06324ed2016-10-31 17:38:30 -070088
Ray Jui787b3c42016-10-31 17:38:35 -070089 /*
90 * To allow MSI to be steered to an external MSI controller (e.g., ARM
91 * GICv3 ITS)
92 */
93 IPROC_PCIE_MSI_GIC_MODE,
94
95 /*
96 * IPROC_PCIE_MSI_BASE_ADDR and IPROC_PCIE_MSI_WINDOW_SIZE define the
97 * window where the MSI posted writes are written, for the writes to be
98 * interpreted as MSI writes.
99 */
100 IPROC_PCIE_MSI_BASE_ADDR,
101 IPROC_PCIE_MSI_WINDOW_SIZE,
102
103 /*
104 * To hold the address of the register where the MSI writes are
105 * programed. When ARM GICv3 ITS is used, this should be programmed
106 * with the address of the GITS_TRANSLATER register.
107 */
108 IPROC_PCIE_MSI_ADDR_LO,
109 IPROC_PCIE_MSI_ADDR_HI,
110
111 /* enable MSI */
112 IPROC_PCIE_MSI_EN_CFG,
113
Ray Jui06324ed2016-10-31 17:38:30 -0700114 /* allow access to root complex configuration space */
Ray Jui943ebae2015-12-04 09:34:59 -0800115 IPROC_PCIE_CFG_IND_ADDR,
116 IPROC_PCIE_CFG_IND_DATA,
Ray Jui06324ed2016-10-31 17:38:30 -0700117
118 /* allow access to device configuration space */
Ray Jui943ebae2015-12-04 09:34:59 -0800119 IPROC_PCIE_CFG_ADDR,
120 IPROC_PCIE_CFG_DATA,
Ray Jui06324ed2016-10-31 17:38:30 -0700121
122 /* enable INTx */
Ray Jui943ebae2015-12-04 09:34:59 -0800123 IPROC_PCIE_INTX_EN,
Ray Jui06324ed2016-10-31 17:38:30 -0700124
125 /* outbound address mapping */
Ray Jui943ebae2015-12-04 09:34:59 -0800126 IPROC_PCIE_OARR_LO,
127 IPROC_PCIE_OARR_HI,
128 IPROC_PCIE_OMAP_LO,
129 IPROC_PCIE_OMAP_HI,
Ray Jui06324ed2016-10-31 17:38:30 -0700130
131 /* link status */
Ray Jui943ebae2015-12-04 09:34:59 -0800132 IPROC_PCIE_LINK_STATUS,
Ray Jui06324ed2016-10-31 17:38:30 -0700133
Ray Jui538928f2016-10-31 17:38:33 -0700134 /* enable APB error for unsupported requests */
135 IPROC_PCIE_APB_ERR_EN,
136
Ray Jui06324ed2016-10-31 17:38:30 -0700137 /* total number of core registers */
138 IPROC_PCIE_MAX_NUM_REG,
Ray Jui943ebae2015-12-04 09:34:59 -0800139};
140
Ray Jui404349c2016-10-31 17:38:32 -0700141/* iProc PCIe PAXB BCMA registers */
142static const u16 iproc_pcie_reg_paxb_bcma[] = {
143 [IPROC_PCIE_CLK_CTRL] = 0x000,
144 [IPROC_PCIE_CFG_IND_ADDR] = 0x120,
145 [IPROC_PCIE_CFG_IND_DATA] = 0x124,
146 [IPROC_PCIE_CFG_ADDR] = 0x1f8,
147 [IPROC_PCIE_CFG_DATA] = 0x1fc,
148 [IPROC_PCIE_INTX_EN] = 0x330,
149 [IPROC_PCIE_LINK_STATUS] = 0xf0c,
150};
151
Ray Jui943ebae2015-12-04 09:34:59 -0800152/* iProc PCIe PAXB registers */
153static const u16 iproc_pcie_reg_paxb[] = {
154 [IPROC_PCIE_CLK_CTRL] = 0x000,
155 [IPROC_PCIE_CFG_IND_ADDR] = 0x120,
156 [IPROC_PCIE_CFG_IND_DATA] = 0x124,
157 [IPROC_PCIE_CFG_ADDR] = 0x1f8,
158 [IPROC_PCIE_CFG_DATA] = 0x1fc,
159 [IPROC_PCIE_INTX_EN] = 0x330,
160 [IPROC_PCIE_OARR_LO] = 0xd20,
161 [IPROC_PCIE_OARR_HI] = 0xd24,
162 [IPROC_PCIE_OMAP_LO] = 0xd40,
163 [IPROC_PCIE_OMAP_HI] = 0xd44,
164 [IPROC_PCIE_LINK_STATUS] = 0xf0c,
Ray Jui538928f2016-10-31 17:38:33 -0700165 [IPROC_PCIE_APB_ERR_EN] = 0xf40,
Ray Jui943ebae2015-12-04 09:34:59 -0800166};
167
168/* iProc PCIe PAXC v1 registers */
169static const u16 iproc_pcie_reg_paxc[] = {
170 [IPROC_PCIE_CLK_CTRL] = 0x000,
171 [IPROC_PCIE_CFG_IND_ADDR] = 0x1f0,
172 [IPROC_PCIE_CFG_IND_DATA] = 0x1f4,
173 [IPROC_PCIE_CFG_ADDR] = 0x1f8,
174 [IPROC_PCIE_CFG_DATA] = 0x1fc,
Ray Jui943ebae2015-12-04 09:34:59 -0800175};
Ray Juie99a1872015-10-16 08:18:24 -0500176
Ray Jui787b3c42016-10-31 17:38:35 -0700177/* iProc PCIe PAXC v2 registers */
178static const u16 iproc_pcie_reg_paxc_v2[] = {
179 [IPROC_PCIE_MSI_GIC_MODE] = 0x050,
180 [IPROC_PCIE_MSI_BASE_ADDR] = 0x074,
181 [IPROC_PCIE_MSI_WINDOW_SIZE] = 0x078,
182 [IPROC_PCIE_MSI_ADDR_LO] = 0x07c,
183 [IPROC_PCIE_MSI_ADDR_HI] = 0x080,
184 [IPROC_PCIE_MSI_EN_CFG] = 0x09c,
185 [IPROC_PCIE_CFG_IND_ADDR] = 0x1f0,
186 [IPROC_PCIE_CFG_IND_DATA] = 0x1f4,
187 [IPROC_PCIE_CFG_ADDR] = 0x1f8,
188 [IPROC_PCIE_CFG_DATA] = 0x1fc,
189};
190
Ray Jui8d9bfe32015-07-21 18:29:40 -0700191static inline struct iproc_pcie *iproc_data(struct pci_bus *bus)
Ray Jui1fb37a82015-04-08 11:21:35 -0700192{
Ray Jui8d9bfe32015-07-21 18:29:40 -0700193 struct iproc_pcie *pcie;
194#ifdef CONFIG_ARM
195 struct pci_sys_data *sys = bus->sysdata;
196
197 pcie = sys->private_data;
198#else
199 pcie = bus->sysdata;
200#endif
201 return pcie;
Ray Jui1fb37a82015-04-08 11:21:35 -0700202}
203
Ray Jui943ebae2015-12-04 09:34:59 -0800204static inline bool iproc_pcie_reg_is_invalid(u16 reg_offset)
205{
206 return !!(reg_offset == IPROC_PCIE_REG_INVALID);
207}
208
209static inline u16 iproc_pcie_reg_offset(struct iproc_pcie *pcie,
210 enum iproc_pcie_reg reg)
211{
212 return pcie->reg_offsets[reg];
213}
214
215static inline u32 iproc_pcie_read_reg(struct iproc_pcie *pcie,
216 enum iproc_pcie_reg reg)
217{
218 u16 offset = iproc_pcie_reg_offset(pcie, reg);
219
220 if (iproc_pcie_reg_is_invalid(offset))
221 return 0;
222
223 return readl(pcie->base + offset);
224}
225
226static inline void iproc_pcie_write_reg(struct iproc_pcie *pcie,
227 enum iproc_pcie_reg reg, u32 val)
228{
229 u16 offset = iproc_pcie_reg_offset(pcie, reg);
230
231 if (iproc_pcie_reg_is_invalid(offset))
232 return;
233
234 writel(val, pcie->base + offset);
235}
236
Ray Jui538928f2016-10-31 17:38:33 -0700237/**
238 * APB error forwarding can be disabled during access of configuration
239 * registers of the endpoint device, to prevent unsupported requests
240 * (typically seen during enumeration with multi-function devices) from
241 * triggering a system exception.
242 */
243static inline void iproc_pcie_apb_err_disable(struct pci_bus *bus,
244 bool disable)
245{
246 struct iproc_pcie *pcie = iproc_data(bus);
247 u32 val;
248
249 if (bus->number && pcie->has_apb_err_disable) {
250 val = iproc_pcie_read_reg(pcie, IPROC_PCIE_APB_ERR_EN);
251 if (disable)
252 val &= ~APB_ERR_EN;
253 else
254 val |= APB_ERR_EN;
255 iproc_pcie_write_reg(pcie, IPROC_PCIE_APB_ERR_EN, val);
256 }
257}
258
Ray Jui943ebae2015-12-04 09:34:59 -0800259static inline void iproc_pcie_ob_write(struct iproc_pcie *pcie,
260 enum iproc_pcie_reg reg,
261 unsigned window, u32 val)
262{
263 u16 offset = iproc_pcie_reg_offset(pcie, reg);
264
265 if (iproc_pcie_reg_is_invalid(offset))
266 return;
267
268 writel(val, pcie->base + offset + (window * 8));
269}
270
Ray Jui1fb37a82015-04-08 11:21:35 -0700271/**
272 * Note access to the configuration registers are protected at the higher layer
273 * by 'pci_lock' in drivers/pci/access.c
274 */
275static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,
276 unsigned int devfn,
277 int where)
278{
Ray Jui8d9bfe32015-07-21 18:29:40 -0700279 struct iproc_pcie *pcie = iproc_data(bus);
Ray Jui1fb37a82015-04-08 11:21:35 -0700280 unsigned slot = PCI_SLOT(devfn);
281 unsigned fn = PCI_FUNC(devfn);
282 unsigned busno = bus->number;
283 u32 val;
Ray Jui943ebae2015-12-04 09:34:59 -0800284 u16 offset;
285
Ray Jui1fb37a82015-04-08 11:21:35 -0700286 /* root complex access */
287 if (busno == 0) {
Ray Jui46560382016-01-27 16:52:24 -0600288 if (slot > 0 || fn > 0)
289 return NULL;
290
Ray Jui943ebae2015-12-04 09:34:59 -0800291 iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_IND_ADDR,
292 where & CFG_IND_ADDR_MASK);
293 offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_IND_DATA);
294 if (iproc_pcie_reg_is_invalid(offset))
Ray Jui1fb37a82015-04-08 11:21:35 -0700295 return NULL;
Ray Jui943ebae2015-12-04 09:34:59 -0800296 else
297 return (pcie->base + offset);
Ray Jui1fb37a82015-04-08 11:21:35 -0700298 }
299
Ray Jui46560382016-01-27 16:52:24 -0600300 /*
301 * PAXC is connected to an internally emulated EP within the SoC. It
302 * allows only one device.
303 */
Ray Jui06324ed2016-10-31 17:38:30 -0700304 if (pcie->ep_is_internal)
Ray Jui46560382016-01-27 16:52:24 -0600305 if (slot > 0)
306 return NULL;
307
Ray Jui1fb37a82015-04-08 11:21:35 -0700308 /* EP device access */
309 val = (busno << CFG_ADDR_BUS_NUM_SHIFT) |
310 (slot << CFG_ADDR_DEV_NUM_SHIFT) |
311 (fn << CFG_ADDR_FUNC_NUM_SHIFT) |
312 (where & CFG_ADDR_REG_NUM_MASK) |
313 (1 & CFG_ADDR_CFG_TYPE_MASK);
Ray Jui943ebae2015-12-04 09:34:59 -0800314 iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_ADDR, val);
315 offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_DATA);
316 if (iproc_pcie_reg_is_invalid(offset))
317 return NULL;
318 else
319 return (pcie->base + offset);
Ray Jui1fb37a82015-04-08 11:21:35 -0700320}
321
Ray Jui538928f2016-10-31 17:38:33 -0700322static int iproc_pcie_config_read32(struct pci_bus *bus, unsigned int devfn,
323 int where, int size, u32 *val)
324{
325 int ret;
326
327 iproc_pcie_apb_err_disable(bus, true);
328 ret = pci_generic_config_read32(bus, devfn, where, size, val);
329 iproc_pcie_apb_err_disable(bus, false);
330
331 return ret;
332}
333
334static int iproc_pcie_config_write32(struct pci_bus *bus, unsigned int devfn,
335 int where, int size, u32 val)
336{
337 int ret;
338
339 iproc_pcie_apb_err_disable(bus, true);
340 ret = pci_generic_config_write32(bus, devfn, where, size, val);
341 iproc_pcie_apb_err_disable(bus, false);
342
343 return ret;
344}
345
Ray Jui1fb37a82015-04-08 11:21:35 -0700346static struct pci_ops iproc_pcie_ops = {
347 .map_bus = iproc_pcie_map_cfg_bus,
Ray Jui538928f2016-10-31 17:38:33 -0700348 .read = iproc_pcie_config_read32,
349 .write = iproc_pcie_config_write32,
Ray Jui1fb37a82015-04-08 11:21:35 -0700350};
351
352static void iproc_pcie_reset(struct iproc_pcie *pcie)
353{
354 u32 val;
355
Ray Jui7cbd50d2016-10-31 17:38:31 -0700356 /*
357 * PAXC and the internal emulated endpoint device downstream should not
358 * be reset. If firmware has been loaded on the endpoint device at an
359 * earlier boot stage, reset here causes issues.
360 */
361 if (pcie->ep_is_internal)
Ray Jui943ebae2015-12-04 09:34:59 -0800362 return;
Ray Jui943ebae2015-12-04 09:34:59 -0800363
Ray Jui1fb37a82015-04-08 11:21:35 -0700364 /*
Ray Jui199ff142015-09-15 17:39:18 -0700365 * Select perst_b signal as reset source. Put the device into reset,
366 * and then bring it out of reset
Ray Jui1fb37a82015-04-08 11:21:35 -0700367 */
Ray Jui943ebae2015-12-04 09:34:59 -0800368 val = iproc_pcie_read_reg(pcie, IPROC_PCIE_CLK_CTRL);
Ray Jui199ff142015-09-15 17:39:18 -0700369 val &= ~EP_PERST_SOURCE_SELECT & ~EP_MODE_SURVIVE_PERST &
370 ~RC_PCIE_RST_OUTPUT;
Ray Jui943ebae2015-12-04 09:34:59 -0800371 iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val);
Ray Jui1fb37a82015-04-08 11:21:35 -0700372 udelay(250);
Ray Jui199ff142015-09-15 17:39:18 -0700373
374 val |= RC_PCIE_RST_OUTPUT;
Ray Jui943ebae2015-12-04 09:34:59 -0800375 iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val);
Ray Jui199ff142015-09-15 17:39:18 -0700376 msleep(100);
Ray Jui1fb37a82015-04-08 11:21:35 -0700377}
378
379static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)
380{
Bjorn Helgaas786aecc2016-10-06 13:36:08 -0500381 struct device *dev = pcie->dev;
Ray Jui1fb37a82015-04-08 11:21:35 -0700382 u8 hdr_type;
Ray Juiaaf22ab2015-09-15 17:39:19 -0700383 u32 link_ctrl, class, val;
Bjorn Helgaase3a16982016-10-06 13:36:07 -0500384 u16 pos = PCI_EXP_CAP, link_status;
Ray Juiaaf22ab2015-09-15 17:39:19 -0700385 bool link_is_active = false;
386
Ray Jui943ebae2015-12-04 09:34:59 -0800387 /*
388 * PAXC connects to emulated endpoint devices directly and does not
389 * have a Serdes. Therefore skip the link detection logic here.
390 */
Ray Jui06324ed2016-10-31 17:38:30 -0700391 if (pcie->ep_is_internal)
Ray Jui943ebae2015-12-04 09:34:59 -0800392 return 0;
393
394 val = iproc_pcie_read_reg(pcie, IPROC_PCIE_LINK_STATUS);
Ray Juiaaf22ab2015-09-15 17:39:19 -0700395 if (!(val & PCIE_PHYLINKUP) || !(val & PCIE_DL_ACTIVE)) {
Bjorn Helgaas786aecc2016-10-06 13:36:08 -0500396 dev_err(dev, "PHY or data link is INACTIVE!\n");
Ray Juiaaf22ab2015-09-15 17:39:19 -0700397 return -ENODEV;
398 }
Ray Jui1fb37a82015-04-08 11:21:35 -0700399
400 /* make sure we are not in EP mode */
401 pci_bus_read_config_byte(bus, 0, PCI_HEADER_TYPE, &hdr_type);
402 if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) {
Bjorn Helgaas786aecc2016-10-06 13:36:08 -0500403 dev_err(dev, "in EP mode, hdr=%#02x\n", hdr_type);
Ray Jui1fb37a82015-04-08 11:21:35 -0700404 return -EFAULT;
405 }
406
407 /* force class to PCI_CLASS_BRIDGE_PCI (0x0604) */
Ray Juiaaf22ab2015-09-15 17:39:19 -0700408#define PCI_BRIDGE_CTRL_REG_OFFSET 0x43c
409#define PCI_CLASS_BRIDGE_MASK 0xffff00
410#define PCI_CLASS_BRIDGE_SHIFT 8
411 pci_bus_read_config_dword(bus, 0, PCI_BRIDGE_CTRL_REG_OFFSET, &class);
412 class &= ~PCI_CLASS_BRIDGE_MASK;
413 class |= (PCI_CLASS_BRIDGE_PCI << PCI_CLASS_BRIDGE_SHIFT);
414 pci_bus_write_config_dword(bus, 0, PCI_BRIDGE_CTRL_REG_OFFSET, class);
Ray Jui1fb37a82015-04-08 11:21:35 -0700415
416 /* check link status to see if link is active */
Ray Jui1fb37a82015-04-08 11:21:35 -0700417 pci_bus_read_config_word(bus, 0, pos + PCI_EXP_LNKSTA, &link_status);
418 if (link_status & PCI_EXP_LNKSTA_NLW)
Ray Juiaaf22ab2015-09-15 17:39:19 -0700419 link_is_active = true;
Ray Jui1fb37a82015-04-08 11:21:35 -0700420
421 if (!link_is_active) {
422 /* try GEN 1 link speed */
Ray Jui1fb37a82015-04-08 11:21:35 -0700423#define PCI_TARGET_LINK_SPEED_MASK 0xf
424#define PCI_TARGET_LINK_SPEED_GEN2 0x2
425#define PCI_TARGET_LINK_SPEED_GEN1 0x1
426 pci_bus_read_config_dword(bus, 0,
Bjorn Helgaase3a16982016-10-06 13:36:07 -0500427 pos + PCI_EXP_LNKCTL2,
Ray Jui1fb37a82015-04-08 11:21:35 -0700428 &link_ctrl);
429 if ((link_ctrl & PCI_TARGET_LINK_SPEED_MASK) ==
430 PCI_TARGET_LINK_SPEED_GEN2) {
431 link_ctrl &= ~PCI_TARGET_LINK_SPEED_MASK;
432 link_ctrl |= PCI_TARGET_LINK_SPEED_GEN1;
433 pci_bus_write_config_dword(bus, 0,
Bjorn Helgaase3a16982016-10-06 13:36:07 -0500434 pos + PCI_EXP_LNKCTL2,
Ray Jui1fb37a82015-04-08 11:21:35 -0700435 link_ctrl);
436 msleep(100);
437
Ray Jui1fb37a82015-04-08 11:21:35 -0700438 pci_bus_read_config_word(bus, 0, pos + PCI_EXP_LNKSTA,
439 &link_status);
440 if (link_status & PCI_EXP_LNKSTA_NLW)
Ray Juiaaf22ab2015-09-15 17:39:19 -0700441 link_is_active = true;
Ray Jui1fb37a82015-04-08 11:21:35 -0700442 }
443 }
444
Bjorn Helgaas786aecc2016-10-06 13:36:08 -0500445 dev_info(dev, "link: %s\n", link_is_active ? "UP" : "DOWN");
Ray Jui1fb37a82015-04-08 11:21:35 -0700446
447 return link_is_active ? 0 : -ENODEV;
448}
449
450static void iproc_pcie_enable(struct iproc_pcie *pcie)
451{
Ray Jui943ebae2015-12-04 09:34:59 -0800452 iproc_pcie_write_reg(pcie, IPROC_PCIE_INTX_EN, SYS_RC_INTX_MASK);
Ray Jui1fb37a82015-04-08 11:21:35 -0700453}
454
Ray Juie99a1872015-10-16 08:18:24 -0500455/**
456 * Some iProc SoCs require the SW to configure the outbound address mapping
457 *
458 * Outbound address translation:
459 *
460 * iproc_pcie_address = axi_address - axi_offset
461 * OARR = iproc_pcie_address
462 * OMAP = pci_addr
463 *
464 * axi_addr -> iproc_pcie_address -> OARR -> OMAP -> pci_address
465 */
466static int iproc_pcie_setup_ob(struct iproc_pcie *pcie, u64 axi_addr,
467 u64 pci_addr, resource_size_t size)
468{
469 struct iproc_pcie_ob *ob = &pcie->ob;
Bjorn Helgaas786aecc2016-10-06 13:36:08 -0500470 struct device *dev = pcie->dev;
Ray Juie99a1872015-10-16 08:18:24 -0500471 unsigned i;
472 u64 max_size = (u64)ob->window_size * MAX_NUM_OB_WINDOWS;
473 u64 remainder;
474
475 if (size > max_size) {
Bjorn Helgaas786aecc2016-10-06 13:36:08 -0500476 dev_err(dev,
Dmitry V. Krivenok57303e92015-11-30 23:45:49 +0300477 "res size %pap exceeds max supported size 0x%llx\n",
Ray Juie99a1872015-10-16 08:18:24 -0500478 &size, max_size);
479 return -EINVAL;
480 }
481
482 div64_u64_rem(size, ob->window_size, &remainder);
483 if (remainder) {
Bjorn Helgaas786aecc2016-10-06 13:36:08 -0500484 dev_err(dev,
Ray Juie99a1872015-10-16 08:18:24 -0500485 "res size %pap needs to be multiple of window size %pap\n",
486 &size, &ob->window_size);
487 return -EINVAL;
488 }
489
490 if (axi_addr < ob->axi_offset) {
Bjorn Helgaas786aecc2016-10-06 13:36:08 -0500491 dev_err(dev, "axi address %pap less than offset %pap\n",
Ray Juie99a1872015-10-16 08:18:24 -0500492 &axi_addr, &ob->axi_offset);
493 return -EINVAL;
494 }
495
496 /*
497 * Translate the AXI address to the internal address used by the iProc
498 * PCIe core before programming the OARR
499 */
500 axi_addr -= ob->axi_offset;
501
502 for (i = 0; i < MAX_NUM_OB_WINDOWS; i++) {
Ray Jui943ebae2015-12-04 09:34:59 -0800503 iproc_pcie_ob_write(pcie, IPROC_PCIE_OARR_LO, i,
504 lower_32_bits(axi_addr) | OARR_VALID |
505 (ob->set_oarr_size ? 1 : 0));
506 iproc_pcie_ob_write(pcie, IPROC_PCIE_OARR_HI, i,
507 upper_32_bits(axi_addr));
508 iproc_pcie_ob_write(pcie, IPROC_PCIE_OMAP_LO, i,
509 lower_32_bits(pci_addr));
510 iproc_pcie_ob_write(pcie, IPROC_PCIE_OMAP_HI, i,
511 upper_32_bits(pci_addr));
Ray Juie99a1872015-10-16 08:18:24 -0500512
513 size -= ob->window_size;
514 if (size == 0)
515 break;
516
517 axi_addr += ob->window_size;
518 pci_addr += ob->window_size;
519 }
520
521 return 0;
522}
523
524static int iproc_pcie_map_ranges(struct iproc_pcie *pcie,
525 struct list_head *resources)
526{
Bjorn Helgaas786aecc2016-10-06 13:36:08 -0500527 struct device *dev = pcie->dev;
Ray Juie99a1872015-10-16 08:18:24 -0500528 struct resource_entry *window;
529 int ret;
530
531 resource_list_for_each_entry(window, resources) {
532 struct resource *res = window->res;
533 u64 res_type = resource_type(res);
534
535 switch (res_type) {
536 case IORESOURCE_IO:
537 case IORESOURCE_BUS:
538 break;
539 case IORESOURCE_MEM:
540 ret = iproc_pcie_setup_ob(pcie, res->start,
541 res->start - window->offset,
542 resource_size(res));
543 if (ret)
544 return ret;
545 break;
546 default:
Bjorn Helgaas786aecc2016-10-06 13:36:08 -0500547 dev_err(dev, "invalid resource %pR\n", res);
Ray Juie99a1872015-10-16 08:18:24 -0500548 return -EINVAL;
549 }
550 }
551
552 return 0;
553}
554
Ray Jui787b3c42016-10-31 17:38:35 -0700555static int iproce_pcie_get_msi(struct iproc_pcie *pcie,
556 struct device_node *msi_node,
557 u64 *msi_addr)
558{
559 struct device *dev = pcie->dev;
560 int ret;
561 struct resource res;
562
563 /*
564 * Check if 'msi-map' points to ARM GICv3 ITS, which is the only
565 * supported external MSI controller that requires steering.
566 */
567 if (!of_device_is_compatible(msi_node, "arm,gic-v3-its")) {
568 dev_err(dev, "unable to find compatible MSI controller\n");
569 return -ENODEV;
570 }
571
572 /* derive GITS_TRANSLATER address from GICv3 */
573 ret = of_address_to_resource(msi_node, 0, &res);
574 if (ret < 0) {
575 dev_err(dev, "unable to obtain MSI controller resources\n");
576 return ret;
577 }
578
579 *msi_addr = res.start + GITS_TRANSLATER;
580 return 0;
581}
582
583static void iproc_pcie_paxc_v2_msi_steer(struct iproc_pcie *pcie, u64 msi_addr)
584{
585 u32 val;
586
587 /*
588 * Program bits [43:13] of address of GITS_TRANSLATER register into
589 * bits [30:0] of the MSI base address register. In fact, in all iProc
590 * based SoCs, all I/O register bases are well below the 32-bit
591 * boundary, so we can safely assume bits [43:32] are always zeros.
592 */
593 iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_BASE_ADDR,
594 (u32)(msi_addr >> 13));
595
596 /* use a default 8K window size */
597 iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_WINDOW_SIZE, 0);
598
599 /* steering MSI to GICv3 ITS */
600 val = iproc_pcie_read_reg(pcie, IPROC_PCIE_MSI_GIC_MODE);
601 val |= GIC_V3_CFG;
602 iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_GIC_MODE, val);
603
604 /*
605 * Program bits [43:2] of address of GITS_TRANSLATER register into the
606 * iProc MSI address registers.
607 */
608 msi_addr >>= 2;
609 iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_ADDR_HI,
610 upper_32_bits(msi_addr));
611 iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_ADDR_LO,
612 lower_32_bits(msi_addr));
613
614 /* enable MSI */
615 val = iproc_pcie_read_reg(pcie, IPROC_PCIE_MSI_EN_CFG);
616 val |= MSI_ENABLE_CFG;
617 iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_EN_CFG, val);
618}
619
620static int iproc_pcie_msi_steer(struct iproc_pcie *pcie,
621 struct device_node *msi_node)
622{
623 struct device *dev = pcie->dev;
624 int ret;
625 u64 msi_addr;
626
627 ret = iproce_pcie_get_msi(pcie, msi_node, &msi_addr);
628 if (ret < 0) {
629 dev_err(dev, "msi steering failed\n");
630 return ret;
631 }
632
633 switch (pcie->type) {
634 case IPROC_PCIE_PAXC_V2:
635 iproc_pcie_paxc_v2_msi_steer(pcie, msi_addr);
636 break;
637 default:
638 return -EINVAL;
639 }
640
641 return 0;
642}
643
Ray Jui3bc2b232016-01-06 18:04:35 -0600644static int iproc_pcie_msi_enable(struct iproc_pcie *pcie)
645{
646 struct device_node *msi_node;
Ray Jui787b3c42016-10-31 17:38:35 -0700647 int ret;
648
649 /*
650 * Either the "msi-parent" or the "msi-map" phandle needs to exist
651 * for us to obtain the MSI node.
652 */
Ray Jui3bc2b232016-01-06 18:04:35 -0600653
654 msi_node = of_parse_phandle(pcie->dev->of_node, "msi-parent", 0);
Ray Jui787b3c42016-10-31 17:38:35 -0700655 if (!msi_node) {
656 const __be32 *msi_map = NULL;
657 int len;
658 u32 phandle;
659
660 msi_map = of_get_property(pcie->dev->of_node, "msi-map", &len);
661 if (!msi_map)
662 return -ENODEV;
663
664 phandle = be32_to_cpup(msi_map + 1);
665 msi_node = of_find_node_by_phandle(phandle);
666 if (!msi_node)
667 return -ENODEV;
668 }
669
670 /*
671 * Certain revisions of the iProc PCIe controller require additional
672 * configurations to steer the MSI writes towards an external MSI
673 * controller.
674 */
675 if (pcie->need_msi_steer) {
676 ret = iproc_pcie_msi_steer(pcie, msi_node);
677 if (ret)
678 return ret;
679 }
Ray Jui3bc2b232016-01-06 18:04:35 -0600680
681 /*
682 * If another MSI controller is being used, the call below should fail
683 * but that is okay
684 */
685 return iproc_msi_init(pcie, msi_node);
686}
687
688static void iproc_pcie_msi_disable(struct iproc_pcie *pcie)
689{
690 iproc_msi_exit(pcie);
691}
692
Ray Jui06324ed2016-10-31 17:38:30 -0700693static int iproc_pcie_rev_init(struct iproc_pcie *pcie)
694{
695 struct device *dev = pcie->dev;
696 unsigned int reg_idx;
697 const u16 *regs;
698
699 switch (pcie->type) {
Ray Jui404349c2016-10-31 17:38:32 -0700700 case IPROC_PCIE_PAXB_BCMA:
701 regs = iproc_pcie_reg_paxb_bcma;
702 break;
Ray Jui06324ed2016-10-31 17:38:30 -0700703 case IPROC_PCIE_PAXB:
704 regs = iproc_pcie_reg_paxb;
Ray Jui538928f2016-10-31 17:38:33 -0700705 pcie->has_apb_err_disable = true;
Ray Jui06324ed2016-10-31 17:38:30 -0700706 break;
707 case IPROC_PCIE_PAXC:
708 regs = iproc_pcie_reg_paxc;
709 pcie->ep_is_internal = true;
710 break;
Ray Jui787b3c42016-10-31 17:38:35 -0700711 case IPROC_PCIE_PAXC_V2:
712 regs = iproc_pcie_reg_paxc_v2;
713 pcie->ep_is_internal = true;
714 pcie->need_msi_steer = true;
715 break;
Ray Jui06324ed2016-10-31 17:38:30 -0700716 default:
717 dev_err(dev, "incompatible iProc PCIe interface\n");
718 return -EINVAL;
719 }
720
721 pcie->reg_offsets = devm_kcalloc(dev, IPROC_PCIE_MAX_NUM_REG,
722 sizeof(*pcie->reg_offsets),
723 GFP_KERNEL);
724 if (!pcie->reg_offsets)
725 return -ENOMEM;
726
727 /* go through the register table and populate all valid registers */
Ray Jui787b3c42016-10-31 17:38:35 -0700728 pcie->reg_offsets[0] = (pcie->type == IPROC_PCIE_PAXC_V2) ?
729 IPROC_PCIE_REG_INVALID : regs[0];
Ray Jui06324ed2016-10-31 17:38:30 -0700730 for (reg_idx = 1; reg_idx < IPROC_PCIE_MAX_NUM_REG; reg_idx++)
731 pcie->reg_offsets[reg_idx] = regs[reg_idx] ?
732 regs[reg_idx] : IPROC_PCIE_REG_INVALID;
733
734 return 0;
735}
736
Hauke Mehrtens18c43422015-05-24 22:37:02 +0200737int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
Ray Jui1fb37a82015-04-08 11:21:35 -0700738{
Bjorn Helgaas786aecc2016-10-06 13:36:08 -0500739 struct device *dev;
Ray Jui1fb37a82015-04-08 11:21:35 -0700740 int ret;
Ray Jui8d9bfe32015-07-21 18:29:40 -0700741 void *sysdata;
Ray Jui1fb37a82015-04-08 11:21:35 -0700742 struct pci_bus *bus;
743
Bjorn Helgaas786aecc2016-10-06 13:36:08 -0500744 dev = pcie->dev;
Ray Jui06324ed2016-10-31 17:38:30 -0700745
746 ret = iproc_pcie_rev_init(pcie);
747 if (ret) {
748 dev_err(dev, "unable to initialize controller parameters\n");
749 return ret;
750 }
751
Bjorn Helgaas786aecc2016-10-06 13:36:08 -0500752 ret = devm_request_pci_bus_resources(dev, res);
Bjorn Helgaasc3245a52016-05-28 18:22:24 -0500753 if (ret)
754 return ret;
755
Markus Elfring93972d12015-06-28 16:42:04 +0200756 ret = phy_init(pcie->phy);
757 if (ret) {
Bjorn Helgaas786aecc2016-10-06 13:36:08 -0500758 dev_err(dev, "unable to initialize PCIe PHY\n");
Markus Elfring93972d12015-06-28 16:42:04 +0200759 return ret;
760 }
Ray Jui1fb37a82015-04-08 11:21:35 -0700761
Markus Elfring93972d12015-06-28 16:42:04 +0200762 ret = phy_power_on(pcie->phy);
763 if (ret) {
Bjorn Helgaas786aecc2016-10-06 13:36:08 -0500764 dev_err(dev, "unable to power on PCIe PHY\n");
Markus Elfring93972d12015-06-28 16:42:04 +0200765 goto err_exit_phy;
Ray Jui1fb37a82015-04-08 11:21:35 -0700766 }
767
768 iproc_pcie_reset(pcie);
769
Ray Juie99a1872015-10-16 08:18:24 -0500770 if (pcie->need_ob_cfg) {
771 ret = iproc_pcie_map_ranges(pcie, res);
772 if (ret) {
Bjorn Helgaas786aecc2016-10-06 13:36:08 -0500773 dev_err(dev, "map failed\n");
Ray Juie99a1872015-10-16 08:18:24 -0500774 goto err_power_off_phy;
775 }
776 }
777
Ray Jui8d9bfe32015-07-21 18:29:40 -0700778#ifdef CONFIG_ARM
Ray Jui1fb37a82015-04-08 11:21:35 -0700779 pcie->sysdata.private_data = pcie;
Ray Jui8d9bfe32015-07-21 18:29:40 -0700780 sysdata = &pcie->sysdata;
781#else
782 sysdata = pcie;
783#endif
Ray Jui1fb37a82015-04-08 11:21:35 -0700784
Bjorn Helgaas786aecc2016-10-06 13:36:08 -0500785 bus = pci_create_root_bus(dev, 0, &iproc_pcie_ops, sysdata, res);
Ray Jui1fb37a82015-04-08 11:21:35 -0700786 if (!bus) {
Bjorn Helgaas786aecc2016-10-06 13:36:08 -0500787 dev_err(dev, "unable to create PCI root bus\n");
Ray Jui1fb37a82015-04-08 11:21:35 -0700788 ret = -ENOMEM;
789 goto err_power_off_phy;
790 }
791 pcie->root_bus = bus;
792
793 ret = iproc_pcie_check_link(pcie, bus);
794 if (ret) {
Bjorn Helgaas786aecc2016-10-06 13:36:08 -0500795 dev_err(dev, "no PCIe EP device detected\n");
Ray Jui1fb37a82015-04-08 11:21:35 -0700796 goto err_rm_root_bus;
797 }
798
799 iproc_pcie_enable(pcie);
800
Ray Jui3bc2b232016-01-06 18:04:35 -0600801 if (IS_ENABLED(CONFIG_PCI_MSI))
802 if (iproc_pcie_msi_enable(pcie))
Bjorn Helgaas786aecc2016-10-06 13:36:08 -0500803 dev_info(dev, "not using iProc MSI\n");
Ray Jui3bc2b232016-01-06 18:04:35 -0600804
Ray Jui1fb37a82015-04-08 11:21:35 -0700805 pci_scan_child_bus(bus);
806 pci_assign_unassigned_bus_resources(bus);
Hauke Mehrtensc1e02ce2015-05-12 23:23:00 +0200807 pci_fixup_irqs(pci_common_swizzle, pcie->map_irq);
Ray Jui1fb37a82015-04-08 11:21:35 -0700808 pci_bus_add_devices(bus);
809
810 return 0;
811
812err_rm_root_bus:
813 pci_stop_root_bus(bus);
814 pci_remove_root_bus(bus);
815
816err_power_off_phy:
Markus Elfring93972d12015-06-28 16:42:04 +0200817 phy_power_off(pcie->phy);
Ray Jui1fb37a82015-04-08 11:21:35 -0700818err_exit_phy:
Markus Elfring93972d12015-06-28 16:42:04 +0200819 phy_exit(pcie->phy);
Ray Jui1fb37a82015-04-08 11:21:35 -0700820 return ret;
821}
822EXPORT_SYMBOL(iproc_pcie_setup);
823
824int iproc_pcie_remove(struct iproc_pcie *pcie)
825{
826 pci_stop_root_bus(pcie->root_bus);
827 pci_remove_root_bus(pcie->root_bus);
828
Ray Jui3bc2b232016-01-06 18:04:35 -0600829 iproc_pcie_msi_disable(pcie);
830
Markus Elfring93972d12015-06-28 16:42:04 +0200831 phy_power_off(pcie->phy);
832 phy_exit(pcie->phy);
Ray Jui1fb37a82015-04-08 11:21:35 -0700833
834 return 0;
835}
836EXPORT_SYMBOL(iproc_pcie_remove);
837
838MODULE_AUTHOR("Ray Jui <rjui@broadcom.com>");
839MODULE_DESCRIPTION("Broadcom iPROC PCIe common driver");
840MODULE_LICENSE("GPL v2");