blob: 83559550e6fbe8e8a176c49dbacb6b4a12c340a2 [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>
Pali Rohár94c30f92021-12-21 12:20:19 +010021#include <reset.h>
Anton Schubert9c28d612015-08-11 11:54:01 +020022#include <asm/io.h>
23#include <asm/arch/cpu.h>
24#include <asm/arch/soc.h>
Pali Rohárca3756c2022-08-05 16:03:41 +020025#include <asm/gpio.h>
Simon Glasscd93d622020-05-10 11:40:13 -060026#include <linux/bitops.h>
Pali Roháre7ff4272021-12-21 12:20:17 +010027#include <linux/delay.h>
Stefan Roese94f453e2019-01-25 11:52:43 +010028#include <linux/errno.h>
29#include <linux/ioport.h>
Anton Schubert9c28d612015-08-11 11:54:01 +020030#include <linux/mbus.h>
Simon Glass1e94b462023-09-14 18:21:46 -060031#include <linux/printk.h>
Pali Rohár537b0142021-12-21 12:20:13 +010032#include <linux/sizes.h>
Anton Schubert9c28d612015-08-11 11:54:01 +020033
Anton Schubert9c28d612015-08-11 11:54:01 +020034/* PCIe unit register offsets */
Pali Rohárfc27e5d2022-02-18 12:25:23 +010035#define MVPCIE_ROOT_PORT_PCI_CFG_OFF 0x0000
36#define MVPCIE_ROOT_PORT_PCI_EXP_OFF 0x0060
37#define MVPCIE_BAR_LO_OFF(n) (0x0010 + ((n) << 3))
38#define MVPCIE_BAR_HI_OFF(n) (0x0014 + ((n) << 3))
39#define MVPCIE_BAR_CTRL_OFF(n) (0x1804 + (((n) - 1) * 4))
40#define MVPCIE_WIN04_CTRL_OFF(n) (0x1820 + ((n) << 4))
41#define MVPCIE_WIN04_BASE_OFF(n) (0x1824 + ((n) << 4))
42#define MVPCIE_WIN04_REMAP_OFF(n) (0x182c + ((n) << 4))
43#define MVPCIE_WIN5_CTRL_OFF 0x1880
44#define MVPCIE_WIN5_BASE_OFF 0x1884
45#define MVPCIE_WIN5_REMAP_OFF 0x188c
46#define MVPCIE_CONF_ADDR_OFF 0x18f8
47#define MVPCIE_CONF_DATA_OFF 0x18fc
48#define MVPCIE_CTRL_OFF 0x1a00
49#define MVPCIE_CTRL_RC_MODE BIT(1)
50#define MVPCIE_STAT_OFF 0x1a04
51#define MVPCIE_STAT_BUS (0xff << 8)
52#define MVPCIE_STAT_DEV (0x1f << 16)
53#define MVPCIE_STAT_LINK_DOWN BIT(0)
Anton Schubert9c28d612015-08-11 11:54:01 +020054
Pali Roháre7ff4272021-12-21 12:20:17 +010055#define LINK_WAIT_RETRIES 100
56#define LINK_WAIT_TIMEOUT 1000
57
Anton Schubert9c28d612015-08-11 11:54:01 +020058struct mvebu_pcie {
59 struct pci_controller hose;
Anton Schubert9c28d612015-08-11 11:54:01 +020060 void __iomem *base;
61 void __iomem *membase;
62 struct resource mem;
63 void __iomem *iobase;
Phil Sutterba8ae032021-01-03 23:06:46 +010064 struct resource io;
Pali Rohárca3756c2022-08-05 16:03:41 +020065 struct gpio_desc reset_gpio;
Pali Rohár137db2a2021-12-21 12:20:15 +010066 u32 intregs;
Anton Schubert9c28d612015-08-11 11:54:01 +020067 u32 port;
68 u32 lane;
Pali Rohár94c30f92021-12-21 12:20:19 +010069 bool is_x4;
Stefan Roese94f453e2019-01-25 11:52:43 +010070 int devfn;
Pali Rohára7b61ab2021-10-22 16:22:10 +020071 int sec_busno;
Stefan Roese94f453e2019-01-25 11:52:43 +010072 char name[16];
73 unsigned int mem_target;
74 unsigned int mem_attr;
Phil Sutterba8ae032021-01-03 23:06:46 +010075 unsigned int io_target;
76 unsigned int io_attr;
Pali Rohára48e4282021-11-11 16:35:45 +010077 u32 cfgcache[(0x3c - 0x10) / 4];
Anton Schubert9c28d612015-08-11 11:54:01 +020078};
79
Anton Schubert9c28d612015-08-11 11:54:01 +020080static inline bool mvebu_pcie_link_up(struct mvebu_pcie *pcie)
81{
82 u32 val;
Pali Rohárfc27e5d2022-02-18 12:25:23 +010083 val = readl(pcie->base + MVPCIE_STAT_OFF);
84 return !(val & MVPCIE_STAT_LINK_DOWN);
Anton Schubert9c28d612015-08-11 11:54:01 +020085}
86
Pali Roháre7ff4272021-12-21 12:20:17 +010087static void mvebu_pcie_wait_for_link(struct mvebu_pcie *pcie)
88{
89 int retries;
90
91 /* check if the link is up or not */
92 for (retries = 0; retries < LINK_WAIT_RETRIES; retries++) {
93 if (mvebu_pcie_link_up(pcie)) {
94 printf("%s: Link up\n", pcie->name);
95 return;
96 }
97
98 udelay(LINK_WAIT_TIMEOUT);
99 }
100
101 printf("%s: Link down\n", pcie->name);
102}
103
Anton Schubert9c28d612015-08-11 11:54:01 +0200104static void mvebu_pcie_set_local_bus_nr(struct mvebu_pcie *pcie, int busno)
105{
106 u32 stat;
107
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100108 stat = readl(pcie->base + MVPCIE_STAT_OFF);
109 stat &= ~MVPCIE_STAT_BUS;
Anton Schubert9c28d612015-08-11 11:54:01 +0200110 stat |= busno << 8;
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100111 writel(stat, pcie->base + MVPCIE_STAT_OFF);
Anton Schubert9c28d612015-08-11 11:54:01 +0200112}
113
114static void mvebu_pcie_set_local_dev_nr(struct mvebu_pcie *pcie, int devno)
115{
116 u32 stat;
117
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100118 stat = readl(pcie->base + MVPCIE_STAT_OFF);
119 stat &= ~MVPCIE_STAT_DEV;
Anton Schubert9c28d612015-08-11 11:54:01 +0200120 stat |= devno << 16;
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100121 writel(stat, pcie->base + MVPCIE_STAT_OFF);
Anton Schubert9c28d612015-08-11 11:54:01 +0200122}
123
Anton Schubert9c28d612015-08-11 11:54:01 +0200124static inline struct mvebu_pcie *hose_to_pcie(struct pci_controller *hose)
125{
126 return container_of(hose, struct mvebu_pcie, hose);
127}
128
Pali Rohára7b61ab2021-10-22 16:22:10 +0200129static bool mvebu_pcie_valid_addr(struct mvebu_pcie *pcie,
130 int busno, int dev, int func)
Marek Behún10eb2cc2021-02-08 23:01:40 +0100131{
Pali Rohár0eebc3d2022-02-15 11:34:01 +0100132 /* On the root bus is only one PCI Bridge */
133 if (busno == 0 && (dev != 0 || func != 0))
Pali Rohára7b61ab2021-10-22 16:22:10 +0200134 return false;
Marek Behún10eb2cc2021-02-08 23:01:40 +0100135
Pali Rohár79b4eb22021-10-22 16:22:12 +0200136 /* Access to other buses is possible when link is up */
Pali Rohár0eebc3d2022-02-15 11:34:01 +0100137 if (busno != 0 && !mvebu_pcie_link_up(pcie))
Pali Rohár79b4eb22021-10-22 16:22:12 +0200138 return false;
139
Pali Rohára7b61ab2021-10-22 16:22:10 +0200140 /* On secondary bus can be only one PCIe device */
141 if (busno == pcie->sec_busno && dev != 0)
142 return false;
143
144 return true;
Marek Behún10eb2cc2021-02-08 23:01:40 +0100145}
146
Simon Glassc4e72c42020-01-27 08:49:37 -0700147static int mvebu_pcie_read_config(const struct udevice *bus, pci_dev_t bdf,
Stefan Roese94f453e2019-01-25 11:52:43 +0100148 uint offset, ulong *valuep,
149 enum pci_size_t size)
Anton Schubert9c28d612015-08-11 11:54:01 +0200150{
Simon Glassc69cda22020-12-03 16:55:20 -0700151 struct mvebu_pcie *pcie = dev_get_plat(bus);
Pali Rohára7b61ab2021-10-22 16:22:10 +0200152 int busno = PCI_BUS(bdf) - dev_seq(bus);
153 u32 addr, data;
Stefan Roese94f453e2019-01-25 11:52:43 +0100154
Marek Behún10eb2cc2021-02-08 23:01:40 +0100155 debug("PCIE CFG read: (b,d,f)=(%2d,%2d,%2d) ",
156 PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
Anton Schubert9c28d612015-08-11 11:54:01 +0200157
Pali Rohára7b61ab2021-10-22 16:22:10 +0200158 if (!mvebu_pcie_valid_addr(pcie, busno, PCI_DEV(bdf), PCI_FUNC(bdf))) {
Stefan Roese6a2fa282021-01-25 15:25:31 +0100159 debug("- out of range\n");
160 *valuep = pci_get_ff(size);
161 return 0;
Anton Schubert9c28d612015-08-11 11:54:01 +0200162 }
163
Pali Rohára7b61ab2021-10-22 16:22:10 +0200164 /*
Pali Rohár0eebc3d2022-02-15 11:34:01 +0100165 * The configuration space of the PCI Bridge on the root bus (zero) is
Pali Rohára48e4282021-11-11 16:35:45 +0100166 * of Type 0 but the BAR registers (including ROM BAR) don't have the
167 * same meaning as in the PCIe specification. Therefore do not access
168 * BAR registers and non-common registers (those which have different
169 * meaning for Type 0 and Type 1 config space) of the PCI Bridge and
170 * instead read their content from driver virtual cfgcache[].
Pali Rohára7b61ab2021-10-22 16:22:10 +0200171 */
Pali Rohár0eebc3d2022-02-15 11:34:01 +0100172 if (busno == 0 && ((offset >= 0x10 && offset < 0x34) ||
173 (offset >= 0x38 && offset < 0x3c))) {
Pali Rohára7b61ab2021-10-22 16:22:10 +0200174 data = pcie->cfgcache[(offset - 0x10) / 4];
175 debug("(addr,size,val)=(0x%04x, %d, 0x%08x) from cfgcache\n",
176 offset, size, data);
177 *valuep = pci_conv_32_to_size(data, offset, size);
178 return 0;
Pali Rohára7b61ab2021-10-22 16:22:10 +0200179 }
180
181 /*
Pali Rohár0eebc3d2022-02-15 11:34:01 +0100182 * PCI bridge is device 0 at the root bus (zero) but mvebu has it
183 * mapped on secondary bus with device number 1.
Pali Rohára7b61ab2021-10-22 16:22:10 +0200184 */
Pali Rohár0eebc3d2022-02-15 11:34:01 +0100185 if (busno == 0)
Pali Rohárd0dd49f2021-11-26 11:42:45 +0100186 addr = PCI_CONF1_EXT_ADDRESS(pcie->sec_busno, 1, 0, offset);
Pali Rohára7b61ab2021-10-22 16:22:10 +0200187 else
Pali Rohárd0dd49f2021-11-26 11:42:45 +0100188 addr = PCI_CONF1_EXT_ADDRESS(busno, PCI_DEV(bdf), PCI_FUNC(bdf), offset);
Pali Rohára7b61ab2021-10-22 16:22:10 +0200189
Anton Schubert9c28d612015-08-11 11:54:01 +0200190 /* write address */
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100191 writel(addr, pcie->base + MVPCIE_CONF_ADDR_OFF);
Marek Behún241d7632021-02-08 23:01:38 +0100192
193 /* read data */
Pali Rohár657177a2021-10-22 16:22:09 +0200194 switch (size) {
195 case PCI_SIZE_8:
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100196 data = readb(pcie->base + MVPCIE_CONF_DATA_OFF + (offset & 3));
Pali Rohár657177a2021-10-22 16:22:09 +0200197 break;
198 case PCI_SIZE_16:
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100199 data = readw(pcie->base + MVPCIE_CONF_DATA_OFF + (offset & 2));
Pali Rohár657177a2021-10-22 16:22:09 +0200200 break;
201 case PCI_SIZE_32:
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100202 data = readl(pcie->base + MVPCIE_CONF_DATA_OFF);
Pali Rohár657177a2021-10-22 16:22:09 +0200203 break;
204 default:
205 return -EINVAL;
206 }
207
Pali Rohár0eebc3d2022-02-15 11:34:01 +0100208 if (busno == 0 && (offset & ~3) == (PCI_HEADER_TYPE & ~3)) {
Pali Rohára7b61ab2021-10-22 16:22:10 +0200209 /*
210 * Change Header Type of PCI Bridge device to Type 1
211 * (0x01, used by PCI Bridges) because mvebu reports
212 * Type 0 (0x00, used by Upstream and Endpoint devices).
213 */
214 data = pci_conv_size_to_32(data, 0, offset, size);
215 data &= ~0x007f0000;
216 data |= PCI_HEADER_TYPE_BRIDGE << 16;
217 data = pci_conv_32_to_size(data, offset, size);
218 }
219
Marek Behún26f7a762021-02-08 23:01:39 +0100220 debug("(addr,size,val)=(0x%04x, %d, 0x%08x)\n", offset, size, data);
Pali Rohár657177a2021-10-22 16:22:09 +0200221 *valuep = data;
Anton Schubert9c28d612015-08-11 11:54:01 +0200222
223 return 0;
224}
225
Stefan Roese94f453e2019-01-25 11:52:43 +0100226static int mvebu_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
227 uint offset, ulong value,
228 enum pci_size_t size)
Anton Schubert9c28d612015-08-11 11:54:01 +0200229{
Simon Glassc69cda22020-12-03 16:55:20 -0700230 struct mvebu_pcie *pcie = dev_get_plat(bus);
Pali Rohára7b61ab2021-10-22 16:22:10 +0200231 int busno = PCI_BUS(bdf) - dev_seq(bus);
232 u32 addr, data;
Stefan Roese94f453e2019-01-25 11:52:43 +0100233
Marek Behún10eb2cc2021-02-08 23:01:40 +0100234 debug("PCIE CFG write: (b,d,f)=(%2d,%2d,%2d) ",
235 PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
Marek Behún26f7a762021-02-08 23:01:39 +0100236 debug("(addr,size,val)=(0x%04x, %d, 0x%08lx)\n", offset, size, value);
Anton Schubert9c28d612015-08-11 11:54:01 +0200237
Pali Rohára7b61ab2021-10-22 16:22:10 +0200238 if (!mvebu_pcie_valid_addr(pcie, busno, PCI_DEV(bdf), PCI_FUNC(bdf))) {
Stefan Roese6a2fa282021-01-25 15:25:31 +0100239 debug("- out of range\n");
240 return 0;
Anton Schubert9c28d612015-08-11 11:54:01 +0200241 }
242
Pali Rohára7b61ab2021-10-22 16:22:10 +0200243 /*
Pali Rohára48e4282021-11-11 16:35:45 +0100244 * As explained in mvebu_pcie_read_config(), PCI Bridge Type 1 specific
245 * config registers are not available, so we write their content only
246 * into driver virtual cfgcache[].
247 * And as explained in mvebu_pcie_probe(), mvebu has its own specific
Pali Rohár0eebc3d2022-02-15 11:34:01 +0100248 * way for configuring secondary bus number.
Pali Rohára7b61ab2021-10-22 16:22:10 +0200249 */
Pali Rohár0eebc3d2022-02-15 11:34:01 +0100250 if (busno == 0 && ((offset >= 0x10 && offset < 0x34) ||
251 (offset >= 0x38 && offset < 0x3c))) {
Pali Rohára7b61ab2021-10-22 16:22:10 +0200252 debug("Writing to cfgcache only\n");
253 data = pcie->cfgcache[(offset - 0x10) / 4];
254 data = pci_conv_size_to_32(data, value, offset, size);
255 /* mvebu PCI bridge does not have configurable bars */
256 if ((offset & ~3) == PCI_BASE_ADDRESS_0 ||
Pali Rohára48e4282021-11-11 16:35:45 +0100257 (offset & ~3) == PCI_BASE_ADDRESS_1 ||
258 (offset & ~3) == PCI_ROM_ADDRESS1)
Pali Rohára7b61ab2021-10-22 16:22:10 +0200259 data = 0x0;
260 pcie->cfgcache[(offset - 0x10) / 4] = data;
Pali Rohára7b61ab2021-10-22 16:22:10 +0200261 /* mvebu has its own way how to set PCI secondary bus number */
262 if (offset == PCI_SECONDARY_BUS ||
263 (offset == PCI_PRIMARY_BUS && size != PCI_SIZE_8)) {
264 pcie->sec_busno = (data >> 8) & 0xff;
265 mvebu_pcie_set_local_bus_nr(pcie, pcie->sec_busno);
266 debug("Secondary bus number was changed to %d\n",
267 pcie->sec_busno);
268 }
269 return 0;
Pali Rohára7b61ab2021-10-22 16:22:10 +0200270 }
271
272 /*
Pali Rohár0eebc3d2022-02-15 11:34:01 +0100273 * PCI bridge is device 0 at the root bus (zero) but mvebu has it
274 * mapped on secondary bus with device number 1.
Pali Rohára7b61ab2021-10-22 16:22:10 +0200275 */
Pali Rohár0eebc3d2022-02-15 11:34:01 +0100276 if (busno == 0)
Pali Rohárd0dd49f2021-11-26 11:42:45 +0100277 addr = PCI_CONF1_EXT_ADDRESS(pcie->sec_busno, 1, 0, offset);
Pali Rohára7b61ab2021-10-22 16:22:10 +0200278 else
Pali Rohárd0dd49f2021-11-26 11:42:45 +0100279 addr = PCI_CONF1_EXT_ADDRESS(busno, PCI_DEV(bdf), PCI_FUNC(bdf), offset);
Pali Rohára7b61ab2021-10-22 16:22:10 +0200280
Marek Behún241d7632021-02-08 23:01:38 +0100281 /* write address */
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100282 writel(addr, pcie->base + MVPCIE_CONF_ADDR_OFF);
Marek Behún241d7632021-02-08 23:01:38 +0100283
284 /* write data */
Pali Rohárdaa9bfd2021-10-22 16:22:08 +0200285 switch (size) {
286 case PCI_SIZE_8:
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100287 writeb(value, pcie->base + MVPCIE_CONF_DATA_OFF + (offset & 3));
Pali Rohárdaa9bfd2021-10-22 16:22:08 +0200288 break;
289 case PCI_SIZE_16:
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100290 writew(value, pcie->base + MVPCIE_CONF_DATA_OFF + (offset & 2));
Pali Rohárdaa9bfd2021-10-22 16:22:08 +0200291 break;
292 case PCI_SIZE_32:
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100293 writel(value, pcie->base + MVPCIE_CONF_DATA_OFF);
Pali Rohárdaa9bfd2021-10-22 16:22:08 +0200294 break;
295 default:
296 return -EINVAL;
297 }
Anton Schubert9c28d612015-08-11 11:54:01 +0200298
299 return 0;
300}
301
302/*
303 * Setup PCIE BARs and Address Decode Wins:
Pali Rohár4a1a5932021-11-11 16:35:42 +0100304 * BAR[0] -> internal registers
305 * BAR[1] -> covers all DRAM banks
306 * BAR[2] -> disabled
Anton Schubert9c28d612015-08-11 11:54:01 +0200307 * WIN[0-3] -> DRAM bank[0-3]
308 */
309static void mvebu_pcie_setup_wins(struct mvebu_pcie *pcie)
310{
311 const struct mbus_dram_target_info *dram = mvebu_mbus_dram_info();
312 u32 size;
313 int i;
314
315 /* First, disable and clear BARs and windows. */
316 for (i = 1; i < 3; i++) {
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100317 writel(0, pcie->base + MVPCIE_BAR_CTRL_OFF(i));
318 writel(0, pcie->base + MVPCIE_BAR_LO_OFF(i));
319 writel(0, pcie->base + MVPCIE_BAR_HI_OFF(i));
Anton Schubert9c28d612015-08-11 11:54:01 +0200320 }
321
322 for (i = 0; i < 5; i++) {
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100323 writel(0, pcie->base + MVPCIE_WIN04_CTRL_OFF(i));
324 writel(0, pcie->base + MVPCIE_WIN04_BASE_OFF(i));
325 writel(0, pcie->base + MVPCIE_WIN04_REMAP_OFF(i));
Anton Schubert9c28d612015-08-11 11:54:01 +0200326 }
327
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100328 writel(0, pcie->base + MVPCIE_WIN5_CTRL_OFF);
329 writel(0, pcie->base + MVPCIE_WIN5_BASE_OFF);
330 writel(0, pcie->base + MVPCIE_WIN5_REMAP_OFF);
Anton Schubert9c28d612015-08-11 11:54:01 +0200331
332 /* Setup windows for DDR banks. Count total DDR size on the fly. */
333 size = 0;
334 for (i = 0; i < dram->num_cs; i++) {
335 const struct mbus_dram_window *cs = dram->cs + i;
336
337 writel(cs->base & 0xffff0000,
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100338 pcie->base + MVPCIE_WIN04_BASE_OFF(i));
339 writel(0, pcie->base + MVPCIE_WIN04_REMAP_OFF(i));
Anton Schubert9c28d612015-08-11 11:54:01 +0200340 writel(((cs->size - 1) & 0xffff0000) |
341 (cs->mbus_attr << 8) |
342 (dram->mbus_dram_target_id << 4) | 1,
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100343 pcie->base + MVPCIE_WIN04_CTRL_OFF(i));
Anton Schubert9c28d612015-08-11 11:54:01 +0200344
345 size += cs->size;
346 }
347
348 /* Round up 'size' to the nearest power of two. */
349 if ((size & (size - 1)) != 0)
350 size = 1 << fls(size);
351
352 /* Setup BAR[1] to all DRAM banks. */
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100353 writel(dram->cs[0].base | 0xc, pcie->base + MVPCIE_BAR_LO_OFF(1));
354 writel(0, pcie->base + MVPCIE_BAR_HI_OFF(1));
Anton Schubert9c28d612015-08-11 11:54:01 +0200355 writel(((size - 1) & 0xffff0000) | 0x1,
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100356 pcie->base + MVPCIE_BAR_CTRL_OFF(1));
Pali Rohár4a1a5932021-11-11 16:35:42 +0100357
358 /* Setup BAR[0] to internal registers. */
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100359 writel(pcie->intregs, pcie->base + MVPCIE_BAR_LO_OFF(0));
360 writel(0, pcie->base + MVPCIE_BAR_HI_OFF(0));
Anton Schubert9c28d612015-08-11 11:54:01 +0200361}
362
Pali Rohárafef9f42021-12-21 12:20:16 +0100363/* Only enable PCIe link, do not setup it */
364static int mvebu_pcie_enable_link(struct mvebu_pcie *pcie, ofnode node)
Anton Schubert9c28d612015-08-11 11:54:01 +0200365{
Pali Rohár94c30f92021-12-21 12:20:19 +0100366 struct reset_ctl rst;
367 int ret;
368
369 ret = reset_get_by_index_nodev(node, 0, &rst);
370 if (ret == -ENOENT) {
371 return 0;
372 } else if (ret < 0) {
373 printf("%s: cannot get reset controller: %d\n", pcie->name, ret);
374 return ret;
375 }
376
377 ret = reset_request(&rst);
378 if (ret) {
379 printf("%s: cannot request reset controller: %d\n", pcie->name, ret);
380 return ret;
381 }
382
383 ret = reset_deassert(&rst);
384 reset_free(&rst);
385 if (ret) {
386 printf("%s: cannot enable PCIe port: %d\n", pcie->name, ret);
387 return ret;
388 }
389
Pali Rohárafef9f42021-12-21 12:20:16 +0100390 return 0;
391}
392
393/* Setup PCIe link but do not enable it */
394static void mvebu_pcie_setup_link(struct mvebu_pcie *pcie)
395{
Anton Schubert9c28d612015-08-11 11:54:01 +0200396 u32 reg;
Anton Schubert9c28d612015-08-11 11:54:01 +0200397
Pali Rohár2344a762021-10-22 16:22:14 +0200398 /* Setup PCIe controller to Root Complex mode */
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100399 reg = readl(pcie->base + MVPCIE_CTRL_OFF);
400 reg |= MVPCIE_CTRL_RC_MODE;
401 writel(reg, pcie->base + MVPCIE_CTRL_OFF);
Pali Rohár94c30f92021-12-21 12:20:19 +0100402
403 /*
404 * Set Maximum Link Width to X1 or X4 in Root Port's PCIe Link
405 * Capability register. This register is defined by PCIe specification
406 * as read-only but this mvebu controller has it as read-write and must
407 * be set to number of SerDes PCIe lanes (1 or 4). If this register is
408 * not set correctly then link with endpoint card is not established.
409 */
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100410 reg = readl(pcie->base + MVPCIE_ROOT_PORT_PCI_EXP_OFF + PCI_EXP_LNKCAP);
Pali Rohár94c30f92021-12-21 12:20:19 +0100411 reg &= ~PCI_EXP_LNKCAP_MLW;
412 reg |= (pcie->is_x4 ? 4 : 1) << 4;
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100413 writel(reg, pcie->base + MVPCIE_ROOT_PORT_PCI_EXP_OFF + PCI_EXP_LNKCAP);
Pali Rohárafef9f42021-12-21 12:20:16 +0100414}
415
416static int mvebu_pcie_probe(struct udevice *dev)
417{
418 struct mvebu_pcie *pcie = dev_get_plat(dev);
419 struct udevice *ctlr = pci_get_controller(dev);
420 struct pci_controller *hose = dev_get_uclass_priv(ctlr);
421 u32 reg;
Pali Rohárca3756c2022-08-05 16:03:41 +0200422 int ret;
423
424 /* Request for optional PERST# GPIO */
425 ret = gpio_request_by_name(dev, "reset-gpios", 0, &pcie->reset_gpio, GPIOD_IS_OUT);
426 if (ret && ret != -ENOENT) {
427 printf("%s: unable to request reset-gpios: %d\n", pcie->name, ret);
428 return ret;
429 }
Pali Rohár2344a762021-10-22 16:22:14 +0200430
Pali Rohára7b61ab2021-10-22 16:22:10 +0200431 /*
432 * Change Class Code of PCI Bridge device to PCI Bridge (0x600400)
433 * because default value is Memory controller (0x508000) which
434 * U-Boot cannot recognize as P2P Bridge.
435 *
436 * Note that this mvebu PCI Bridge does not have compliant Type 1
Pali Rohára48e4282021-11-11 16:35:45 +0100437 * Configuration Space. Header Type is reported as Type 0 and it
438 * has format of Type 0 config space.
Pali Rohára7b61ab2021-10-22 16:22:10 +0200439 *
Pali Rohára48e4282021-11-11 16:35:45 +0100440 * Moreover Type 0 BAR registers (ranges 0x10 - 0x28 and 0x30 - 0x34)
441 * have the same format in Marvell's specification as in PCIe
442 * specification, but their meaning is totally different and they do
443 * different things: they are aliased into internal mvebu registers
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100444 * (e.g. MVPCIE_BAR_LO_OFF) and these should not be changed or
Pali Rohára48e4282021-11-11 16:35:45 +0100445 * reconfigured by pci device drivers.
446 *
447 * So our driver converts Type 0 config space to Type 1 and reports
448 * Header Type as Type 1. Access to BAR registers and to non-existent
449 * Type 1 registers is redirected to the virtual cfgcache[] buffer,
450 * which avoids changing unrelated registers.
Pali Rohára7b61ab2021-10-22 16:22:10 +0200451 */
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100452 reg = readl(pcie->base + MVPCIE_ROOT_PORT_PCI_CFG_OFF + PCI_CLASS_REVISION);
Pali Rohára7b61ab2021-10-22 16:22:10 +0200453 reg &= ~0xffffff00;
Pali Rohárd7b90402022-02-18 13:18:40 +0100454 reg |= PCI_CLASS_BRIDGE_PCI_NORMAL << 8;
Pali Rohárfc27e5d2022-02-18 12:25:23 +0100455 writel(reg, pcie->base + MVPCIE_ROOT_PORT_PCI_CFG_OFF + PCI_CLASS_REVISION);
Anton Schubert9c28d612015-08-11 11:54:01 +0200456
Pali Rohára7b61ab2021-10-22 16:22:10 +0200457 /*
458 * mvebu uses local bus number and local device number to determinate
459 * type of config request. Type 0 is used if target bus number equals
460 * local bus number and target device number differs from local device
461 * number. Type 1 is used if target bus number differs from local bus
462 * number. And when target bus number equals local bus number and
463 * target device equals local device number then request is routed to
464 * PCI Bridge which represent local PCIe Root Port.
465 *
Pali Rohár0eebc3d2022-02-15 11:34:01 +0100466 * It means that PCI root and secondary buses shares one bus number
Pali Rohára7b61ab2021-10-22 16:22:10 +0200467 * which is configured via local bus number. Determination if config
Pali Rohár0eebc3d2022-02-15 11:34:01 +0100468 * request should go to root or secondary bus is done based on local
Pali Rohára7b61ab2021-10-22 16:22:10 +0200469 * device number.
470 *
471 * PCIe is point-to-point bus, so at secondary bus is always exactly one
472 * device with number 0. So set local device number to 1, it would not
473 * conflict with any device on secondary bus number and will ensure that
474 * accessing secondary bus and all buses behind secondary would work
475 * automatically and correctly. Therefore this configuration of local
476 * device number implies that setting of local bus number configures
477 * secondary bus number. Set it to 0 as U-Boot CONFIG_PCI_PNP code will
478 * later configure it via config write requests to the correct value.
479 * mvebu_pcie_write_config() catches config write requests which tries
Pali Rohár0eebc3d2022-02-15 11:34:01 +0100480 * to change secondary bus number and correctly updates local bus number
481 * based on new secondary bus number.
Pali Rohára7b61ab2021-10-22 16:22:10 +0200482 *
483 * With this configuration is PCI Bridge available at secondary bus as
Pali Rohár0eebc3d2022-02-15 11:34:01 +0100484 * device number 1. But it must be available at root bus (zero) as device
Pali Rohára7b61ab2021-10-22 16:22:10 +0200485 * number 0. So in mvebu_pcie_read_config() and mvebu_pcie_write_config()
Pali Rohár0eebc3d2022-02-15 11:34:01 +0100486 * functions rewrite address to the real one when accessing the root bus.
Pali Rohára7b61ab2021-10-22 16:22:10 +0200487 */
488 mvebu_pcie_set_local_bus_nr(pcie, 0);
489 mvebu_pcie_set_local_dev_nr(pcie, 1);
Anton Schubert9c28d612015-08-11 11:54:01 +0200490
Pali Rohár43640712022-01-13 14:28:04 +0100491 /*
492 * Kirkwood arch code already maps mbus windows for PCIe IO and MEM.
493 * So skip calling mvebu_mbus_add_window_by_id() function as it would
494 * fail on error "conflicts with another window" which means conflict
495 * with existing PCIe window mappings.
496 */
497#ifndef CONFIG_ARCH_KIRKWOOD
Pali Rohár537b0142021-12-21 12:20:13 +0100498 if (resource_size(&pcie->mem) &&
499 mvebu_mbus_add_window_by_id(pcie->mem_target, pcie->mem_attr,
Stefan Roese94f453e2019-01-25 11:52:43 +0100500 (phys_addr_t)pcie->mem.start,
Pali Roháre1cee892021-11-11 16:35:43 +0100501 resource_size(&pcie->mem))) {
Pali Rohárafef9f42021-12-21 12:20:16 +0100502 printf("%s: unable to add mbus window for mem at %08x+%08x\n",
503 pcie->name,
Pali Roháre1cee892021-11-11 16:35:43 +0100504 (u32)pcie->mem.start, (unsigned)resource_size(&pcie->mem));
Pali Rohár537b0142021-12-21 12:20:13 +0100505 pcie->mem.start = 0;
506 pcie->mem.end = -1;
Stefan Roese94f453e2019-01-25 11:52:43 +0100507 }
508
Pali Rohár537b0142021-12-21 12:20:13 +0100509 if (resource_size(&pcie->io) &&
510 mvebu_mbus_add_window_by_id(pcie->io_target, pcie->io_attr,
Phil Sutterba8ae032021-01-03 23:06:46 +0100511 (phys_addr_t)pcie->io.start,
Pali Roháre1cee892021-11-11 16:35:43 +0100512 resource_size(&pcie->io))) {
Pali Rohárafef9f42021-12-21 12:20:16 +0100513 printf("%s: unable to add mbus window for IO at %08x+%08x\n",
514 pcie->name,
Pali Roháre1cee892021-11-11 16:35:43 +0100515 (u32)pcie->io.start, (unsigned)resource_size(&pcie->io));
Pali Rohár537b0142021-12-21 12:20:13 +0100516 pcie->io.start = 0;
517 pcie->io.end = -1;
Phil Sutterba8ae032021-01-03 23:06:46 +0100518 }
Pali Rohár43640712022-01-13 14:28:04 +0100519#endif
Phil Sutterba8ae032021-01-03 23:06:46 +0100520
Stefan Roese94f453e2019-01-25 11:52:43 +0100521 /* Setup windows and configure host bridge */
522 mvebu_pcie_setup_wins(pcie);
523
Stefan Roese94f453e2019-01-25 11:52:43 +0100524 /* PCI memory space */
525 pci_set_region(hose->regions + 0, pcie->mem.start,
Pali Roháre1cee892021-11-11 16:35:43 +0100526 pcie->mem.start, resource_size(&pcie->mem), PCI_REGION_MEM);
Pali Rohár537b0142021-12-21 12:20:13 +0100527 hose->region_count = 1;
528
529 if (resource_size(&pcie->mem)) {
530 pci_set_region(hose->regions + hose->region_count,
531 pcie->mem.start, pcie->mem.start,
532 resource_size(&pcie->mem),
533 PCI_REGION_MEM);
534 hose->region_count++;
535 }
536
537 if (resource_size(&pcie->io)) {
538 pci_set_region(hose->regions + hose->region_count,
539 pcie->io.start, pcie->io.start,
540 resource_size(&pcie->io),
541 PCI_REGION_IO);
542 hose->region_count++;
543 }
Stefan Roese94f453e2019-01-25 11:52:43 +0100544
Pali Rohára7b61ab2021-10-22 16:22:10 +0200545 /* PCI Bridge support 32-bit I/O and 64-bit prefetch mem addressing */
546 pcie->cfgcache[(PCI_IO_BASE - 0x10) / 4] =
547 PCI_IO_RANGE_TYPE_32 | (PCI_IO_RANGE_TYPE_32 << 8);
548 pcie->cfgcache[(PCI_PREF_MEMORY_BASE - 0x10) / 4] =
549 PCI_PREF_RANGE_TYPE_64 | (PCI_PREF_RANGE_TYPE_64 << 16);
550
Pali Rohárca3756c2022-08-05 16:03:41 +0200551 /* Release PERST# via GPIO when it was defined */
552 if (dm_gpio_is_valid(&pcie->reset_gpio))
553 dm_gpio_set_value(&pcie->reset_gpio, 0);
554
Pali Roháre7ff4272021-12-21 12:20:17 +0100555 mvebu_pcie_wait_for_link(pcie);
556
Stefan Roese94f453e2019-01-25 11:52:43 +0100557 return 0;
558}
559
Stefan Roese94f453e2019-01-25 11:52:43 +0100560#define DT_FLAGS_TO_TYPE(flags) (((flags) >> 24) & 0x03)
561#define DT_TYPE_IO 0x1
562#define DT_TYPE_MEM32 0x2
563#define DT_CPUADDR_TO_TARGET(cpuaddr) (((cpuaddr) >> 56) & 0xFF)
564#define DT_CPUADDR_TO_ATTR(cpuaddr) (((cpuaddr) >> 48) & 0xFF)
565
566static int mvebu_get_tgt_attr(ofnode node, int devfn,
567 unsigned long type,
568 unsigned int *tgt,
569 unsigned int *attr)
570{
571 const int na = 3, ns = 2;
572 const __be32 *range;
573 int rlen, nranges, rangesz, pna, i;
574
575 *tgt = -1;
576 *attr = -1;
577
578 range = ofnode_get_property(node, "ranges", &rlen);
579 if (!range)
580 return -EINVAL;
581
Stefan Roese0df62e82019-02-11 07:53:34 +0100582 /*
583 * Linux uses of_n_addr_cells() to get the number of address cells
584 * here. Currently this function is only available in U-Boot when
585 * CONFIG_OF_LIVE is enabled. Until this is enabled for MVEBU in
586 * general, lets't hardcode the "pna" value in the U-Boot code.
587 */
Stefan Roese94f453e2019-01-25 11:52:43 +0100588 pna = 2; /* hardcoded for now because of lack of of_n_addr_cells() */
589 rangesz = pna + na + ns;
590 nranges = rlen / sizeof(__be32) / rangesz;
591
592 for (i = 0; i < nranges; i++, range += rangesz) {
593 u32 flags = of_read_number(range, 1);
594 u32 slot = of_read_number(range + 1, 1);
595 u64 cpuaddr = of_read_number(range + na, pna);
596 unsigned long rtype;
597
598 if (DT_FLAGS_TO_TYPE(flags) == DT_TYPE_IO)
599 rtype = IORESOURCE_IO;
600 else if (DT_FLAGS_TO_TYPE(flags) == DT_TYPE_MEM32)
601 rtype = IORESOURCE_MEM;
602 else
Anton Schubert9c28d612015-08-11 11:54:01 +0200603 continue;
Anton Schubert9c28d612015-08-11 11:54:01 +0200604
Stefan Roese94f453e2019-01-25 11:52:43 +0100605 /*
606 * The Linux code used PCI_SLOT() here, which expects devfn
607 * in bits 7..0. PCI_DEV() in U-Boot is similar to PCI_SLOT(),
608 * only expects devfn in 15..8, where its saved in this driver.
609 */
610 if (slot == PCI_DEV(devfn) && type == rtype) {
611 *tgt = DT_CPUADDR_TO_TARGET(cpuaddr);
612 *attr = DT_CPUADDR_TO_ATTR(cpuaddr);
613 return 0;
Phil Sutter9a045272015-12-25 14:41:20 +0100614 }
Anton Schubert9c28d612015-08-11 11:54:01 +0200615 }
Stefan Roese94f453e2019-01-25 11:52:43 +0100616
617 return -ENOENT;
Anton Schubert9c28d612015-08-11 11:54:01 +0200618}
Stefan Roese94f453e2019-01-25 11:52:43 +0100619
Pali Rohárafef9f42021-12-21 12:20:16 +0100620static int mvebu_pcie_port_parse_dt(ofnode node, ofnode parent, struct mvebu_pcie *pcie)
Stefan Roese94f453e2019-01-25 11:52:43 +0100621{
Pali Rohárafef9f42021-12-21 12:20:16 +0100622 struct fdt_pci_addr pci_addr;
Pali Rohár6f4988f2021-12-21 12:20:14 +0100623 const u32 *addr;
Pali Rohár94c30f92021-12-21 12:20:19 +0100624 u32 num_lanes;
Stefan Roese94f453e2019-01-25 11:52:43 +0100625 int ret = 0;
Pali Rohár6f4988f2021-12-21 12:20:14 +0100626 int len;
Stefan Roese94f453e2019-01-25 11:52:43 +0100627
628 /* Get port number, lane number and memory target / attr */
Pali Rohárafef9f42021-12-21 12:20:16 +0100629 if (ofnode_read_u32(node, "marvell,pcie-port",
Stefan Roese94f453e2019-01-25 11:52:43 +0100630 &pcie->port)) {
631 ret = -ENODEV;
632 goto err;
633 }
634
Pali Rohárafef9f42021-12-21 12:20:16 +0100635 if (ofnode_read_u32(node, "marvell,pcie-lane", &pcie->lane))
Stefan Roese94f453e2019-01-25 11:52:43 +0100636 pcie->lane = 0;
637
638 sprintf(pcie->name, "pcie%d.%d", pcie->port, pcie->lane);
639
Pali Rohár94c30f92021-12-21 12:20:19 +0100640 if (!ofnode_read_u32(node, "num-lanes", &num_lanes) && num_lanes == 4)
641 pcie->is_x4 = true;
642
Pali Rohárafef9f42021-12-21 12:20:16 +0100643 /* devfn is in bits [15:8], see PCI_DEV usage */
Simon Glassf69d3d62023-09-26 08:14:58 -0600644 ret = ofnode_read_pci_addr(node, FDT_PCI_SPACE_CONFIG, "reg", &pci_addr,
645 NULL);
Pali Rohárafef9f42021-12-21 12:20:16 +0100646 if (ret < 0) {
647 printf("%s: property \"reg\" is invalid\n", pcie->name);
Stefan Roese94f453e2019-01-25 11:52:43 +0100648 goto err;
649 }
Pali Rohárafef9f42021-12-21 12:20:16 +0100650 pcie->devfn = pci_addr.phys_hi & 0xff00;
Stefan Roese94f453e2019-01-25 11:52:43 +0100651
Pali Rohárafef9f42021-12-21 12:20:16 +0100652 ret = mvebu_get_tgt_attr(parent, pcie->devfn,
Stefan Roese94f453e2019-01-25 11:52:43 +0100653 IORESOURCE_MEM,
654 &pcie->mem_target, &pcie->mem_attr);
655 if (ret < 0) {
656 printf("%s: cannot get tgt/attr for mem window\n", pcie->name);
657 goto err;
658 }
659
Pali Rohárafef9f42021-12-21 12:20:16 +0100660 ret = mvebu_get_tgt_attr(parent, pcie->devfn,
Phil Sutterba8ae032021-01-03 23:06:46 +0100661 IORESOURCE_IO,
662 &pcie->io_target, &pcie->io_attr);
663 if (ret < 0) {
664 printf("%s: cannot get tgt/attr for IO window\n", pcie->name);
665 goto err;
666 }
667
Stefan Roese94f453e2019-01-25 11:52:43 +0100668 /* Parse PCIe controller register base from DT */
Pali Rohárafef9f42021-12-21 12:20:16 +0100669 addr = ofnode_get_property(node, "assigned-addresses", &len);
Pali Rohár6f4988f2021-12-21 12:20:14 +0100670 if (!addr) {
671 printf("%s: property \"assigned-addresses\" not found\n", pcie->name);
672 ret = -FDT_ERR_NOTFOUND;
Stefan Roese94f453e2019-01-25 11:52:43 +0100673 goto err;
Pali Rohár6f4988f2021-12-21 12:20:14 +0100674 }
675
Pali Rohárafef9f42021-12-21 12:20:16 +0100676 pcie->base = (void *)(u32)ofnode_translate_address(node, addr);
Pali Rohár137db2a2021-12-21 12:20:15 +0100677 pcie->intregs = (u32)pcie->base - fdt32_to_cpu(addr[2]);
Stefan Roese94f453e2019-01-25 11:52:43 +0100678
Stefan Roese94f453e2019-01-25 11:52:43 +0100679 return 0;
680
681err:
682 return ret;
683}
684
685static const struct dm_pci_ops mvebu_pcie_ops = {
686 .read_config = mvebu_pcie_read_config,
687 .write_config = mvebu_pcie_write_config,
688};
689
690static struct driver pcie_mvebu_drv = {
691 .name = "pcie_mvebu",
692 .id = UCLASS_PCI,
693 .ops = &mvebu_pcie_ops,
694 .probe = mvebu_pcie_probe,
Simon Glasscaa4daa2020-12-03 16:55:18 -0700695 .plat_auto = sizeof(struct mvebu_pcie),
Stefan Roese94f453e2019-01-25 11:52:43 +0100696};
697
698/*
699 * Use a MISC device to bind the n instances (child nodes) of the
700 * PCIe base controller in UCLASS_PCI.
701 */
702static int mvebu_pcie_bind(struct udevice *parent)
703{
Pali Rohárafef9f42021-12-21 12:20:16 +0100704 struct mvebu_pcie **ports_pcie;
Stefan Roese94f453e2019-01-25 11:52:43 +0100705 struct mvebu_pcie *pcie;
706 struct uclass_driver *drv;
707 struct udevice *dev;
Pali Rohár537b0142021-12-21 12:20:13 +0100708 struct resource mem;
709 struct resource io;
Pali Rohárafef9f42021-12-21 12:20:16 +0100710 int ports_count, i;
711 ofnode *ports_nodes;
Stefan Roese94f453e2019-01-25 11:52:43 +0100712 ofnode subnode;
713
Pali Rohár03a8a5e2021-10-22 16:22:15 +0200714 /* Lookup pci driver */
Stefan Roese94f453e2019-01-25 11:52:43 +0100715 drv = lists_uclass_lookup(UCLASS_PCI);
716 if (!drv) {
717 puts("Cannot find PCI driver\n");
718 return -ENOENT;
719 }
720
Pali Rohárafef9f42021-12-21 12:20:16 +0100721 ports_count = ofnode_get_child_count(dev_ofnode(parent));
722 ports_pcie = calloc(ports_count, sizeof(*ports_pcie));
723 ports_nodes = calloc(ports_count, sizeof(*ports_nodes));
724 if (!ports_pcie || !ports_nodes) {
725 free(ports_pcie);
726 free(ports_nodes);
727 return -ENOMEM;
728 }
729 ports_count = 0;
730
Pali Rohár43640712022-01-13 14:28:04 +0100731#ifdef CONFIG_ARCH_KIRKWOOD
732 mem.start = KW_DEFADR_PCI_MEM;
733 mem.end = KW_DEFADR_PCI_MEM + KW_DEFADR_PCI_MEM_SIZE - 1;
734 io.start = KW_DEFADR_PCI_IO;
735 io.end = KW_DEFADR_PCI_IO + KW_DEFADR_PCI_IO_SIZE - 1;
736#else
Pali Rohár537b0142021-12-21 12:20:13 +0100737 mem.start = MBUS_PCI_MEM_BASE;
738 mem.end = MBUS_PCI_MEM_BASE + MBUS_PCI_MEM_SIZE - 1;
739 io.start = MBUS_PCI_IO_BASE;
740 io.end = MBUS_PCI_IO_BASE + MBUS_PCI_IO_SIZE - 1;
Pali Rohár43640712022-01-13 14:28:04 +0100741#endif
Pali Rohár537b0142021-12-21 12:20:13 +0100742
Pali Rohárafef9f42021-12-21 12:20:16 +0100743 /* First phase: Fill mvebu_pcie struct for each port */
Stefan Roese94f453e2019-01-25 11:52:43 +0100744 ofnode_for_each_subnode(subnode, dev_ofnode(parent)) {
Simon Glass89090662022-09-06 20:27:17 -0600745 if (!ofnode_is_enabled(subnode))
Stefan Roese94f453e2019-01-25 11:52:43 +0100746 continue;
747
748 pcie = calloc(1, sizeof(*pcie));
749 if (!pcie)
Pali Rohárafef9f42021-12-21 12:20:16 +0100750 continue;
751
752 if (mvebu_pcie_port_parse_dt(subnode, dev_ofnode(parent), pcie) < 0) {
753 free(pcie);
754 continue;
755 }
Stefan Roese94f453e2019-01-25 11:52:43 +0100756
Pali Rohár537b0142021-12-21 12:20:13 +0100757 /*
758 * MVEBU PCIe controller needs MEMORY and I/O BARs to be mapped
759 * into SoCs address space. Each controller will map 128M of MEM
760 * and 64K of I/O space when registered.
761 */
762
763 if (resource_size(&mem) >= SZ_128M) {
764 pcie->mem.start = mem.start;
765 pcie->mem.end = mem.start + SZ_128M - 1;
766 mem.start += SZ_128M;
767 } else {
Pali Rohárafef9f42021-12-21 12:20:16 +0100768 printf("%s: unable to assign mbus window for mem\n", pcie->name);
Pali Rohár537b0142021-12-21 12:20:13 +0100769 pcie->mem.start = 0;
770 pcie->mem.end = -1;
771 }
772
773 if (resource_size(&io) >= SZ_64K) {
774 pcie->io.start = io.start;
775 pcie->io.end = io.start + SZ_64K - 1;
776 io.start += SZ_64K;
777 } else {
Pali Rohárafef9f42021-12-21 12:20:16 +0100778 printf("%s: unable to assign mbus window for io\n", pcie->name);
Pali Rohár537b0142021-12-21 12:20:13 +0100779 pcie->io.start = 0;
780 pcie->io.end = -1;
781 }
782
Pali Rohárafef9f42021-12-21 12:20:16 +0100783 ports_pcie[ports_count] = pcie;
784 ports_nodes[ports_count] = subnode;
785 ports_count++;
786 }
787
788 /* Second phase: Setup all PCIe links (do not enable them yet) */
789 for (i = 0; i < ports_count; i++)
790 mvebu_pcie_setup_link(ports_pcie[i]);
791
792 /* Third phase: Enable all PCIe links and create for each UCLASS_PCI device */
793 for (i = 0; i < ports_count; i++) {
794 pcie = ports_pcie[i];
795 subnode = ports_nodes[i];
796
797 /*
798 * PCIe link can be enabled only after all PCIe links were
799 * properly configured. This is because more PCIe links shares
800 * one enable bit and some PCIe links cannot be enabled
801 * individually.
802 */
803 if (mvebu_pcie_enable_link(pcie, subnode) < 0) {
804 free(pcie);
805 continue;
806 }
807
Stefan Roese94f453e2019-01-25 11:52:43 +0100808 /* Create child device UCLASS_PCI and bind it */
Simon Glass734206d2020-11-28 17:50:01 -0700809 device_bind(parent, &pcie_mvebu_drv, pcie->name, pcie, subnode,
810 &dev);
Stefan Roese94f453e2019-01-25 11:52:43 +0100811 }
812
Pali Rohárafef9f42021-12-21 12:20:16 +0100813 free(ports_pcie);
814 free(ports_nodes);
815
Stefan Roese94f453e2019-01-25 11:52:43 +0100816 return 0;
817}
818
819static const struct udevice_id mvebu_pcie_ids[] = {
820 { .compatible = "marvell,armada-xp-pcie" },
821 { .compatible = "marvell,armada-370-pcie" },
Pali Rohár43640712022-01-13 14:28:04 +0100822 { .compatible = "marvell,kirkwood-pcie" },
Stefan Roese94f453e2019-01-25 11:52:43 +0100823 { }
824};
825
826U_BOOT_DRIVER(pcie_mvebu_base) = {
827 .name = "pcie_mvebu_base",
828 .id = UCLASS_MISC,
829 .of_match = mvebu_pcie_ids,
830 .bind = mvebu_pcie_bind,
831};