uboot/drivers/pci/pcie_dw_sifive.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * SiFive FU740 DesignWare PCIe Controller
   4 *
   5 * Copyright (C) 2020-2021 SiFive, Inc.
   6 *
   7 * Based in early part on the i.MX6 PCIe host controller shim which is:
   8 *
   9 * Copyright (C) 2013 Kosagi
  10 *              http://www.kosagi.com
  11 *
  12 * Based on driver from author: Alan Mikhak <amikhak@wirelessfabric.com>
  13 */
  14#include <asm/io.h>
  15#include <asm-generic/gpio.h>
  16#include <clk.h>
  17#include <common.h>
  18#include <dm.h>
  19#include <dm/device_compat.h>
  20#include <generic-phy.h>
  21#include <linux/bitops.h>
  22#include <linux/log2.h>
  23#include <pci.h>
  24#include <pci_ep.h>
  25#include <pci_ids.h>
  26#include <regmap.h>
  27#include <reset.h>
  28#include <syscon.h>
  29
  30#include "pcie_dw_common.h"
  31
  32struct pcie_sifive {
  33        /* Must be first member of the struct */
  34        struct pcie_dw dw;
  35
  36        /* private control regs */
  37        void __iomem *priv_base;
  38
  39        /* reset, power, clock resources */
  40        int sys_int_pin;
  41        struct gpio_desc pwren_gpio;
  42        struct gpio_desc reset_gpio;
  43        struct clk aux_ck;
  44        struct reset_ctl reset;
  45};
  46
  47enum pcie_sifive_devtype {
  48        SV_PCIE_UNKNOWN_TYPE = 0,
  49        SV_PCIE_ENDPOINT_TYPE = 1,
  50        SV_PCIE_HOST_TYPE = 3
  51};
  52
  53#define ASSERTION_DELAY         100
  54#define PCIE_PERST_ASSERT       0x0
  55#define PCIE_PERST_DEASSERT     0x1
  56#define PCIE_PHY_RESET          0x1
  57#define PCIE_PHY_RESET_DEASSERT 0x0
  58#define GPIO_LOW                0x0
  59#define GPIO_HIGH               0x1
  60#define PCIE_PHY_SEL            0x1
  61
  62#define sv_info(sv, fmt, arg...)        printf(fmt, ## arg)
  63#define sv_warn(sv, fmt, arg...)        printf(fmt, ## arg)
  64#define sv_debug(sv, fmt, arg...)       debug(fmt, ## arg)
  65#define sv_err(sv, fmt, arg...)         printf(fmt, ## arg)
  66
  67/* Doorbell Interface */
  68#define DBI_OFFSET                      0x0
  69#define DBI_SIZE                        0x1000
  70
  71#define PL_OFFSET                       0x700
  72
  73#define PHY_DEBUG_R0                    (PL_OFFSET + 0x28)
  74
  75#define PHY_DEBUG_R1                    (PL_OFFSET + 0x2c)
  76#define PHY_DEBUG_R1_LINK_UP            (0x1 << 4)
  77#define PHY_DEBUG_R1_LINK_IN_TRAINING   (0x1 << 29)
  78
  79#define PCIE_MISC_CONTROL_1             0x8bc
  80#define DBI_RO_WR_EN                    BIT(0)
  81
  82/* pcie reset */
  83#define PCIEX8MGMT_PERST_N              0x0
  84
  85/* LTSSM */
  86#define PCIEX8MGMT_APP_LTSSM_ENABLE     0x10
  87#define LTSSM_ENABLE_BIT                BIT(0)
  88
  89/* phy reset */
  90#define PCIEX8MGMT_APP_HOLD_PHY_RST     0x18
  91
  92/* device type */
  93#define PCIEX8MGMT_DEVICE_TYPE          0x708
  94#define DEVICE_TYPE_EP                  0x0
  95#define DEVICE_TYPE_RC                  0x4
  96
  97/* phy control registers*/
  98#define PCIEX8MGMT_PHY0_CR_PARA_ADDR    0x860
  99#define PCIEX8MGMT_PHY0_CR_PARA_RD_EN   0x870
 100#define PCIEX8MGMT_PHY0_CR_PARA_RD_DATA 0x878
 101#define PCIEX8MGMT_PHY0_CR_PARA_SEL     0x880
 102#define PCIEX8MGMT_PHY0_CR_PARA_WR_DATA 0x888
 103#define PCIEX8MGMT_PHY0_CR_PARA_WR_EN   0x890
 104#define PCIEX8MGMT_PHY0_CR_PARA_ACK     0x898
 105#define PCIEX8MGMT_PHY1_CR_PARA_ADDR    0x8a0
 106#define PCIEX8MGMT_PHY1_CR_PARA_RD_EN   0x8b0
 107#define PCIEX8MGMT_PHY1_CR_PARA_RD_DATA 0x8b8
 108#define PCIEX8MGMT_PHY1_CR_PARA_SEL     0x8c0
 109#define PCIEX8MGMT_PHY1_CR_PARA_WR_DATA 0x8c8
 110#define PCIEX8MGMT_PHY1_CR_PARA_WR_EN   0x8d0
 111#define PCIEX8MGMT_PHY1_CR_PARA_ACK     0x8d8
 112
 113#define PCIEX8MGMT_LANE_NUM             8
 114#define PCIEX8MGMT_LANE                 0x1008
 115#define PCIEX8MGMT_LANE_OFF             0x100
 116#define PCIEX8MGMT_TERM_MODE            0x0e21
 117
 118#define PCIE_CAP_BASE                   0x70
 119#define PCI_CONFIG(r)                   (DBI_OFFSET + (r))
 120#define PCIE_CAPABILITIES(r)            PCI_CONFIG(PCIE_CAP_BASE + (r))
 121
 122/* Link capability */
 123#define PF0_PCIE_CAP_LINK_CAP           PCIE_CAPABILITIES(0xc)
 124#define PCIE_LINK_CAP_MAX_SPEED_MASK    0xf
 125#define PCIE_LINK_CAP_MAX_SPEED_GEN1    BIT(0)
 126#define PCIE_LINK_CAP_MAX_SPEED_GEN2    BIT(1)
 127#define PCIE_LINK_CAP_MAX_SPEED_GEN3    BIT(2)
 128#define PCIE_LINK_CAP_MAX_SPEED_GEN4    BIT(3)
 129
 130static enum pcie_sifive_devtype pcie_sifive_get_devtype(struct pcie_sifive *sv)
 131{
 132        u32 val;
 133
 134        val = readl(sv->priv_base + PCIEX8MGMT_DEVICE_TYPE);
 135        switch (val) {
 136        case DEVICE_TYPE_RC:
 137                return SV_PCIE_HOST_TYPE;
 138        case DEVICE_TYPE_EP:
 139                return SV_PCIE_ENDPOINT_TYPE;
 140        default:
 141                return SV_PCIE_UNKNOWN_TYPE;
 142        }
 143}
 144
 145static void pcie_sifive_priv_set_state(struct pcie_sifive *sv, u32 reg,
 146                                       u32 bits, int state)
 147{
 148        u32 val;
 149
 150        val = readl(sv->priv_base + reg);
 151        val = state ? (val | bits) : (val & !bits);
 152        writel(val, sv->priv_base + reg);
 153}
 154
 155static void pcie_sifive_assert_reset(struct pcie_sifive *sv)
 156{
 157        dm_gpio_set_value(&sv->reset_gpio, GPIO_LOW);
 158        writel(PCIE_PERST_ASSERT, sv->priv_base + PCIEX8MGMT_PERST_N);
 159        mdelay(ASSERTION_DELAY);
 160}
 161
 162static void pcie_sifive_power_on(struct pcie_sifive *sv)
 163{
 164        dm_gpio_set_value(&sv->pwren_gpio, GPIO_HIGH);
 165        mdelay(ASSERTION_DELAY);
 166}
 167
 168static void pcie_sifive_deassert_reset(struct pcie_sifive *sv)
 169{
 170        writel(PCIE_PERST_DEASSERT, sv->priv_base + PCIEX8MGMT_PERST_N);
 171        dm_gpio_set_value(&sv->reset_gpio, GPIO_HIGH);
 172        mdelay(ASSERTION_DELAY);
 173}
 174
 175static int pcie_sifive_setphy(const u8 phy, const u8 write,
 176                              const u16 addr, const u16 wrdata,
 177                              u16 *rddata, struct pcie_sifive *sv)
 178{
 179        unsigned char ack = 0;
 180
 181        if (!(phy == 0 || phy == 1))
 182                return -2;
 183
 184        /* setup phy para */
 185        writel(addr, sv->priv_base +
 186               (phy ? PCIEX8MGMT_PHY1_CR_PARA_ADDR :
 187                PCIEX8MGMT_PHY0_CR_PARA_ADDR));
 188
 189        if (write)
 190                writel(wrdata, sv->priv_base +
 191                       (phy ? PCIEX8MGMT_PHY1_CR_PARA_WR_DATA :
 192                        PCIEX8MGMT_PHY0_CR_PARA_WR_DATA));
 193
 194        /* enable access if write */
 195        if (write)
 196                writel(1, sv->priv_base +
 197                       (phy ? PCIEX8MGMT_PHY1_CR_PARA_WR_EN :
 198                        PCIEX8MGMT_PHY0_CR_PARA_WR_EN));
 199        else
 200                writel(1, sv->priv_base +
 201                       (phy ? PCIEX8MGMT_PHY1_CR_PARA_RD_EN :
 202                        PCIEX8MGMT_PHY0_CR_PARA_RD_EN));
 203
 204        /* wait for wait_idle */
 205        do {
 206                u32 val;
 207
 208                val = readl(sv->priv_base +
 209                            (phy ? PCIEX8MGMT_PHY1_CR_PARA_ACK :
 210                             PCIEX8MGMT_PHY0_CR_PARA_ACK));
 211                if (val) {
 212                        ack = 1;
 213                        if (!write)
 214                                readl(sv->priv_base +
 215                                      (phy ? PCIEX8MGMT_PHY1_CR_PARA_RD_DATA :
 216                                       PCIEX8MGMT_PHY0_CR_PARA_RD_DATA));
 217                        mdelay(1);
 218                }
 219        } while (!ack);
 220
 221        /* clear */
 222        if (write)
 223                writel(0, sv->priv_base +
 224                       (phy ? PCIEX8MGMT_PHY1_CR_PARA_WR_EN :
 225                        PCIEX8MGMT_PHY0_CR_PARA_WR_EN));
 226        else
 227                writel(0, sv->priv_base +
 228                       (phy ? PCIEX8MGMT_PHY1_CR_PARA_RD_EN :
 229                        PCIEX8MGMT_PHY0_CR_PARA_RD_EN));
 230
 231        while (readl(sv->priv_base +
 232                     (phy ? PCIEX8MGMT_PHY1_CR_PARA_ACK :
 233                      PCIEX8MGMT_PHY0_CR_PARA_ACK))) {
 234                /* wait for ~wait_idle */
 235        }
 236
 237        return 0;
 238}
 239
 240static void pcie_sifive_init_phy(struct pcie_sifive *sv)
 241{
 242        int lane;
 243
 244        /* enable phy cr_para_sel interfaces */
 245        writel(PCIE_PHY_SEL, sv->priv_base + PCIEX8MGMT_PHY0_CR_PARA_SEL);
 246        writel(PCIE_PHY_SEL, sv->priv_base + PCIEX8MGMT_PHY1_CR_PARA_SEL);
 247        mdelay(1);
 248
 249        /* set PHY AC termination mode */
 250        for (lane = 0; lane < PCIEX8MGMT_LANE_NUM; lane++) {
 251                pcie_sifive_setphy(0, 1,
 252                                   PCIEX8MGMT_LANE +
 253                                   (PCIEX8MGMT_LANE_OFF * lane),
 254                                   PCIEX8MGMT_TERM_MODE, NULL, sv);
 255                pcie_sifive_setphy(1, 1,
 256                                   PCIEX8MGMT_LANE +
 257                                   (PCIEX8MGMT_LANE_OFF * lane),
 258                                   PCIEX8MGMT_TERM_MODE, NULL, sv);
 259        }
 260}
 261
 262static int pcie_sifive_check_link(struct pcie_sifive *sv)
 263{
 264        u32 val;
 265
 266        val = readl(sv->dw.dbi_base + PHY_DEBUG_R1);
 267        return (val & PHY_DEBUG_R1_LINK_UP) &&
 268                !(val & PHY_DEBUG_R1_LINK_IN_TRAINING);
 269}
 270
 271static void pcie_sifive_force_gen1(struct pcie_sifive *sv)
 272{
 273        u32 val, linkcap;
 274
 275        /*
 276         * Force Gen1 operation when starting the link. In case the link is
 277         * started in Gen2 mode, there is a possibility the devices on the
 278         * bus will not be detected at all. This happens with PCIe switches.
 279         */
 280
 281        /* ctrl_ro_wr_enable */
 282        val = readl(sv->dw.dbi_base + PCIE_MISC_CONTROL_1);
 283        val |= DBI_RO_WR_EN;
 284        writel(val, sv->dw.dbi_base + PCIE_MISC_CONTROL_1);
 285
 286        /* configure link cap */
 287        linkcap = readl(sv->dw.dbi_base + PF0_PCIE_CAP_LINK_CAP);
 288        linkcap |= PCIE_LINK_CAP_MAX_SPEED_MASK;
 289        writel(linkcap, sv->dw.dbi_base + PF0_PCIE_CAP_LINK_CAP);
 290
 291        /* ctrl_ro_wr_disable */
 292        val &= ~DBI_RO_WR_EN;
 293        writel(val, sv->dw.dbi_base + PCIE_MISC_CONTROL_1);
 294}
 295
 296static void pcie_sifive_print_phy_debug(struct pcie_sifive *sv)
 297{
 298        sv_err(sv, "PHY DEBUG_R0=0x%08x DEBUG_R1=0x%08x\n",
 299               readl(sv->dw.dbi_base + PHY_DEBUG_R0),
 300               readl(sv->dw.dbi_base + PHY_DEBUG_R1));
 301}
 302
 303static int pcie_sifive_wait_for_link(struct pcie_sifive *sv)
 304{
 305        u32 val;
 306        int timeout;
 307
 308        /* Wait for the link to train */
 309        mdelay(20);
 310        timeout = 20;
 311
 312        do {
 313                mdelay(1);
 314        } while (--timeout && !pcie_sifive_check_link(sv));
 315
 316        val = readl(sv->dw.dbi_base + PHY_DEBUG_R1);
 317        if (!(val & PHY_DEBUG_R1_LINK_UP) ||
 318            (val & PHY_DEBUG_R1_LINK_IN_TRAINING)) {
 319                sv_info(sv, "Failed to negotiate PCIe link!\n");
 320                pcie_sifive_print_phy_debug(sv);
 321                writel(PCIE_PHY_RESET,
 322                       sv->priv_base + PCIEX8MGMT_APP_HOLD_PHY_RST);
 323                return -ETIMEDOUT;
 324        }
 325
 326        return 0;
 327}
 328
 329static int pcie_sifive_start_link(struct pcie_sifive *sv)
 330{
 331        if (pcie_sifive_check_link(sv))
 332                return -EALREADY;
 333
 334        pcie_sifive_force_gen1(sv);
 335
 336        /* set ltssm */
 337        pcie_sifive_priv_set_state(sv, PCIEX8MGMT_APP_LTSSM_ENABLE,
 338                                   LTSSM_ENABLE_BIT, 1);
 339        return 0;
 340}
 341
 342static int pcie_sifive_init_port(struct udevice *dev,
 343                                 enum pcie_sifive_devtype mode)
 344{
 345        struct pcie_sifive *sv = dev_get_priv(dev);
 346        int ret;
 347
 348        /* Power on reset */
 349        pcie_sifive_assert_reset(sv);
 350        pcie_sifive_power_on(sv);
 351        pcie_sifive_deassert_reset(sv);
 352
 353        /* Enable pcieauxclk */
 354        ret = clk_enable(&sv->aux_ck);
 355        if (ret)
 356                dev_err(dev, "unable to enable pcie_aux clock\n");
 357
 358        /*
 359         * assert hold_phy_rst (hold the controller LTSSM in reset
 360         * after power_up_rst_n for register programming with cr_para)
 361         */
 362        writel(PCIE_PHY_RESET, sv->priv_base + PCIEX8MGMT_APP_HOLD_PHY_RST);
 363
 364        /* deassert power_up_rst_n */
 365        ret = reset_deassert(&sv->reset);
 366        if (ret < 0) {
 367                dev_err(dev, "failed to deassert reset");
 368                return -EINVAL;
 369        }
 370
 371        pcie_sifive_init_phy(sv);
 372
 373        /* disable pcieauxclk */
 374        clk_disable(&sv->aux_ck);
 375
 376        /* deassert hold_phy_rst */
 377        writel(PCIE_PHY_RESET_DEASSERT,
 378               sv->priv_base + PCIEX8MGMT_APP_HOLD_PHY_RST);
 379
 380        /* enable pcieauxclk */
 381        clk_enable(&sv->aux_ck);
 382
 383        /* Set desired mode while core is not operational */
 384        if (mode == SV_PCIE_HOST_TYPE)
 385                writel(DEVICE_TYPE_RC,
 386                       sv->priv_base + PCIEX8MGMT_DEVICE_TYPE);
 387        else
 388                writel(DEVICE_TYPE_EP,
 389                       sv->priv_base + PCIEX8MGMT_DEVICE_TYPE);
 390
 391        /* Confirm desired mode from operational core */
 392        if (pcie_sifive_get_devtype(sv) != mode)
 393                return -EINVAL;
 394
 395        pcie_dw_setup_host(&sv->dw);
 396
 397        if (pcie_sifive_start_link(sv) == -EALREADY)
 398                sv_info(sv, "PCIe link is already up\n");
 399        else if (pcie_sifive_wait_for_link(sv) == -ETIMEDOUT)
 400                return -ETIMEDOUT;
 401
 402        return 0;
 403}
 404
 405static int pcie_sifive_probe(struct udevice *dev)
 406{
 407        struct pcie_sifive *sv = dev_get_priv(dev);
 408        struct udevice *parent = pci_get_controller(dev);
 409        struct pci_controller *hose = dev_get_uclass_priv(parent);
 410        int err;
 411
 412        sv->dw.first_busno = dev_seq(dev);
 413        sv->dw.dev = dev;
 414
 415        err = pcie_sifive_init_port(dev, SV_PCIE_HOST_TYPE);
 416        if (err) {
 417                sv_info(sv, "Failed to init port.\n");
 418                return err;
 419        }
 420
 421        printf("PCIE-%d: Link up (Gen%d-x%d, Bus%d)\n",
 422               dev_seq(dev), pcie_dw_get_link_speed(&sv->dw),
 423               pcie_dw_get_link_width(&sv->dw),
 424               hose->first_busno);
 425
 426        return pcie_dw_prog_outbound_atu_unroll(&sv->dw,
 427                                                PCIE_ATU_REGION_INDEX0,
 428                                                PCIE_ATU_TYPE_MEM,
 429                                                sv->dw.mem.phys_start,
 430                                                sv->dw.mem.bus_start,
 431                                                sv->dw.mem.size);
 432}
 433
 434static void __iomem *get_fdt_addr(struct udevice *dev, const char *name)
 435{
 436        fdt_addr_t addr;
 437
 438        addr = dev_read_addr_name(dev, name);
 439
 440        return (addr == FDT_ADDR_T_NONE) ? NULL : (void __iomem *)addr;
 441}
 442
 443static int pcie_sifive_of_to_plat(struct udevice *dev)
 444{
 445        struct pcie_sifive *sv = dev_get_priv(dev);
 446        int err;
 447
 448        /* get designware DBI base addr */
 449        sv->dw.dbi_base = get_fdt_addr(dev, "dbi");
 450        if (!sv->dw.dbi_base)
 451                return -EINVAL;
 452
 453        /* get private control base addr */
 454        sv->priv_base = get_fdt_addr(dev, "mgmt");
 455        if (!sv->priv_base)
 456                return -EINVAL;
 457
 458        gpio_request_by_name(dev, "pwren-gpios", 0, &sv->pwren_gpio,
 459                             GPIOD_IS_OUT);
 460
 461        if (!dm_gpio_is_valid(&sv->pwren_gpio)) {
 462                sv_info(sv, "pwren_gpio is invalid\n");
 463                return -EINVAL;
 464        }
 465
 466        gpio_request_by_name(dev, "reset-gpios", 0, &sv->reset_gpio,
 467                             GPIOD_IS_OUT);
 468
 469        if (!dm_gpio_is_valid(&sv->reset_gpio)) {
 470                sv_info(sv, "reset_gpio is invalid\n");
 471                return -EINVAL;
 472        }
 473
 474        err = clk_get_by_index(dev, 0, &sv->aux_ck);
 475        if (err) {
 476                sv_info(sv, "clk_get_by_index(aux_ck) failed: %d\n", err);
 477                return err;
 478        }
 479
 480        err = reset_get_by_index(dev, 0, &sv->reset);
 481        if (err) {
 482                sv_info(sv, "reset_get_by_index(reset) failed: %d\n", err);
 483                return err;
 484        }
 485
 486        return 0;
 487}
 488
 489static const struct dm_pci_ops pcie_sifive_ops = {
 490        .read_config    = pcie_dw_read_config,
 491        .write_config   = pcie_dw_write_config,
 492};
 493
 494static const struct udevice_id pcie_sifive_ids[] = {
 495        { .compatible = "sifive,fu740-pcie" },
 496        {}
 497};
 498
 499U_BOOT_DRIVER(pcie_sifive) = {
 500        .name           = "pcie_sifive",
 501        .id             = UCLASS_PCI,
 502        .of_match       = pcie_sifive_ids,
 503        .ops            = &pcie_sifive_ops,
 504        .of_to_plat     = pcie_sifive_of_to_plat,
 505        .probe          = pcie_sifive_probe,
 506        .priv_auto      = sizeof(struct pcie_sifive),
 507};
 508