uboot/drivers/pci/pcie_layerscape_ep.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2020 NXP
   4 * Layerscape PCIe EP driver
   5 */
   6
   7#include <common.h>
   8#include <asm/arch/fsl_serdes.h>
   9#include <dm.h>
  10#include <asm/global_data.h>
  11#include <dm/devres.h>
  12#include <errno.h>
  13#include <pci_ep.h>
  14#include <asm/io.h>
  15#include <linux/sizes.h>
  16#include <linux/log2.h>
  17#include "pcie_layerscape.h"
  18
  19DECLARE_GLOBAL_DATA_PTR;
  20
  21static void ls_pcie_ep_enable_cfg(struct ls_pcie_ep *pcie_ep)
  22{
  23        struct ls_pcie *pcie = pcie_ep->pcie;
  24        u32 config;
  25
  26        config = ctrl_readl(pcie,  PCIE_PF_CONFIG);
  27        config |= PCIE_CONFIG_READY;
  28        ctrl_writel(pcie, config, PCIE_PF_CONFIG);
  29}
  30
  31static int ls_ep_set_bar(struct udevice *dev, uint fn, struct pci_bar *ep_bar)
  32{
  33        struct ls_pcie_ep *pcie_ep = dev_get_priv(dev);
  34        struct ls_pcie *pcie = pcie_ep->pcie;
  35        dma_addr_t bar_phys = ep_bar->phys_addr;
  36        enum pci_barno bar = ep_bar->barno;
  37        u32 reg = PCI_BASE_ADDRESS_0 + (4 * bar);
  38        int flags = ep_bar->flags;
  39        int type, idx;
  40        u64 size;
  41
  42        idx  = bar;
  43        /* BAR size is 2^(aperture + 11) */
  44        size = max_t(size_t, ep_bar->size, FSL_PCIE_EP_MIN_APERTURE);
  45
  46        if (!(flags & PCI_BASE_ADDRESS_SPACE))
  47                type = PCIE_ATU_TYPE_MEM;
  48        else
  49                type = PCIE_ATU_TYPE_IO;
  50
  51        ls_pcie_atu_inbound_set(pcie, fn, 0, type, idx, bar, bar_phys);
  52
  53        dbi_writel(pcie, lower_32_bits(size - 1), reg + PCIE_NO_SRIOV_BAR_BASE);
  54        dbi_writel(pcie, flags, reg);
  55
  56        if (flags & PCI_BASE_ADDRESS_MEM_TYPE_64) {
  57                dbi_writel(pcie, upper_32_bits(size - 1),
  58                           reg + 4 + PCIE_NO_SRIOV_BAR_BASE);
  59                dbi_writel(pcie, 0, reg + 4);
  60        }
  61
  62        return 0;
  63}
  64
  65static struct pci_ep_ops ls_pcie_ep_ops = {
  66        .set_bar = ls_ep_set_bar,
  67};
  68
  69static void ls_pcie_ep_setup_atu(struct ls_pcie_ep *pcie_ep, u32 pf)
  70{
  71        struct ls_pcie *pcie = pcie_ep->pcie;
  72        u32 vf_flag = 0;
  73        u64 phys = 0;
  74
  75        phys = CONFIG_SYS_PCI_EP_MEMORY_BASE + pf * SZ_64M;
  76
  77        phys = ALIGN(phys, PCIE_BAR0_SIZE);
  78        /* ATU 0 : INBOUND : map BAR0 */
  79        ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM,
  80                                0 + pf * BAR_NUM, 0, phys);
  81        /* ATU 1 : INBOUND : map BAR1 */
  82        phys = ALIGN(phys + PCIE_BAR0_SIZE, PCIE_BAR1_SIZE);
  83        ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM,
  84                                1 + pf * BAR_NUM, 1, phys);
  85        /* ATU 2 : INBOUND : map BAR2 */
  86        phys = ALIGN(phys + PCIE_BAR1_SIZE, PCIE_BAR2_SIZE);
  87        ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM,
  88                                2 + pf * BAR_NUM, 2, phys);
  89        /* ATU 3 : INBOUND : map BAR2 */
  90        phys = ALIGN(phys + PCIE_BAR2_SIZE, PCIE_BAR4_SIZE);
  91        ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM,
  92                                3 + pf * BAR_NUM, 4, phys);
  93
  94        if (pcie_ep->sriov_flag) {
  95                vf_flag = 1;
  96                /* ATU 4 : INBOUND : map BAR0 */
  97                phys = ALIGN(phys + PCIE_BAR4_SIZE, PCIE_BAR0_SIZE);
  98                ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM,
  99                                        4 + pf * BAR_NUM, 0, phys);
 100                /* ATU 5 : INBOUND : map BAR1 */
 101                phys = ALIGN(phys + PCIE_BAR0_SIZE * PCIE_VF_NUM,
 102                             PCIE_BAR1_SIZE);
 103                ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM,
 104                                        5 + pf * BAR_NUM, 1, phys);
 105                /* ATU 6 : INBOUND : map BAR2 */
 106                phys = ALIGN(phys + PCIE_BAR1_SIZE * PCIE_VF_NUM,
 107                             PCIE_BAR2_SIZE);
 108                ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM,
 109                                        6 + pf * BAR_NUM, 2, phys);
 110                /* ATU 7 : INBOUND : map BAR4 */
 111                phys = ALIGN(phys + PCIE_BAR2_SIZE * PCIE_VF_NUM,
 112                             PCIE_BAR4_SIZE);
 113                ls_pcie_atu_inbound_set(pcie, pf, vf_flag, PCIE_ATU_TYPE_MEM,
 114                                        7 + pf * BAR_NUM, 4, phys);
 115        }
 116
 117        /* ATU: OUTBOUND : map MEM */
 118        ls_pcie_atu_outbound_set(pcie, pf, PCIE_ATU_TYPE_MEM,
 119                                 (u64)pcie_ep->addr_res.start +
 120                                 pf * CONFIG_SYS_PCI_MEMORY_SIZE,
 121                                 0, CONFIG_SYS_PCI_MEMORY_SIZE);
 122}
 123
 124/* BAR0 and BAR1 are 32bit BAR2 and BAR4 are 64bit */
 125static void ls_pcie_ep_setup_bar(void *bar_base, int bar, u32 size)
 126{
 127        u32 mask;
 128
 129        /* The least inbound window is 4KiB */
 130        if (size < SZ_4K)
 131                mask = 0;
 132        else
 133                mask = size - 1;
 134
 135        switch (bar) {
 136        case 0:
 137                writel(mask, bar_base + PCI_BASE_ADDRESS_0);
 138                break;
 139        case 1:
 140                writel(mask, bar_base + PCI_BASE_ADDRESS_1);
 141                break;
 142        case 2:
 143                writel(mask, bar_base + PCI_BASE_ADDRESS_2);
 144                writel(0, bar_base + PCI_BASE_ADDRESS_3);
 145                break;
 146        case 4:
 147                writel(mask, bar_base + PCI_BASE_ADDRESS_4);
 148                writel(0, bar_base + PCI_BASE_ADDRESS_5);
 149                break;
 150        default:
 151                break;
 152        }
 153}
 154
 155static void ls_pcie_ep_setup_bars(void *bar_base)
 156{
 157        /* BAR0 - 32bit - MEM */
 158        ls_pcie_ep_setup_bar(bar_base, 0, PCIE_BAR0_SIZE);
 159        /* BAR1 - 32bit - MEM*/
 160        ls_pcie_ep_setup_bar(bar_base, 1, PCIE_BAR1_SIZE);
 161        /* BAR2 - 64bit - MEM */
 162        ls_pcie_ep_setup_bar(bar_base, 2, PCIE_BAR2_SIZE);
 163        /* BAR4 - 64bit - MEM */
 164        ls_pcie_ep_setup_bar(bar_base, 4, PCIE_BAR4_SIZE);
 165}
 166
 167static void ls_pcie_ep_setup_vf_bars(void *bar_base)
 168{
 169        /* VF BAR0 MASK register at offset 0x19c*/
 170        bar_base += PCIE_SRIOV_VFBAR0 - PCI_BASE_ADDRESS_0;
 171
 172        /* VF-BAR0 - 32bit - MEM */
 173        ls_pcie_ep_setup_bar(bar_base, 0, PCIE_BAR0_SIZE);
 174        /* VF-BAR1 - 32bit - MEM*/
 175        ls_pcie_ep_setup_bar(bar_base, 1, PCIE_BAR1_SIZE);
 176        /* VF-BAR2 - 64bit - MEM */
 177        ls_pcie_ep_setup_bar(bar_base, 2, PCIE_BAR2_SIZE);
 178        /* VF-BAR4 - 64bit - MEM */
 179        ls_pcie_ep_setup_bar(bar_base, 4, PCIE_BAR4_SIZE);
 180}
 181
 182static void ls_pcie_setup_ep(struct ls_pcie_ep *pcie_ep)
 183{
 184        u32 sriov;
 185        u32 pf, vf;
 186        void *bar_base = NULL;
 187        struct ls_pcie *pcie = pcie_ep->pcie;
 188
 189        sriov = readl(pcie->dbi + PCIE_SRIOV);
 190        if (PCI_EXT_CAP_ID(sriov) == PCI_EXT_CAP_ID_SRIOV) {
 191                pcie_ep->sriov_flag = 1;
 192                for (pf = 0; pf < PCIE_PF_NUM; pf++) {
 193                        /*
 194                         * The VF_BARn_REG register's Prefetchable and Type bit
 195                         * fields are overwritten by a write to VF's BAR Mask
 196                         * register. Before writing to the VF_BARn_MASK_REG
 197                         * register, write 0b to the PCIE_MISC_CONTROL_1_OFF
 198                         * register.
 199                         */
 200                        writel(0, pcie->dbi + PCIE_MISC_CONTROL_1_OFF);
 201
 202                        bar_base = pcie->dbi +
 203                                   PCIE_MASK_OFFSET(pcie_ep->cfg2_flag, pf,
 204                                                    pcie_ep->pf1_offset);
 205
 206                        if (pcie_ep->cfg2_flag) {
 207                                ctrl_writel(pcie,
 208                                            PCIE_LCTRL0_VAL(pf, 0),
 209                                            PCIE_PF_VF_CTRL);
 210                                ls_pcie_ep_setup_bars(bar_base);
 211
 212                                for (vf = 1; vf <= PCIE_VF_NUM; vf++) {
 213                                        ctrl_writel(pcie,
 214                                                    PCIE_LCTRL0_VAL(pf, vf),
 215                                                    PCIE_PF_VF_CTRL);
 216                                        ls_pcie_ep_setup_vf_bars(bar_base);
 217                                }
 218                        } else {
 219                                ls_pcie_ep_setup_bars(bar_base);
 220                                ls_pcie_ep_setup_vf_bars(bar_base);
 221                        }
 222
 223                        ls_pcie_ep_setup_atu(pcie_ep, pf);
 224                }
 225
 226                if (pcie_ep->cfg2_flag)  /* Disable CFG2 */
 227                        ctrl_writel(pcie, 0, PCIE_PF_VF_CTRL);
 228        } else {
 229                ls_pcie_ep_setup_bars(pcie->dbi + PCIE_NO_SRIOV_BAR_BASE);
 230                ls_pcie_ep_setup_atu(pcie_ep, 0);
 231        }
 232
 233        ls_pcie_dump_atu(pcie, PCIE_ATU_REGION_NUM_SRIOV,
 234                         PCIE_ATU_REGION_INBOUND);
 235
 236        ls_pcie_ep_enable_cfg(pcie_ep);
 237}
 238
 239static int ls_pcie_ep_probe(struct udevice *dev)
 240{
 241        struct ls_pcie_ep *pcie_ep = dev_get_priv(dev);
 242        struct ls_pcie *pcie;
 243        u16 link_sta;
 244        int ret;
 245        u32 svr;
 246
 247        pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
 248        if (!pcie)
 249                return -ENOMEM;
 250
 251        pcie_ep->pcie = pcie;
 252
 253        pcie->dbi = (void __iomem *)devfdt_get_addr_index(dev, 0);
 254        if (!pcie->dbi)
 255                return -ENOMEM;
 256
 257        pcie->ctrl = (void __iomem *)devfdt_get_addr_index(dev, 1);
 258        if (!pcie->ctrl)
 259                return -ENOMEM;
 260
 261        ret = fdt_get_named_resource(gd->fdt_blob, dev_of_offset(dev),
 262                                     "reg", "reg-names",
 263                                     "addr_space", &pcie_ep->addr_res);
 264        if (ret) {
 265                printf("%s: resource \"addr_space\" not found\n", dev->name);
 266                return ret;
 267        }
 268
 269        pcie->idx = ((unsigned long)pcie->dbi - PCIE_SYS_BASE_ADDR) /
 270                    PCIE_CCSR_SIZE;
 271
 272        /* This controller is disabled by RCW */
 273        if (!is_serdes_configured(PCIE_SRDS_PRTCL(pcie->idx)))
 274                return 0;
 275
 276        pcie->big_endian = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
 277                                           "big-endian");
 278
 279        svr = SVR_SOC_VER(get_svr());
 280
 281        if (svr == SVR_LX2160A || svr == SVR_LX2162A ||
 282            svr == SVR_LX2120A || svr == SVR_LX2080A ||
 283            svr == SVR_LX2122A || svr == SVR_LX2082A)
 284                pcie_ep->pf1_offset = LX2160_PCIE_PF1_OFFSET;
 285        else
 286                pcie_ep->pf1_offset = LS_PCIE_PF1_OFFSET;
 287
 288        if (svr == SVR_LS2080A || svr == SVR_LS2085A)
 289                pcie_ep->cfg2_flag = 1;
 290        else
 291                pcie_ep->cfg2_flag = 0;
 292
 293        pcie->mode = readb(pcie->dbi + PCI_HEADER_TYPE) & 0x7f;
 294        if (pcie->mode != PCI_HEADER_TYPE_NORMAL)
 295                return 0;
 296
 297        pcie_ep->max_functions = fdtdec_get_int(gd->fdt_blob,
 298                                                dev_of_offset(dev),
 299                                                "max-functions", 1);
 300        pcie_ep->num_ib_wins = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 301                                              "num-ib-windows", 8);
 302        pcie_ep->num_ob_wins = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 303                                              "num-ob-windows", 8);
 304
 305        printf("PCIe%u: %s %s", PCIE_SRDS_PRTCL(pcie->idx), dev->name,
 306               "Endpoint");
 307        ls_pcie_setup_ep(pcie_ep);
 308
 309        if (!ls_pcie_link_up(pcie)) {
 310                /* Let the user know there's no PCIe link */
 311                printf(": no link\n");
 312                return 0;
 313        }
 314
 315        /* Print the negotiated PCIe link width */
 316        link_sta = readw(pcie->dbi + PCIE_LINK_STA);
 317        printf(": x%d gen%d\n", (link_sta & PCIE_LINK_WIDTH_MASK) >> 4,
 318               link_sta & PCIE_LINK_SPEED_MASK);
 319
 320        return 0;
 321}
 322
 323static int ls_pcie_ep_remove(struct udevice *dev)
 324{
 325        return 0;
 326}
 327
 328const struct udevice_id ls_pcie_ep_ids[] = {
 329        { .compatible = "fsl,ls-pcie-ep" },
 330        { }
 331};
 332
 333U_BOOT_DRIVER(pci_layerscape_ep) = {
 334        .name = "pci_layerscape_ep",
 335        .id     = UCLASS_PCI_EP,
 336        .of_match = ls_pcie_ep_ids,
 337        .ops = &ls_pcie_ep_ops,
 338        .probe = ls_pcie_ep_probe,
 339        .remove = ls_pcie_ep_remove,
 340        .priv_auto      = sizeof(struct ls_pcie_ep),
 341};
 342