uboot/drivers/pci/pcie_rockchip.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Rockchip AXI PCIe host controller driver
   4 *
   5 * Copyright (c) 2016 Rockchip, Inc.
   6 * Copyright (c) 2020 Amarula Solutions(India)
   7 * Copyright (c) 2020 Jagan Teki <jagan@amarulasolutions.com>
   8 * Copyright (c) 2019 Patrick Wildt <patrick@blueri.se>
   9 * Copyright (c) 2018 Mark Kettenis <kettenis@openbsd.org>
  10 *
  11 * Bits taken from Linux Rockchip PCIe host controller.
  12 */
  13
  14#include <common.h>
  15#include <clk.h>
  16#include <dm.h>
  17#include <dm/device_compat.h>
  18#include <generic-phy.h>
  19#include <pci.h>
  20#include <power-domain.h>
  21#include <power/regulator.h>
  22#include <reset.h>
  23#include <syscon.h>
  24#include <asm/io.h>
  25#include <asm-generic/gpio.h>
  26#include <asm/arch-rockchip/clock.h>
  27#include <linux/iopoll.h>
  28
  29DECLARE_GLOBAL_DATA_PTR;
  30
  31#define HIWORD_UPDATE(mask, val)        (((mask) << 16) | (val))
  32#define HIWORD_UPDATE_BIT(val)          HIWORD_UPDATE(val, val)
  33
  34#define ENCODE_LANES(x)                 ((((x) >> 1) & 3) << 4)
  35#define PCIE_CLIENT_BASE                0x0
  36#define PCIE_CLIENT_CONFIG              (PCIE_CLIENT_BASE + 0x00)
  37#define PCIE_CLIENT_CONF_ENABLE         HIWORD_UPDATE_BIT(0x0001)
  38#define PCIE_CLIENT_LINK_TRAIN_ENABLE   HIWORD_UPDATE_BIT(0x0002)
  39#define PCIE_CLIENT_MODE_RC             HIWORD_UPDATE_BIT(0x0040)
  40#define PCIE_CLIENT_GEN_SEL_1           HIWORD_UPDATE(0x0080, 0)
  41#define PCIE_CLIENT_BASIC_STATUS1       0x0048
  42#define PCIE_CLIENT_LINK_STATUS_UP      GENMASK(21, 20)
  43#define PCIE_CLIENT_LINK_STATUS_MASK    GENMASK(21, 20)
  44#define PCIE_LINK_UP(x) \
  45        (((x) & PCIE_CLIENT_LINK_STATUS_MASK) == PCIE_CLIENT_LINK_STATUS_UP)
  46#define PCIE_RC_NORMAL_BASE             0x800000
  47#define PCIE_LM_BASE                    0x900000
  48#define PCIE_LM_VENDOR_ID              (PCIE_LM_BASE + 0x44)
  49#define PCIE_LM_VENDOR_ROCKCHIP         0x1d87
  50#define PCIE_LM_RCBAR                   (PCIE_LM_BASE + 0x300)
  51#define PCIE_LM_RCBARPIE                BIT(19)
  52#define PCIE_LM_RCBARPIS                BIT(20)
  53#define PCIE_RC_BASE                    0xa00000
  54#define PCIE_RC_CONFIG_DCR              (PCIE_RC_BASE + 0x0c4)
  55#define PCIE_RC_CONFIG_DCR_CSPL_SHIFT   18
  56#define PCIE_RC_CONFIG_DCR_CPLS_SHIFT   26
  57#define PCIE_RC_PCIE_LCAP               (PCIE_RC_BASE + 0x0cc)
  58#define PCIE_RC_PCIE_LCAP_APMS_L0S      BIT(10)
  59#define PCIE_ATR_BASE                   0xc00000
  60#define PCIE_ATR_OB_ADDR0(i)            (PCIE_ATR_BASE + 0x000 + (i) * 0x20)
  61#define PCIE_ATR_OB_ADDR1(i)            (PCIE_ATR_BASE + 0x004 + (i) * 0x20)
  62#define PCIE_ATR_OB_DESC0(i)            (PCIE_ATR_BASE + 0x008 + (i) * 0x20)
  63#define PCIE_ATR_OB_DESC1(i)            (PCIE_ATR_BASE + 0x00c + (i) * 0x20)
  64#define PCIE_ATR_IB_ADDR0(i)            (PCIE_ATR_BASE + 0x800 + (i) * 0x8)
  65#define PCIE_ATR_IB_ADDR1(i)            (PCIE_ATR_BASE + 0x804 + (i) * 0x8)
  66#define PCIE_ATR_HDR_MEM                0x2
  67#define PCIE_ATR_HDR_IO                 0x6
  68#define PCIE_ATR_HDR_CFG_TYPE0          0xa
  69#define PCIE_ATR_HDR_CFG_TYPE1          0xb
  70#define PCIE_ATR_HDR_RID                BIT(23)
  71
  72#define PCIE_ATR_OB_REGION0_SIZE        (32 * 1024 * 1024)
  73#define PCIE_ATR_OB_REGION_SIZE         (1 * 1024 * 1024)
  74
  75struct rockchip_pcie {
  76        fdt_addr_t axi_base;
  77        fdt_addr_t apb_base;
  78        int first_busno;
  79        struct udevice *dev;
  80
  81        /* resets */
  82        struct reset_ctl core_rst;
  83        struct reset_ctl mgmt_rst;
  84        struct reset_ctl mgmt_sticky_rst;
  85        struct reset_ctl pipe_rst;
  86        struct reset_ctl pm_rst;
  87        struct reset_ctl pclk_rst;
  88        struct reset_ctl aclk_rst;
  89
  90        /* gpio */
  91        struct gpio_desc ep_gpio;
  92
  93        /* vpcie regulators */
  94        struct udevice *vpcie12v;
  95        struct udevice *vpcie3v3;
  96        struct udevice *vpcie1v8;
  97        struct udevice *vpcie0v9;
  98
  99        /* phy */
 100        struct phy pcie_phy;
 101};
 102
 103static int rockchip_pcie_off_conf(pci_dev_t bdf, uint offset)
 104{
 105        unsigned int bus = PCI_BUS(bdf);
 106        unsigned int dev = PCI_DEV(bdf);
 107        unsigned int func = PCI_FUNC(bdf);
 108
 109        return (bus << 20) | (dev << 15) | (func << 12) | (offset & ~0x3);
 110}
 111
 112static int rockchip_pcie_rd_conf(const struct udevice *udev, pci_dev_t bdf,
 113                                 uint offset, ulong *valuep,
 114                                 enum pci_size_t size)
 115{
 116        struct rockchip_pcie *priv = dev_get_priv(udev);
 117        unsigned int bus = PCI_BUS(bdf);
 118        unsigned int dev = PCI_DEV(bdf);
 119        int where = rockchip_pcie_off_conf(bdf, offset);
 120        ulong value;
 121
 122        if (bus == priv->first_busno && dev == 0) {
 123                value = readl(priv->apb_base + PCIE_RC_NORMAL_BASE + where);
 124                *valuep = pci_conv_32_to_size(value, offset, size);
 125                return 0;
 126        }
 127
 128        if ((bus == priv->first_busno + 1) && dev == 0) {
 129                value = readl(priv->axi_base + where);
 130                *valuep = pci_conv_32_to_size(value, offset, size);
 131                return 0;
 132        }
 133
 134        *valuep = pci_get_ff(size);
 135
 136        return 0;
 137}
 138
 139static int rockchip_pcie_wr_conf(struct udevice *udev, pci_dev_t bdf,
 140                                 uint offset, ulong value,
 141                                 enum pci_size_t size)
 142{
 143        struct rockchip_pcie *priv = dev_get_priv(udev);
 144        unsigned int bus = PCI_BUS(bdf);
 145        unsigned int dev = PCI_DEV(bdf);
 146        int where = rockchip_pcie_off_conf(bdf, offset);
 147        ulong old;
 148
 149        if (bus == priv->first_busno && dev == 0) {
 150                old = readl(priv->apb_base + PCIE_RC_NORMAL_BASE + where);
 151                value = pci_conv_size_to_32(old, value, offset, size);
 152                writel(value, priv->apb_base + PCIE_RC_NORMAL_BASE + where);
 153                return 0;
 154        }
 155
 156        if ((bus == priv->first_busno + 1) && dev == 0) {
 157                old = readl(priv->axi_base + where);
 158                value = pci_conv_size_to_32(old, value, offset, size);
 159                writel(value, priv->axi_base + where);
 160                return 0;
 161        }
 162
 163        return 0;
 164}
 165
 166static int rockchip_pcie_atr_init(struct rockchip_pcie *priv)
 167{
 168        struct udevice *ctlr = pci_get_controller(priv->dev);
 169        struct pci_controller *hose = dev_get_uclass_priv(ctlr);
 170        u64 addr, size, offset;
 171        u32 type;
 172        int i, region;
 173
 174        /* Use region 0 to map PCI configuration space. */
 175        writel(25 - 1, priv->apb_base + PCIE_ATR_OB_ADDR0(0));
 176        writel(0, priv->apb_base + PCIE_ATR_OB_ADDR1(0));
 177        writel(PCIE_ATR_HDR_CFG_TYPE0 | PCIE_ATR_HDR_RID,
 178               priv->apb_base + PCIE_ATR_OB_DESC0(0));
 179        writel(0, priv->apb_base + PCIE_ATR_OB_DESC1(0));
 180
 181        for (i = 0; i < hose->region_count; i++) {
 182                if (hose->regions[i].flags == PCI_REGION_SYS_MEMORY)
 183                        continue;
 184
 185                if (hose->regions[i].flags == PCI_REGION_IO)
 186                        type = PCIE_ATR_HDR_IO;
 187                else
 188                        type = PCIE_ATR_HDR_MEM;
 189
 190                /* Only support identity mappings. */
 191                if (hose->regions[i].bus_start !=
 192                    hose->regions[i].phys_start)
 193                        return -EINVAL;
 194
 195                /* Only support mappings aligned on a region boundary. */
 196                addr = hose->regions[i].bus_start;
 197                if (addr & (PCIE_ATR_OB_REGION_SIZE - 1))
 198                        return -EINVAL;
 199
 200                /* Mappings should lie between AXI and APB regions. */
 201                size = hose->regions[i].size;
 202                if (addr < (u64)priv->axi_base + PCIE_ATR_OB_REGION0_SIZE)
 203                        return -EINVAL;
 204                if (addr + size > (u64)priv->apb_base)
 205                        return -EINVAL;
 206
 207                offset = addr - (u64)priv->axi_base - PCIE_ATR_OB_REGION0_SIZE;
 208                region = 1 + (offset / PCIE_ATR_OB_REGION_SIZE);
 209                while (size > 0) {
 210                        writel(32 - 1,
 211                               priv->apb_base + PCIE_ATR_OB_ADDR0(region));
 212                        writel(0, priv->apb_base + PCIE_ATR_OB_ADDR1(region));
 213                        writel(type | PCIE_ATR_HDR_RID,
 214                               priv->apb_base + PCIE_ATR_OB_DESC0(region));
 215                        writel(0, priv->apb_base + PCIE_ATR_OB_DESC1(region));
 216
 217                        addr += PCIE_ATR_OB_REGION_SIZE;
 218                        size -= PCIE_ATR_OB_REGION_SIZE;
 219                        region++;
 220                }
 221        }
 222
 223        /* Passthrough inbound translations unmodified. */
 224        writel(32 - 1, priv->apb_base + PCIE_ATR_IB_ADDR0(2));
 225        writel(0, priv->apb_base + PCIE_ATR_IB_ADDR1(2));
 226
 227        return 0;
 228}
 229
 230static int rockchip_pcie_init_port(struct udevice *dev)
 231{
 232        struct rockchip_pcie *priv = dev_get_priv(dev);
 233        u32 cr, val, status;
 234        int ret;
 235
 236        if (dm_gpio_is_valid(&priv->ep_gpio))
 237                dm_gpio_set_value(&priv->ep_gpio, 0);
 238
 239        ret = reset_assert(&priv->aclk_rst);
 240        if (ret) {
 241                dev_err(dev, "failed to assert aclk reset (ret=%d)\n", ret);
 242                return ret;
 243        }
 244
 245        ret = reset_assert(&priv->pclk_rst);
 246        if (ret) {
 247                dev_err(dev, "failed to assert pclk reset (ret=%d)\n", ret);
 248                return ret;
 249        }
 250
 251        ret = reset_assert(&priv->pm_rst);
 252        if (ret) {
 253                dev_err(dev, "failed to assert pm reset (ret=%d)\n", ret);
 254                return ret;
 255        }
 256
 257        ret = generic_phy_init(&priv->pcie_phy);
 258        if (ret) {
 259                dev_err(dev, "failed to init phy (ret=%d)\n", ret);
 260                goto err_exit_phy;
 261        }
 262
 263        ret = reset_assert(&priv->core_rst);
 264        if (ret) {
 265                dev_err(dev, "failed to assert core reset (ret=%d)\n", ret);
 266                goto err_exit_phy;
 267        }
 268
 269        ret = reset_assert(&priv->mgmt_rst);
 270        if (ret) {
 271                dev_err(dev, "failed to assert mgmt reset (ret=%d)\n", ret);
 272                goto err_exit_phy;
 273        }
 274
 275        ret = reset_assert(&priv->mgmt_sticky_rst);
 276        if (ret) {
 277                dev_err(dev, "failed to assert mgmt-sticky reset (ret=%d)\n",
 278                        ret);
 279                goto err_exit_phy;
 280        }
 281
 282        ret = reset_assert(&priv->pipe_rst);
 283        if (ret) {
 284                dev_err(dev, "failed to assert pipe reset (ret=%d)\n", ret);
 285                goto err_exit_phy;
 286        }
 287
 288        udelay(10);
 289
 290        ret = reset_deassert(&priv->pm_rst);
 291        if (ret) {
 292                dev_err(dev, "failed to deassert pm reset (ret=%d)\n", ret);
 293                goto err_exit_phy;
 294        }
 295
 296        ret = reset_deassert(&priv->aclk_rst);
 297        if (ret) {
 298                dev_err(dev, "failed to deassert aclk reset (ret=%d)\n", ret);
 299                goto err_exit_phy;
 300        }
 301
 302        ret = reset_deassert(&priv->pclk_rst);
 303        if (ret) {
 304                dev_err(dev, "failed to deassert pclk reset (ret=%d)\n", ret);
 305                goto err_exit_phy;
 306        }
 307
 308        /* Select GEN1 for now */
 309        cr = PCIE_CLIENT_GEN_SEL_1;
 310        /* Set Root complex mode */
 311        cr |= PCIE_CLIENT_CONF_ENABLE | PCIE_CLIENT_MODE_RC;
 312        writel(cr, priv->apb_base + PCIE_CLIENT_CONFIG);
 313
 314        ret = generic_phy_power_on(&priv->pcie_phy);
 315        if (ret) {
 316                dev_err(dev, "failed to power on phy (ret=%d)\n", ret);
 317                goto err_power_off_phy;
 318        }
 319
 320        ret = reset_deassert(&priv->mgmt_sticky_rst);
 321        if (ret) {
 322                dev_err(dev, "failed to deassert mgmt-sticky reset (ret=%d)\n",
 323                        ret);
 324                goto err_power_off_phy;
 325        }
 326
 327        ret = reset_deassert(&priv->core_rst);
 328        if (ret) {
 329                dev_err(dev, "failed to deassert core reset (ret=%d)\n", ret);
 330                goto err_power_off_phy;
 331        }
 332
 333        ret = reset_deassert(&priv->mgmt_rst);
 334        if (ret) {
 335                dev_err(dev, "failed to deassert mgmt reset (ret=%d)\n", ret);
 336                goto err_power_off_phy;
 337        }
 338
 339        ret = reset_deassert(&priv->pipe_rst);
 340        if (ret) {
 341                dev_err(dev, "failed to deassert pipe reset (ret=%d)\n", ret);
 342                goto err_power_off_phy;
 343        }
 344
 345        /* Enable Gen1 training */
 346        writel(PCIE_CLIENT_LINK_TRAIN_ENABLE,
 347               priv->apb_base + PCIE_CLIENT_CONFIG);
 348
 349        if (dm_gpio_is_valid(&priv->ep_gpio))
 350                dm_gpio_set_value(&priv->ep_gpio, 1);
 351
 352        ret = readl_poll_sleep_timeout
 353                        (priv->apb_base + PCIE_CLIENT_BASIC_STATUS1,
 354                        status, PCIE_LINK_UP(status), 20, 500 * 1000);
 355        if (ret) {
 356                dev_err(dev, "PCIe link training gen1 timeout!\n");
 357                goto err_power_off_phy;
 358        }
 359
 360        /* Initialize Root Complex registers. */
 361        writel(PCIE_LM_VENDOR_ROCKCHIP, priv->apb_base + PCIE_LM_VENDOR_ID);
 362        writel(PCI_CLASS_BRIDGE_PCI << 16,
 363               priv->apb_base + PCIE_RC_BASE + PCI_CLASS_REVISION);
 364        writel(PCIE_LM_RCBARPIE | PCIE_LM_RCBARPIS,
 365               priv->apb_base + PCIE_LM_RCBAR);
 366
 367        if (dev_read_bool(dev, "aspm-no-l0s")) {
 368                val = readl(priv->apb_base + PCIE_RC_PCIE_LCAP);
 369                val &= ~PCIE_RC_PCIE_LCAP_APMS_L0S;
 370                writel(val, priv->apb_base + PCIE_RC_PCIE_LCAP);
 371        }
 372
 373        /* Configure Address Translation. */
 374        ret = rockchip_pcie_atr_init(priv);
 375        if (ret) {
 376                dev_err(dev, "PCIE-%d: ATR init failed\n", dev->seq);
 377                goto err_power_off_phy;
 378        }
 379
 380        return 0;
 381
 382err_power_off_phy:
 383        generic_phy_power_off(&priv->pcie_phy);
 384err_exit_phy:
 385        generic_phy_exit(&priv->pcie_phy);
 386        return ret;
 387}
 388
 389static int rockchip_pcie_set_vpcie(struct udevice *dev)
 390{
 391        struct rockchip_pcie *priv = dev_get_priv(dev);
 392        int ret;
 393
 394        if (priv->vpcie3v3) {
 395                ret = regulator_set_enable(priv->vpcie3v3, true);
 396                if (ret) {
 397                        dev_err(dev, "failed to enable vpcie3v3 (ret=%d)\n",
 398                                ret);
 399                        return ret;
 400                }
 401        }
 402
 403        if (priv->vpcie1v8) {
 404                ret = regulator_set_enable(priv->vpcie1v8, true);
 405                if (ret) {
 406                        dev_err(dev, "failed to enable vpcie1v8 (ret=%d)\n",
 407                                ret);
 408                        goto err_disable_3v3;
 409                }
 410        }
 411
 412        if (priv->vpcie0v9) {
 413                ret = regulator_set_enable(priv->vpcie0v9, true);
 414                if (ret) {
 415                        dev_err(dev, "failed to enable vpcie0v9 (ret=%d)\n",
 416                                ret);
 417                        goto err_disable_1v8;
 418                }
 419        }
 420
 421        return 0;
 422
 423err_disable_1v8:
 424        if (priv->vpcie1v8)
 425                regulator_set_enable(priv->vpcie1v8, false);
 426err_disable_3v3:
 427        if (priv->vpcie3v3)
 428                regulator_set_enable(priv->vpcie3v3, false);
 429        return ret;
 430}
 431
 432static int rockchip_pcie_parse_dt(struct udevice *dev)
 433{
 434        struct rockchip_pcie *priv = dev_get_priv(dev);
 435        int ret;
 436
 437        priv->axi_base = dev_read_addr_name(dev, "axi-base");
 438        if (!priv->axi_base)
 439                return -ENODEV;
 440
 441        priv->apb_base = dev_read_addr_name(dev, "apb-base");
 442        if (!priv->axi_base)
 443                return -ENODEV;
 444
 445        ret = gpio_request_by_name(dev, "ep-gpios", 0,
 446                                   &priv->ep_gpio, GPIOD_IS_OUT);
 447        if (ret) {
 448                dev_err(dev, "failed to find ep-gpios property\n");
 449                return ret;
 450        }
 451
 452        ret = reset_get_by_name(dev, "core", &priv->core_rst);
 453        if (ret) {
 454                dev_err(dev, "failed to get core reset (ret=%d)\n", ret);
 455                return ret;
 456        }
 457
 458        ret = reset_get_by_name(dev, "mgmt", &priv->mgmt_rst);
 459        if (ret) {
 460                dev_err(dev, "failed to get mgmt reset (ret=%d)\n", ret);
 461                return ret;
 462        }
 463
 464        ret = reset_get_by_name(dev, "mgmt-sticky", &priv->mgmt_sticky_rst);
 465        if (ret) {
 466                dev_err(dev, "failed to get mgmt-sticky reset (ret=%d)\n", ret);
 467                return ret;
 468        }
 469
 470        ret = reset_get_by_name(dev, "pipe", &priv->pipe_rst);
 471        if (ret) {
 472                dev_err(dev, "failed to get pipe reset (ret=%d)\n", ret);
 473                return ret;
 474        }
 475
 476        ret = reset_get_by_name(dev, "pm", &priv->pm_rst);
 477        if (ret) {
 478                dev_err(dev, "failed to get pm reset (ret=%d)\n", ret);
 479                return ret;
 480        }
 481
 482        ret = reset_get_by_name(dev, "pclk", &priv->pclk_rst);
 483        if (ret) {
 484                dev_err(dev, "failed to get pclk reset (ret=%d)\n", ret);
 485                return ret;
 486        }
 487
 488        ret = reset_get_by_name(dev, "aclk", &priv->aclk_rst);
 489        if (ret) {
 490                dev_err(dev, "failed to get aclk reset (ret=%d)\n", ret);
 491                return ret;
 492        }
 493
 494        ret = device_get_supply_regulator(dev, "vpcie3v3-supply",
 495                                          &priv->vpcie3v3);
 496        if (ret && ret != -ENOENT) {
 497                dev_err(dev, "failed to get vpcie3v3 supply (ret=%d)\n", ret);
 498                return ret;
 499        }
 500
 501        ret = device_get_supply_regulator(dev, "vpcie1v8-supply",
 502                                          &priv->vpcie1v8);
 503        if (ret && ret != -ENOENT) {
 504                dev_err(dev, "failed to get vpcie1v8 supply (ret=%d)\n", ret);
 505                return ret;
 506        }
 507
 508        ret = device_get_supply_regulator(dev, "vpcie0v9-supply",
 509                                          &priv->vpcie0v9);
 510        if (ret && ret != -ENOENT) {
 511                dev_err(dev, "failed to get vpcie0v9 supply (ret=%d)\n", ret);
 512                return ret;
 513        }
 514
 515        ret = generic_phy_get_by_index(dev, 0, &priv->pcie_phy);
 516        if (ret) {
 517                dev_err(dev, "failed to get pcie-phy (ret=%d)\n", ret);
 518                return ret;
 519        }
 520
 521        return 0;
 522}
 523
 524static int rockchip_pcie_probe(struct udevice *dev)
 525{
 526        struct rockchip_pcie *priv = dev_get_priv(dev);
 527        struct udevice *ctlr = pci_get_controller(dev);
 528        struct pci_controller *hose = dev_get_uclass_priv(ctlr);
 529        int ret;
 530
 531        priv->first_busno = dev->seq;
 532        priv->dev = dev;
 533
 534        ret = rockchip_pcie_parse_dt(dev);
 535        if (ret)
 536                return ret;
 537
 538        ret = rockchip_pcie_set_vpcie(dev);
 539        if (ret)
 540                return ret;
 541
 542        ret = rockchip_pcie_init_port(dev);
 543        if (ret)
 544                return ret;
 545
 546        dev_info(dev, "PCIE-%d: Link up (Bus%d)\n",
 547                 dev->seq, hose->first_busno);
 548
 549        return 0;
 550}
 551
 552static const struct dm_pci_ops rockchip_pcie_ops = {
 553        .read_config    = rockchip_pcie_rd_conf,
 554        .write_config   = rockchip_pcie_wr_conf,
 555};
 556
 557static const struct udevice_id rockchip_pcie_ids[] = {
 558        { .compatible = "rockchip,rk3399-pcie" },
 559        { }
 560};
 561
 562U_BOOT_DRIVER(rockchip_pcie) = {
 563        .name                   = "rockchip_pcie",
 564        .id                     = UCLASS_PCI,
 565        .of_match               = rockchip_pcie_ids,
 566        .ops                    = &rockchip_pcie_ops,
 567        .probe                  = rockchip_pcie_probe,
 568        .priv_auto_alloc_size   = sizeof(struct rockchip_pcie),
 569};
 570