[PATCH v7 4/8] drivers: pci: add pcie support for fu740

Green Wan green.wan at sifive.com
Tue May 4 03:53:13 CEST 2021


On Mon, May 3, 2021 at 9:08 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
>
> On 22/04/2021 11:11, Green Wan wrote:
> > Add pcie driver for SiFive fu740, the driver depends on
> > fu740 gpio, clk and reset driver to do init. Force running at Gen1
> > for better capatible enumeration.
> >
> > Several devices are tested:
> > a) M.2 NVMe SSD
> > b) USB-to-PCI adapter
> > c) Ethernet adapter (E1000 compatible)
> >
> > Signed-off-by: Green Wan <green.wan at sifive.com>
> > ---
> >  drivers/pci/Kconfig          |  10 +
> >  drivers/pci/Makefile         |   1 +
> >  drivers/pci/pcie_dw_sifive.c | 508 +++++++++++++++++++++++++++++++++++
> >  3 files changed, 519 insertions(+)
> >  create mode 100644 drivers/pci/pcie_dw_sifive.c
> >
> > diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
> > index cdcdd8f456..b11dd5c02d 100644
> > --- a/drivers/pci/Kconfig
> > +++ b/drivers/pci/Kconfig
> > @@ -97,6 +97,16 @@ config PCIE_DW_MVEBU
> >         Armada-8K SoCs. The PCIe controller on Armada-8K is based on
> >         DesignWare hardware.
> >
> > +config PCIE_DW_SIFIVE
> > +     bool "Enable SiFive FU740 PCIe"
> > +     depends on CLK_SIFIVE_PRCI
> > +     depends on RESET_SIFIVE
> > +     depends on SIFIVE_GPIO
> > +     select PCIE_DW_COMMON
> > +     help
> > +       Say Y here if you want to enable PCIe controller support on
> > +       FU740.
> > +
> >  config PCIE_FSL
> >       bool "FSL PowerPC PCIe support"
> >       depends on DM_PCI
> > diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
> > index 96d61821fe..7351f8027d 100644
> > --- a/drivers/pci/Makefile
> > +++ b/drivers/pci/Makefile
> > @@ -53,3 +53,4 @@ obj-$(CONFIG_PCIE_DW_ROCKCHIP) += pcie_dw_rockchip.o
> >  obj-$(CONFIG_PCIE_DW_MESON) += pcie_dw_meson.o
> >  obj-$(CONFIG_PCI_BRCMSTB) += pcie_brcmstb.o
> >  obj-$(CONFIG_PCI_OCTEONTX) += pci_octeontx.o
> > +obj-$(CONFIG_PCIE_DW_SIFIVE) += pcie_dw_sifive.o
> > diff --git a/drivers/pci/pcie_dw_sifive.c b/drivers/pci/pcie_dw_sifive.c
> > new file mode 100644
> > index 0000000000..599eb0ece2
> > --- /dev/null
> > +++ b/drivers/pci/pcie_dw_sifive.c
> > @@ -0,0 +1,508 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * SiFive FU740 DesignWare PCIe Controller
> > + *
> > + * Copyright (C) 2020-2021 SiFive, Inc.
> > + *
> > + * Based in early part on the i.MX6 PCIe host controller shim which is:
> > + *
> > + * Copyright (C) 2013 Kosagi
> > + *           http://www.kosagi.com
> > + *
> > + * Based on driver from author: Alan Mikhak <amikhak at wirelessfabric.com>
> > + */
> > +#include <asm/io.h>
> > +#include <asm-generic/gpio.h>
> > +#include <clk.h>
> > +#include <common.h>
> > +#include <dm.h>
> > +#include <dm/device_compat.h>
> > +#include <generic-phy.h>
> > +#include <linux/bitops.h>
> > +#include <linux/log2.h>
> > +#include <pci.h>
> > +#include <pci_ep.h>
> > +#include <pci_ids.h>
> > +#include <regmap.h>
> > +#include <reset.h>
> > +#include <syscon.h>
> > +
> > +#include "pcie_dw_common.h"
> > +
> > +struct pcie_sifive {
> > +     /* Must be first member of the struct */
> > +     struct pcie_dw dw;
> > +
> > +     /* private control regs */
> > +     void __iomem *priv_base;
> > +
> > +     /* reset, power, clock resources */
> > +     int sys_int_pin;
> > +     struct gpio_desc pwren_gpio;
> > +     struct gpio_desc reset_gpio;
> > +     struct clk aux_ck;
> > +     struct reset_ctl reset;
> > +};
> > +
> > +enum pcie_sifive_devtype {
> > +     SV_PCIE_UNKNOWN_TYPE = 0,
> > +     SV_PCIE_ENDPOINT_TYPE = 1,
> > +     SV_PCIE_HOST_TYPE = 3
> > +};
> > +
> > +#define ASSERTION_DELAY              100
> > +#define PCIE_PERST_ASSERT    0x0
> > +#define PCIE_PERST_DEASSERT  0x1
> > +#define PCIE_PHY_RESET               0x1
> > +#define PCIE_PHY_RESET_DEASSERT      0x0
> > +#define GPIO_LOW             0x0
> > +#define GPIO_HIGH            0x1
> > +#define PCIE_PHY_SEL         0x1
> > +
> > +#define sv_info(sv, fmt, arg...)     printf(fmt, ## arg)
> > +#define sv_warn(sv, fmt, arg...)     printf(fmt, ## arg)
> > +#define sv_debug(sv, fmt, arg...)    debug(fmt, ## arg)
> > +#define sv_err(sv, fmt, arg...)              printf(fmt, ## arg)
> > +
> > +/* Doorbell Interface */
> > +#define DBI_OFFSET                   0x0
> > +#define DBI_SIZE                     0x1000
> > +
> > +#define PL_OFFSET                    0x700
> > +
> > +#define PHY_DEBUG_R0                 (PL_OFFSET + 0x28)
> > +
> > +#define PHY_DEBUG_R1                 (PL_OFFSET + 0x2c)
> > +#define PHY_DEBUG_R1_LINK_UP         (0x1 << 4)
> > +#define PHY_DEBUG_R1_LINK_IN_TRAINING        (0x1 << 29)
> > +
> > +#define PCIE_MISC_CONTROL_1          0x8bc
> > +#define DBI_RO_WR_EN                 BIT(0)
> > +
> > +/* pcie reset */
> > +#define PCIEX8MGMT_PERST_N           0x0
> > +
> > +/* LTSSM */
> > +#define PCIEX8MGMT_APP_LTSSM_ENABLE  0x10
> > +#define LTSSM_ENABLE_BIT             BIT(0)
> > +
> > +/* phy reset */
> > +#define PCIEX8MGMT_APP_HOLD_PHY_RST  0x18
> > +
> > +/* device type */
> > +#define PCIEX8MGMT_DEVICE_TYPE               0x708
> > +#define DEVICE_TYPE_EP                       0x0
> > +#define DEVICE_TYPE_RC                       0x4
> > +
> > +/* phy control registers*/
> > +#define PCIEX8MGMT_PHY0_CR_PARA_ADDR 0x860
> > +#define PCIEX8MGMT_PHY0_CR_PARA_RD_EN        0x870
> > +#define PCIEX8MGMT_PHY0_CR_PARA_RD_DATA      0x878
> > +#define PCIEX8MGMT_PHY0_CR_PARA_SEL  0x880
> > +#define PCIEX8MGMT_PHY0_CR_PARA_WR_DATA      0x888
> > +#define PCIEX8MGMT_PHY0_CR_PARA_WR_EN        0x890
> > +#define PCIEX8MGMT_PHY0_CR_PARA_ACK  0x898
> > +#define PCIEX8MGMT_PHY1_CR_PARA_ADDR 0x8a0
> > +#define PCIEX8MGMT_PHY1_CR_PARA_RD_EN        0x8b0
> > +#define PCIEX8MGMT_PHY1_CR_PARA_RD_DATA      0x8b8
> > +#define PCIEX8MGMT_PHY1_CR_PARA_SEL  0x8c0
> > +#define PCIEX8MGMT_PHY1_CR_PARA_WR_DATA      0x8c8
> > +#define PCIEX8MGMT_PHY1_CR_PARA_WR_EN        0x8d0
> > +#define PCIEX8MGMT_PHY1_CR_PARA_ACK  0x8d8
> > +
> > +#define PCIEX8MGMT_LANE_NUM          8
> > +#define PCIEX8MGMT_LANE                      0x1008
> > +#define PCIEX8MGMT_LANE_OFF          0x100
> > +#define PCIEX8MGMT_TERM_MODE         0x0e21
> > +
> > +#define PCIE_CAP_BASE                        0x70
> > +#define PCI_CONFIG(r)                        (DBI_OFFSET + (r))
> > +#define PCIE_CAPABILITIES(r)         PCI_CONFIG(PCIE_CAP_BASE + (r))
> > +
> > +/* Link capability */
> > +#define PF0_PCIE_CAP_LINK_CAP                PCIE_CAPABILITIES(0xc)
> > +#define PCIE_LINK_CAP_MAX_SPEED_MASK 0xf
> > +#define PCIE_LINK_CAP_MAX_SPEED_GEN1 BIT(0)
> > +#define PCIE_LINK_CAP_MAX_SPEED_GEN2 BIT(1)
> > +#define PCIE_LINK_CAP_MAX_SPEED_GEN3 BIT(2)
> > +#define PCIE_LINK_CAP_MAX_SPEED_GEN4 BIT(3)
> > +
> > +static enum pcie_sifive_devtype pcie_sifive_get_devtype(struct pcie_sifive *sv)
> > +{
> > +     u32 val;
> > +
> > +     val = readl(sv->priv_base + PCIEX8MGMT_DEVICE_TYPE);
> > +     switch (val) {
> > +     case DEVICE_TYPE_RC:
> > +             return SV_PCIE_HOST_TYPE;
> > +     case DEVICE_TYPE_EP:
> > +             return SV_PCIE_ENDPOINT_TYPE;
> > +     default:
> > +             return SV_PCIE_UNKNOWN_TYPE;
> > +     }
> > +}
> > +
> > +static void pcie_sifive_priv_set_state(struct pcie_sifive *sv, u32 reg,
> > +                                    u32 bits, int state)
> > +{
> > +     u32 val;
> > +
> > +     val = readl(sv->priv_base + reg);
> > +     val = state ? (val | bits) : (val & !bits);
> > +     writel(val, sv->priv_base + reg);
> > +}
> > +
> > +static void pcie_sifive_assert_reset(struct pcie_sifive *sv)
> > +{
> > +     dm_gpio_set_value(&sv->reset_gpio, GPIO_LOW);
> > +     writel(PCIE_PERST_ASSERT, sv->priv_base + PCIEX8MGMT_PERST_N);
> > +     mdelay(ASSERTION_DELAY);
> > +}
> > +
> > +static void pcie_sifive_power_on(struct pcie_sifive *sv)
> > +{
> > +     dm_gpio_set_value(&sv->pwren_gpio, GPIO_HIGH);
> > +     mdelay(ASSERTION_DELAY);
> > +}
> > +
> > +static void pcie_sifive_deassert_reset(struct pcie_sifive *sv)
> > +{
> > +     writel(PCIE_PERST_DEASSERT, sv->priv_base + PCIEX8MGMT_PERST_N);
> > +     dm_gpio_set_value(&sv->reset_gpio, GPIO_HIGH);
> > +     mdelay(ASSERTION_DELAY);
> > +}
> > +
> > +static int pcie_sifive_setphy(const u8 phy, const u8 write,
> > +                           const u16 addr, const u16 wrdata,
> > +                           u16 *rddata, struct pcie_sifive *sv)
> > +{
> > +     unsigned char ack = 0;
> > +
> > +     if (!(phy == 0 || phy == 1))
> > +             return -2;
> > +
> > +     /* setup phy para */
> > +     writel(addr, sv->priv_base +
> > +            (phy ? PCIEX8MGMT_PHY1_CR_PARA_ADDR :
> > +             PCIEX8MGMT_PHY0_CR_PARA_ADDR));
> > +
> > +     if (write)
> > +             writel(wrdata, sv->priv_base +
> > +                    (phy ? PCIEX8MGMT_PHY1_CR_PARA_WR_DATA :
> > +                     PCIEX8MGMT_PHY0_CR_PARA_WR_DATA));
> > +
> > +     /* enable access if write */
> > +     if (write)
> > +             writel(1, sv->priv_base +
> > +                    (phy ? PCIEX8MGMT_PHY1_CR_PARA_WR_EN :
> > +                     PCIEX8MGMT_PHY0_CR_PARA_WR_EN));
> > +     else
> > +             writel(1, sv->priv_base +
> > +                    (phy ? PCIEX8MGMT_PHY1_CR_PARA_RD_EN :
> > +                     PCIEX8MGMT_PHY0_CR_PARA_RD_EN));
> > +
> > +     /* wait for wait_idle */
> > +     do {
> > +             u32 val;
> > +
> > +             val = readl(sv->priv_base +
> > +                         (phy ? PCIEX8MGMT_PHY1_CR_PARA_ACK :
> > +                          PCIEX8MGMT_PHY0_CR_PARA_ACK));
> > +             if (val) {
> > +                     ack = 1;
> > +                     if (!write)
> > +                             readl(sv->priv_base +
> > +                                   (phy ? PCIEX8MGMT_PHY1_CR_PARA_RD_DATA :
> > +                                    PCIEX8MGMT_PHY0_CR_PARA_RD_DATA));
> > +                     mdelay(1);
> > +             }
> > +     } while (!ack);
> > +
> > +     /* clear */
> > +     if (write)
> > +             writel(0, sv->priv_base +
> > +                    (phy ? PCIEX8MGMT_PHY1_CR_PARA_WR_EN :
> > +                     PCIEX8MGMT_PHY0_CR_PARA_WR_EN));
> > +     else
> > +             writel(0, sv->priv_base +
> > +                    (phy ? PCIEX8MGMT_PHY1_CR_PARA_RD_EN :
> > +                     PCIEX8MGMT_PHY0_CR_PARA_RD_EN));
> > +
> > +     while (readl(sv->priv_base +
> > +                  (phy ? PCIEX8MGMT_PHY1_CR_PARA_ACK :
> > +                   PCIEX8MGMT_PHY0_CR_PARA_ACK))) {
> > +             /* wait for ~wait_idle */
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static void pcie_sifive_init_phy(struct pcie_sifive *sv)
> > +{
> > +     int lane;
> > +
> > +     /* enable phy cr_para_sel interfaces */
> > +     writel(PCIE_PHY_SEL, sv->priv_base + PCIEX8MGMT_PHY0_CR_PARA_SEL);
> > +     writel(PCIE_PHY_SEL, sv->priv_base + PCIEX8MGMT_PHY1_CR_PARA_SEL);
> > +     mdelay(1);
> > +
> > +     /* set PHY AC termination mode */
> > +     for (lane = 0; lane < PCIEX8MGMT_LANE_NUM; lane++) {
> > +             pcie_sifive_setphy(0, 1,
> > +                                PCIEX8MGMT_LANE +
> > +                                (PCIEX8MGMT_LANE_OFF * lane),
> > +                                PCIEX8MGMT_TERM_MODE, NULL, sv);
> > +             pcie_sifive_setphy(1, 1,
> > +                                PCIEX8MGMT_LANE +
> > +                                (PCIEX8MGMT_LANE_OFF * lane),
> > +                                PCIEX8MGMT_TERM_MODE, NULL, sv);
> > +     }
> > +}
> > +
> > +static int pcie_sifive_check_link(struct pcie_sifive *sv)
> > +{
> > +     u32 val;
> > +
> > +     val = readl(sv->dw.dbi_base + PHY_DEBUG_R1);
> > +     return (val & PHY_DEBUG_R1_LINK_UP) &&
> > +             !(val & PHY_DEBUG_R1_LINK_IN_TRAINING);
> > +}
> > +
> > +static void pcie_sifive_force_gen1(struct pcie_sifive *sv)
> > +{
> > +     u32 val, linkcap;
> > +
> > +     /*
> > +      * Force Gen1 operation when starting the link. In case the link is
> > +      * started in Gen2 mode, there is a possibility the devices on the
> > +      * bus will not be detected at all. This happens with PCIe switches.
> > +      */
> > +
> > +     /* ctrl_ro_wr_enable */
> > +     val = readl(sv->dw.dbi_base + PCIE_MISC_CONTROL_1);
> > +     val |= DBI_RO_WR_EN;
> > +     writel(val, sv->dw.dbi_base + PCIE_MISC_CONTROL_1);
> > +
> > +     /* configure link cap */
> > +     linkcap = readl(sv->dw.dbi_base + PF0_PCIE_CAP_LINK_CAP);
> > +     linkcap |= PCIE_LINK_CAP_MAX_SPEED_MASK;
> > +     writel(linkcap, sv->dw.dbi_base + PF0_PCIE_CAP_LINK_CAP);
> > +
> > +     /* ctrl_ro_wr_disable */
> > +     val &= ~DBI_RO_WR_EN;
> > +     writel(val, sv->dw.dbi_base + PCIE_MISC_CONTROL_1);
> > +}
> > +
> > +static void pcie_sifive_print_phy_debug(struct pcie_sifive *sv)
> > +{
> > +     sv_err(sv, "PHY DEBUG_R0=0x%08x DEBUG_R1=0x%08x\n",
> > +            readl(sv->dw.dbi_base + PHY_DEBUG_R0),
> > +            readl(sv->dw.dbi_base + PHY_DEBUG_R1));
> > +}
> > +
> > +static int pcie_sifive_wait_for_link(struct pcie_sifive *sv)
> > +{
> > +     u32 val;
> > +     int timeout;
> > +
> > +     /* Wait for the link to train */
> > +     mdelay(20);
> > +     timeout = 20;
> > +
> > +     do {
> > +             mdelay(1);
> > +     } while (--timeout && !pcie_sifive_check_link(sv));
> > +
> > +     val = readl(sv->dw.dbi_base + PHY_DEBUG_R1);
> > +     if (!(val & PHY_DEBUG_R1_LINK_UP) ||
> > +         (val & PHY_DEBUG_R1_LINK_IN_TRAINING)) {
> > +             sv_info(sv, "Failed to negotiate PCIe link!\n");
> > +             pcie_sifive_print_phy_debug(sv);
> > +             writel(PCIE_PHY_RESET,
> > +                    sv->priv_base + PCIEX8MGMT_APP_HOLD_PHY_RST);
> > +             return -ETIMEDOUT;
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static int pcie_sifive_start_link(struct pcie_sifive *sv)
> > +{
> > +     if (pcie_sifive_check_link(sv))
> > +             return -EALREADY;
> > +
> > +     pcie_sifive_force_gen1(sv);
> > +
> > +     /* set ltssm */
> > +     pcie_sifive_priv_set_state(sv, PCIEX8MGMT_APP_LTSSM_ENABLE,
> > +                                LTSSM_ENABLE_BIT, 1);
> > +     return 0;
> > +}
> > +
> > +static int pcie_sifive_init_port(struct udevice *dev,
> > +                              enum pcie_sifive_devtype mode)
> > +{
> > +     struct pcie_sifive *sv = dev_get_priv(dev);
> > +     int ret;
> > +
> > +     /* Power on reset */
> > +     pcie_sifive_assert_reset(sv);
> > +     pcie_sifive_power_on(sv);
> > +     pcie_sifive_deassert_reset(sv);
> > +
> > +     /* Enable pcieauxclk */
> > +     ret = clk_enable(&sv->aux_ck);
> > +     if (ret)
> > +             dev_err(dev, "unable to enable pcie_aux clock\n");
> > +
> > +     /*
> > +      * assert hold_phy_rst (hold the controller LTSSM in reset
> > +      * after power_up_rst_n for register programming with cr_para)
> > +      */
> > +     writel(PCIE_PHY_RESET, sv->priv_base + PCIEX8MGMT_APP_HOLD_PHY_RST);
> > +
> > +     /* deassert power_up_rst_n */
> > +     ret = reset_deassert(&sv->reset);
> > +     if (ret < 0) {
> > +             dev_err(dev, "failed to deassert reset");
> > +             return -EINVAL;
> > +     }
> > +
> > +     pcie_sifive_init_phy(sv);
> > +
> > +     /* disable pcieauxclk */
> > +     clk_disable(&sv->aux_ck);
> > +
> > +     /* deassert hold_phy_rst */
> > +     writel(PCIE_PHY_RESET_DEASSERT,
> > +            sv->priv_base + PCIEX8MGMT_APP_HOLD_PHY_RST);
> > +
> > +     /* enable pcieauxclk */
> > +     clk_enable(&sv->aux_ck);
> > +
> > +     /* Set desired mode while core is not operational */
> > +     if (mode == SV_PCIE_HOST_TYPE)
> > +             writel(DEVICE_TYPE_RC,
> > +                    sv->priv_base + PCIEX8MGMT_DEVICE_TYPE);
> > +     else
> > +             writel(DEVICE_TYPE_EP,
> > +                    sv->priv_base + PCIEX8MGMT_DEVICE_TYPE);
> > +
> > +     /* Confirm desired mode from operational core */
> > +     if (pcie_sifive_get_devtype(sv) != mode)
> > +             return -EINVAL;
> > +
> > +     pcie_dw_setup_host(&sv->dw);
> > +
> > +     if (pcie_sifive_start_link(sv) == -EALREADY)
> > +             sv_info(sv, "PCIe link is already up\n");
> > +     else if (pcie_sifive_wait_for_link(sv) == -ETIMEDOUT)
> > +             return -ETIMEDOUT;
> > +
> > +     return 0;
> > +}
> > +
> > +static int pcie_sifive_probe(struct udevice *dev)
> > +{
> > +     struct pcie_sifive *sv = dev_get_priv(dev);
> > +     struct udevice *parent = pci_get_controller(dev);
> > +     struct pci_controller *hose = dev_get_uclass_priv(parent);
> > +     int err;
> > +
> > +     sv->dw.first_busno = dev_seq(dev);
> > +     sv->dw.dev = dev;
> > +
> > +     err = pcie_sifive_init_port(dev, SV_PCIE_HOST_TYPE);
> > +     if (err) {
> > +             sv_info(sv, "Failed to init port.\n");
> > +             return err;
> > +     }
> > +
> > +     printf("PCIE-%d: Link up (Gen%d-x%d, Bus%d)\n",
> > +            dev_seq(dev), pcie_dw_get_link_speed(&sv->dw),
> > +            pcie_dw_get_link_width(&sv->dw),
> > +            hose->first_busno);
> > +
> > +     return pcie_dw_prog_outbound_atu_unroll(&sv->dw,
> > +                                             PCIE_ATU_REGION_INDEX0,
> > +                                             PCIE_ATU_TYPE_MEM,
> > +                                             sv->dw.mem.phys_start,
> > +                                             sv->dw.mem.bus_start,
> > +                                             sv->dw.mem.size);
> > +}
> > +
> > +static void __iomem *get_fdt_addr(struct udevice *dev, const char *name)
> > +{
> > +     fdt_addr_t addr;
> > +
> > +     addr = dev_read_addr_name(dev, name);
> > +
> > +     return (addr == FDT_ADDR_T_NONE) ? NULL : (void __iomem *)addr;
> > +}
> > +
> > +static int pcie_sifive_of_to_plat(struct udevice *dev)
> > +{
> > +     struct pcie_sifive *sv = dev_get_priv(dev);
> > +     int err;
> > +
> > +     /* get designware DBI base addr */
> > +     sv->dw.dbi_base = get_fdt_addr(dev, "dbi");
> > +     if (!sv->dw.dbi_base)
> > +             return -EINVAL;
> > +
> > +     /* get private control base addr */
> > +     sv->priv_base = get_fdt_addr(dev, "mgmt");
> > +     if (!sv->priv_base)
> > +             return -EINVAL;
> > +
> > +     gpio_request_by_name(dev, "pwren-gpios", 0, &sv->pwren_gpio,
> > +                          GPIOD_IS_OUT);
> > +
> > +     if (!dm_gpio_is_valid(&sv->pwren_gpio)) {
> > +             sv_info(sv, "pwren_gpio is invalid\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     gpio_request_by_name(dev, "reset-gpios", 0, &sv->reset_gpio,
> > +                          GPIOD_IS_OUT);
> > +
> > +     if (!dm_gpio_is_valid(&sv->reset_gpio)) {
> > +             sv_info(sv, "reset_gpio is invalid\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     err = clk_get_by_index(dev, 0, &sv->aux_ck);
> > +     if (err) {
> > +             sv_info(sv, "clk_get_by_index(aux_ck) failed: %d\n", err);
> > +             return err;
> > +     }
> > +
> > +     err = reset_get_by_index(dev, 0, &sv->reset);
> > +     if (err) {
> > +             sv_info(sv, "reset_get_by_index(reset) failed: %d\n", err);
> > +             return err;
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static const struct dm_pci_ops pcie_sifive_ops = {
> > +     .read_config    = pcie_dw_read_config,
> > +     .write_config   = pcie_dw_write_config,
> > +};
> > +
> > +static const struct udevice_id pcie_sifive_ids[] = {
> > +     { .compatible = "sifive,fu740-pcie" },
> > +     { .compatible = "sifive,fu740-pcie-ecam" },
>
> Are you sure the controller in ECAM mode should use this driver ?
> The Linux bindings only declare "sifive,fu740-pcie"
>

You are right. I should remove it. Thanks.
- Green

> > +     {}
> > +};
> > +
> > +U_BOOT_DRIVER(pcie_sifive) = {
> > +     .name           = "pcie_sifive",
> > +     .id             = UCLASS_PCI,
> > +     .of_match       = pcie_sifive_ids,
> > +     .ops            = &pcie_sifive_ops,
> > +     .of_to_plat     = pcie_sifive_of_to_plat,
> > +     .probe          = pcie_sifive_probe,
> > +     .priv_auto      = sizeof(struct pcie_sifive),
> > +};
> >
>
> otherwise,
>
> Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>
>
> Neil


More information about the U-Boot mailing list