blob: 2e2fa3187794674942713732497a2abfad7ec8fb [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0
Anton Schubert9c28d612015-08-11 11:54:01 +02002/*
3 * PCIe driver for Marvell MVEBU SoCs
4 *
5 * Based on Barebox drivers/pci/pci-mvebu.c
6 *
7 * Ported to U-Boot by:
8 * Anton Schubert <anton.schubert@gmx.de>
9 * Stefan Roese <sr@denx.de>
Pali Rohár22f69fc2021-12-16 12:04:06 +010010 * Pali Rohár <pali@kernel.org>
Anton Schubert9c28d612015-08-11 11:54:01 +020011 */
12
13#include <common.h>
Stefan Roese94f453e2019-01-25 11:52:43 +010014#include <dm.h>
Simon Glassf7ae49f2020-05-10 11:40:05 -060015#include <log.h>
Simon Glass336d4612020-02-03 07:36:16 -070016#include <malloc.h>
Stefan Roese94f453e2019-01-25 11:52:43 +010017#include <dm/device-internal.h>
18#include <dm/lists.h>
19#include <dm/of_access.h>
Anton Schubert9c28d612015-08-11 11:54:01 +020020#include <pci.h>
Anton Schubert9c28d612015-08-11 11:54:01 +020021#include <asm/io.h>
22#include <asm/arch/cpu.h>
23#include <asm/arch/soc.h>
Simon Glasscd93d622020-05-10 11:40:13 -060024#include <linux/bitops.h>
Stefan Roese94f453e2019-01-25 11:52:43 +010025#include <linux/errno.h>
26#include <linux/ioport.h>
Anton Schubert9c28d612015-08-11 11:54:01 +020027#include <linux/mbus.h>
Pali Rohár537b0142021-12-21 12:20:13 +010028#include <linux/sizes.h>
Anton Schubert9c28d612015-08-11 11:54:01 +020029
Anton Schubert9c28d612015-08-11 11:54:01 +020030/* PCIe unit register offsets */
31#define SELECT(x, n) ((x >> n) & 1UL)
32
33#define PCIE_DEV_ID_OFF 0x0000
34#define PCIE_CMD_OFF 0x0004
35#define PCIE_DEV_REV_OFF 0x0008
36#define PCIE_BAR_LO_OFF(n) (0x0010 + ((n) << 3))
37#define PCIE_BAR_HI_OFF(n) (0x0014 + ((n) << 3))
Pali Rohára7b61ab2021-10-22 16:22:10 +020038#define PCIE_EXP_ROM_BAR_OFF 0x0030
Anton Schubert9c28d612015-08-11 11:54:01 +020039#define PCIE_CAPAB_OFF 0x0060
40#define PCIE_CTRL_STAT_OFF 0x0068
41#define PCIE_HEADER_LOG_4_OFF 0x0128
42#define PCIE_BAR_CTRL_OFF(n) (0x1804 + (((n) - 1) * 4))
43#define PCIE_WIN04_CTRL_OFF(n) (0x1820 + ((n) << 4))
44#define PCIE_WIN04_BASE_OFF(n) (0x1824 + ((n) << 4))
45#define PCIE_WIN04_REMAP_OFF(n) (0x182c + ((n) << 4))
46#define PCIE_WIN5_CTRL_OFF 0x1880
47#define PCIE_WIN5_BASE_OFF 0x1884
48#define PCIE_WIN5_REMAP_OFF 0x188c
49#define PCIE_CONF_ADDR_OFF 0x18f8
Anton Schubert9c28d612015-08-11 11:54:01 +020050#define PCIE_CONF_DATA_OFF 0x18fc
51#define PCIE_MASK_OFF 0x1910
52#define PCIE_MASK_ENABLE_INTS (0xf << 24)
53#define PCIE_CTRL_OFF 0x1a00
54#define PCIE_CTRL_X1_MODE BIT(0)
Pali Rohár2344a762021-10-22 16:22:14 +020055#define PCIE_CTRL_RC_MODE BIT(1)
Anton Schubert9c28d612015-08-11 11:54:01 +020056#define PCIE_STAT_OFF 0x1a04
57#define PCIE_STAT_BUS (0xff << 8)
58#define PCIE_STAT_DEV (0x1f << 16)
59#define PCIE_STAT_LINK_DOWN BIT(0)
60#define PCIE_DEBUG_CTRL 0x1a60
61#define PCIE_DEBUG_SOFT_RESET BIT(20)
62
Anton Schubert9c28d612015-08-11 11:54:01 +020063struct mvebu_pcie {
64 struct pci_controller hose;
Anton Schubert9c28d612015-08-11 11:54:01 +020065 void __iomem *base;
66 void __iomem *membase;
67 struct resource mem;
68 void __iomem *iobase;
Phil Sutterba8ae032021-01-03 23:06:46 +010069 struct resource io;
Anton Schubert9c28d612015-08-11 11:54:01 +020070 u32 port;
71 u32 lane;
Stefan Roese94f453e2019-01-25 11:52:43 +010072 int devfn;
Anton Schubert9c28d612015-08-11 11:54:01 +020073 u32 lane_mask;
Marek Behún10eb2cc2021-02-08 23:01:40 +010074 int first_busno;
Pali Rohára7b61ab2021-10-22 16:22:10 +020075 int sec_busno;
Stefan Roese94f453e2019-01-25 11:52:43 +010076 char name[16];
77 unsigned int mem_target;
78 unsigned int mem_attr;
Phil Sutterba8ae032021-01-03 23:06:46 +010079 unsigned int io_target;
80 unsigned int io_attr;
Pali Rohára48e4282021-11-11 16:35:45 +010081 u32 cfgcache[(0x3c - 0x10) / 4];
Anton Schubert9c28d612015-08-11 11:54:01 +020082};
83
Anton Schubert9c28d612015-08-11 11:54:01 +020084static inline bool mvebu_pcie_link_up(struct mvebu_pcie *pcie)
85{
86 u32 val;
87 val = readl(pcie->base + PCIE_STAT_OFF);
88 return !(val & PCIE_STAT_LINK_DOWN);
89}
90
91static void mvebu_pcie_set_local_bus_nr(struct mvebu_pcie *pcie, int busno)
92{
93 u32 stat;
94
95 stat = readl(pcie->base + PCIE_STAT_OFF);
96 stat &= ~PCIE_STAT_BUS;
97 stat |= busno << 8;
98 writel(stat, pcie->base + PCIE_STAT_OFF);
99}
100
101static void mvebu_pcie_set_local_dev_nr(struct mvebu_pcie *pcie, int devno)
102{
103 u32 stat;
104
105 stat = readl(pcie->base + PCIE_STAT_OFF);
106 stat &= ~PCIE_STAT_DEV;
107 stat |= devno << 16;
108 writel(stat, pcie->base + PCIE_STAT_OFF);
109}
110
Anton Schubert9c28d612015-08-11 11:54:01 +0200111static inline struct mvebu_pcie *hose_to_pcie(struct pci_controller *hose)
112{
113 return container_of(hose, struct mvebu_pcie, hose);
114}
115
Pali Rohára7b61ab2021-10-22 16:22:10 +0200116static bool mvebu_pcie_valid_addr(struct mvebu_pcie *pcie,
117 int busno, int dev, int func)
Marek Behún10eb2cc2021-02-08 23:01:40 +0100118{
Pali Rohára7b61ab2021-10-22 16:22:10 +0200119 /* On primary bus is only one PCI Bridge */
120 if (busno == pcie->first_busno && (dev != 0 || func != 0))
121 return false;
Marek Behún10eb2cc2021-02-08 23:01:40 +0100122
Pali Rohár79b4eb22021-10-22 16:22:12 +0200123 /* Access to other buses is possible when link is up */
124 if (busno != pcie->first_busno && !mvebu_pcie_link_up(pcie))
125 return false;
126
Pali Rohára7b61ab2021-10-22 16:22:10 +0200127 /* On secondary bus can be only one PCIe device */
128 if (busno == pcie->sec_busno && dev != 0)
129 return false;
130
131 return true;
Marek Behún10eb2cc2021-02-08 23:01:40 +0100132}
133
Simon Glassc4e72c42020-01-27 08:49:37 -0700134static int mvebu_pcie_read_config(const struct udevice *bus, pci_dev_t bdf,
Stefan Roese94f453e2019-01-25 11:52:43 +0100135 uint offset, ulong *valuep,
136 enum pci_size_t size)
Anton Schubert9c28d612015-08-11 11:54:01 +0200137{
Simon Glassc69cda22020-12-03 16:55:20 -0700138 struct mvebu_pcie *pcie = dev_get_plat(bus);
Pali Rohára7b61ab2021-10-22 16:22:10 +0200139 int busno = PCI_BUS(bdf) - dev_seq(bus);
140 u32 addr, data;
Stefan Roese94f453e2019-01-25 11:52:43 +0100141
Marek Behún10eb2cc2021-02-08 23:01:40 +0100142 debug("PCIE CFG read: (b,d,f)=(%2d,%2d,%2d) ",
143 PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
Anton Schubert9c28d612015-08-11 11:54:01 +0200144
Pali Rohára7b61ab2021-10-22 16:22:10 +0200145 if (!mvebu_pcie_valid_addr(pcie, busno, PCI_DEV(bdf), PCI_FUNC(bdf))) {
Stefan Roese6a2fa282021-01-25 15:25:31 +0100146 debug("- out of range\n");
147 *valuep = pci_get_ff(size);
148 return 0;
Anton Schubert9c28d612015-08-11 11:54:01 +0200149 }
150
Pali Rohára7b61ab2021-10-22 16:22:10 +0200151 /*
Pali Rohára48e4282021-11-11 16:35:45 +0100152 * The configuration space of the PCI Bridge on primary (first) bus is
153 * of Type 0 but the BAR registers (including ROM BAR) don't have the
154 * same meaning as in the PCIe specification. Therefore do not access
155 * BAR registers and non-common registers (those which have different
156 * meaning for Type 0 and Type 1 config space) of the PCI Bridge and
157 * instead read their content from driver virtual cfgcache[].
Pali Rohára7b61ab2021-10-22 16:22:10 +0200158 */
Pali Rohára48e4282021-11-11 16:35:45 +0100159 if (busno == pcie->first_busno && ((offset >= 0x10 && offset < 0x34) ||
160 (offset >= 0x38 && offset < 0x3c))) {
Pali Rohára7b61ab2021-10-22 16:22:10 +0200161 data = pcie->cfgcache[(offset - 0x10) / 4];
162 debug("(addr,size,val)=(0x%04x, %d, 0x%08x) from cfgcache\n",
163 offset, size, data);
164 *valuep = pci_conv_32_to_size(data, offset, size);
165 return 0;
Pali Rohára7b61ab2021-10-22 16:22:10 +0200166 }
167
168 /*
169 * PCI bridge is device 0 at primary bus but mvebu has it mapped on
170 * secondary bus with device number 1.
171 */
172 if (busno == pcie->first_busno)
Pali Rohárd0dd49f2021-11-26 11:42:45 +0100173 addr = PCI_CONF1_EXT_ADDRESS(pcie->sec_busno, 1, 0, offset);
Pali Rohára7b61ab2021-10-22 16:22:10 +0200174 else
Pali Rohárd0dd49f2021-11-26 11:42:45 +0100175 addr = PCI_CONF1_EXT_ADDRESS(busno, PCI_DEV(bdf), PCI_FUNC(bdf), offset);
Pali Rohára7b61ab2021-10-22 16:22:10 +0200176
Anton Schubert9c28d612015-08-11 11:54:01 +0200177 /* write address */
Pali Rohára7b61ab2021-10-22 16:22:10 +0200178 writel(addr, pcie->base + PCIE_CONF_ADDR_OFF);
Marek Behún241d7632021-02-08 23:01:38 +0100179
180 /* read data */
Pali Rohár657177a2021-10-22 16:22:09 +0200181 switch (size) {
182 case PCI_SIZE_8:
183 data = readb(pcie->base + PCIE_CONF_DATA_OFF + (offset & 3));
184 break;
185 case PCI_SIZE_16:
186 data = readw(pcie->base + PCIE_CONF_DATA_OFF + (offset & 2));
187 break;
188 case PCI_SIZE_32:
189 data = readl(pcie->base + PCIE_CONF_DATA_OFF);
190 break;
191 default:
192 return -EINVAL;
193 }
194
Pali Rohára7b61ab2021-10-22 16:22:10 +0200195 if (busno == pcie->first_busno &&
196 (offset & ~3) == (PCI_HEADER_TYPE & ~3)) {
197 /*
198 * Change Header Type of PCI Bridge device to Type 1
199 * (0x01, used by PCI Bridges) because mvebu reports
200 * Type 0 (0x00, used by Upstream and Endpoint devices).
201 */
202 data = pci_conv_size_to_32(data, 0, offset, size);
203 data &= ~0x007f0000;
204 data |= PCI_HEADER_TYPE_BRIDGE << 16;
205 data = pci_conv_32_to_size(data, offset, size);
206 }
207
Marek Behún26f7a762021-02-08 23:01:39 +0100208 debug("(addr,size,val)=(0x%04x, %d, 0x%08x)\n", offset, size, data);
Pali Rohár657177a2021-10-22 16:22:09 +0200209 *valuep = data;
Anton Schubert9c28d612015-08-11 11:54:01 +0200210
211 return 0;
212}
213
Stefan Roese94f453e2019-01-25 11:52:43 +0100214static int mvebu_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
215 uint offset, ulong value,
216 enum pci_size_t size)
Anton Schubert9c28d612015-08-11 11:54:01 +0200217{
Simon Glassc69cda22020-12-03 16:55:20 -0700218 struct mvebu_pcie *pcie = dev_get_plat(bus);
Pali Rohára7b61ab2021-10-22 16:22:10 +0200219 int busno = PCI_BUS(bdf) - dev_seq(bus);
220 u32 addr, data;
Stefan Roese94f453e2019-01-25 11:52:43 +0100221
Marek Behún10eb2cc2021-02-08 23:01:40 +0100222 debug("PCIE CFG write: (b,d,f)=(%2d,%2d,%2d) ",
223 PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
Marek Behún26f7a762021-02-08 23:01:39 +0100224 debug("(addr,size,val)=(0x%04x, %d, 0x%08lx)\n", offset, size, value);
Anton Schubert9c28d612015-08-11 11:54:01 +0200225
Pali Rohára7b61ab2021-10-22 16:22:10 +0200226 if (!mvebu_pcie_valid_addr(pcie, busno, PCI_DEV(bdf), PCI_FUNC(bdf))) {
Stefan Roese6a2fa282021-01-25 15:25:31 +0100227 debug("- out of range\n");
228 return 0;
Anton Schubert9c28d612015-08-11 11:54:01 +0200229 }
230
Pali Rohára7b61ab2021-10-22 16:22:10 +0200231 /*
Pali Rohára48e4282021-11-11 16:35:45 +0100232 * As explained in mvebu_pcie_read_config(), PCI Bridge Type 1 specific
233 * config registers are not available, so we write their content only
234 * into driver virtual cfgcache[].
235 * And as explained in mvebu_pcie_probe(), mvebu has its own specific
236 * way for configuring primary and secondary bus numbers.
Pali Rohára7b61ab2021-10-22 16:22:10 +0200237 */
Pali Rohára48e4282021-11-11 16:35:45 +0100238 if (busno == pcie->first_busno && ((offset >= 0x10 && offset < 0x34) ||
239 (offset >= 0x38 && offset < 0x3c))) {
Pali Rohára7b61ab2021-10-22 16:22:10 +0200240 debug("Writing to cfgcache only\n");
241 data = pcie->cfgcache[(offset - 0x10) / 4];
242 data = pci_conv_size_to_32(data, value, offset, size);
243 /* mvebu PCI bridge does not have configurable bars */
244 if ((offset & ~3) == PCI_BASE_ADDRESS_0 ||
Pali Rohára48e4282021-11-11 16:35:45 +0100245 (offset & ~3) == PCI_BASE_ADDRESS_1 ||
246 (offset & ~3) == PCI_ROM_ADDRESS1)
Pali Rohára7b61ab2021-10-22 16:22:10 +0200247 data = 0x0;
248 pcie->cfgcache[(offset - 0x10) / 4] = data;
249 /* mvebu has its own way how to set PCI primary bus number */
250 if (offset == PCI_PRIMARY_BUS) {
251 pcie->first_busno = data & 0xff;
252 debug("Primary bus number was changed to %d\n",
253 pcie->first_busno);
254 }
255 /* mvebu has its own way how to set PCI secondary bus number */
256 if (offset == PCI_SECONDARY_BUS ||
257 (offset == PCI_PRIMARY_BUS && size != PCI_SIZE_8)) {
258 pcie->sec_busno = (data >> 8) & 0xff;
259 mvebu_pcie_set_local_bus_nr(pcie, pcie->sec_busno);
260 debug("Secondary bus number was changed to %d\n",
261 pcie->sec_busno);
262 }
263 return 0;
Pali Rohára7b61ab2021-10-22 16:22:10 +0200264 }
265
266 /*
267 * PCI bridge is device 0 at primary bus but mvebu has it mapped on
268 * secondary bus with device number 1.
269 */
270 if (busno == pcie->first_busno)
Pali Rohárd0dd49f2021-11-26 11:42:45 +0100271 addr = PCI_CONF1_EXT_ADDRESS(pcie->sec_busno, 1, 0, offset);
Pali Rohára7b61ab2021-10-22 16:22:10 +0200272 else
Pali Rohárd0dd49f2021-11-26 11:42:45 +0100273 addr = PCI_CONF1_EXT_ADDRESS(busno, PCI_DEV(bdf), PCI_FUNC(bdf), offset);
Pali Rohára7b61ab2021-10-22 16:22:10 +0200274
Marek Behún241d7632021-02-08 23:01:38 +0100275 /* write address */
Pali Rohára7b61ab2021-10-22 16:22:10 +0200276 writel(addr, pcie->base + PCIE_CONF_ADDR_OFF);
Marek Behún241d7632021-02-08 23:01:38 +0100277
278 /* write data */
Pali Rohárdaa9bfd2021-10-22 16:22:08 +0200279 switch (size) {
280 case PCI_SIZE_8:
281 writeb(value, pcie->base + PCIE_CONF_DATA_OFF + (offset & 3));
282 break;
283 case PCI_SIZE_16:
284 writew(value, pcie->base + PCIE_CONF_DATA_OFF + (offset & 2));
285 break;
286 case PCI_SIZE_32:
287 writel(value, pcie->base + PCIE_CONF_DATA_OFF);
288 break;
289 default:
290 return -EINVAL;
291 }
Anton Schubert9c28d612015-08-11 11:54:01 +0200292
293 return 0;
294}
295
296/*
297 * Setup PCIE BARs and Address Decode Wins:
Pali Rohár4a1a5932021-11-11 16:35:42 +0100298 * BAR[0] -> internal registers
299 * BAR[1] -> covers all DRAM banks
300 * BAR[2] -> disabled
Anton Schubert9c28d612015-08-11 11:54:01 +0200301 * WIN[0-3] -> DRAM bank[0-3]
302 */
303static void mvebu_pcie_setup_wins(struct mvebu_pcie *pcie)
304{
305 const struct mbus_dram_target_info *dram = mvebu_mbus_dram_info();
306 u32 size;
307 int i;
308
309 /* First, disable and clear BARs and windows. */
310 for (i = 1; i < 3; i++) {
311 writel(0, pcie->base + PCIE_BAR_CTRL_OFF(i));
312 writel(0, pcie->base + PCIE_BAR_LO_OFF(i));
313 writel(0, pcie->base + PCIE_BAR_HI_OFF(i));
314 }
315
316 for (i = 0; i < 5; i++) {
317 writel(0, pcie->base + PCIE_WIN04_CTRL_OFF(i));
318 writel(0, pcie->base + PCIE_WIN04_BASE_OFF(i));
319 writel(0, pcie->base + PCIE_WIN04_REMAP_OFF(i));
320 }
321
322 writel(0, pcie->base + PCIE_WIN5_CTRL_OFF);
323 writel(0, pcie->base + PCIE_WIN5_BASE_OFF);
324 writel(0, pcie->base + PCIE_WIN5_REMAP_OFF);
325
326 /* Setup windows for DDR banks. Count total DDR size on the fly. */
327 size = 0;
328 for (i = 0; i < dram->num_cs; i++) {
329 const struct mbus_dram_window *cs = dram->cs + i;
330
331 writel(cs->base & 0xffff0000,
332 pcie->base + PCIE_WIN04_BASE_OFF(i));
333 writel(0, pcie->base + PCIE_WIN04_REMAP_OFF(i));
334 writel(((cs->size - 1) & 0xffff0000) |
335 (cs->mbus_attr << 8) |
336 (dram->mbus_dram_target_id << 4) | 1,
337 pcie->base + PCIE_WIN04_CTRL_OFF(i));
338
339 size += cs->size;
340 }
341
342 /* Round up 'size' to the nearest power of two. */
343 if ((size & (size - 1)) != 0)
344 size = 1 << fls(size);
345
346 /* Setup BAR[1] to all DRAM banks. */
347 writel(dram->cs[0].base | 0xc, pcie->base + PCIE_BAR_LO_OFF(1));
348 writel(0, pcie->base + PCIE_BAR_HI_OFF(1));
349 writel(((size - 1) & 0xffff0000) | 0x1,
350 pcie->base + PCIE_BAR_CTRL_OFF(1));
Pali Rohár4a1a5932021-11-11 16:35:42 +0100351
352 /* Setup BAR[0] to internal registers. */
353 writel(SOC_REGS_PHY_BASE, pcie->base + PCIE_BAR_LO_OFF(0));
354 writel(0, pcie->base + PCIE_BAR_HI_OFF(0));
Anton Schubert9c28d612015-08-11 11:54:01 +0200355}
356
Stefan Roese94f453e2019-01-25 11:52:43 +0100357static int mvebu_pcie_probe(struct udevice *dev)
Anton Schubert9c28d612015-08-11 11:54:01 +0200358{
Simon Glassc69cda22020-12-03 16:55:20 -0700359 struct mvebu_pcie *pcie = dev_get_plat(dev);
Stefan Roese94f453e2019-01-25 11:52:43 +0100360 struct udevice *ctlr = pci_get_controller(dev);
361 struct pci_controller *hose = dev_get_uclass_priv(ctlr);
Anton Schubert9c28d612015-08-11 11:54:01 +0200362 u32 reg;
Anton Schubert9c28d612015-08-11 11:54:01 +0200363
Pali Rohár2344a762021-10-22 16:22:14 +0200364 /* Setup PCIe controller to Root Complex mode */
365 reg = readl(pcie->base + PCIE_CTRL_OFF);
366 reg |= PCIE_CTRL_RC_MODE;
367 writel(reg, pcie->base + PCIE_CTRL_OFF);
368
Pali Rohára7b61ab2021-10-22 16:22:10 +0200369 /*
370 * Change Class Code of PCI Bridge device to PCI Bridge (0x600400)
371 * because default value is Memory controller (0x508000) which
372 * U-Boot cannot recognize as P2P Bridge.
373 *
374 * Note that this mvebu PCI Bridge does not have compliant Type 1
Pali Rohára48e4282021-11-11 16:35:45 +0100375 * Configuration Space. Header Type is reported as Type 0 and it
376 * has format of Type 0 config space.
Pali Rohára7b61ab2021-10-22 16:22:10 +0200377 *
Pali Rohára48e4282021-11-11 16:35:45 +0100378 * Moreover Type 0 BAR registers (ranges 0x10 - 0x28 and 0x30 - 0x34)
379 * have the same format in Marvell's specification as in PCIe
380 * specification, but their meaning is totally different and they do
381 * different things: they are aliased into internal mvebu registers
382 * (e.g. PCIE_BAR_LO_OFF) and these should not be changed or
383 * reconfigured by pci device drivers.
384 *
385 * So our driver converts Type 0 config space to Type 1 and reports
386 * Header Type as Type 1. Access to BAR registers and to non-existent
387 * Type 1 registers is redirected to the virtual cfgcache[] buffer,
388 * which avoids changing unrelated registers.
Pali Rohára7b61ab2021-10-22 16:22:10 +0200389 */
390 reg = readl(pcie->base + PCIE_DEV_REV_OFF);
391 reg &= ~0xffffff00;
392 reg |= (PCI_CLASS_BRIDGE_PCI << 8) << 8;
393 writel(reg, pcie->base + PCIE_DEV_REV_OFF);
Anton Schubert9c28d612015-08-11 11:54:01 +0200394
Pali Rohára7b61ab2021-10-22 16:22:10 +0200395 /*
396 * mvebu uses local bus number and local device number to determinate
397 * type of config request. Type 0 is used if target bus number equals
398 * local bus number and target device number differs from local device
399 * number. Type 1 is used if target bus number differs from local bus
400 * number. And when target bus number equals local bus number and
401 * target device equals local device number then request is routed to
402 * PCI Bridge which represent local PCIe Root Port.
403 *
404 * It means that PCI primary and secondary buses shares one bus number
405 * which is configured via local bus number. Determination if config
406 * request should go to primary or secondary bus is done based on local
407 * device number.
408 *
409 * PCIe is point-to-point bus, so at secondary bus is always exactly one
410 * device with number 0. So set local device number to 1, it would not
411 * conflict with any device on secondary bus number and will ensure that
412 * accessing secondary bus and all buses behind secondary would work
413 * automatically and correctly. Therefore this configuration of local
414 * device number implies that setting of local bus number configures
415 * secondary bus number. Set it to 0 as U-Boot CONFIG_PCI_PNP code will
416 * later configure it via config write requests to the correct value.
417 * mvebu_pcie_write_config() catches config write requests which tries
418 * to change primary/secondary bus number and correctly updates local
419 * bus number based on new secondary bus number.
420 *
421 * With this configuration is PCI Bridge available at secondary bus as
422 * device number 1. But it must be available at primary bus as device
423 * number 0. So in mvebu_pcie_read_config() and mvebu_pcie_write_config()
424 * functions rewrite address to the real one when accessing primary bus.
425 */
426 mvebu_pcie_set_local_bus_nr(pcie, 0);
427 mvebu_pcie_set_local_dev_nr(pcie, 1);
Anton Schubert9c28d612015-08-11 11:54:01 +0200428
Pali Rohár537b0142021-12-21 12:20:13 +0100429 if (resource_size(&pcie->mem) &&
430 mvebu_mbus_add_window_by_id(pcie->mem_target, pcie->mem_attr,
Stefan Roese94f453e2019-01-25 11:52:43 +0100431 (phys_addr_t)pcie->mem.start,
Pali Roháre1cee892021-11-11 16:35:43 +0100432 resource_size(&pcie->mem))) {
Stefan Roese94f453e2019-01-25 11:52:43 +0100433 printf("PCIe unable to add mbus window for mem at %08x+%08x\n",
Pali Roháre1cee892021-11-11 16:35:43 +0100434 (u32)pcie->mem.start, (unsigned)resource_size(&pcie->mem));
Pali Rohár537b0142021-12-21 12:20:13 +0100435 pcie->mem.start = 0;
436 pcie->mem.end = -1;
Stefan Roese94f453e2019-01-25 11:52:43 +0100437 }
438
Pali Rohár537b0142021-12-21 12:20:13 +0100439 if (resource_size(&pcie->io) &&
440 mvebu_mbus_add_window_by_id(pcie->io_target, pcie->io_attr,
Phil Sutterba8ae032021-01-03 23:06:46 +0100441 (phys_addr_t)pcie->io.start,
Pali Roháre1cee892021-11-11 16:35:43 +0100442 resource_size(&pcie->io))) {
Phil Sutterba8ae032021-01-03 23:06:46 +0100443 printf("PCIe unable to add mbus window for IO at %08x+%08x\n",
Pali Roháre1cee892021-11-11 16:35:43 +0100444 (u32)pcie->io.start, (unsigned)resource_size(&pcie->io));
Pali Rohár537b0142021-12-21 12:20:13 +0100445 pcie->io.start = 0;
446 pcie->io.end = -1;
Phil Sutterba8ae032021-01-03 23:06:46 +0100447 }
448
Stefan Roese94f453e2019-01-25 11:52:43 +0100449 /* Setup windows and configure host bridge */
450 mvebu_pcie_setup_wins(pcie);
451
Stefan Roese94f453e2019-01-25 11:52:43 +0100452 /* PCI memory space */
453 pci_set_region(hose->regions + 0, pcie->mem.start,
Pali Roháre1cee892021-11-11 16:35:43 +0100454 pcie->mem.start, resource_size(&pcie->mem), PCI_REGION_MEM);
Pali Rohár537b0142021-12-21 12:20:13 +0100455 hose->region_count = 1;
456
457 if (resource_size(&pcie->mem)) {
458 pci_set_region(hose->regions + hose->region_count,
459 pcie->mem.start, pcie->mem.start,
460 resource_size(&pcie->mem),
461 PCI_REGION_MEM);
462 hose->region_count++;
463 }
464
465 if (resource_size(&pcie->io)) {
466 pci_set_region(hose->regions + hose->region_count,
467 pcie->io.start, pcie->io.start,
468 resource_size(&pcie->io),
469 PCI_REGION_IO);
470 hose->region_count++;
471 }
Stefan Roese94f453e2019-01-25 11:52:43 +0100472
Pali Rohára7b61ab2021-10-22 16:22:10 +0200473 /* PCI Bridge support 32-bit I/O and 64-bit prefetch mem addressing */
474 pcie->cfgcache[(PCI_IO_BASE - 0x10) / 4] =
475 PCI_IO_RANGE_TYPE_32 | (PCI_IO_RANGE_TYPE_32 << 8);
476 pcie->cfgcache[(PCI_PREF_MEMORY_BASE - 0x10) / 4] =
477 PCI_PREF_RANGE_TYPE_64 | (PCI_PREF_RANGE_TYPE_64 << 16);
478
Stefan Roese94f453e2019-01-25 11:52:43 +0100479 return 0;
480}
481
Stefan Roese94f453e2019-01-25 11:52:43 +0100482#define DT_FLAGS_TO_TYPE(flags) (((flags) >> 24) & 0x03)
483#define DT_TYPE_IO 0x1
484#define DT_TYPE_MEM32 0x2
485#define DT_CPUADDR_TO_TARGET(cpuaddr) (((cpuaddr) >> 56) & 0xFF)
486#define DT_CPUADDR_TO_ATTR(cpuaddr) (((cpuaddr) >> 48) & 0xFF)
487
488static int mvebu_get_tgt_attr(ofnode node, int devfn,
489 unsigned long type,
490 unsigned int *tgt,
491 unsigned int *attr)
492{
493 const int na = 3, ns = 2;
494 const __be32 *range;
495 int rlen, nranges, rangesz, pna, i;
496
497 *tgt = -1;
498 *attr = -1;
499
500 range = ofnode_get_property(node, "ranges", &rlen);
501 if (!range)
502 return -EINVAL;
503
Stefan Roese0df62e82019-02-11 07:53:34 +0100504 /*
505 * Linux uses of_n_addr_cells() to get the number of address cells
506 * here. Currently this function is only available in U-Boot when
507 * CONFIG_OF_LIVE is enabled. Until this is enabled for MVEBU in
508 * general, lets't hardcode the "pna" value in the U-Boot code.
509 */
Stefan Roese94f453e2019-01-25 11:52:43 +0100510 pna = 2; /* hardcoded for now because of lack of of_n_addr_cells() */
511 rangesz = pna + na + ns;
512 nranges = rlen / sizeof(__be32) / rangesz;
513
514 for (i = 0; i < nranges; i++, range += rangesz) {
515 u32 flags = of_read_number(range, 1);
516 u32 slot = of_read_number(range + 1, 1);
517 u64 cpuaddr = of_read_number(range + na, pna);
518 unsigned long rtype;
519
520 if (DT_FLAGS_TO_TYPE(flags) == DT_TYPE_IO)
521 rtype = IORESOURCE_IO;
522 else if (DT_FLAGS_TO_TYPE(flags) == DT_TYPE_MEM32)
523 rtype = IORESOURCE_MEM;
524 else
Anton Schubert9c28d612015-08-11 11:54:01 +0200525 continue;
Anton Schubert9c28d612015-08-11 11:54:01 +0200526
Stefan Roese94f453e2019-01-25 11:52:43 +0100527 /*
528 * The Linux code used PCI_SLOT() here, which expects devfn
529 * in bits 7..0. PCI_DEV() in U-Boot is similar to PCI_SLOT(),
530 * only expects devfn in 15..8, where its saved in this driver.
531 */
532 if (slot == PCI_DEV(devfn) && type == rtype) {
533 *tgt = DT_CPUADDR_TO_TARGET(cpuaddr);
534 *attr = DT_CPUADDR_TO_ATTR(cpuaddr);
535 return 0;
Phil Sutter9a045272015-12-25 14:41:20 +0100536 }
Anton Schubert9c28d612015-08-11 11:54:01 +0200537 }
Stefan Roese94f453e2019-01-25 11:52:43 +0100538
539 return -ENOENT;
Anton Schubert9c28d612015-08-11 11:54:01 +0200540}
Stefan Roese94f453e2019-01-25 11:52:43 +0100541
Simon Glassd1998a92020-12-03 16:55:21 -0700542static int mvebu_pcie_of_to_plat(struct udevice *dev)
Stefan Roese94f453e2019-01-25 11:52:43 +0100543{
Simon Glassc69cda22020-12-03 16:55:20 -0700544 struct mvebu_pcie *pcie = dev_get_plat(dev);
Pali Rohár6f4988f2021-12-21 12:20:14 +0100545 const u32 *addr;
Stefan Roese94f453e2019-01-25 11:52:43 +0100546 int ret = 0;
Pali Rohár6f4988f2021-12-21 12:20:14 +0100547 int len;
Stefan Roese94f453e2019-01-25 11:52:43 +0100548
549 /* Get port number, lane number and memory target / attr */
550 if (ofnode_read_u32(dev_ofnode(dev), "marvell,pcie-port",
551 &pcie->port)) {
552 ret = -ENODEV;
553 goto err;
554 }
555
556 if (ofnode_read_u32(dev_ofnode(dev), "marvell,pcie-lane", &pcie->lane))
557 pcie->lane = 0;
558
559 sprintf(pcie->name, "pcie%d.%d", pcie->port, pcie->lane);
560
561 /* pci_get_devfn() returns devfn in bits 15..8, see PCI_DEV usage */
562 pcie->devfn = pci_get_devfn(dev);
563 if (pcie->devfn < 0) {
564 ret = -ENODEV;
565 goto err;
566 }
567
568 ret = mvebu_get_tgt_attr(dev_ofnode(dev->parent), pcie->devfn,
569 IORESOURCE_MEM,
570 &pcie->mem_target, &pcie->mem_attr);
571 if (ret < 0) {
572 printf("%s: cannot get tgt/attr for mem window\n", pcie->name);
573 goto err;
574 }
575
Phil Sutterba8ae032021-01-03 23:06:46 +0100576 ret = mvebu_get_tgt_attr(dev_ofnode(dev->parent), pcie->devfn,
577 IORESOURCE_IO,
578 &pcie->io_target, &pcie->io_attr);
579 if (ret < 0) {
580 printf("%s: cannot get tgt/attr for IO window\n", pcie->name);
581 goto err;
582 }
583
Stefan Roese94f453e2019-01-25 11:52:43 +0100584 /* Parse PCIe controller register base from DT */
Pali Rohár6f4988f2021-12-21 12:20:14 +0100585 addr = ofnode_get_property(dev_ofnode(dev), "assigned-addresses", &len);
586 if (!addr) {
587 printf("%s: property \"assigned-addresses\" not found\n", pcie->name);
588 ret = -FDT_ERR_NOTFOUND;
Stefan Roese94f453e2019-01-25 11:52:43 +0100589 goto err;
Pali Rohár6f4988f2021-12-21 12:20:14 +0100590 }
591
592 pcie->base = (void *)(fdt32_to_cpu(addr[2]) + SOC_REGS_PHY_BASE);
Stefan Roese94f453e2019-01-25 11:52:43 +0100593
Stefan Roese94f453e2019-01-25 11:52:43 +0100594 return 0;
595
596err:
597 return ret;
598}
599
600static const struct dm_pci_ops mvebu_pcie_ops = {
601 .read_config = mvebu_pcie_read_config,
602 .write_config = mvebu_pcie_write_config,
603};
604
605static struct driver pcie_mvebu_drv = {
606 .name = "pcie_mvebu",
607 .id = UCLASS_PCI,
608 .ops = &mvebu_pcie_ops,
609 .probe = mvebu_pcie_probe,
Simon Glassd1998a92020-12-03 16:55:21 -0700610 .of_to_plat = mvebu_pcie_of_to_plat,
Simon Glasscaa4daa2020-12-03 16:55:18 -0700611 .plat_auto = sizeof(struct mvebu_pcie),
Stefan Roese94f453e2019-01-25 11:52:43 +0100612};
613
614/*
615 * Use a MISC device to bind the n instances (child nodes) of the
616 * PCIe base controller in UCLASS_PCI.
617 */
618static int mvebu_pcie_bind(struct udevice *parent)
619{
620 struct mvebu_pcie *pcie;
621 struct uclass_driver *drv;
622 struct udevice *dev;
Pali Rohár537b0142021-12-21 12:20:13 +0100623 struct resource mem;
624 struct resource io;
Stefan Roese94f453e2019-01-25 11:52:43 +0100625 ofnode subnode;
626
Pali Rohár03a8a5e2021-10-22 16:22:15 +0200627 /* Lookup pci driver */
Stefan Roese94f453e2019-01-25 11:52:43 +0100628 drv = lists_uclass_lookup(UCLASS_PCI);
629 if (!drv) {
630 puts("Cannot find PCI driver\n");
631 return -ENOENT;
632 }
633
Pali Rohár537b0142021-12-21 12:20:13 +0100634 mem.start = MBUS_PCI_MEM_BASE;
635 mem.end = MBUS_PCI_MEM_BASE + MBUS_PCI_MEM_SIZE - 1;
636 io.start = MBUS_PCI_IO_BASE;
637 io.end = MBUS_PCI_IO_BASE + MBUS_PCI_IO_SIZE - 1;
638
Stefan Roese94f453e2019-01-25 11:52:43 +0100639 ofnode_for_each_subnode(subnode, dev_ofnode(parent)) {
640 if (!ofnode_is_available(subnode))
641 continue;
642
643 pcie = calloc(1, sizeof(*pcie));
644 if (!pcie)
645 return -ENOMEM;
646
Pali Rohár537b0142021-12-21 12:20:13 +0100647 /*
648 * MVEBU PCIe controller needs MEMORY and I/O BARs to be mapped
649 * into SoCs address space. Each controller will map 128M of MEM
650 * and 64K of I/O space when registered.
651 */
652
653 if (resource_size(&mem) >= SZ_128M) {
654 pcie->mem.start = mem.start;
655 pcie->mem.end = mem.start + SZ_128M - 1;
656 mem.start += SZ_128M;
657 } else {
658 printf("PCIe unable to assign mbus window for mem\n");
659 pcie->mem.start = 0;
660 pcie->mem.end = -1;
661 }
662
663 if (resource_size(&io) >= SZ_64K) {
664 pcie->io.start = io.start;
665 pcie->io.end = io.start + SZ_64K - 1;
666 io.start += SZ_64K;
667 } else {
668 printf("PCIe unable to assign mbus window for io\n");
669 pcie->io.start = 0;
670 pcie->io.end = -1;
671 }
672
Stefan Roese94f453e2019-01-25 11:52:43 +0100673 /* Create child device UCLASS_PCI and bind it */
Simon Glass734206d2020-11-28 17:50:01 -0700674 device_bind(parent, &pcie_mvebu_drv, pcie->name, pcie, subnode,
675 &dev);
Stefan Roese94f453e2019-01-25 11:52:43 +0100676 }
677
678 return 0;
679}
680
681static const struct udevice_id mvebu_pcie_ids[] = {
682 { .compatible = "marvell,armada-xp-pcie" },
683 { .compatible = "marvell,armada-370-pcie" },
684 { }
685};
686
687U_BOOT_DRIVER(pcie_mvebu_base) = {
688 .name = "pcie_mvebu_base",
689 .id = UCLASS_MISC,
690 .of_match = mvebu_pcie_ids,
691 .bind = mvebu_pcie_bind,
692};