Prepare v2023.10
[platform/kernel/u-boot.git] / drivers / pci / pcie_layerscape_fixup.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2017-2021 NXP
4  * Copyright 2014-2015 Freescale Semiconductor, Inc.
5  * Layerscape PCIe driver
6  */
7
8 #include <common.h>
9 #include <dm.h>
10 #include <init.h>
11 #include <log.h>
12 #include <pci.h>
13 #include <asm/arch/fsl_serdes.h>
14 #include <asm/io.h>
15 #include <errno.h>
16 #ifdef CONFIG_OF_BOARD_SETUP
17 #include <linux/libfdt.h>
18 #include <fdt_support.h>
19 #ifdef CONFIG_ARM
20 #include <asm/arch/clock.h>
21 #endif
22 #include <malloc.h>
23 #include <env.h>
24 #include "pcie_layerscape.h"
25 #include "pcie_layerscape_fixup_common.h"
26
27 int next_stream_id;
28
29 static int fdt_pcie_get_nodeoffset(void *blob, struct ls_pcie_rc *pcie_rc)
30 {
31         int nodeoffset;
32         uint svr;
33         char *compat = NULL;
34
35         /* find pci controller node */
36         nodeoffset = fdt_node_offset_by_compat_reg(blob, "fsl,ls-pcie",
37                                                    pcie_rc->dbi_res.start);
38         if (nodeoffset < 0) {
39 #ifdef CONFIG_FSL_PCIE_COMPAT /* Compatible with older version of dts node */
40                 svr = (get_svr() >> SVR_VAR_PER_SHIFT) & 0xFFFFFE;
41                 if (svr == SVR_LS2088A || svr == SVR_LS2084A ||
42                     svr == SVR_LS2048A || svr == SVR_LS2044A ||
43                     svr == SVR_LS2081A || svr == SVR_LS2041A)
44                         compat = "fsl,ls2088a-pcie";
45                 else
46                         compat = CONFIG_FSL_PCIE_COMPAT;
47
48                 nodeoffset =
49                         fdt_node_offset_by_compat_reg(blob, compat,
50                                                       pcie_rc->dbi_res.start);
51 #endif
52         }
53
54         return nodeoffset;
55 }
56
57 #if defined(CONFIG_FSL_LSCH3) || defined(CONFIG_FSL_LSCH2)
58 /*
59  * Return next available LUT index.
60  */
61 static int ls_pcie_next_lut_index(struct ls_pcie_rc *pcie_rc)
62 {
63         if (pcie_rc->next_lut_index < PCIE_LUT_ENTRY_COUNT)
64                 return pcie_rc->next_lut_index++;
65         else
66                 return -ENOSPC;  /* LUT is full */
67 }
68
69 static void lut_writel(struct ls_pcie_rc *pcie_rc, unsigned int value,
70                        unsigned int offset)
71 {
72         struct ls_pcie *pcie = pcie_rc->pcie;
73
74         if (pcie->big_endian)
75                 out_be32(pcie->lut + offset, value);
76         else
77                 out_le32(pcie->lut + offset, value);
78 }
79
80 /*
81  * Program a single LUT entry
82  */
83 static void ls_pcie_lut_set_mapping(struct ls_pcie_rc *pcie_rc, int index,
84                                     u32 devid, u32 streamid)
85 {
86         /* leave mask as all zeroes, want to match all bits */
87         lut_writel(pcie_rc, devid << 16, PCIE_LUT_UDR(index));
88         lut_writel(pcie_rc, streamid | PCIE_LUT_ENABLE, PCIE_LUT_LDR(index));
89 }
90
91 /*
92  * An msi-map is a property to be added to the pci controller
93  * node.  It is a table, where each entry consists of 4 fields
94  * e.g.:
95  *
96  *      msi-map = <[devid] [phandle-to-msi-ctrl] [stream-id] [count]
97  *                 [devid] [phandle-to-msi-ctrl] [stream-id] [count]>;
98  */
99 static void fdt_pcie_set_msi_map_entry_ls(void *blob,
100                                           struct ls_pcie_rc *pcie_rc,
101                                           u32 devid, u32 streamid)
102 {
103         u32 *prop;
104         u32 phandle;
105         int nodeoffset;
106         uint svr;
107         char *compat = NULL;
108         struct ls_pcie *pcie = pcie_rc->pcie;
109
110         /* find pci controller node */
111         nodeoffset = fdt_node_offset_by_compat_reg(blob, "fsl,ls-pcie",
112                                                    pcie_rc->dbi_res.start);
113         if (nodeoffset < 0) {
114 #ifdef CONFIG_FSL_PCIE_COMPAT /* Compatible with older version of dts node */
115                 svr = (get_svr() >> SVR_VAR_PER_SHIFT) & 0xFFFFFE;
116                 if (svr == SVR_LS2088A || svr == SVR_LS2084A ||
117                     svr == SVR_LS2048A || svr == SVR_LS2044A ||
118                     svr == SVR_LS2081A || svr == SVR_LS2041A)
119                         compat = "fsl,ls2088a-pcie";
120                 else
121                         compat = CONFIG_FSL_PCIE_COMPAT;
122                 if (compat)
123                         nodeoffset = fdt_node_offset_by_compat_reg(blob,
124                                         compat, pcie_rc->dbi_res.start);
125 #endif
126                 if (nodeoffset < 0)
127                         return;
128         }
129
130         /* get phandle to MSI controller */
131         prop = (u32 *)fdt_getprop(blob, nodeoffset, "msi-parent", 0);
132         if (prop == NULL) {
133                 debug("\n%s: ERROR: missing msi-parent: PCIe%d\n",
134                       __func__, pcie->idx);
135                 return;
136         }
137         phandle = fdt32_to_cpu(*prop);
138
139         /* set one msi-map row */
140         fdt_appendprop_u32(blob, nodeoffset, "msi-map", devid);
141         fdt_appendprop_u32(blob, nodeoffset, "msi-map", phandle);
142         fdt_appendprop_u32(blob, nodeoffset, "msi-map", streamid);
143         fdt_appendprop_u32(blob, nodeoffset, "msi-map", 1);
144 }
145
146 /*
147  * An iommu-map is a property to be added to the pci controller
148  * node.  It is a table, where each entry consists of 4 fields
149  * e.g.:
150  *
151  *      iommu-map = <[devid] [phandle-to-iommu-ctrl] [stream-id] [count]
152  *                 [devid] [phandle-to-iommu-ctrl] [stream-id] [count]>;
153  */
154 static void fdt_pcie_set_iommu_map_entry_ls(void *blob,
155                                             struct ls_pcie_rc *pcie_rc,
156                                             u32 devid, u32 streamid)
157 {
158         u32 *prop;
159         u32 iommu_map[4];
160         int nodeoffset;
161         int lenp;
162         struct ls_pcie *pcie = pcie_rc->pcie;
163
164         nodeoffset = fdt_pcie_get_nodeoffset(blob, pcie_rc);
165         if (nodeoffset < 0)
166                 return;
167
168         /* get phandle to iommu controller */
169         prop = fdt_getprop_w(blob, nodeoffset, "iommu-map", &lenp);
170         if (prop == NULL) {
171                 debug("\n%s: ERROR: missing iommu-map: PCIe%d\n",
172                       __func__, pcie->idx);
173                 return;
174         }
175
176         /* set iommu-map row */
177         iommu_map[0] = cpu_to_fdt32(devid);
178         iommu_map[1] = *++prop;
179         iommu_map[2] = cpu_to_fdt32(streamid);
180         iommu_map[3] = cpu_to_fdt32(1);
181
182         if (devid == 0) {
183                 fdt_setprop_inplace(blob, nodeoffset, "iommu-map",
184                                     iommu_map, 16);
185         } else {
186                 fdt_appendprop(blob, nodeoffset, "iommu-map", iommu_map, 16);
187         }
188 }
189
190 static int fdt_fixup_pcie_device_ls(void *blob, pci_dev_t bdf,
191                                     struct ls_pcie_rc *pcie_rc)
192 {
193         int streamid, index;
194
195         streamid = pcie_next_streamid(pcie_rc->stream_id_cur,
196                                       pcie_rc->pcie->idx);
197         if (streamid < 0) {
198                 printf("ERROR: out of stream ids for BDF %d.%d.%d\n",
199                        PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
200                 return -ENOENT;
201         }
202         pcie_rc->stream_id_cur++;
203
204         index = ls_pcie_next_lut_index(pcie_rc);
205         if (index < 0) {
206                 printf("ERROR: out of LUT indexes for BDF %d.%d.%d\n",
207                        PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
208                 return -ENOENT;
209         }
210
211         /* map PCI b.d.f to streamID in LUT */
212         ls_pcie_lut_set_mapping(pcie_rc, index, bdf >> 8, streamid);
213         /* update msi-map in device tree */
214         fdt_pcie_set_msi_map_entry_ls(blob, pcie_rc, bdf >> 8, streamid);
215         /* update iommu-map in device tree */
216         fdt_pcie_set_iommu_map_entry_ls(blob, pcie_rc, bdf >> 8, streamid);
217
218         return 0;
219 }
220
221 struct extra_iommu_entry {
222         int action;
223         pci_dev_t bdf;
224         int num_vfs;
225         bool noari;
226 };
227
228 #define EXTRA_IOMMU_ENTRY_HOTPLUG       1
229 #define EXTRA_IOMMU_ENTRY_VFS           2
230
231 static struct extra_iommu_entry *get_extra_iommu_ents(void *blob,
232                                                       int nodeoffset,
233                                                       phys_addr_t addr,
234                                                       int *cnt)
235 {
236         const char *s, *p, *tok;
237         struct extra_iommu_entry *entries;
238         int i = 0, b, d, f;
239
240         /*
241          * Retrieve extra IOMMU configuration from env var or from device tree.
242          * Env var is given priority.
243          */
244         s = env_get("pci_iommu_extra");
245         if (!s) {
246                 s = fdt_getprop(blob, nodeoffset, "pci-iommu-extra", NULL);
247         } else {
248                 phys_addr_t pci_base;
249                 char *endp;
250
251                 /*
252                  * In env var case the config string has "pci@0x..." in
253                  * addition. Parse this part and match it by address against
254                  * the input pci controller's registers base address.
255                  */
256                 tok = s;
257                 p = strchrnul(s + 1, ',');
258                 s = NULL;
259                 do {
260                         if (!strncmp(tok, "pci", 3)) {
261                                 pci_base = simple_strtoul(tok  + 4, &endp, 0);
262                                 if (pci_base == addr) {
263                                         s = endp + 1;
264                                         break;
265                                 }
266                         }
267                         p = strchrnul(p + 1, ',');
268                         tok = p + 1;
269                 } while (*p);
270         }
271
272         /*
273          * If no env var or device tree property found or pci register base
274          * address mismatches, bail out
275          */
276         if (!s)
277                 return NULL;
278
279         /*
280          * In order to find how many action entries to allocate, count number
281          * of actions by interating through the pairs of bdfs and actions.
282          */
283         *cnt = 0;
284         p = s;
285         while (*p && strncmp(p, "pci", 3)) {
286                 if (*p == ',')
287                         (*cnt)++;
288                 p++;
289         }
290         if (!(*p))
291                 (*cnt)++;
292
293         if (!(*cnt) || (*cnt) % 2) {
294                 printf("ERROR: invalid or odd extra iommu token count %d\n",
295                        *cnt);
296                 return NULL;
297         }
298         *cnt = (*cnt) / 2;
299
300         entries = malloc((*cnt) * sizeof(*entries));
301         if (!entries) {
302                 printf("ERROR: fail to allocate extra iommu entries\n");
303                 return NULL;
304         }
305
306         /*
307          * Parse action entries one by one and store the information in the
308          * newly allocated actions array.
309          */
310         p = s;
311         while (p) {
312                 /* Extract BDF */
313                 b = simple_strtoul(p, (char **)&p, 0); p++;
314                 d = simple_strtoul(p, (char **)&p, 0); p++;
315                 f = simple_strtoul(p, (char **)&p, 0); p++;
316                 entries[i].bdf = PCI_BDF(b, d, f);
317
318                 /* Parse action */
319                 if (!strncmp(p, "hp", 2)) {
320                         /* Hot-plug entry */
321                         entries[i].action = EXTRA_IOMMU_ENTRY_HOTPLUG;
322                         p += 2;
323                 } else if (!strncmp(p, "vfs", 3) ||
324                            !strncmp(p, "noari_vfs", 9)) {
325                         /* VFs or VFs with ARI disabled entry */
326                         entries[i].action = EXTRA_IOMMU_ENTRY_VFS;
327                         entries[i].noari = !strncmp(p, "noari_vfs", 9);
328
329                         /*
330                          * Parse and store total number of VFs to allocate
331                          * IOMMU entries for.
332                          */
333                         p = strchr(p, '=');
334                         entries[i].num_vfs = simple_strtoul(p + 1, (char **)&p,
335                                                             0);
336                         if (*p)
337                                 p++;
338                 } else {
339                         printf("ERROR: invalid action in extra iommu entry\n");
340                         free(entries);
341
342                         return NULL;
343                 }
344
345                 if (!(*p) || !strncmp(p, "pci", 3))
346                         break;
347
348                 i++;
349         }
350
351         return entries;
352 }
353
354 static void get_vf_offset_and_stride(struct udevice *dev, int sriov_pos,
355                                      struct extra_iommu_entry *entry,
356                                      u16 *offset, u16 *stride)
357 {
358         u16 tmp16;
359         u32 tmp32;
360         bool have_ari = false;
361         int pos;
362         struct udevice *pf_dev;
363
364         dm_pci_read_config16(dev, sriov_pos + PCI_SRIOV_TOTAL_VF, &tmp16);
365         if (entry->num_vfs > tmp16) {
366                 printf("WARN: requested no. of VFs %d exceeds total of %d\n",
367                        entry->num_vfs, tmp16);
368         }
369
370         /*
371          * The code below implements the VF Discovery recomandations specified
372          * in PCIe base spec "9.2.1.2 VF Discovery", quoted below:
373          *
374          * VF Discovery
375          *
376          * The First VF Offset and VF Stride fields in the SR-IOV extended
377          * capability are 16-bit Routing ID offsets. These offsets are used to
378          * compute the Routing IDs for the VFs with the following restrictions:
379          *  - The value in NumVFs in a PF (Section 9.3.3.7) may affect the
380          *    values in First VF Offset (Section 9.3.3.9) and VF Stride
381          *    (Section 9.3.3.10) of that PF.
382          *  - The value in ARI Capable Hierarchy (Section 9.3.3.3.5) in the
383          *    lowest-numbered PF of the Device (for example PF0) may affect
384          *    the values in First VF Offset and VF Stride in all PFs of the
385          *    Device.
386          *  - NumVFs of a PF may only be changed when VF Enable
387          *    (Section 9.3.3.3.1) of that PF is Clear.
388          *  - ARI Capable Hierarchy (Section 9.3.3.3.5) may only be changed
389          *    when VF Enable is Clear in all PFs of a Device.
390          */
391
392         /* Clear VF enable for all PFs */
393         device_foreach_child(pf_dev, dev->parent) {
394                 dm_pci_read_config16(pf_dev, sriov_pos + PCI_SRIOV_CTRL,
395                                      &tmp16);
396                 tmp16 &= ~PCI_SRIOV_CTRL_VFE;
397                 dm_pci_write_config16(pf_dev, sriov_pos + PCI_SRIOV_CTRL,
398                                       tmp16);
399         }
400
401         /* Obtain a reference to PF0 device */
402         if (dm_pci_bus_find_bdf(PCI_BDF(PCI_BUS(entry->bdf),
403                                         PCI_DEV(entry->bdf), 0), &pf_dev)) {
404                 printf("WARN: failed to get PF0\n");
405         }
406
407         if (entry->noari)
408                 goto skip_ari;
409
410         /* Check that connected downstream port supports ARI Forwarding */
411         pos = dm_pci_find_capability(dev->parent, PCI_CAP_ID_EXP);
412         dm_pci_read_config32(dev->parent, pos + PCI_EXP_DEVCAP2, &tmp32);
413         if (!(tmp32 & PCI_EXP_DEVCAP2_ARI))
414                 goto skip_ari;
415
416         /* Check that PF supports Alternate Routing ID */
417         if (!dm_pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI))
418                 goto skip_ari;
419
420         /* Set ARI Capable Hierarcy for PF0 */
421         dm_pci_read_config16(pf_dev, sriov_pos + PCI_SRIOV_CTRL, &tmp16);
422         tmp16 |= PCI_SRIOV_CTRL_ARI;
423         dm_pci_write_config16(pf_dev, sriov_pos + PCI_SRIOV_CTRL, tmp16);
424         have_ari = true;
425
426 skip_ari:
427         if (!have_ari) {
428                 /*
429                  * No ARI support or disabled so clear ARI Capable Hierarcy
430                  * for PF0
431                  */
432                 dm_pci_read_config16(pf_dev, sriov_pos + PCI_SRIOV_CTRL,
433                                      &tmp16);
434                 tmp16 &= ~PCI_SRIOV_CTRL_ARI;
435                 dm_pci_write_config16(pf_dev, sriov_pos + PCI_SRIOV_CTRL,
436                                       tmp16);
437         }
438
439         /* Set requested number of VFs */
440         dm_pci_write_config16(dev, sriov_pos + PCI_SRIOV_NUM_VF,
441                               entry->num_vfs);
442
443         /* Read VF stride and offset with the configs just made */
444         dm_pci_read_config16(dev, sriov_pos + PCI_SRIOV_VF_OFFSET, offset);
445         dm_pci_read_config16(dev, sriov_pos + PCI_SRIOV_VF_STRIDE, stride);
446
447         if (have_ari) {
448                 /* Reset to default ARI Capable Hierarcy bit for PF0 */
449                 dm_pci_read_config16(pf_dev, sriov_pos + PCI_SRIOV_CTRL,
450                                      &tmp16);
451                 tmp16 &= ~PCI_SRIOV_CTRL_ARI;
452                 dm_pci_write_config16(pf_dev, sriov_pos + PCI_SRIOV_CTRL,
453                                       tmp16);
454         }
455         /* Reset to default the number of VFs */
456         dm_pci_write_config16(dev, sriov_pos + PCI_SRIOV_NUM_VF, 0);
457 }
458
459 static int fdt_fixup_pci_vfs(void *blob, struct extra_iommu_entry *entry,
460                              struct ls_pcie_rc *pcie_rc)
461 {
462         struct udevice *dev, *bus;
463         u16 vf_offset, vf_stride;
464         int i, sriov_pos;
465         pci_dev_t bdf;
466
467         if (dm_pci_bus_find_bdf(entry->bdf, &dev)) {
468                 printf("ERROR: BDF %d.%d.%d not found\n", PCI_BUS(entry->bdf),
469                        PCI_DEV(entry->bdf), PCI_FUNC(entry->bdf));
470                 return 0;
471         }
472
473         sriov_pos = dm_pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV);
474         if (!sriov_pos) {
475                 printf("WARN: trying to set VFs on non-SRIOV dev\n");
476                 return 0;
477         }
478
479         get_vf_offset_and_stride(dev, sriov_pos, entry, &vf_offset, &vf_stride);
480
481         for (bus = dev; device_is_on_pci_bus(bus);)
482                 bus = bus->parent;
483
484         bdf = entry->bdf - PCI_BDF(dev_seq(bus), 0, 0) + (vf_offset << 8);
485
486         for (i = 0; i < entry->num_vfs; i++) {
487                 if (fdt_fixup_pcie_device_ls(blob, bdf, pcie_rc) < 0)
488                         return -1;
489                 bdf += vf_stride << 8;
490         }
491
492         printf("Added %d iommu VF mappings for PF %d.%d.%d\n",
493                entry->num_vfs, PCI_BUS(entry->bdf),
494                PCI_DEV(entry->bdf), PCI_FUNC(entry->bdf));
495
496         return 0;
497 }
498
499 static void fdt_fixup_pcie_ls(void *blob)
500 {
501         struct udevice *dev, *bus;
502         struct ls_pcie_rc *pcie_rc;
503         pci_dev_t bdf;
504         struct extra_iommu_entry *entries;
505         int i, cnt, nodeoffset;
506
507
508         /* Scan all known buses */
509         for (pci_find_first_device(&dev);
510              dev;
511              pci_find_next_device(&dev)) {
512                 for (bus = dev; device_is_on_pci_bus(bus);)
513                         bus = bus->parent;
514
515                 /* Only do the fixups for layerscape PCIe controllers */
516                 if (!device_is_compatible(bus, "fsl,ls-pcie") &&
517                     !device_is_compatible(bus, CONFIG_FSL_PCIE_COMPAT))
518                         continue;
519
520                 pcie_rc = dev_get_priv(bus);
521
522                 /* the DT fixup must be relative to the hose first_busno */
523                 bdf = dm_pci_get_bdf(dev) - PCI_BDF(dev_seq(bus), 0, 0);
524
525                 if (fdt_fixup_pcie_device_ls(blob, bdf, pcie_rc) < 0)
526                         break;
527         }
528
529         if (!IS_ENABLED(CONFIG_PCI_IOMMU_EXTRA_MAPPINGS))
530                 return;
531
532         list_for_each_entry(pcie_rc, &ls_pcie_list, list) {
533                 nodeoffset = fdt_pcie_get_nodeoffset(blob, pcie_rc);
534                 if (nodeoffset < 0) {
535                         printf("ERROR: couldn't find pci node\n");
536                         continue;
537                 }
538
539                 entries = get_extra_iommu_ents(blob, nodeoffset,
540                                                pcie_rc->dbi_res.start, &cnt);
541                 if (!entries)
542                         continue;
543
544                 for (i = 0; i < cnt; i++) {
545                         if (entries[i].action == EXTRA_IOMMU_ENTRY_HOTPLUG) {
546                                 bdf = entries[i].bdf;
547                                 printf("Added iommu map for hotplug %d.%d.%d\n",
548                                        PCI_BUS(bdf), PCI_DEV(bdf),
549                                        PCI_FUNC(bdf));
550                                 if (fdt_fixup_pcie_device_ls(blob, bdf,
551                                                              pcie_rc) < 0) {
552                                         free(entries);
553                                         return;
554                                 }
555                         } else if (entries[i].action == EXTRA_IOMMU_ENTRY_VFS) {
556                                 if (fdt_fixup_pci_vfs(blob, &entries[i],
557                                                       pcie_rc) < 0) {
558                                         free(entries);
559                                         return;
560                                 }
561                         } else {
562                                 printf("Invalid action %d for BDF %d.%d.%d\n",
563                                        entries[i].action,
564                                        PCI_BUS(entries[i].bdf),
565                                        PCI_DEV(entries[i].bdf),
566                                        PCI_FUNC(entries[i].bdf));
567                         }
568                 }
569                 free(entries);
570         }
571 }
572 #endif
573
574 static void ft_pcie_rc_fix(void *blob, struct ls_pcie_rc *pcie_rc)
575 {
576         int off;
577         struct ls_pcie *pcie = pcie_rc->pcie;
578
579         off = fdt_pcie_get_nodeoffset(blob, pcie_rc);
580         if (off < 0)
581                 return;
582
583         if (pcie_rc->enabled && pcie->mode == PCI_HEADER_TYPE_BRIDGE)
584                 fdt_set_node_status(blob, off, FDT_STATUS_OKAY);
585         else
586                 fdt_set_node_status(blob, off, FDT_STATUS_DISABLED);
587 }
588
589 static void ft_pcie_ep_fix(void *blob, struct ls_pcie_rc *pcie_rc)
590 {
591         int off;
592         struct ls_pcie *pcie = pcie_rc->pcie;
593
594         off = fdt_node_offset_by_compat_reg(blob, CONFIG_FSL_PCIE_EP_COMPAT,
595                                             pcie_rc->dbi_res.start);
596         if (off < 0)
597                 return;
598
599         if (pcie_rc->enabled && pcie->mode == PCI_HEADER_TYPE_NORMAL)
600                 fdt_set_node_status(blob, off, FDT_STATUS_OKAY);
601         else
602                 fdt_set_node_status(blob, off, FDT_STATUS_DISABLED);
603 }
604
605 static void ft_pcie_ls_setup(void *blob, struct ls_pcie_rc *pcie_rc)
606 {
607         ft_pcie_ep_fix(blob, pcie_rc);
608         ft_pcie_rc_fix(blob, pcie_rc);
609
610         pcie_rc->stream_id_cur = 0;
611         pcie_rc->next_lut_index = 0;
612 }
613
614 /* Fixup Kernel DT for PCIe */
615 void ft_pci_setup_ls(void *blob, struct bd_info *bd)
616 {
617         struct ls_pcie_rc *pcie_rc;
618
619 #if defined(CONFIG_FSL_LSCH3) || defined(CONFIG_FSL_LSCH2)
620         pcie_board_fix_fdt(blob);
621 #endif
622
623         list_for_each_entry(pcie_rc, &ls_pcie_list, list)
624                 ft_pcie_ls_setup(blob, pcie_rc);
625
626 #if defined(CONFIG_FSL_LSCH3) || defined(CONFIG_FSL_LSCH2)
627         next_stream_id = FSL_PEX_STREAM_ID_START;
628         fdt_fixup_pcie_ls(blob);
629 #endif
630 }
631
632 #else /* !CONFIG_OF_BOARD_SETUP */
633 void ft_pci_setup_ls(void *blob, struct bd_info *bd)
634 {
635 }
636 #endif