uboot/drivers/pci/pcie_layerscape_rc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2020 NXP
   4 * Layerscape PCIe driver
   5 */
   6
   7#include <common.h>
   8#include <asm/arch/fsl_serdes.h>
   9#include <pci.h>
  10#include <asm/global_data.h>
  11#include <asm/io.h>
  12#include <errno.h>
  13#include <malloc.h>
  14#include <dm.h>
  15#include <dm/devres.h>
  16#if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) || \
  17        defined(CONFIG_ARM)
  18#include <asm/arch/clock.h>
  19#endif
  20#include "pcie_layerscape.h"
  21
  22DECLARE_GLOBAL_DATA_PTR;
  23
  24static void ls_pcie_cfg0_set_busdev(struct ls_pcie_rc *pcie_rc, u32 busdev)
  25{
  26        struct ls_pcie *pcie = pcie_rc->pcie;
  27
  28        dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0,
  29                   PCIE_ATU_VIEWPORT);
  30        dbi_writel(pcie, busdev, PCIE_ATU_LOWER_TARGET);
  31}
  32
  33static void ls_pcie_cfg1_set_busdev(struct ls_pcie_rc *pcie_rc, u32 busdev)
  34{
  35        struct ls_pcie *pcie = pcie_rc->pcie;
  36
  37        dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
  38                   PCIE_ATU_VIEWPORT);
  39        dbi_writel(pcie, busdev, PCIE_ATU_LOWER_TARGET);
  40}
  41
  42static void ls_pcie_setup_atu(struct ls_pcie_rc *pcie_rc)
  43{
  44        struct pci_region *io, *mem, *pref;
  45        unsigned long long offset = 0;
  46        struct ls_pcie *pcie = pcie_rc->pcie;
  47        int idx = 0;
  48        uint svr;
  49
  50        svr = get_svr();
  51        if (((svr >> SVR_VAR_PER_SHIFT) & SVR_LS102XA_MASK) == SVR_LS102XA) {
  52                offset = LS1021_PCIE_SPACE_OFFSET +
  53                         LS1021_PCIE_SPACE_SIZE * pcie->idx;
  54        }
  55
  56        /* ATU 0 : OUTBOUND : CFG0 */
  57        ls_pcie_atu_outbound_set(pcie, PCIE_ATU_REGION_INDEX0,
  58                                 PCIE_ATU_TYPE_CFG0,
  59                                 pcie_rc->cfg_res.start + offset,
  60                                 0,
  61                                 fdt_resource_size(&pcie_rc->cfg_res) / 2);
  62        /* ATU 1 : OUTBOUND : CFG1 */
  63        ls_pcie_atu_outbound_set(pcie, PCIE_ATU_REGION_INDEX1,
  64                                 PCIE_ATU_TYPE_CFG1,
  65                                 pcie_rc->cfg_res.start + offset +
  66                                 fdt_resource_size(&pcie_rc->cfg_res) / 2,
  67                                 0,
  68                                 fdt_resource_size(&pcie_rc->cfg_res) / 2);
  69
  70        pci_get_regions(pcie_rc->bus, &io, &mem, &pref);
  71        idx = PCIE_ATU_REGION_INDEX1 + 1;
  72
  73        /* Fix the pcie memory map for LS2088A series SoCs */
  74        svr = (svr >> SVR_VAR_PER_SHIFT) & 0xFFFFFE;
  75        if (svr == SVR_LS2088A || svr == SVR_LS2084A ||
  76            svr == SVR_LS2048A || svr == SVR_LS2044A ||
  77            svr == SVR_LS2081A || svr == SVR_LS2041A) {
  78                if (io)
  79                        io->phys_start = (io->phys_start &
  80                                         (PCIE_PHYS_SIZE - 1)) +
  81                                         LS2088A_PCIE1_PHYS_ADDR +
  82                                         LS2088A_PCIE_PHYS_SIZE * pcie->idx;
  83                if (mem)
  84                        mem->phys_start = (mem->phys_start &
  85                                         (PCIE_PHYS_SIZE - 1)) +
  86                                         LS2088A_PCIE1_PHYS_ADDR +
  87                                         LS2088A_PCIE_PHYS_SIZE * pcie->idx;
  88                if (pref)
  89                        pref->phys_start = (pref->phys_start &
  90                                         (PCIE_PHYS_SIZE - 1)) +
  91                                         LS2088A_PCIE1_PHYS_ADDR +
  92                                         LS2088A_PCIE_PHYS_SIZE * pcie->idx;
  93        }
  94
  95        if (io)
  96                /* ATU : OUTBOUND : IO */
  97                ls_pcie_atu_outbound_set(pcie, idx++,
  98                                         PCIE_ATU_TYPE_IO,
  99                                         io->phys_start + offset,
 100                                         io->bus_start,
 101                                         io->size);
 102
 103        if (mem)
 104                /* ATU : OUTBOUND : MEM */
 105                ls_pcie_atu_outbound_set(pcie, idx++,
 106                                         PCIE_ATU_TYPE_MEM,
 107                                         mem->phys_start + offset,
 108                                         mem->bus_start,
 109                                         mem->size);
 110
 111        if (pref)
 112                /* ATU : OUTBOUND : pref */
 113                ls_pcie_atu_outbound_set(pcie, idx++,
 114                                         PCIE_ATU_TYPE_MEM,
 115                                         pref->phys_start + offset,
 116                                         pref->bus_start,
 117                                         pref->size);
 118
 119        ls_pcie_dump_atu(pcie, PCIE_ATU_REGION_NUM, PCIE_ATU_REGION_OUTBOUND);
 120}
 121
 122/* Return 0 if the address is valid, -errno if not valid */
 123static int ls_pcie_addr_valid(struct ls_pcie_rc *pcie_rc, pci_dev_t bdf)
 124{
 125        struct udevice *bus = pcie_rc->bus;
 126        struct ls_pcie *pcie = pcie_rc->pcie;
 127
 128        if (pcie->mode == PCI_HEADER_TYPE_NORMAL)
 129                return -ENODEV;
 130
 131        if (!pcie_rc->enabled)
 132                return -ENXIO;
 133
 134        if (PCI_BUS(bdf) < dev_seq(bus))
 135                return -EINVAL;
 136
 137        if ((PCI_BUS(bdf) > dev_seq(bus)) && (!ls_pcie_link_up(pcie)))
 138                return -EINVAL;
 139
 140        if (PCI_BUS(bdf) <= (dev_seq(bus) + 1) && (PCI_DEV(bdf) > 0))
 141                return -EINVAL;
 142
 143        return 0;
 144}
 145
 146int ls_pcie_conf_address(const struct udevice *bus, pci_dev_t bdf,
 147                         uint offset, void **paddress)
 148{
 149        struct ls_pcie_rc *pcie_rc = dev_get_priv(bus);
 150        struct ls_pcie *pcie = pcie_rc->pcie;
 151        u32 busdev;
 152
 153        if (ls_pcie_addr_valid(pcie_rc, bdf))
 154                return -EINVAL;
 155
 156        if (PCI_BUS(bdf) == dev_seq(bus)) {
 157                *paddress = pcie->dbi + offset;
 158                return 0;
 159        }
 160
 161        busdev = PCIE_ATU_BUS(PCI_BUS(bdf) - dev_seq(bus)) |
 162                 PCIE_ATU_DEV(PCI_DEV(bdf)) |
 163                 PCIE_ATU_FUNC(PCI_FUNC(bdf));
 164
 165        if (PCI_BUS(bdf) == dev_seq(bus) + 1) {
 166                ls_pcie_cfg0_set_busdev(pcie_rc, busdev);
 167                *paddress = pcie_rc->cfg0 + offset;
 168        } else {
 169                ls_pcie_cfg1_set_busdev(pcie_rc, busdev);
 170                *paddress = pcie_rc->cfg1 + offset;
 171        }
 172        return 0;
 173}
 174
 175static int ls_pcie_read_config(const struct udevice *bus, pci_dev_t bdf,
 176                               uint offset, ulong *valuep,
 177                               enum pci_size_t size)
 178{
 179        return pci_generic_mmap_read_config(bus, ls_pcie_conf_address,
 180                                            bdf, offset, valuep, size);
 181}
 182
 183static int ls_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
 184                                uint offset, ulong value,
 185                                enum pci_size_t size)
 186{
 187        return pci_generic_mmap_write_config(bus, ls_pcie_conf_address,
 188                                             bdf, offset, value, size);
 189}
 190
 191/* Clear multi-function bit */
 192static void ls_pcie_clear_multifunction(struct ls_pcie_rc *pcie_rc)
 193{
 194        struct ls_pcie *pcie = pcie_rc->pcie;
 195
 196        writeb(PCI_HEADER_TYPE_BRIDGE, pcie->dbi + PCI_HEADER_TYPE);
 197}
 198
 199/* Fix class value */
 200static void ls_pcie_fix_class(struct ls_pcie_rc *pcie_rc)
 201{
 202        struct ls_pcie *pcie = pcie_rc->pcie;
 203
 204        writew(PCI_CLASS_BRIDGE_PCI, pcie->dbi + PCI_CLASS_DEVICE);
 205}
 206
 207/* Drop MSG TLP except for Vendor MSG */
 208static void ls_pcie_drop_msg_tlp(struct ls_pcie_rc *pcie_rc)
 209{
 210        struct ls_pcie *pcie = pcie_rc->pcie;
 211        u32 val;
 212
 213        val = dbi_readl(pcie, PCIE_STRFMR1);
 214        val &= 0xDFFFFFFF;
 215        dbi_writel(pcie, val, PCIE_STRFMR1);
 216}
 217
 218/* Disable all bars in RC mode */
 219static void ls_pcie_disable_bars(struct ls_pcie_rc *pcie_rc)
 220{
 221        struct ls_pcie *pcie = pcie_rc->pcie;
 222
 223        dbi_writel(pcie, 0, PCIE_CS2_OFFSET + PCI_BASE_ADDRESS_0);
 224        dbi_writel(pcie, 0, PCIE_CS2_OFFSET + PCI_BASE_ADDRESS_1);
 225        dbi_writel(pcie, 0xfffffffe, PCIE_CS2_OFFSET + PCI_ROM_ADDRESS1);
 226}
 227
 228static void ls_pcie_setup_ctrl(struct ls_pcie_rc *pcie_rc)
 229{
 230        struct ls_pcie *pcie = pcie_rc->pcie;
 231
 232        ls_pcie_setup_atu(pcie_rc);
 233
 234        ls_pcie_dbi_ro_wr_en(pcie);
 235        ls_pcie_fix_class(pcie_rc);
 236        ls_pcie_clear_multifunction(pcie_rc);
 237        ls_pcie_drop_msg_tlp(pcie_rc);
 238        ls_pcie_dbi_ro_wr_dis(pcie);
 239
 240        ls_pcie_disable_bars(pcie_rc);
 241        pcie_rc->stream_id_cur = 0;
 242}
 243
 244static int ls_pcie_probe(struct udevice *dev)
 245{
 246        struct ls_pcie_rc *pcie_rc = dev_get_priv(dev);
 247        const void *fdt = gd->fdt_blob;
 248        int node = dev_of_offset(dev);
 249        struct ls_pcie *pcie;
 250        u16 link_sta;
 251        uint svr;
 252        int ret;
 253        fdt_size_t cfg_size;
 254
 255        pcie_rc->bus = dev;
 256
 257        pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
 258        if (!pcie)
 259                return -ENOMEM;
 260
 261        pcie_rc->pcie = pcie;
 262
 263        ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
 264                                     "dbi", &pcie_rc->dbi_res);
 265        if (ret) {
 266                printf("ls-pcie: resource \"dbi\" not found\n");
 267                return ret;
 268        }
 269
 270        pcie->idx = (pcie_rc->dbi_res.start - PCIE_SYS_BASE_ADDR) /
 271                    PCIE_CCSR_SIZE;
 272
 273        list_add(&pcie_rc->list, &ls_pcie_list);
 274
 275        pcie_rc->enabled = is_serdes_configured(PCIE_SRDS_PRTCL(pcie->idx));
 276        if (!pcie_rc->enabled) {
 277                printf("PCIe%d: %s disabled\n", PCIE_SRDS_PRTCL(pcie->idx),
 278                       dev->name);
 279                return 0;
 280        }
 281
 282        pcie->dbi = map_physmem(pcie_rc->dbi_res.start,
 283                                fdt_resource_size(&pcie_rc->dbi_res),
 284                                MAP_NOCACHE);
 285
 286        pcie->mode = readb(pcie->dbi + PCI_HEADER_TYPE) & 0x7f;
 287        if (pcie->mode == PCI_HEADER_TYPE_NORMAL)
 288                return 0;
 289
 290        ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
 291                                     "lut", &pcie_rc->lut_res);
 292        if (!ret)
 293                pcie->lut = map_physmem(pcie_rc->lut_res.start,
 294                                        fdt_resource_size(&pcie_rc->lut_res),
 295                                        MAP_NOCACHE);
 296
 297        ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
 298                                     "ctrl", &pcie_rc->ctrl_res);
 299        if (!ret)
 300                pcie->ctrl = map_physmem(pcie_rc->ctrl_res.start,
 301                                         fdt_resource_size(&pcie_rc->ctrl_res),
 302                                         MAP_NOCACHE);
 303        if (!pcie->ctrl)
 304                pcie->ctrl = pcie->lut;
 305
 306        if (!pcie->ctrl) {
 307                printf("%s: NOT find CTRL\n", dev->name);
 308                return -1;
 309        }
 310
 311        ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
 312                                     "config", &pcie_rc->cfg_res);
 313        if (ret) {
 314                printf("%s: resource \"config\" not found\n", dev->name);
 315                return ret;
 316        }
 317
 318        cfg_size = fdt_resource_size(&pcie_rc->cfg_res);
 319        if (cfg_size < SZ_8K) {
 320                printf("PCIe%d: %s Invalid size(0x%llx) for resource \"config\",expected minimum 0x%x\n",
 321                       PCIE_SRDS_PRTCL(pcie->idx), dev->name, (u64)cfg_size, SZ_8K);
 322                return 0;
 323        }
 324
 325        /*
 326         * Fix the pcie memory map address and PF control registers address
 327         * for LS2088A series SoCs
 328         */
 329        svr = get_svr();
 330        svr = (svr >> SVR_VAR_PER_SHIFT) & 0xFFFFFE;
 331        if (svr == SVR_LS2088A || svr == SVR_LS2084A ||
 332            svr == SVR_LS2048A || svr == SVR_LS2044A ||
 333            svr == SVR_LS2081A || svr == SVR_LS2041A) {
 334                pcie_rc->cfg_res.start = LS2088A_PCIE1_PHYS_ADDR +
 335                                         LS2088A_PCIE_PHYS_SIZE * pcie->idx;
 336                pcie_rc->cfg_res.end = pcie_rc->cfg_res.start + cfg_size;
 337                pcie->ctrl = pcie->lut + 0x40000;
 338        }
 339
 340        pcie_rc->cfg0 = map_physmem(pcie_rc->cfg_res.start,
 341                                    fdt_resource_size(&pcie_rc->cfg_res),
 342                                    MAP_NOCACHE);
 343        pcie_rc->cfg1 = pcie_rc->cfg0 +
 344                        fdt_resource_size(&pcie_rc->cfg_res) / 2;
 345
 346        pcie->big_endian = fdtdec_get_bool(fdt, node, "big-endian");
 347
 348        debug("%s dbi:%lx lut:%lx ctrl:0x%lx cfg0:0x%lx, big-endian:%d\n",
 349              dev->name, (unsigned long)pcie->dbi, (unsigned long)pcie->lut,
 350              (unsigned long)pcie->ctrl, (unsigned long)pcie_rc->cfg0,
 351              pcie->big_endian);
 352
 353        printf("PCIe%u: %s %s", PCIE_SRDS_PRTCL(pcie->idx), dev->name,
 354               "Root Complex");
 355        ls_pcie_setup_ctrl(pcie_rc);
 356
 357        if (!ls_pcie_link_up(pcie)) {
 358                /* Let the user know there's no PCIe link */
 359                printf(": no link\n");
 360                return 0;
 361        }
 362
 363        /* Print the negotiated PCIe link width */
 364        link_sta = readw(pcie->dbi + PCIE_LINK_STA);
 365        printf(": x%d gen%d\n", (link_sta & PCIE_LINK_WIDTH_MASK) >> 4,
 366               link_sta & PCIE_LINK_SPEED_MASK);
 367
 368        return 0;
 369}
 370
 371static const struct dm_pci_ops ls_pcie_ops = {
 372        .read_config    = ls_pcie_read_config,
 373        .write_config   = ls_pcie_write_config,
 374};
 375
 376static const struct udevice_id ls_pcie_ids[] = {
 377        { .compatible = "fsl,ls-pcie" },
 378        { }
 379};
 380
 381U_BOOT_DRIVER(pci_layerscape) = {
 382        .name = "pci_layerscape",
 383        .id = UCLASS_PCI,
 384        .of_match = ls_pcie_ids,
 385        .ops = &ls_pcie_ops,
 386        .probe  = ls_pcie_probe,
 387        .priv_auto      = sizeof(struct ls_pcie_rc),
 388};
 389