uboot/drivers/pci/pcie_layerscape_fixup.c
<<
>>
Prefs
   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
  27int next_stream_id;
  28
  29static 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 */
  61static 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
  69static 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 */
  83static 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 */
  99static 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 */
 154static 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
 190static 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
 221struct 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
 231static 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
 354static 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
 426skip_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
 459static 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
 499static 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                goto skip;
 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
 572skip:
 573        pcie_board_fix_fdt(blob);
 574}
 575#endif
 576
 577static void ft_pcie_rc_fix(void *blob, struct ls_pcie_rc *pcie_rc)
 578{
 579        int off;
 580        struct ls_pcie *pcie = pcie_rc->pcie;
 581
 582        off = fdt_pcie_get_nodeoffset(blob, pcie_rc);
 583        if (off < 0)
 584                return;
 585
 586        if (pcie_rc->enabled && pcie->mode == PCI_HEADER_TYPE_BRIDGE)
 587                fdt_set_node_status(blob, off, FDT_STATUS_OKAY, 0);
 588        else
 589                fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
 590}
 591
 592static void ft_pcie_ep_fix(void *blob, struct ls_pcie_rc *pcie_rc)
 593{
 594        int off;
 595        struct ls_pcie *pcie = pcie_rc->pcie;
 596
 597        off = fdt_node_offset_by_compat_reg(blob, CONFIG_FSL_PCIE_EP_COMPAT,
 598                                            pcie_rc->dbi_res.start);
 599        if (off < 0)
 600                return;
 601
 602        if (pcie_rc->enabled && pcie->mode == PCI_HEADER_TYPE_NORMAL)
 603                fdt_set_node_status(blob, off, FDT_STATUS_OKAY, 0);
 604        else
 605                fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
 606}
 607
 608static void ft_pcie_ls_setup(void *blob, struct ls_pcie_rc *pcie_rc)
 609{
 610        ft_pcie_ep_fix(blob, pcie_rc);
 611        ft_pcie_rc_fix(blob, pcie_rc);
 612
 613        pcie_rc->stream_id_cur = 0;
 614        pcie_rc->next_lut_index = 0;
 615}
 616
 617/* Fixup Kernel DT for PCIe */
 618void ft_pci_setup_ls(void *blob, struct bd_info *bd)
 619{
 620        struct ls_pcie_rc *pcie_rc;
 621
 622        list_for_each_entry(pcie_rc, &ls_pcie_list, list)
 623                ft_pcie_ls_setup(blob, pcie_rc);
 624
 625#if defined(CONFIG_FSL_LSCH3) || defined(CONFIG_FSL_LSCH2)
 626        next_stream_id = FSL_PEX_STREAM_ID_START;
 627        fdt_fixup_pcie_ls(blob);
 628#endif
 629}
 630
 631#else /* !CONFIG_OF_BOARD_SETUP */
 632void ft_pci_setup_ls(void *blob, struct bd_info *bd)
 633{
 634}
 635#endif
 636