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