xref: /linux/drivers/pci/controller/dwc/pcie-histb.c (revision 06d07429858317ded2db7986113a9e0129cd599b)
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