linux/drivers/pci/dwc/pcie-histb.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * PCIe host controller driver for HiSilicon STB SoCs
   4 *
   5 * Copyright (C) 2016-2017 HiSilicon Co., Ltd. http://www.hisilicon.com
   6 *
   7 * Authors: Ruqiang Ju <juruqiang@hisilicon.com>
   8 *          Jianguo Sun <sunjianguo1@huawei.com>
   9 */
  10
  11#include <linux/clk.h>
  12#include <linux/delay.h>
  13#include <linux/interrupt.h>
  14#include <linux/kernel.h>
  15#include <linux/module.h>
  16#include <linux/of.h>
  17#include <linux/of_gpio.h>
  18#include <linux/pci.h>
  19#include <linux/phy/phy.h>
  20#include <linux/platform_device.h>
  21#include <linux/resource.h>
  22#include <linux/reset.h>
  23
  24#include "pcie-designware.h"
  25
  26#define to_histb_pcie(x)        dev_get_drvdata((x)->dev)
  27
  28#define PCIE_SYS_CTRL0                  0x0000
  29#define PCIE_SYS_CTRL1                  0x0004
  30#define PCIE_SYS_CTRL7                  0x001C
  31#define PCIE_SYS_CTRL13                 0x0034
  32#define PCIE_SYS_CTRL15                 0x003C
  33#define PCIE_SYS_CTRL16                 0x0040
  34#define PCIE_SYS_CTRL17                 0x0044
  35
  36#define PCIE_SYS_STAT0                  0x0100
  37#define PCIE_SYS_STAT4                  0x0110
  38
  39#define PCIE_RDLH_LINK_UP               BIT(5)
  40#define PCIE_XMLH_LINK_UP               BIT(15)
  41#define PCIE_ELBI_SLV_DBI_ENABLE        BIT(21)
  42#define PCIE_APP_LTSSM_ENABLE           BIT(11)
  43
  44#define PCIE_DEVICE_TYPE_MASK           GENMASK(31, 28)
  45#define PCIE_WM_EP                      0
  46#define PCIE_WM_LEGACY                  BIT(1)
  47#define PCIE_WM_RC                      BIT(30)
  48
  49#define PCIE_LTSSM_STATE_MASK           GENMASK(5, 0)
  50#define PCIE_LTSSM_STATE_ACTIVE         0x11
  51
  52struct histb_pcie {
  53        struct dw_pcie *pci;
  54        struct clk *aux_clk;
  55        struct clk *pipe_clk;
  56        struct clk *sys_clk;
  57        struct clk *bus_clk;
  58        struct phy *phy;
  59        struct reset_control *soft_reset;
  60        struct reset_control *sys_reset;
  61        struct reset_control *bus_reset;
  62        void __iomem *ctrl;
  63        int reset_gpio;
  64};
  65
  66static u32 histb_pcie_readl(struct histb_pcie *histb_pcie, u32 reg)
  67{
  68        return readl(histb_pcie->ctrl + reg);
  69}
  70
  71static void histb_pcie_writel(struct histb_pcie *histb_pcie, u32 reg, u32 val)
  72{
  73        writel(val, histb_pcie->ctrl + reg);
  74}
  75
  76static void histb_pcie_dbi_w_mode(struct pcie_port *pp, bool enable)
  77{
  78        struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
  79        struct histb_pcie *hipcie = to_histb_pcie(pci);
  80        u32 val;
  81
  82        val = histb_pcie_readl(hipcie, PCIE_SYS_CTRL0);
  83        if (enable)
  84                val |= PCIE_ELBI_SLV_DBI_ENABLE;
  85        else
  86                val &= ~PCIE_ELBI_SLV_DBI_ENABLE;
  87        histb_pcie_writel(hipcie, PCIE_SYS_CTRL0, val);
  88}
  89
  90static void histb_pcie_dbi_r_mode(struct pcie_port *pp, bool enable)
  91{
  92        struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
  93        struct histb_pcie *hipcie = to_histb_pcie(pci);
  94        u32 val;
  95
  96        val = histb_pcie_readl(hipcie, PCIE_SYS_CTRL1);
  97        if (enable)
  98                val |= PCIE_ELBI_SLV_DBI_ENABLE;
  99        else
 100                val &= ~PCIE_ELBI_SLV_DBI_ENABLE;
 101        histb_pcie_writel(hipcie, PCIE_SYS_CTRL1, val);
 102}
 103
 104static u32 histb_pcie_read_dbi(struct dw_pcie *pci, void __iomem *base,
 105                               u32 reg, size_t size)
 106{
 107        u32 val;
 108
 109        histb_pcie_dbi_r_mode(&pci->pp, true);
 110        dw_pcie_read(base + reg, size, &val);
 111        histb_pcie_dbi_r_mode(&pci->pp, false);
 112
 113        return val;
 114}
 115
 116static void histb_pcie_write_dbi(struct dw_pcie *pci, void __iomem *base,
 117                                 u32 reg, size_t size, u32 val)
 118{
 119        histb_pcie_dbi_w_mode(&pci->pp, true);
 120        dw_pcie_write(base + reg, size, val);
 121        histb_pcie_dbi_w_mode(&pci->pp, false);
 122}
 123
 124static int histb_pcie_rd_own_conf(struct pcie_port *pp, int where,
 125                                  int size, u32 *val)
 126{
 127        struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
 128        int ret;
 129
 130        histb_pcie_dbi_r_mode(pp, true);
 131        ret = dw_pcie_read(pci->dbi_base + where, size, val);
 132        histb_pcie_dbi_r_mode(pp, false);
 133
 134        return ret;
 135}
 136
 137static int histb_pcie_wr_own_conf(struct pcie_port *pp, int where,
 138                                  int size, u32 val)
 139{
 140        struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
 141        int ret;
 142
 143        histb_pcie_dbi_w_mode(pp, true);
 144        ret = dw_pcie_write(pci->dbi_base + where, size, val);
 145        histb_pcie_dbi_w_mode(pp, false);
 146
 147        return ret;
 148}
 149
 150static int histb_pcie_link_up(struct dw_pcie *pci)
 151{
 152        struct histb_pcie *hipcie = to_histb_pcie(pci);
 153        u32 regval;
 154        u32 status;
 155
 156        regval = histb_pcie_readl(hipcie, PCIE_SYS_STAT0);
 157        status = histb_pcie_readl(hipcie, PCIE_SYS_STAT4);
 158        status &= PCIE_LTSSM_STATE_MASK;
 159        if ((regval & PCIE_XMLH_LINK_UP) && (regval & PCIE_RDLH_LINK_UP) &&
 160            (status == PCIE_LTSSM_STATE_ACTIVE))
 161                return 1;
 162
 163        return 0;
 164}
 165
 166static int histb_pcie_establish_link(struct pcie_port *pp)
 167{
 168        struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
 169        struct histb_pcie *hipcie = to_histb_pcie(pci);
 170        u32 regval;
 171
 172        if (dw_pcie_link_up(pci)) {
 173                dev_info(pci->dev, "Link already up\n");
 174                return 0;
 175        }
 176
 177        /* PCIe RC work mode */
 178        regval = histb_pcie_readl(hipcie, PCIE_SYS_CTRL0);
 179        regval &= ~PCIE_DEVICE_TYPE_MASK;
 180        regval |= PCIE_WM_RC;
 181        histb_pcie_writel(hipcie, PCIE_SYS_CTRL0, regval);
 182
 183        /* setup root complex */
 184        dw_pcie_setup_rc(pp);
 185
 186        /* assert LTSSM enable */
 187        regval = histb_pcie_readl(hipcie, PCIE_SYS_CTRL7);
 188        regval |= PCIE_APP_LTSSM_ENABLE;
 189        histb_pcie_writel(hipcie, PCIE_SYS_CTRL7, regval);
 190
 191        return dw_pcie_wait_for_link(pci);
 192}
 193
 194static int histb_pcie_host_init(struct pcie_port *pp)
 195{
 196        histb_pcie_establish_link(pp);
 197
 198        if (IS_ENABLED(CONFIG_PCI_MSI))
 199                dw_pcie_msi_init(pp);
 200
 201        return 0;
 202}
 203
 204static struct dw_pcie_host_ops histb_pcie_host_ops = {
 205        .rd_own_conf = histb_pcie_rd_own_conf,
 206        .wr_own_conf = histb_pcie_wr_own_conf,
 207        .host_init = histb_pcie_host_init,
 208};
 209
 210static irqreturn_t histb_pcie_msi_irq_handler(int irq, void *arg)
 211{
 212        struct pcie_port *pp = arg;
 213
 214        return dw_handle_msi_irq(pp);
 215}
 216
 217static void histb_pcie_host_disable(struct histb_pcie *hipcie)
 218{
 219        reset_control_assert(hipcie->soft_reset);
 220        reset_control_assert(hipcie->sys_reset);
 221        reset_control_assert(hipcie->bus_reset);
 222
 223        clk_disable_unprepare(hipcie->aux_clk);
 224        clk_disable_unprepare(hipcie->pipe_clk);
 225        clk_disable_unprepare(hipcie->sys_clk);
 226        clk_disable_unprepare(hipcie->bus_clk);
 227
 228        if (gpio_is_valid(hipcie->reset_gpio))
 229                gpio_set_value_cansleep(hipcie->reset_gpio, 0);
 230}
 231
 232static int histb_pcie_host_enable(struct pcie_port *pp)
 233{
 234        struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
 235        struct histb_pcie *hipcie = to_histb_pcie(pci);
 236        struct device *dev = pci->dev;
 237        int ret;
 238
 239        /* power on PCIe device if have */
 240        if (gpio_is_valid(hipcie->reset_gpio))
 241                gpio_set_value_cansleep(hipcie->reset_gpio, 1);
 242
 243        ret = clk_prepare_enable(hipcie->bus_clk);
 244        if (ret) {
 245                dev_err(dev, "cannot prepare/enable bus clk\n");
 246                goto err_bus_clk;
 247        }
 248
 249        ret = clk_prepare_enable(hipcie->sys_clk);
 250        if (ret) {
 251                dev_err(dev, "cannot prepare/enable sys clk\n");
 252                goto err_sys_clk;
 253        }
 254
 255        ret = clk_prepare_enable(hipcie->pipe_clk);
 256        if (ret) {
 257                dev_err(dev, "cannot prepare/enable pipe clk\n");
 258                goto err_pipe_clk;
 259        }
 260
 261        ret = clk_prepare_enable(hipcie->aux_clk);
 262        if (ret) {
 263                dev_err(dev, "cannot prepare/enable aux clk\n");
 264                goto err_aux_clk;
 265        }
 266
 267        reset_control_assert(hipcie->soft_reset);
 268        reset_control_deassert(hipcie->soft_reset);
 269
 270        reset_control_assert(hipcie->sys_reset);
 271        reset_control_deassert(hipcie->sys_reset);
 272
 273        reset_control_assert(hipcie->bus_reset);
 274        reset_control_deassert(hipcie->bus_reset);
 275
 276        return 0;
 277
 278err_aux_clk:
 279        clk_disable_unprepare(hipcie->aux_clk);
 280err_pipe_clk:
 281        clk_disable_unprepare(hipcie->pipe_clk);
 282err_sys_clk:
 283        clk_disable_unprepare(hipcie->sys_clk);
 284err_bus_clk:
 285        clk_disable_unprepare(hipcie->bus_clk);
 286
 287        return ret;
 288}
 289
 290static const struct dw_pcie_ops dw_pcie_ops = {
 291        .read_dbi = histb_pcie_read_dbi,
 292        .write_dbi = histb_pcie_write_dbi,
 293        .link_up = histb_pcie_link_up,
 294};
 295
 296static int histb_pcie_probe(struct platform_device *pdev)
 297{
 298        struct histb_pcie *hipcie;
 299        struct dw_pcie *pci;
 300        struct pcie_port *pp;
 301        struct resource *res;
 302        struct device_node *np = pdev->dev.of_node;
 303        struct device *dev = &pdev->dev;
 304        enum of_gpio_flags of_flags;
 305        unsigned long flag = GPIOF_DIR_OUT;
 306        int ret;
 307
 308        hipcie = devm_kzalloc(dev, sizeof(*hipcie), GFP_KERNEL);
 309        if (!hipcie)
 310                return -ENOMEM;
 311
 312        pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
 313        if (!pci)
 314                return -ENOMEM;
 315
 316        hipcie->pci = pci;
 317        pp = &pci->pp;
 318        pci->dev = dev;
 319        pci->ops = &dw_pcie_ops;
 320
 321        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "control");
 322        hipcie->ctrl = devm_ioremap_resource(dev, res);
 323        if (IS_ERR(hipcie->ctrl)) {
 324                dev_err(dev, "cannot get control reg base\n");
 325                return PTR_ERR(hipcie->ctrl);
 326        }
 327
 328        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc-dbi");
 329        pci->dbi_base = devm_ioremap_resource(dev, res);
 330        if (IS_ERR(pci->dbi_base)) {
 331                dev_err(dev, "cannot get rc-dbi base\n");
 332                return PTR_ERR(pci->dbi_base);
 333        }
 334
 335        hipcie->reset_gpio = of_get_named_gpio_flags(np,
 336                                "reset-gpios", 0, &of_flags);
 337        if (of_flags & OF_GPIO_ACTIVE_LOW)
 338                flag |= GPIOF_ACTIVE_LOW;
 339        if (gpio_is_valid(hipcie->reset_gpio)) {
 340                ret = devm_gpio_request_one(dev, hipcie->reset_gpio,
 341                                flag, "PCIe device power control");
 342                if (ret) {
 343                        dev_err(dev, "unable to request gpio\n");
 344                        return ret;
 345                }
 346        }
 347
 348        hipcie->aux_clk = devm_clk_get(dev, "aux");
 349        if (IS_ERR(hipcie->aux_clk)) {
 350                dev_err(dev, "Failed to get PCIe aux clk\n");
 351                return PTR_ERR(hipcie->aux_clk);
 352        }
 353
 354        hipcie->pipe_clk = devm_clk_get(dev, "pipe");
 355        if (IS_ERR(hipcie->pipe_clk)) {
 356                dev_err(dev, "Failed to get PCIe pipe clk\n");
 357                return PTR_ERR(hipcie->pipe_clk);
 358        }
 359
 360        hipcie->sys_clk = devm_clk_get(dev, "sys");
 361        if (IS_ERR(hipcie->sys_clk)) {
 362                dev_err(dev, "Failed to get PCIEe sys clk\n");
 363                return PTR_ERR(hipcie->sys_clk);
 364        }
 365
 366        hipcie->bus_clk = devm_clk_get(dev, "bus");
 367        if (IS_ERR(hipcie->bus_clk)) {
 368                dev_err(dev, "Failed to get PCIe bus clk\n");
 369                return PTR_ERR(hipcie->bus_clk);
 370        }
 371
 372        hipcie->soft_reset = devm_reset_control_get(dev, "soft");
 373        if (IS_ERR(hipcie->soft_reset)) {
 374                dev_err(dev, "couldn't get soft reset\n");
 375                return PTR_ERR(hipcie->soft_reset);
 376        }
 377
 378        hipcie->sys_reset = devm_reset_control_get(dev, "sys");
 379        if (IS_ERR(hipcie->sys_reset)) {
 380                dev_err(dev, "couldn't get sys reset\n");
 381                return PTR_ERR(hipcie->sys_reset);
 382        }
 383
 384        hipcie->bus_reset = devm_reset_control_get(dev, "bus");
 385        if (IS_ERR(hipcie->bus_reset)) {
 386                dev_err(dev, "couldn't get bus reset\n");
 387                return PTR_ERR(hipcie->bus_reset);
 388        }
 389
 390        if (IS_ENABLED(CONFIG_PCI_MSI)) {
 391                pp->msi_irq = platform_get_irq_byname(pdev, "msi");
 392                if (pp->msi_irq < 0) {
 393                        dev_err(dev, "Failed to get MSI IRQ\n");
 394                        return pp->msi_irq;
 395                }
 396
 397                ret = devm_request_irq(dev, pp->msi_irq,
 398                                       histb_pcie_msi_irq_handler,
 399                                       IRQF_SHARED, "histb-pcie-msi", pp);
 400                if (ret) {
 401                        dev_err(dev, "cannot request MSI IRQ\n");
 402                        return ret;
 403                }
 404        }
 405
 406        hipcie->phy = devm_phy_get(dev, "phy");
 407        if (IS_ERR(hipcie->phy)) {
 408                dev_info(dev, "no pcie-phy found\n");
 409                hipcie->phy = NULL;
 410                /* fall through here!
 411                 * if no pcie-phy found, phy init
 412                 * should be done under boot!
 413                 */
 414        } else {
 415                phy_init(hipcie->phy);
 416        }
 417
 418        pp->root_bus_nr = -1;
 419        pp->ops = &histb_pcie_host_ops;
 420
 421        platform_set_drvdata(pdev, hipcie);
 422
 423        ret = histb_pcie_host_enable(pp);
 424        if (ret) {
 425                dev_err(dev, "failed to enable host\n");
 426                return ret;
 427        }
 428
 429        ret = dw_pcie_host_init(pp);
 430        if (ret) {
 431                dev_err(dev, "failed to initialize host\n");
 432                return ret;
 433        }
 434
 435        return 0;
 436}
 437
 438static int histb_pcie_remove(struct platform_device *pdev)
 439{
 440        struct histb_pcie *hipcie = platform_get_drvdata(pdev);
 441
 442        histb_pcie_host_disable(hipcie);
 443
 444        if (hipcie->phy)
 445                phy_exit(hipcie->phy);
 446
 447        return 0;
 448}
 449
 450static const struct of_device_id histb_pcie_of_match[] = {
 451        { .compatible = "hisilicon,hi3798cv200-pcie", },
 452        {},
 453};
 454MODULE_DEVICE_TABLE(of, histb_pcie_of_match);
 455
 456static struct platform_driver histb_pcie_platform_driver = {
 457        .probe  = histb_pcie_probe,
 458        .remove = histb_pcie_remove,
 459        .driver = {
 460                .name = "histb-pcie",
 461                .of_match_table = histb_pcie_of_match,
 462        },
 463};
 464module_platform_driver(histb_pcie_platform_driver);
 465
 466MODULE_DESCRIPTION("HiSilicon STB PCIe host controller driver");
 467MODULE_LICENSE("GPL v2");
 468