16e0832faSShawn Lin // SPDX-License-Identifier: GPL-2.0
26e0832faSShawn Lin /*
36e0832faSShawn Lin * PCIe host controller driver for HiSilicon STB SoCs
46e0832faSShawn Lin *
56e0832faSShawn Lin * Copyright (C) 2016-2017 HiSilicon Co., Ltd. http://www.hisilicon.com
66e0832faSShawn Lin *
76e0832faSShawn Lin * Authors: Ruqiang Ju <juruqiang@hisilicon.com>
86e0832faSShawn Lin * Jianguo Sun <sunjianguo1@huawei.com>
96e0832faSShawn Lin */
106e0832faSShawn Lin
116e0832faSShawn Lin #include <linux/clk.h>
126e0832faSShawn Lin #include <linux/delay.h>
131d26a55fSDmitry Torokhov #include <linux/gpio/consumer.h>
146e0832faSShawn Lin #include <linux/interrupt.h>
156e0832faSShawn Lin #include <linux/kernel.h>
166e0832faSShawn Lin #include <linux/module.h>
176e0832faSShawn Lin #include <linux/of.h>
186e0832faSShawn Lin #include <linux/pci.h>
196e0832faSShawn Lin #include <linux/phy/phy.h>
206e0832faSShawn Lin #include <linux/platform_device.h>
216e0832faSShawn Lin #include <linux/resource.h>
226e0832faSShawn Lin #include <linux/reset.h>
236e0832faSShawn Lin
246e0832faSShawn Lin #include "pcie-designware.h"
256e0832faSShawn Lin
266e0832faSShawn Lin #define to_histb_pcie(x) dev_get_drvdata((x)->dev)
276e0832faSShawn Lin
286e0832faSShawn Lin #define PCIE_SYS_CTRL0 0x0000
296e0832faSShawn Lin #define PCIE_SYS_CTRL1 0x0004
306e0832faSShawn Lin #define PCIE_SYS_CTRL7 0x001C
316e0832faSShawn Lin #define PCIE_SYS_CTRL13 0x0034
326e0832faSShawn Lin #define PCIE_SYS_CTRL15 0x003C
336e0832faSShawn Lin #define PCIE_SYS_CTRL16 0x0040
346e0832faSShawn Lin #define PCIE_SYS_CTRL17 0x0044
356e0832faSShawn Lin
366e0832faSShawn Lin #define PCIE_SYS_STAT0 0x0100
376e0832faSShawn Lin #define PCIE_SYS_STAT4 0x0110
386e0832faSShawn Lin
396e0832faSShawn Lin #define PCIE_RDLH_LINK_UP BIT(5)
406e0832faSShawn Lin #define PCIE_XMLH_LINK_UP BIT(15)
416e0832faSShawn Lin #define PCIE_ELBI_SLV_DBI_ENABLE BIT(21)
426e0832faSShawn Lin #define PCIE_APP_LTSSM_ENABLE BIT(11)
436e0832faSShawn Lin
446e0832faSShawn Lin #define PCIE_DEVICE_TYPE_MASK GENMASK(31, 28)
456e0832faSShawn Lin #define PCIE_WM_EP 0
466e0832faSShawn Lin #define PCIE_WM_LEGACY BIT(1)
476e0832faSShawn Lin #define PCIE_WM_RC BIT(30)
486e0832faSShawn Lin
496e0832faSShawn Lin #define PCIE_LTSSM_STATE_MASK GENMASK(5, 0)
506e0832faSShawn Lin #define PCIE_LTSSM_STATE_ACTIVE 0x11
516e0832faSShawn Lin
526e0832faSShawn Lin struct histb_pcie {
536e0832faSShawn Lin struct dw_pcie *pci;
546e0832faSShawn Lin struct clk *aux_clk;
556e0832faSShawn Lin struct clk *pipe_clk;
566e0832faSShawn Lin struct clk *sys_clk;
576e0832faSShawn Lin struct clk *bus_clk;
586e0832faSShawn Lin struct phy *phy;
596e0832faSShawn Lin struct reset_control *soft_reset;
606e0832faSShawn Lin struct reset_control *sys_reset;
616e0832faSShawn Lin struct reset_control *bus_reset;
626e0832faSShawn Lin void __iomem *ctrl;
631d26a55fSDmitry Torokhov struct gpio_desc *reset_gpio;
646e0832faSShawn Lin struct regulator *vpcie;
656e0832faSShawn Lin };
666e0832faSShawn Lin
histb_pcie_readl(struct histb_pcie * histb_pcie,u32 reg)676e0832faSShawn Lin static u32 histb_pcie_readl(struct histb_pcie *histb_pcie, u32 reg)
686e0832faSShawn Lin {
696e0832faSShawn Lin return readl(histb_pcie->ctrl + reg);
706e0832faSShawn Lin }
716e0832faSShawn Lin
histb_pcie_writel(struct histb_pcie * histb_pcie,u32 reg,u32 val)726e0832faSShawn Lin static void histb_pcie_writel(struct histb_pcie *histb_pcie, u32 reg, u32 val)
736e0832faSShawn Lin {
746e0832faSShawn Lin writel(val, histb_pcie->ctrl + reg);
756e0832faSShawn Lin }
766e0832faSShawn Lin
histb_pcie_dbi_w_mode(struct dw_pcie_rp * pp,bool enable)7760b3c27fSSerge Semin static void histb_pcie_dbi_w_mode(struct dw_pcie_rp *pp, bool enable)
786e0832faSShawn Lin {
796e0832faSShawn Lin struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
806e0832faSShawn Lin struct histb_pcie *hipcie = to_histb_pcie(pci);
816e0832faSShawn Lin u32 val;
826e0832faSShawn Lin
836e0832faSShawn Lin val = histb_pcie_readl(hipcie, PCIE_SYS_CTRL0);
846e0832faSShawn Lin if (enable)
856e0832faSShawn Lin val |= PCIE_ELBI_SLV_DBI_ENABLE;
866e0832faSShawn Lin else
876e0832faSShawn Lin val &= ~PCIE_ELBI_SLV_DBI_ENABLE;
886e0832faSShawn Lin histb_pcie_writel(hipcie, PCIE_SYS_CTRL0, val);
896e0832faSShawn Lin }
906e0832faSShawn Lin
histb_pcie_dbi_r_mode(struct dw_pcie_rp * pp,bool enable)9160b3c27fSSerge Semin static void histb_pcie_dbi_r_mode(struct dw_pcie_rp *pp, bool enable)
926e0832faSShawn Lin {
936e0832faSShawn Lin struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
946e0832faSShawn Lin struct histb_pcie *hipcie = to_histb_pcie(pci);
956e0832faSShawn Lin u32 val;
966e0832faSShawn Lin
976e0832faSShawn Lin val = histb_pcie_readl(hipcie, PCIE_SYS_CTRL1);
986e0832faSShawn Lin if (enable)
996e0832faSShawn Lin val |= PCIE_ELBI_SLV_DBI_ENABLE;
1006e0832faSShawn Lin else
1016e0832faSShawn Lin val &= ~PCIE_ELBI_SLV_DBI_ENABLE;
1026e0832faSShawn Lin histb_pcie_writel(hipcie, PCIE_SYS_CTRL1, val);
1036e0832faSShawn Lin }
1046e0832faSShawn Lin
histb_pcie_read_dbi(struct dw_pcie * pci,void __iomem * base,u32 reg,size_t size)1056e0832faSShawn Lin static u32 histb_pcie_read_dbi(struct dw_pcie *pci, void __iomem *base,
1066e0832faSShawn Lin u32 reg, size_t size)
1076e0832faSShawn Lin {
1086e0832faSShawn Lin u32 val;
1096e0832faSShawn Lin
1106e0832faSShawn Lin histb_pcie_dbi_r_mode(&pci->pp, true);
1116e0832faSShawn Lin dw_pcie_read(base + reg, size, &val);
1126e0832faSShawn Lin histb_pcie_dbi_r_mode(&pci->pp, false);
1136e0832faSShawn Lin
1146e0832faSShawn Lin return val;
1156e0832faSShawn Lin }
1166e0832faSShawn Lin
histb_pcie_write_dbi(struct dw_pcie * pci,void __iomem * base,u32 reg,size_t size,u32 val)1176e0832faSShawn Lin static void histb_pcie_write_dbi(struct dw_pcie *pci, void __iomem *base,
1186e0832faSShawn Lin u32 reg, size_t size, u32 val)
1196e0832faSShawn Lin {
1206e0832faSShawn Lin histb_pcie_dbi_w_mode(&pci->pp, true);
1216e0832faSShawn Lin dw_pcie_write(base + reg, size, val);
1226e0832faSShawn Lin histb_pcie_dbi_w_mode(&pci->pp, false);
1236e0832faSShawn Lin }
1246e0832faSShawn Lin
histb_pcie_rd_own_conf(struct pci_bus * bus,unsigned int devfn,int where,int size,u32 * val)125c4a42ee9SRob Herring static int histb_pcie_rd_own_conf(struct pci_bus *bus, unsigned int devfn,
126c4a42ee9SRob Herring int where, int size, u32 *val)
1276e0832faSShawn Lin {
128c4a42ee9SRob Herring struct dw_pcie *pci = to_dw_pcie_from_pp(bus->sysdata);
1296e0832faSShawn Lin
130f4a44c1eSNaveen Naidu if (PCI_SLOT(devfn))
131c4a42ee9SRob Herring return PCIBIOS_DEVICE_NOT_FOUND;
1326e0832faSShawn Lin
133c4a42ee9SRob Herring *val = dw_pcie_read_dbi(pci, where, size);
134c4a42ee9SRob Herring return PCIBIOS_SUCCESSFUL;
1356e0832faSShawn Lin }
1366e0832faSShawn Lin
histb_pcie_wr_own_conf(struct pci_bus * bus,unsigned int devfn,int where,int size,u32 val)137c4a42ee9SRob Herring static int histb_pcie_wr_own_conf(struct pci_bus *bus, unsigned int devfn,
138c4a42ee9SRob Herring int where, int size, u32 val)
139c4a42ee9SRob Herring {
140c4a42ee9SRob Herring struct dw_pcie *pci = to_dw_pcie_from_pp(bus->sysdata);
141c4a42ee9SRob Herring
142c4a42ee9SRob Herring if (PCI_SLOT(devfn))
143c4a42ee9SRob Herring return PCIBIOS_DEVICE_NOT_FOUND;
144c4a42ee9SRob Herring
145c4a42ee9SRob Herring dw_pcie_write_dbi(pci, where, size, val);
146c4a42ee9SRob Herring return PCIBIOS_SUCCESSFUL;
147c4a42ee9SRob Herring }
148c4a42ee9SRob Herring
149c4a42ee9SRob Herring static struct pci_ops histb_pci_ops = {
150c4a42ee9SRob Herring .read = histb_pcie_rd_own_conf,
151c4a42ee9SRob Herring .write = histb_pcie_wr_own_conf,
152c4a42ee9SRob Herring };
153c4a42ee9SRob Herring
histb_pcie_link_up(struct dw_pcie * pci)1546e0832faSShawn Lin static int histb_pcie_link_up(struct dw_pcie *pci)
1556e0832faSShawn Lin {
1566e0832faSShawn Lin struct histb_pcie *hipcie = to_histb_pcie(pci);
1576e0832faSShawn Lin u32 regval;
1586e0832faSShawn Lin u32 status;
1596e0832faSShawn Lin
1606e0832faSShawn Lin regval = histb_pcie_readl(hipcie, PCIE_SYS_STAT0);
1616e0832faSShawn Lin status = histb_pcie_readl(hipcie, PCIE_SYS_STAT4);
1626e0832faSShawn Lin status &= PCIE_LTSSM_STATE_MASK;
1636e0832faSShawn Lin if ((regval & PCIE_XMLH_LINK_UP) && (regval & PCIE_RDLH_LINK_UP) &&
1646e0832faSShawn Lin (status == PCIE_LTSSM_STATE_ACTIVE))
1656e0832faSShawn Lin return 1;
1666e0832faSShawn Lin
1676e0832faSShawn Lin return 0;
1686e0832faSShawn Lin }
1696e0832faSShawn Lin
histb_pcie_start_link(struct dw_pcie * pci)170886a9c13SRob Herring static int histb_pcie_start_link(struct dw_pcie *pci)
171886a9c13SRob Herring {
172886a9c13SRob Herring struct histb_pcie *hipcie = to_histb_pcie(pci);
173886a9c13SRob Herring u32 regval;
174886a9c13SRob Herring
175886a9c13SRob Herring /* assert LTSSM enable */
176886a9c13SRob Herring regval = histb_pcie_readl(hipcie, PCIE_SYS_CTRL7);
177886a9c13SRob Herring regval |= PCIE_APP_LTSSM_ENABLE;
178886a9c13SRob Herring histb_pcie_writel(hipcie, PCIE_SYS_CTRL7, regval);
179886a9c13SRob Herring
180886a9c13SRob Herring return 0;
181886a9c13SRob Herring }
182886a9c13SRob Herring
histb_pcie_host_init(struct dw_pcie_rp * pp)18360b3c27fSSerge Semin static int histb_pcie_host_init(struct dw_pcie_rp *pp)
1846e0832faSShawn Lin {
1856e0832faSShawn Lin struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
1866e0832faSShawn Lin struct histb_pcie *hipcie = to_histb_pcie(pci);
1876e0832faSShawn Lin u32 regval;
1886e0832faSShawn Lin
189886a9c13SRob Herring pp->bridge->ops = &histb_pci_ops;
1906e0832faSShawn Lin
1916e0832faSShawn Lin /* PCIe RC work mode */
1926e0832faSShawn Lin regval = histb_pcie_readl(hipcie, PCIE_SYS_CTRL0);
1936e0832faSShawn Lin regval &= ~PCIE_DEVICE_TYPE_MASK;
1946e0832faSShawn Lin regval |= PCIE_WM_RC;
1956e0832faSShawn Lin histb_pcie_writel(hipcie, PCIE_SYS_CTRL0, regval);
1966e0832faSShawn Lin
1976e0832faSShawn Lin return 0;
1986e0832faSShawn Lin }
1996e0832faSShawn Lin
200b69f4abcSJulia Lawall static const struct dw_pcie_host_ops histb_pcie_host_ops = {
201*aea370b2SYoshihiro Shimoda .init = histb_pcie_host_init,
2026e0832faSShawn Lin };
2036e0832faSShawn Lin
histb_pcie_host_disable(struct histb_pcie * hipcie)2046e0832faSShawn Lin static void histb_pcie_host_disable(struct histb_pcie *hipcie)
2056e0832faSShawn Lin {
2066e0832faSShawn Lin reset_control_assert(hipcie->soft_reset);
2076e0832faSShawn Lin reset_control_assert(hipcie->sys_reset);
2086e0832faSShawn Lin reset_control_assert(hipcie->bus_reset);
2096e0832faSShawn Lin
2106e0832faSShawn Lin clk_disable_unprepare(hipcie->aux_clk);
2116e0832faSShawn Lin clk_disable_unprepare(hipcie->pipe_clk);
2126e0832faSShawn Lin clk_disable_unprepare(hipcie->sys_clk);
2136e0832faSShawn Lin clk_disable_unprepare(hipcie->bus_clk);
2146e0832faSShawn Lin
2151d26a55fSDmitry Torokhov if (hipcie->reset_gpio)
2161d26a55fSDmitry Torokhov gpiod_set_value_cansleep(hipcie->reset_gpio, 1);
2176e0832faSShawn Lin
2186e0832faSShawn Lin if (hipcie->vpcie)
2196e0832faSShawn Lin regulator_disable(hipcie->vpcie);
2206e0832faSShawn Lin }
2216e0832faSShawn Lin
histb_pcie_host_enable(struct dw_pcie_rp * pp)22260b3c27fSSerge Semin static int histb_pcie_host_enable(struct dw_pcie_rp *pp)
2236e0832faSShawn Lin {
2246e0832faSShawn Lin struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
2256e0832faSShawn Lin struct histb_pcie *hipcie = to_histb_pcie(pci);
2266e0832faSShawn Lin struct device *dev = pci->dev;
2276e0832faSShawn Lin int ret;
2286e0832faSShawn Lin
2296e0832faSShawn Lin /* power on PCIe device if have */
2306e0832faSShawn Lin if (hipcie->vpcie) {
2316e0832faSShawn Lin ret = regulator_enable(hipcie->vpcie);
2326e0832faSShawn Lin if (ret) {
2336e0832faSShawn Lin dev_err(dev, "failed to enable regulator: %d\n", ret);
2346e0832faSShawn Lin return ret;
2356e0832faSShawn Lin }
2366e0832faSShawn Lin }
2376e0832faSShawn Lin
2381d26a55fSDmitry Torokhov if (hipcie->reset_gpio)
2391d26a55fSDmitry Torokhov gpiod_set_value_cansleep(hipcie->reset_gpio, 0);
2406e0832faSShawn Lin
2416e0832faSShawn Lin ret = clk_prepare_enable(hipcie->bus_clk);
2426e0832faSShawn Lin if (ret) {
2436e0832faSShawn Lin dev_err(dev, "cannot prepare/enable bus clk\n");
2446e0832faSShawn Lin goto err_bus_clk;
2456e0832faSShawn Lin }
2466e0832faSShawn Lin
2476e0832faSShawn Lin ret = clk_prepare_enable(hipcie->sys_clk);
2486e0832faSShawn Lin if (ret) {
2496e0832faSShawn Lin dev_err(dev, "cannot prepare/enable sys clk\n");
2506e0832faSShawn Lin goto err_sys_clk;
2516e0832faSShawn Lin }
2526e0832faSShawn Lin
2536e0832faSShawn Lin ret = clk_prepare_enable(hipcie->pipe_clk);
2546e0832faSShawn Lin if (ret) {
2556e0832faSShawn Lin dev_err(dev, "cannot prepare/enable pipe clk\n");
2566e0832faSShawn Lin goto err_pipe_clk;
2576e0832faSShawn Lin }
2586e0832faSShawn Lin
2596e0832faSShawn Lin ret = clk_prepare_enable(hipcie->aux_clk);
2606e0832faSShawn Lin if (ret) {
2616e0832faSShawn Lin dev_err(dev, "cannot prepare/enable aux clk\n");
2626e0832faSShawn Lin goto err_aux_clk;
2636e0832faSShawn Lin }
2646e0832faSShawn Lin
2656e0832faSShawn Lin reset_control_assert(hipcie->soft_reset);
2666e0832faSShawn Lin reset_control_deassert(hipcie->soft_reset);
2676e0832faSShawn Lin
2686e0832faSShawn Lin reset_control_assert(hipcie->sys_reset);
2696e0832faSShawn Lin reset_control_deassert(hipcie->sys_reset);
2706e0832faSShawn Lin
2716e0832faSShawn Lin reset_control_assert(hipcie->bus_reset);
2726e0832faSShawn Lin reset_control_deassert(hipcie->bus_reset);
2736e0832faSShawn Lin
2746e0832faSShawn Lin return 0;
2756e0832faSShawn Lin
2766e0832faSShawn Lin err_aux_clk:
2776e0832faSShawn Lin clk_disable_unprepare(hipcie->pipe_clk);
2786e0832faSShawn Lin err_pipe_clk:
2796e0832faSShawn Lin clk_disable_unprepare(hipcie->sys_clk);
2806e0832faSShawn Lin err_sys_clk:
2816e0832faSShawn Lin clk_disable_unprepare(hipcie->bus_clk);
2826e0832faSShawn Lin err_bus_clk:
2836e0832faSShawn Lin if (hipcie->vpcie)
2846e0832faSShawn Lin regulator_disable(hipcie->vpcie);
2856e0832faSShawn Lin
2866e0832faSShawn Lin return ret;
2876e0832faSShawn Lin }
2886e0832faSShawn Lin
2896e0832faSShawn Lin static const struct dw_pcie_ops dw_pcie_ops = {
2906e0832faSShawn Lin .read_dbi = histb_pcie_read_dbi,
2916e0832faSShawn Lin .write_dbi = histb_pcie_write_dbi,
2926e0832faSShawn Lin .link_up = histb_pcie_link_up,
293886a9c13SRob Herring .start_link = histb_pcie_start_link,
2946e0832faSShawn Lin };
2956e0832faSShawn Lin
histb_pcie_probe(struct platform_device * pdev)2966e0832faSShawn Lin static int histb_pcie_probe(struct platform_device *pdev)
2976e0832faSShawn Lin {
2986e0832faSShawn Lin struct histb_pcie *hipcie;
2996e0832faSShawn Lin struct dw_pcie *pci;
30060b3c27fSSerge Semin struct dw_pcie_rp *pp;
3016e0832faSShawn Lin struct device *dev = &pdev->dev;
3026e0832faSShawn Lin int ret;
3036e0832faSShawn Lin
3046e0832faSShawn Lin hipcie = devm_kzalloc(dev, sizeof(*hipcie), GFP_KERNEL);
3056e0832faSShawn Lin if (!hipcie)
3066e0832faSShawn Lin return -ENOMEM;
3076e0832faSShawn Lin
3086e0832faSShawn Lin pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
3096e0832faSShawn Lin if (!pci)
3106e0832faSShawn Lin return -ENOMEM;
3116e0832faSShawn Lin
3126e0832faSShawn Lin hipcie->pci = pci;
3136e0832faSShawn Lin pp = &pci->pp;
3146e0832faSShawn Lin pci->dev = dev;
3156e0832faSShawn Lin pci->ops = &dw_pcie_ops;
3166e0832faSShawn Lin
317936fa5cdSDejin Zheng hipcie->ctrl = devm_platform_ioremap_resource_byname(pdev, "control");
3186e0832faSShawn Lin if (IS_ERR(hipcie->ctrl)) {
3196e0832faSShawn Lin dev_err(dev, "cannot get control reg base\n");
3206e0832faSShawn Lin return PTR_ERR(hipcie->ctrl);
3216e0832faSShawn Lin }
3226e0832faSShawn Lin
323936fa5cdSDejin Zheng pci->dbi_base = devm_platform_ioremap_resource_byname(pdev, "rc-dbi");
3246e0832faSShawn Lin if (IS_ERR(pci->dbi_base)) {
3256e0832faSShawn Lin dev_err(dev, "cannot get rc-dbi base\n");
3266e0832faSShawn Lin return PTR_ERR(pci->dbi_base);
3276e0832faSShawn Lin }
3286e0832faSShawn Lin
3296e0832faSShawn Lin hipcie->vpcie = devm_regulator_get_optional(dev, "vpcie");
3306e0832faSShawn Lin if (IS_ERR(hipcie->vpcie)) {
3318f9e1641SThierry Reding if (PTR_ERR(hipcie->vpcie) != -ENODEV)
3328f9e1641SThierry Reding return PTR_ERR(hipcie->vpcie);
3336e0832faSShawn Lin hipcie->vpcie = NULL;
3346e0832faSShawn Lin }
3356e0832faSShawn Lin
3361d26a55fSDmitry Torokhov hipcie->reset_gpio = devm_gpiod_get_optional(dev, "reset",
3371d26a55fSDmitry Torokhov GPIOD_OUT_HIGH);
3381d26a55fSDmitry Torokhov ret = PTR_ERR_OR_ZERO(hipcie->reset_gpio);
3396e0832faSShawn Lin if (ret) {
3401d26a55fSDmitry Torokhov dev_err(dev, "unable to request reset gpio: %d\n", ret);
3416e0832faSShawn Lin return ret;
3426e0832faSShawn Lin }
3431d26a55fSDmitry Torokhov
3441d26a55fSDmitry Torokhov ret = gpiod_set_consumer_name(hipcie->reset_gpio,
3451d26a55fSDmitry Torokhov "PCIe device power control");
3461d26a55fSDmitry Torokhov if (ret) {
3471d26a55fSDmitry Torokhov dev_err(dev, "unable to set reset gpio name: %d\n", ret);
3481d26a55fSDmitry Torokhov return ret;
3496e0832faSShawn Lin }
3506e0832faSShawn Lin
3516e0832faSShawn Lin hipcie->aux_clk = devm_clk_get(dev, "aux");
3526e0832faSShawn Lin if (IS_ERR(hipcie->aux_clk)) {
3536e0832faSShawn Lin dev_err(dev, "Failed to get PCIe aux clk\n");
3546e0832faSShawn Lin return PTR_ERR(hipcie->aux_clk);
3556e0832faSShawn Lin }
3566e0832faSShawn Lin
3576e0832faSShawn Lin hipcie->pipe_clk = devm_clk_get(dev, "pipe");
3586e0832faSShawn Lin if (IS_ERR(hipcie->pipe_clk)) {
3596e0832faSShawn Lin dev_err(dev, "Failed to get PCIe pipe clk\n");
3606e0832faSShawn Lin return PTR_ERR(hipcie->pipe_clk);
3616e0832faSShawn Lin }
3626e0832faSShawn Lin
3636e0832faSShawn Lin hipcie->sys_clk = devm_clk_get(dev, "sys");
3646e0832faSShawn Lin if (IS_ERR(hipcie->sys_clk)) {
3656e0832faSShawn Lin dev_err(dev, "Failed to get PCIEe sys clk\n");
3666e0832faSShawn Lin return PTR_ERR(hipcie->sys_clk);
3676e0832faSShawn Lin }
3686e0832faSShawn Lin
3696e0832faSShawn Lin hipcie->bus_clk = devm_clk_get(dev, "bus");
3706e0832faSShawn Lin if (IS_ERR(hipcie->bus_clk)) {
3716e0832faSShawn Lin dev_err(dev, "Failed to get PCIe bus clk\n");
3726e0832faSShawn Lin return PTR_ERR(hipcie->bus_clk);
3736e0832faSShawn Lin }
3746e0832faSShawn Lin
3756e0832faSShawn Lin hipcie->soft_reset = devm_reset_control_get(dev, "soft");
3766e0832faSShawn Lin if (IS_ERR(hipcie->soft_reset)) {
3776e0832faSShawn Lin dev_err(dev, "couldn't get soft reset\n");
3786e0832faSShawn Lin return PTR_ERR(hipcie->soft_reset);
3796e0832faSShawn Lin }
3806e0832faSShawn Lin
3816e0832faSShawn Lin hipcie->sys_reset = devm_reset_control_get(dev, "sys");
3826e0832faSShawn Lin if (IS_ERR(hipcie->sys_reset)) {
3836e0832faSShawn Lin dev_err(dev, "couldn't get sys reset\n");
3846e0832faSShawn Lin return PTR_ERR(hipcie->sys_reset);
3856e0832faSShawn Lin }
3866e0832faSShawn Lin
3876e0832faSShawn Lin hipcie->bus_reset = devm_reset_control_get(dev, "bus");
3886e0832faSShawn Lin if (IS_ERR(hipcie->bus_reset)) {
3896e0832faSShawn Lin dev_err(dev, "couldn't get bus reset\n");
3906e0832faSShawn Lin return PTR_ERR(hipcie->bus_reset);
3916e0832faSShawn Lin }
3926e0832faSShawn Lin
3936e0832faSShawn Lin hipcie->phy = devm_phy_get(dev, "phy");
3946e0832faSShawn Lin if (IS_ERR(hipcie->phy)) {
3956e0832faSShawn Lin dev_info(dev, "no pcie-phy found\n");
3966e0832faSShawn Lin hipcie->phy = NULL;
3976e0832faSShawn Lin /* fall through here!
3986e0832faSShawn Lin * if no pcie-phy found, phy init
3996e0832faSShawn Lin * should be done under boot!
4006e0832faSShawn Lin */
4016e0832faSShawn Lin } else {
4026e0832faSShawn Lin phy_init(hipcie->phy);
4036e0832faSShawn Lin }
4046e0832faSShawn Lin
4056e0832faSShawn Lin pp->ops = &histb_pcie_host_ops;
4066e0832faSShawn Lin
4076e0832faSShawn Lin platform_set_drvdata(pdev, hipcie);
4086e0832faSShawn Lin
4096e0832faSShawn Lin ret = histb_pcie_host_enable(pp);
4106e0832faSShawn Lin if (ret) {
4116e0832faSShawn Lin dev_err(dev, "failed to enable host\n");
4126e0832faSShawn Lin return ret;
4136e0832faSShawn Lin }
4146e0832faSShawn Lin
4156e0832faSShawn Lin ret = dw_pcie_host_init(pp);
4166e0832faSShawn Lin if (ret) {
4176e0832faSShawn Lin dev_err(dev, "failed to initialize host\n");
4186e0832faSShawn Lin return ret;
4196e0832faSShawn Lin }
4206e0832faSShawn Lin
4216e0832faSShawn Lin return 0;
4226e0832faSShawn Lin }
4236e0832faSShawn Lin
histb_pcie_remove(struct platform_device * pdev)424221879c9SUwe Kleine-König static void histb_pcie_remove(struct platform_device *pdev)
4256e0832faSShawn Lin {
4266e0832faSShawn Lin struct histb_pcie *hipcie = platform_get_drvdata(pdev);
4276e0832faSShawn Lin
4286e0832faSShawn Lin histb_pcie_host_disable(hipcie);
4296e0832faSShawn Lin
4306e0832faSShawn Lin if (hipcie->phy)
4316e0832faSShawn Lin phy_exit(hipcie->phy);
4326e0832faSShawn Lin }
4336e0832faSShawn Lin
4346e0832faSShawn Lin static const struct of_device_id histb_pcie_of_match[] = {
4356e0832faSShawn Lin { .compatible = "hisilicon,hi3798cv200-pcie", },
4366e0832faSShawn Lin {},
4376e0832faSShawn Lin };
4386e0832faSShawn Lin MODULE_DEVICE_TABLE(of, histb_pcie_of_match);
4396e0832faSShawn Lin
4406e0832faSShawn Lin static struct platform_driver histb_pcie_platform_driver = {
4416e0832faSShawn Lin .probe = histb_pcie_probe,
442221879c9SUwe Kleine-König .remove_new = histb_pcie_remove,
4436e0832faSShawn Lin .driver = {
4446e0832faSShawn Lin .name = "histb-pcie",
4456e0832faSShawn Lin .of_match_table = histb_pcie_of_match,
4466e0832faSShawn Lin },
4476e0832faSShawn Lin };
4486e0832faSShawn Lin module_platform_driver(histb_pcie_platform_driver);
4496e0832faSShawn Lin
4506e0832faSShawn Lin MODULE_DESCRIPTION("HiSilicon STB PCIe host controller driver");
451