linux/drivers/pci/controller/cadence/pci-j721e.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/**
   3 * pci-j721e - PCIe controller driver for TI's J721E SoCs
   4 *
   5 * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com
   6 * Author: Kishon Vijay Abraham I <kishon@ti.com>
   7 */
   8
   9#include <linux/delay.h>
  10#include <linux/gpio/consumer.h>
  11#include <linux/io.h>
  12#include <linux/irqchip/chained_irq.h>
  13#include <linux/irqdomain.h>
  14#include <linux/mfd/syscon.h>
  15#include <linux/of.h>
  16#include <linux/of_device.h>
  17#include <linux/of_irq.h>
  18#include <linux/pci.h>
  19#include <linux/pm_runtime.h>
  20#include <linux/regmap.h>
  21
  22#include "../../pci.h"
  23#include "pcie-cadence.h"
  24
  25#define ENABLE_REG_SYS_2        0x108
  26#define STATUS_REG_SYS_2        0x508
  27#define STATUS_CLR_REG_SYS_2    0x708
  28#define LINK_DOWN               BIT(1)
  29
  30#define J721E_PCIE_USER_CMD_STATUS      0x4
  31#define LINK_TRAINING_ENABLE            BIT(0)
  32
  33#define J721E_PCIE_USER_LINKSTATUS      0x14
  34#define LINK_STATUS                     GENMASK(1, 0)
  35
  36enum link_status {
  37        NO_RECEIVERS_DETECTED,
  38        LINK_TRAINING_IN_PROGRESS,
  39        LINK_UP_DL_IN_PROGRESS,
  40        LINK_UP_DL_COMPLETED,
  41};
  42
  43#define J721E_MODE_RC                   BIT(7)
  44#define LANE_COUNT_MASK                 BIT(8)
  45#define LANE_COUNT(n)                   ((n) << 8)
  46
  47#define GENERATION_SEL_MASK             GENMASK(1, 0)
  48
  49#define MAX_LANES                       2
  50
  51struct j721e_pcie {
  52        struct device           *dev;
  53        u32                     mode;
  54        u32                     num_lanes;
  55        struct cdns_pcie        *cdns_pcie;
  56        void __iomem            *user_cfg_base;
  57        void __iomem            *intd_cfg_base;
  58};
  59
  60enum j721e_pcie_mode {
  61        PCI_MODE_RC,
  62        PCI_MODE_EP,
  63};
  64
  65struct j721e_pcie_data {
  66        enum j721e_pcie_mode    mode;
  67};
  68
  69static inline u32 j721e_pcie_user_readl(struct j721e_pcie *pcie, u32 offset)
  70{
  71        return readl(pcie->user_cfg_base + offset);
  72}
  73
  74static inline void j721e_pcie_user_writel(struct j721e_pcie *pcie, u32 offset,
  75                                          u32 value)
  76{
  77        writel(value, pcie->user_cfg_base + offset);
  78}
  79
  80static inline u32 j721e_pcie_intd_readl(struct j721e_pcie *pcie, u32 offset)
  81{
  82        return readl(pcie->intd_cfg_base + offset);
  83}
  84
  85static inline void j721e_pcie_intd_writel(struct j721e_pcie *pcie, u32 offset,
  86                                          u32 value)
  87{
  88        writel(value, pcie->intd_cfg_base + offset);
  89}
  90
  91static irqreturn_t j721e_pcie_link_irq_handler(int irq, void *priv)
  92{
  93        struct j721e_pcie *pcie = priv;
  94        struct device *dev = pcie->dev;
  95        u32 reg;
  96
  97        reg = j721e_pcie_intd_readl(pcie, STATUS_REG_SYS_2);
  98        if (!(reg & LINK_DOWN))
  99                return IRQ_NONE;
 100
 101        dev_err(dev, "LINK DOWN!\n");
 102
 103        j721e_pcie_intd_writel(pcie, STATUS_CLR_REG_SYS_2, LINK_DOWN);
 104        return IRQ_HANDLED;
 105}
 106
 107static void j721e_pcie_config_link_irq(struct j721e_pcie *pcie)
 108{
 109        u32 reg;
 110
 111        reg = j721e_pcie_intd_readl(pcie, ENABLE_REG_SYS_2);
 112        reg |= LINK_DOWN;
 113        j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_2, reg);
 114}
 115
 116static int j721e_pcie_start_link(struct cdns_pcie *cdns_pcie)
 117{
 118        struct j721e_pcie *pcie = dev_get_drvdata(cdns_pcie->dev);
 119        u32 reg;
 120
 121        reg = j721e_pcie_user_readl(pcie, J721E_PCIE_USER_CMD_STATUS);
 122        reg |= LINK_TRAINING_ENABLE;
 123        j721e_pcie_user_writel(pcie, J721E_PCIE_USER_CMD_STATUS, reg);
 124
 125        return 0;
 126}
 127
 128static void j721e_pcie_stop_link(struct cdns_pcie *cdns_pcie)
 129{
 130        struct j721e_pcie *pcie = dev_get_drvdata(cdns_pcie->dev);
 131        u32 reg;
 132
 133        reg = j721e_pcie_user_readl(pcie, J721E_PCIE_USER_CMD_STATUS);
 134        reg &= ~LINK_TRAINING_ENABLE;
 135        j721e_pcie_user_writel(pcie, J721E_PCIE_USER_CMD_STATUS, reg);
 136}
 137
 138static bool j721e_pcie_link_up(struct cdns_pcie *cdns_pcie)
 139{
 140        struct j721e_pcie *pcie = dev_get_drvdata(cdns_pcie->dev);
 141        u32 reg;
 142
 143        reg = j721e_pcie_user_readl(pcie, J721E_PCIE_USER_LINKSTATUS);
 144        reg &= LINK_STATUS;
 145        if (reg == LINK_UP_DL_COMPLETED)
 146                return true;
 147
 148        return false;
 149}
 150
 151static const struct cdns_pcie_ops j721e_pcie_ops = {
 152        .start_link = j721e_pcie_start_link,
 153        .stop_link = j721e_pcie_stop_link,
 154        .link_up = j721e_pcie_link_up,
 155};
 156
 157static int j721e_pcie_set_mode(struct j721e_pcie *pcie, struct regmap *syscon,
 158                               unsigned int offset)
 159{
 160        struct device *dev = pcie->dev;
 161        u32 mask = J721E_MODE_RC;
 162        u32 mode = pcie->mode;
 163        u32 val = 0;
 164        int ret = 0;
 165
 166        if (mode == PCI_MODE_RC)
 167                val = J721E_MODE_RC;
 168
 169        ret = regmap_update_bits(syscon, offset, mask, val);
 170        if (ret)
 171                dev_err(dev, "failed to set pcie mode\n");
 172
 173        return ret;
 174}
 175
 176static int j721e_pcie_set_link_speed(struct j721e_pcie *pcie,
 177                                     struct regmap *syscon, unsigned int offset)
 178{
 179        struct device *dev = pcie->dev;
 180        struct device_node *np = dev->of_node;
 181        int link_speed;
 182        u32 val = 0;
 183        int ret;
 184
 185        link_speed = of_pci_get_max_link_speed(np);
 186        if (link_speed < 2)
 187                link_speed = 2;
 188
 189        val = link_speed - 1;
 190        ret = regmap_update_bits(syscon, offset, GENERATION_SEL_MASK, val);
 191        if (ret)
 192                dev_err(dev, "failed to set link speed\n");
 193
 194        return ret;
 195}
 196
 197static int j721e_pcie_set_lane_count(struct j721e_pcie *pcie,
 198                                     struct regmap *syscon, unsigned int offset)
 199{
 200        struct device *dev = pcie->dev;
 201        u32 lanes = pcie->num_lanes;
 202        u32 val = 0;
 203        int ret;
 204
 205        val = LANE_COUNT(lanes - 1);
 206        ret = regmap_update_bits(syscon, offset, LANE_COUNT_MASK, val);
 207        if (ret)
 208                dev_err(dev, "failed to set link count\n");
 209
 210        return ret;
 211}
 212
 213static int j721e_pcie_ctrl_init(struct j721e_pcie *pcie)
 214{
 215        struct device *dev = pcie->dev;
 216        struct device_node *node = dev->of_node;
 217        struct of_phandle_args args;
 218        unsigned int offset = 0;
 219        struct regmap *syscon;
 220        int ret;
 221
 222        syscon = syscon_regmap_lookup_by_phandle(node, "ti,syscon-pcie-ctrl");
 223        if (IS_ERR(syscon)) {
 224                dev_err(dev, "Unable to get ti,syscon-pcie-ctrl regmap\n");
 225                return PTR_ERR(syscon);
 226        }
 227
 228        /* Do not error out to maintain old DT compatibility */
 229        ret = of_parse_phandle_with_fixed_args(node, "ti,syscon-pcie-ctrl", 1,
 230                                               0, &args);
 231        if (!ret)
 232                offset = args.args[0];
 233
 234        ret = j721e_pcie_set_mode(pcie, syscon, offset);
 235        if (ret < 0) {
 236                dev_err(dev, "Failed to set pci mode\n");
 237                return ret;
 238        }
 239
 240        ret = j721e_pcie_set_link_speed(pcie, syscon, offset);
 241        if (ret < 0) {
 242                dev_err(dev, "Failed to set link speed\n");
 243                return ret;
 244        }
 245
 246        ret = j721e_pcie_set_lane_count(pcie, syscon, offset);
 247        if (ret < 0) {
 248                dev_err(dev, "Failed to set num-lanes\n");
 249                return ret;
 250        }
 251
 252        return 0;
 253}
 254
 255static int cdns_ti_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
 256                                    int where, int size, u32 *value)
 257{
 258        if (pci_is_root_bus(bus))
 259                return pci_generic_config_read32(bus, devfn, where, size,
 260                                                 value);
 261
 262        return pci_generic_config_read(bus, devfn, where, size, value);
 263}
 264
 265static int cdns_ti_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
 266                                     int where, int size, u32 value)
 267{
 268        if (pci_is_root_bus(bus))
 269                return pci_generic_config_write32(bus, devfn, where, size,
 270                                                  value);
 271
 272        return pci_generic_config_write(bus, devfn, where, size, value);
 273}
 274
 275static struct pci_ops cdns_ti_pcie_host_ops = {
 276        .map_bus        = cdns_pci_map_bus,
 277        .read           = cdns_ti_pcie_config_read,
 278        .write          = cdns_ti_pcie_config_write,
 279};
 280
 281static const struct j721e_pcie_data j721e_pcie_rc_data = {
 282        .mode = PCI_MODE_RC,
 283};
 284
 285static const struct j721e_pcie_data j721e_pcie_ep_data = {
 286        .mode = PCI_MODE_EP,
 287};
 288
 289static const struct of_device_id of_j721e_pcie_match[] = {
 290        {
 291                .compatible = "ti,j721e-pcie-host",
 292                .data = &j721e_pcie_rc_data,
 293        },
 294        {
 295                .compatible = "ti,j721e-pcie-ep",
 296                .data = &j721e_pcie_ep_data,
 297        },
 298        {},
 299};
 300
 301static int j721e_pcie_probe(struct platform_device *pdev)
 302{
 303        struct device *dev = &pdev->dev;
 304        struct device_node *node = dev->of_node;
 305        struct pci_host_bridge *bridge;
 306        struct j721e_pcie_data *data;
 307        struct cdns_pcie *cdns_pcie;
 308        struct j721e_pcie *pcie;
 309        struct cdns_pcie_rc *rc;
 310        struct cdns_pcie_ep *ep;
 311        struct gpio_desc *gpiod;
 312        void __iomem *base;
 313        u32 num_lanes;
 314        u32 mode;
 315        int ret;
 316        int irq;
 317
 318        data = (struct j721e_pcie_data *)of_device_get_match_data(dev);
 319        if (!data)
 320                return -EINVAL;
 321
 322        mode = (u32)data->mode;
 323
 324        pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
 325        if (!pcie)
 326                return -ENOMEM;
 327
 328        pcie->dev = dev;
 329        pcie->mode = mode;
 330
 331        base = devm_platform_ioremap_resource_byname(pdev, "intd_cfg");
 332        if (IS_ERR(base))
 333                return PTR_ERR(base);
 334        pcie->intd_cfg_base = base;
 335
 336        base = devm_platform_ioremap_resource_byname(pdev, "user_cfg");
 337        if (IS_ERR(base))
 338                return PTR_ERR(base);
 339        pcie->user_cfg_base = base;
 340
 341        ret = of_property_read_u32(node, "num-lanes", &num_lanes);
 342        if (ret || num_lanes > MAX_LANES)
 343                num_lanes = 1;
 344        pcie->num_lanes = num_lanes;
 345
 346        if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48)))
 347                return -EINVAL;
 348
 349        irq = platform_get_irq_byname(pdev, "link_state");
 350        if (irq < 0)
 351                return irq;
 352
 353        dev_set_drvdata(dev, pcie);
 354        pm_runtime_enable(dev);
 355        ret = pm_runtime_get_sync(dev);
 356        if (ret < 0) {
 357                dev_err(dev, "pm_runtime_get_sync failed\n");
 358                goto err_get_sync;
 359        }
 360
 361        ret = j721e_pcie_ctrl_init(pcie);
 362        if (ret < 0) {
 363                dev_err(dev, "pm_runtime_get_sync failed\n");
 364                goto err_get_sync;
 365        }
 366
 367        ret = devm_request_irq(dev, irq, j721e_pcie_link_irq_handler, 0,
 368                               "j721e-pcie-link-down-irq", pcie);
 369        if (ret < 0) {
 370                dev_err(dev, "failed to request link state IRQ %d\n", irq);
 371                goto err_get_sync;
 372        }
 373
 374        j721e_pcie_config_link_irq(pcie);
 375
 376        switch (mode) {
 377        case PCI_MODE_RC:
 378                if (!IS_ENABLED(CONFIG_PCIE_CADENCE_HOST)) {
 379                        ret = -ENODEV;
 380                        goto err_get_sync;
 381                }
 382
 383                bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc));
 384                if (!bridge) {
 385                        ret = -ENOMEM;
 386                        goto err_get_sync;
 387                }
 388
 389                bridge->ops = &cdns_ti_pcie_host_ops;
 390                rc = pci_host_bridge_priv(bridge);
 391
 392                cdns_pcie = &rc->pcie;
 393                cdns_pcie->dev = dev;
 394                cdns_pcie->ops = &j721e_pcie_ops;
 395                pcie->cdns_pcie = cdns_pcie;
 396
 397                gpiod = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
 398                if (IS_ERR(gpiod)) {
 399                        ret = PTR_ERR(gpiod);
 400                        if (ret != -EPROBE_DEFER)
 401                                dev_err(dev, "Failed to get reset GPIO\n");
 402                        goto err_get_sync;
 403                }
 404
 405                ret = cdns_pcie_init_phy(dev, cdns_pcie);
 406                if (ret) {
 407                        dev_err(dev, "Failed to init phy\n");
 408                        goto err_get_sync;
 409                }
 410
 411                /*
 412                 * "Power Sequencing and Reset Signal Timings" table in
 413                 * PCI EXPRESS CARD ELECTROMECHANICAL SPECIFICATION, REV. 3.0
 414                 * indicates PERST# should be deasserted after minimum of 100us
 415                 * once REFCLK is stable. The REFCLK to the connector in RC
 416                 * mode is selected while enabling the PHY. So deassert PERST#
 417                 * after 100 us.
 418                 */
 419                if (gpiod) {
 420                        usleep_range(100, 200);
 421                        gpiod_set_value_cansleep(gpiod, 1);
 422                }
 423
 424                ret = cdns_pcie_host_setup(rc);
 425                if (ret < 0)
 426                        goto err_pcie_setup;
 427
 428                break;
 429        case PCI_MODE_EP:
 430                if (!IS_ENABLED(CONFIG_PCIE_CADENCE_EP)) {
 431                        ret = -ENODEV;
 432                        goto err_get_sync;
 433                }
 434
 435                ep = devm_kzalloc(dev, sizeof(*ep), GFP_KERNEL);
 436                if (!ep) {
 437                        ret = -ENOMEM;
 438                        goto err_get_sync;
 439                }
 440
 441                cdns_pcie = &ep->pcie;
 442                cdns_pcie->dev = dev;
 443                cdns_pcie->ops = &j721e_pcie_ops;
 444                pcie->cdns_pcie = cdns_pcie;
 445
 446                ret = cdns_pcie_init_phy(dev, cdns_pcie);
 447                if (ret) {
 448                        dev_err(dev, "Failed to init phy\n");
 449                        goto err_get_sync;
 450                }
 451
 452                ret = cdns_pcie_ep_setup(ep);
 453                if (ret < 0)
 454                        goto err_pcie_setup;
 455
 456                break;
 457        default:
 458                dev_err(dev, "INVALID device type %d\n", mode);
 459        }
 460
 461        return 0;
 462
 463err_pcie_setup:
 464        cdns_pcie_disable_phy(cdns_pcie);
 465
 466err_get_sync:
 467        pm_runtime_put(dev);
 468        pm_runtime_disable(dev);
 469
 470        return ret;
 471}
 472
 473static int j721e_pcie_remove(struct platform_device *pdev)
 474{
 475        struct j721e_pcie *pcie = platform_get_drvdata(pdev);
 476        struct cdns_pcie *cdns_pcie = pcie->cdns_pcie;
 477        struct device *dev = &pdev->dev;
 478
 479        cdns_pcie_disable_phy(cdns_pcie);
 480        pm_runtime_put(dev);
 481        pm_runtime_disable(dev);
 482
 483        return 0;
 484}
 485
 486static struct platform_driver j721e_pcie_driver = {
 487        .probe  = j721e_pcie_probe,
 488        .remove = j721e_pcie_remove,
 489        .driver = {
 490                .name   = "j721e-pcie",
 491                .of_match_table = of_j721e_pcie_match,
 492                .suppress_bind_attrs = true,
 493        },
 494};
 495builtin_platform_driver(j721e_pcie_driver);
 496