linux/drivers/pci/host/pcie-qcom.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
   3 * Copyright 2015 Linaro Limited.
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License version 2 and
   7 * only version 2 as published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope that it will be useful,
  10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 * GNU General Public License for more details.
  13 */
  14
  15#include <linux/clk.h>
  16#include <linux/delay.h>
  17#include <linux/gpio.h>
  18#include <linux/interrupt.h>
  19#include <linux/io.h>
  20#include <linux/iopoll.h>
  21#include <linux/kernel.h>
  22#include <linux/module.h>
  23#include <linux/of_device.h>
  24#include <linux/of_gpio.h>
  25#include <linux/pci.h>
  26#include <linux/platform_device.h>
  27#include <linux/phy/phy.h>
  28#include <linux/regulator/consumer.h>
  29#include <linux/reset.h>
  30#include <linux/slab.h>
  31#include <linux/types.h>
  32
  33#include "pcie-designware.h"
  34
  35#define PCIE20_PARF_PHY_CTRL                    0x40
  36#define PCIE20_PARF_PHY_REFCLK                  0x4C
  37#define PCIE20_PARF_DBI_BASE_ADDR               0x168
  38#define PCIE20_PARF_SLV_ADDR_SPACE_SIZE         0x16c
  39#define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT       0x178
  40
  41#define PCIE20_ELBI_SYS_CTRL                    0x04
  42#define PCIE20_ELBI_SYS_CTRL_LT_ENABLE          BIT(0)
  43
  44#define PCIE20_CAP                              0x70
  45
  46#define PERST_DELAY_US                          1000
  47
  48struct qcom_pcie_resources_v0 {
  49        struct clk *iface_clk;
  50        struct clk *core_clk;
  51        struct clk *phy_clk;
  52        struct reset_control *pci_reset;
  53        struct reset_control *axi_reset;
  54        struct reset_control *ahb_reset;
  55        struct reset_control *por_reset;
  56        struct reset_control *phy_reset;
  57        struct regulator *vdda;
  58        struct regulator *vdda_phy;
  59        struct regulator *vdda_refclk;
  60};
  61
  62struct qcom_pcie_resources_v1 {
  63        struct clk *iface;
  64        struct clk *aux;
  65        struct clk *master_bus;
  66        struct clk *slave_bus;
  67        struct reset_control *core;
  68        struct regulator *vdda;
  69};
  70
  71union qcom_pcie_resources {
  72        struct qcom_pcie_resources_v0 v0;
  73        struct qcom_pcie_resources_v1 v1;
  74};
  75
  76struct qcom_pcie;
  77
  78struct qcom_pcie_ops {
  79        int (*get_resources)(struct qcom_pcie *pcie);
  80        int (*init)(struct qcom_pcie *pcie);
  81        void (*deinit)(struct qcom_pcie *pcie);
  82};
  83
  84struct qcom_pcie {
  85        struct pcie_port pp;
  86        struct device *dev;
  87        union qcom_pcie_resources res;
  88        void __iomem *parf;
  89        void __iomem *dbi;
  90        void __iomem *elbi;
  91        struct phy *phy;
  92        struct gpio_desc *reset;
  93        struct qcom_pcie_ops *ops;
  94};
  95
  96#define to_qcom_pcie(x)         container_of(x, struct qcom_pcie, pp)
  97
  98static void qcom_ep_reset_assert(struct qcom_pcie *pcie)
  99{
 100        gpiod_set_value(pcie->reset, 1);
 101        usleep_range(PERST_DELAY_US, PERST_DELAY_US + 500);
 102}
 103
 104static void qcom_ep_reset_deassert(struct qcom_pcie *pcie)
 105{
 106        gpiod_set_value(pcie->reset, 0);
 107        usleep_range(PERST_DELAY_US, PERST_DELAY_US + 500);
 108}
 109
 110static irqreturn_t qcom_pcie_msi_irq_handler(int irq, void *arg)
 111{
 112        struct pcie_port *pp = arg;
 113
 114        return dw_handle_msi_irq(pp);
 115}
 116
 117static int qcom_pcie_establish_link(struct qcom_pcie *pcie)
 118{
 119        struct device *dev = pcie->dev;
 120        unsigned int retries = 0;
 121        u32 val;
 122
 123        if (dw_pcie_link_up(&pcie->pp))
 124                return 0;
 125
 126        /* enable link training */
 127        val = readl(pcie->elbi + PCIE20_ELBI_SYS_CTRL);
 128        val |= PCIE20_ELBI_SYS_CTRL_LT_ENABLE;
 129        writel(val, pcie->elbi + PCIE20_ELBI_SYS_CTRL);
 130
 131        do {
 132                if (dw_pcie_link_up(&pcie->pp))
 133                        return 0;
 134                usleep_range(250, 1000);
 135        } while (retries < 200);
 136
 137        dev_warn(dev, "phy link never came up\n");
 138
 139        return -ETIMEDOUT;
 140}
 141
 142static int qcom_pcie_get_resources_v0(struct qcom_pcie *pcie)
 143{
 144        struct qcom_pcie_resources_v0 *res = &pcie->res.v0;
 145        struct device *dev = pcie->dev;
 146
 147        res->vdda = devm_regulator_get(dev, "vdda");
 148        if (IS_ERR(res->vdda))
 149                return PTR_ERR(res->vdda);
 150
 151        res->vdda_phy = devm_regulator_get(dev, "vdda_phy");
 152        if (IS_ERR(res->vdda_phy))
 153                return PTR_ERR(res->vdda_phy);
 154
 155        res->vdda_refclk = devm_regulator_get(dev, "vdda_refclk");
 156        if (IS_ERR(res->vdda_refclk))
 157                return PTR_ERR(res->vdda_refclk);
 158
 159        res->iface_clk = devm_clk_get(dev, "iface");
 160        if (IS_ERR(res->iface_clk))
 161                return PTR_ERR(res->iface_clk);
 162
 163        res->core_clk = devm_clk_get(dev, "core");
 164        if (IS_ERR(res->core_clk))
 165                return PTR_ERR(res->core_clk);
 166
 167        res->phy_clk = devm_clk_get(dev, "phy");
 168        if (IS_ERR(res->phy_clk))
 169                return PTR_ERR(res->phy_clk);
 170
 171        res->pci_reset = devm_reset_control_get(dev, "pci");
 172        if (IS_ERR(res->pci_reset))
 173                return PTR_ERR(res->pci_reset);
 174
 175        res->axi_reset = devm_reset_control_get(dev, "axi");
 176        if (IS_ERR(res->axi_reset))
 177                return PTR_ERR(res->axi_reset);
 178
 179        res->ahb_reset = devm_reset_control_get(dev, "ahb");
 180        if (IS_ERR(res->ahb_reset))
 181                return PTR_ERR(res->ahb_reset);
 182
 183        res->por_reset = devm_reset_control_get(dev, "por");
 184        if (IS_ERR(res->por_reset))
 185                return PTR_ERR(res->por_reset);
 186
 187        res->phy_reset = devm_reset_control_get(dev, "phy");
 188        if (IS_ERR(res->phy_reset))
 189                return PTR_ERR(res->phy_reset);
 190
 191        return 0;
 192}
 193
 194static int qcom_pcie_get_resources_v1(struct qcom_pcie *pcie)
 195{
 196        struct qcom_pcie_resources_v1 *res = &pcie->res.v1;
 197        struct device *dev = pcie->dev;
 198
 199        res->vdda = devm_regulator_get(dev, "vdda");
 200        if (IS_ERR(res->vdda))
 201                return PTR_ERR(res->vdda);
 202
 203        res->iface = devm_clk_get(dev, "iface");
 204        if (IS_ERR(res->iface))
 205                return PTR_ERR(res->iface);
 206
 207        res->aux = devm_clk_get(dev, "aux");
 208        if (IS_ERR(res->aux))
 209                return PTR_ERR(res->aux);
 210
 211        res->master_bus = devm_clk_get(dev, "master_bus");
 212        if (IS_ERR(res->master_bus))
 213                return PTR_ERR(res->master_bus);
 214
 215        res->slave_bus = devm_clk_get(dev, "slave_bus");
 216        if (IS_ERR(res->slave_bus))
 217                return PTR_ERR(res->slave_bus);
 218
 219        res->core = devm_reset_control_get(dev, "core");
 220        if (IS_ERR(res->core))
 221                return PTR_ERR(res->core);
 222
 223        return 0;
 224}
 225
 226static void qcom_pcie_deinit_v0(struct qcom_pcie *pcie)
 227{
 228        struct qcom_pcie_resources_v0 *res = &pcie->res.v0;
 229
 230        reset_control_assert(res->pci_reset);
 231        reset_control_assert(res->axi_reset);
 232        reset_control_assert(res->ahb_reset);
 233        reset_control_assert(res->por_reset);
 234        reset_control_assert(res->pci_reset);
 235        clk_disable_unprepare(res->iface_clk);
 236        clk_disable_unprepare(res->core_clk);
 237        clk_disable_unprepare(res->phy_clk);
 238        regulator_disable(res->vdda);
 239        regulator_disable(res->vdda_phy);
 240        regulator_disable(res->vdda_refclk);
 241}
 242
 243static int qcom_pcie_init_v0(struct qcom_pcie *pcie)
 244{
 245        struct qcom_pcie_resources_v0 *res = &pcie->res.v0;
 246        struct device *dev = pcie->dev;
 247        u32 val;
 248        int ret;
 249
 250        ret = regulator_enable(res->vdda);
 251        if (ret) {
 252                dev_err(dev, "cannot enable vdda regulator\n");
 253                return ret;
 254        }
 255
 256        ret = regulator_enable(res->vdda_refclk);
 257        if (ret) {
 258                dev_err(dev, "cannot enable vdda_refclk regulator\n");
 259                goto err_refclk;
 260        }
 261
 262        ret = regulator_enable(res->vdda_phy);
 263        if (ret) {
 264                dev_err(dev, "cannot enable vdda_phy regulator\n");
 265                goto err_vdda_phy;
 266        }
 267
 268        ret = reset_control_assert(res->ahb_reset);
 269        if (ret) {
 270                dev_err(dev, "cannot assert ahb reset\n");
 271                goto err_assert_ahb;
 272        }
 273
 274        ret = clk_prepare_enable(res->iface_clk);
 275        if (ret) {
 276                dev_err(dev, "cannot prepare/enable iface clock\n");
 277                goto err_assert_ahb;
 278        }
 279
 280        ret = clk_prepare_enable(res->phy_clk);
 281        if (ret) {
 282                dev_err(dev, "cannot prepare/enable phy clock\n");
 283                goto err_clk_phy;
 284        }
 285
 286        ret = clk_prepare_enable(res->core_clk);
 287        if (ret) {
 288                dev_err(dev, "cannot prepare/enable core clock\n");
 289                goto err_clk_core;
 290        }
 291
 292        ret = reset_control_deassert(res->ahb_reset);
 293        if (ret) {
 294                dev_err(dev, "cannot deassert ahb reset\n");
 295                goto err_deassert_ahb;
 296        }
 297
 298        /* enable PCIe clocks and resets */
 299        val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
 300        val &= ~BIT(0);
 301        writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
 302
 303        /* enable external reference clock */
 304        val = readl(pcie->parf + PCIE20_PARF_PHY_REFCLK);
 305        val |= BIT(16);
 306        writel(val, pcie->parf + PCIE20_PARF_PHY_REFCLK);
 307
 308        ret = reset_control_deassert(res->phy_reset);
 309        if (ret) {
 310                dev_err(dev, "cannot deassert phy reset\n");
 311                return ret;
 312        }
 313
 314        ret = reset_control_deassert(res->pci_reset);
 315        if (ret) {
 316                dev_err(dev, "cannot deassert pci reset\n");
 317                return ret;
 318        }
 319
 320        ret = reset_control_deassert(res->por_reset);
 321        if (ret) {
 322                dev_err(dev, "cannot deassert por reset\n");
 323                return ret;
 324        }
 325
 326        ret = reset_control_deassert(res->axi_reset);
 327        if (ret) {
 328                dev_err(dev, "cannot deassert axi reset\n");
 329                return ret;
 330        }
 331
 332        /* wait for clock acquisition */
 333        usleep_range(1000, 1500);
 334
 335        return 0;
 336
 337err_deassert_ahb:
 338        clk_disable_unprepare(res->core_clk);
 339err_clk_core:
 340        clk_disable_unprepare(res->phy_clk);
 341err_clk_phy:
 342        clk_disable_unprepare(res->iface_clk);
 343err_assert_ahb:
 344        regulator_disable(res->vdda_phy);
 345err_vdda_phy:
 346        regulator_disable(res->vdda_refclk);
 347err_refclk:
 348        regulator_disable(res->vdda);
 349
 350        return ret;
 351}
 352
 353static void qcom_pcie_deinit_v1(struct qcom_pcie *pcie)
 354{
 355        struct qcom_pcie_resources_v1 *res = &pcie->res.v1;
 356
 357        reset_control_assert(res->core);
 358        clk_disable_unprepare(res->slave_bus);
 359        clk_disable_unprepare(res->master_bus);
 360        clk_disable_unprepare(res->iface);
 361        clk_disable_unprepare(res->aux);
 362        regulator_disable(res->vdda);
 363}
 364
 365static int qcom_pcie_init_v1(struct qcom_pcie *pcie)
 366{
 367        struct qcom_pcie_resources_v1 *res = &pcie->res.v1;
 368        struct device *dev = pcie->dev;
 369        int ret;
 370
 371        ret = reset_control_deassert(res->core);
 372        if (ret) {
 373                dev_err(dev, "cannot deassert core reset\n");
 374                return ret;
 375        }
 376
 377        ret = clk_prepare_enable(res->aux);
 378        if (ret) {
 379                dev_err(dev, "cannot prepare/enable aux clock\n");
 380                goto err_res;
 381        }
 382
 383        ret = clk_prepare_enable(res->iface);
 384        if (ret) {
 385                dev_err(dev, "cannot prepare/enable iface clock\n");
 386                goto err_aux;
 387        }
 388
 389        ret = clk_prepare_enable(res->master_bus);
 390        if (ret) {
 391                dev_err(dev, "cannot prepare/enable master_bus clock\n");
 392                goto err_iface;
 393        }
 394
 395        ret = clk_prepare_enable(res->slave_bus);
 396        if (ret) {
 397                dev_err(dev, "cannot prepare/enable slave_bus clock\n");
 398                goto err_master;
 399        }
 400
 401        ret = regulator_enable(res->vdda);
 402        if (ret) {
 403                dev_err(dev, "cannot enable vdda regulator\n");
 404                goto err_slave;
 405        }
 406
 407        /* change DBI base address */
 408        writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
 409
 410        if (IS_ENABLED(CONFIG_PCI_MSI)) {
 411                u32 val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT);
 412
 413                val |= BIT(31);
 414                writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT);
 415        }
 416
 417        return 0;
 418err_slave:
 419        clk_disable_unprepare(res->slave_bus);
 420err_master:
 421        clk_disable_unprepare(res->master_bus);
 422err_iface:
 423        clk_disable_unprepare(res->iface);
 424err_aux:
 425        clk_disable_unprepare(res->aux);
 426err_res:
 427        reset_control_assert(res->core);
 428
 429        return ret;
 430}
 431
 432static int qcom_pcie_link_up(struct pcie_port *pp)
 433{
 434        struct qcom_pcie *pcie = to_qcom_pcie(pp);
 435        u16 val = readw(pcie->dbi + PCIE20_CAP + PCI_EXP_LNKSTA);
 436
 437        return !!(val & PCI_EXP_LNKSTA_DLLLA);
 438}
 439
 440static void qcom_pcie_host_init(struct pcie_port *pp)
 441{
 442        struct qcom_pcie *pcie = to_qcom_pcie(pp);
 443        int ret;
 444
 445        qcom_ep_reset_assert(pcie);
 446
 447        ret = pcie->ops->init(pcie);
 448        if (ret)
 449                goto err_deinit;
 450
 451        ret = phy_power_on(pcie->phy);
 452        if (ret)
 453                goto err_deinit;
 454
 455        dw_pcie_setup_rc(pp);
 456
 457        if (IS_ENABLED(CONFIG_PCI_MSI))
 458                dw_pcie_msi_init(pp);
 459
 460        qcom_ep_reset_deassert(pcie);
 461
 462        ret = qcom_pcie_establish_link(pcie);
 463        if (ret)
 464                goto err;
 465
 466        return;
 467err:
 468        qcom_ep_reset_assert(pcie);
 469        phy_power_off(pcie->phy);
 470err_deinit:
 471        pcie->ops->deinit(pcie);
 472}
 473
 474static int qcom_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
 475                                 u32 *val)
 476{
 477        /* the device class is not reported correctly from the register */
 478        if (where == PCI_CLASS_REVISION && size == 4) {
 479                *val = readl(pp->dbi_base + PCI_CLASS_REVISION);
 480                *val &= 0xff;   /* keep revision id */
 481                *val |= PCI_CLASS_BRIDGE_PCI << 16;
 482                return PCIBIOS_SUCCESSFUL;
 483        }
 484
 485        return dw_pcie_cfg_read(pp->dbi_base + where, size, val);
 486}
 487
 488static struct pcie_host_ops qcom_pcie_dw_ops = {
 489        .link_up = qcom_pcie_link_up,
 490        .host_init = qcom_pcie_host_init,
 491        .rd_own_conf = qcom_pcie_rd_own_conf,
 492};
 493
 494static const struct qcom_pcie_ops ops_v0 = {
 495        .get_resources = qcom_pcie_get_resources_v0,
 496        .init = qcom_pcie_init_v0,
 497        .deinit = qcom_pcie_deinit_v0,
 498};
 499
 500static const struct qcom_pcie_ops ops_v1 = {
 501        .get_resources = qcom_pcie_get_resources_v1,
 502        .init = qcom_pcie_init_v1,
 503        .deinit = qcom_pcie_deinit_v1,
 504};
 505
 506static int qcom_pcie_probe(struct platform_device *pdev)
 507{
 508        struct device *dev = &pdev->dev;
 509        struct resource *res;
 510        struct qcom_pcie *pcie;
 511        struct pcie_port *pp;
 512        int ret;
 513
 514        pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
 515        if (!pcie)
 516                return -ENOMEM;
 517
 518        pcie->ops = (struct qcom_pcie_ops *)of_device_get_match_data(dev);
 519        pcie->dev = dev;
 520
 521        pcie->reset = devm_gpiod_get_optional(dev, "perst", GPIOD_OUT_LOW);
 522        if (IS_ERR(pcie->reset))
 523                return PTR_ERR(pcie->reset);
 524
 525        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "parf");
 526        pcie->parf = devm_ioremap_resource(dev, res);
 527        if (IS_ERR(pcie->parf))
 528                return PTR_ERR(pcie->parf);
 529
 530        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
 531        pcie->dbi = devm_ioremap_resource(dev, res);
 532        if (IS_ERR(pcie->dbi))
 533                return PTR_ERR(pcie->dbi);
 534
 535        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "elbi");
 536        pcie->elbi = devm_ioremap_resource(dev, res);
 537        if (IS_ERR(pcie->elbi))
 538                return PTR_ERR(pcie->elbi);
 539
 540        pcie->phy = devm_phy_optional_get(dev, "pciephy");
 541        if (IS_ERR(pcie->phy))
 542                return PTR_ERR(pcie->phy);
 543
 544        ret = pcie->ops->get_resources(pcie);
 545        if (ret)
 546                return ret;
 547
 548        pp = &pcie->pp;
 549        pp->dev = dev;
 550        pp->dbi_base = pcie->dbi;
 551        pp->root_bus_nr = -1;
 552        pp->ops = &qcom_pcie_dw_ops;
 553
 554        if (IS_ENABLED(CONFIG_PCI_MSI)) {
 555                pp->msi_irq = platform_get_irq_byname(pdev, "msi");
 556                if (pp->msi_irq < 0)
 557                        return pp->msi_irq;
 558
 559                ret = devm_request_irq(dev, pp->msi_irq,
 560                                       qcom_pcie_msi_irq_handler,
 561                                       IRQF_SHARED, "qcom-pcie-msi", pp);
 562                if (ret) {
 563                        dev_err(dev, "cannot request msi irq\n");
 564                        return ret;
 565                }
 566        }
 567
 568        ret = phy_init(pcie->phy);
 569        if (ret)
 570                return ret;
 571
 572        ret = dw_pcie_host_init(pp);
 573        if (ret) {
 574                dev_err(dev, "cannot initialize host\n");
 575                return ret;
 576        }
 577
 578        platform_set_drvdata(pdev, pcie);
 579
 580        return 0;
 581}
 582
 583static int qcom_pcie_remove(struct platform_device *pdev)
 584{
 585        struct qcom_pcie *pcie = platform_get_drvdata(pdev);
 586
 587        qcom_ep_reset_assert(pcie);
 588        phy_power_off(pcie->phy);
 589        phy_exit(pcie->phy);
 590        pcie->ops->deinit(pcie);
 591
 592        return 0;
 593}
 594
 595static const struct of_device_id qcom_pcie_match[] = {
 596        { .compatible = "qcom,pcie-ipq8064", .data = &ops_v0 },
 597        { .compatible = "qcom,pcie-apq8064", .data = &ops_v0 },
 598        { .compatible = "qcom,pcie-apq8084", .data = &ops_v1 },
 599        { }
 600};
 601MODULE_DEVICE_TABLE(of, qcom_pcie_match);
 602
 603static struct platform_driver qcom_pcie_driver = {
 604        .probe = qcom_pcie_probe,
 605        .remove = qcom_pcie_remove,
 606        .driver = {
 607                .name = "qcom-pcie",
 608                .of_match_table = qcom_pcie_match,
 609        },
 610};
 611
 612module_platform_driver(qcom_pcie_driver);
 613
 614MODULE_AUTHOR("Stanimir Varbanov <svarbanov@mm-sol.com>");
 615MODULE_DESCRIPTION("Qualcomm PCIe root complex driver");
 616MODULE_LICENSE("GPL v2");
 617