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> 136e0832faSShawn Lin #include <linux/interrupt.h> 146e0832faSShawn Lin #include <linux/kernel.h> 156e0832faSShawn Lin #include <linux/module.h> 166e0832faSShawn Lin #include <linux/of.h> 176e0832faSShawn Lin #include <linux/of_gpio.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; 636e0832faSShawn Lin int reset_gpio; 646e0832faSShawn Lin struct regulator *vpcie; 656e0832faSShawn Lin }; 666e0832faSShawn Lin 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 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 776e0832faSShawn Lin static void histb_pcie_dbi_w_mode(struct pcie_port *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 916e0832faSShawn Lin static void histb_pcie_dbi_r_mode(struct pcie_port *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 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 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 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 130*f4a44c1eSNaveen 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 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 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 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 183886a9c13SRob Herring static int histb_pcie_host_init(struct pcie_port *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 = { 2016e0832faSShawn Lin .host_init = histb_pcie_host_init, 2026e0832faSShawn Lin }; 2036e0832faSShawn Lin 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 2156e0832faSShawn Lin if (gpio_is_valid(hipcie->reset_gpio)) 2166e0832faSShawn Lin gpio_set_value_cansleep(hipcie->reset_gpio, 0); 2176e0832faSShawn Lin 2186e0832faSShawn Lin if (hipcie->vpcie) 2196e0832faSShawn Lin regulator_disable(hipcie->vpcie); 2206e0832faSShawn Lin } 2216e0832faSShawn Lin 2226e0832faSShawn Lin static int histb_pcie_host_enable(struct pcie_port *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 2386e0832faSShawn Lin if (gpio_is_valid(hipcie->reset_gpio)) 2396e0832faSShawn Lin gpio_set_value_cansleep(hipcie->reset_gpio, 1); 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 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; 3006e0832faSShawn Lin struct pcie_port *pp; 3016e0832faSShawn Lin struct device_node *np = pdev->dev.of_node; 3026e0832faSShawn Lin struct device *dev = &pdev->dev; 3036e0832faSShawn Lin enum of_gpio_flags of_flags; 3046e0832faSShawn Lin unsigned long flag = GPIOF_DIR_OUT; 3056e0832faSShawn Lin int ret; 3066e0832faSShawn Lin 3076e0832faSShawn Lin hipcie = devm_kzalloc(dev, sizeof(*hipcie), GFP_KERNEL); 3086e0832faSShawn Lin if (!hipcie) 3096e0832faSShawn Lin return -ENOMEM; 3106e0832faSShawn Lin 3116e0832faSShawn Lin pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL); 3126e0832faSShawn Lin if (!pci) 3136e0832faSShawn Lin return -ENOMEM; 3146e0832faSShawn Lin 3156e0832faSShawn Lin hipcie->pci = pci; 3166e0832faSShawn Lin pp = &pci->pp; 3176e0832faSShawn Lin pci->dev = dev; 3186e0832faSShawn Lin pci->ops = &dw_pcie_ops; 3196e0832faSShawn Lin 320936fa5cdSDejin Zheng hipcie->ctrl = devm_platform_ioremap_resource_byname(pdev, "control"); 3216e0832faSShawn Lin if (IS_ERR(hipcie->ctrl)) { 3226e0832faSShawn Lin dev_err(dev, "cannot get control reg base\n"); 3236e0832faSShawn Lin return PTR_ERR(hipcie->ctrl); 3246e0832faSShawn Lin } 3256e0832faSShawn Lin 326936fa5cdSDejin Zheng pci->dbi_base = devm_platform_ioremap_resource_byname(pdev, "rc-dbi"); 3276e0832faSShawn Lin if (IS_ERR(pci->dbi_base)) { 3286e0832faSShawn Lin dev_err(dev, "cannot get rc-dbi base\n"); 3296e0832faSShawn Lin return PTR_ERR(pci->dbi_base); 3306e0832faSShawn Lin } 3316e0832faSShawn Lin 3326e0832faSShawn Lin hipcie->vpcie = devm_regulator_get_optional(dev, "vpcie"); 3336e0832faSShawn Lin if (IS_ERR(hipcie->vpcie)) { 3348f9e1641SThierry Reding if (PTR_ERR(hipcie->vpcie) != -ENODEV) 3358f9e1641SThierry Reding return PTR_ERR(hipcie->vpcie); 3366e0832faSShawn Lin hipcie->vpcie = NULL; 3376e0832faSShawn Lin } 3386e0832faSShawn Lin 3396e0832faSShawn Lin hipcie->reset_gpio = of_get_named_gpio_flags(np, 3406e0832faSShawn Lin "reset-gpios", 0, &of_flags); 3416e0832faSShawn Lin if (of_flags & OF_GPIO_ACTIVE_LOW) 3426e0832faSShawn Lin flag |= GPIOF_ACTIVE_LOW; 3436e0832faSShawn Lin if (gpio_is_valid(hipcie->reset_gpio)) { 3446e0832faSShawn Lin ret = devm_gpio_request_one(dev, hipcie->reset_gpio, 3456e0832faSShawn Lin flag, "PCIe device power control"); 3466e0832faSShawn Lin if (ret) { 3476e0832faSShawn Lin dev_err(dev, "unable to request gpio\n"); 3486e0832faSShawn Lin return ret; 3496e0832faSShawn Lin } 3506e0832faSShawn Lin } 3516e0832faSShawn Lin 3526e0832faSShawn Lin hipcie->aux_clk = devm_clk_get(dev, "aux"); 3536e0832faSShawn Lin if (IS_ERR(hipcie->aux_clk)) { 3546e0832faSShawn Lin dev_err(dev, "Failed to get PCIe aux clk\n"); 3556e0832faSShawn Lin return PTR_ERR(hipcie->aux_clk); 3566e0832faSShawn Lin } 3576e0832faSShawn Lin 3586e0832faSShawn Lin hipcie->pipe_clk = devm_clk_get(dev, "pipe"); 3596e0832faSShawn Lin if (IS_ERR(hipcie->pipe_clk)) { 3606e0832faSShawn Lin dev_err(dev, "Failed to get PCIe pipe clk\n"); 3616e0832faSShawn Lin return PTR_ERR(hipcie->pipe_clk); 3626e0832faSShawn Lin } 3636e0832faSShawn Lin 3646e0832faSShawn Lin hipcie->sys_clk = devm_clk_get(dev, "sys"); 3656e0832faSShawn Lin if (IS_ERR(hipcie->sys_clk)) { 3666e0832faSShawn Lin dev_err(dev, "Failed to get PCIEe sys clk\n"); 3676e0832faSShawn Lin return PTR_ERR(hipcie->sys_clk); 3686e0832faSShawn Lin } 3696e0832faSShawn Lin 3706e0832faSShawn Lin hipcie->bus_clk = devm_clk_get(dev, "bus"); 3716e0832faSShawn Lin if (IS_ERR(hipcie->bus_clk)) { 3726e0832faSShawn Lin dev_err(dev, "Failed to get PCIe bus clk\n"); 3736e0832faSShawn Lin return PTR_ERR(hipcie->bus_clk); 3746e0832faSShawn Lin } 3756e0832faSShawn Lin 3766e0832faSShawn Lin hipcie->soft_reset = devm_reset_control_get(dev, "soft"); 3776e0832faSShawn Lin if (IS_ERR(hipcie->soft_reset)) { 3786e0832faSShawn Lin dev_err(dev, "couldn't get soft reset\n"); 3796e0832faSShawn Lin return PTR_ERR(hipcie->soft_reset); 3806e0832faSShawn Lin } 3816e0832faSShawn Lin 3826e0832faSShawn Lin hipcie->sys_reset = devm_reset_control_get(dev, "sys"); 3836e0832faSShawn Lin if (IS_ERR(hipcie->sys_reset)) { 3846e0832faSShawn Lin dev_err(dev, "couldn't get sys reset\n"); 3856e0832faSShawn Lin return PTR_ERR(hipcie->sys_reset); 3866e0832faSShawn Lin } 3876e0832faSShawn Lin 3886e0832faSShawn Lin hipcie->bus_reset = devm_reset_control_get(dev, "bus"); 3896e0832faSShawn Lin if (IS_ERR(hipcie->bus_reset)) { 3906e0832faSShawn Lin dev_err(dev, "couldn't get bus reset\n"); 3916e0832faSShawn Lin return PTR_ERR(hipcie->bus_reset); 3926e0832faSShawn Lin } 3936e0832faSShawn Lin 3946e0832faSShawn Lin hipcie->phy = devm_phy_get(dev, "phy"); 3956e0832faSShawn Lin if (IS_ERR(hipcie->phy)) { 3966e0832faSShawn Lin dev_info(dev, "no pcie-phy found\n"); 3976e0832faSShawn Lin hipcie->phy = NULL; 3986e0832faSShawn Lin /* fall through here! 3996e0832faSShawn Lin * if no pcie-phy found, phy init 4006e0832faSShawn Lin * should be done under boot! 4016e0832faSShawn Lin */ 4026e0832faSShawn Lin } else { 4036e0832faSShawn Lin phy_init(hipcie->phy); 4046e0832faSShawn Lin } 4056e0832faSShawn Lin 4066e0832faSShawn Lin pp->ops = &histb_pcie_host_ops; 4076e0832faSShawn Lin 4086e0832faSShawn Lin platform_set_drvdata(pdev, hipcie); 4096e0832faSShawn Lin 4106e0832faSShawn Lin ret = histb_pcie_host_enable(pp); 4116e0832faSShawn Lin if (ret) { 4126e0832faSShawn Lin dev_err(dev, "failed to enable host\n"); 4136e0832faSShawn Lin return ret; 4146e0832faSShawn Lin } 4156e0832faSShawn Lin 4166e0832faSShawn Lin ret = dw_pcie_host_init(pp); 4176e0832faSShawn Lin if (ret) { 4186e0832faSShawn Lin dev_err(dev, "failed to initialize host\n"); 4196e0832faSShawn Lin return ret; 4206e0832faSShawn Lin } 4216e0832faSShawn Lin 4226e0832faSShawn Lin return 0; 4236e0832faSShawn Lin } 4246e0832faSShawn Lin 4256e0832faSShawn Lin static int histb_pcie_remove(struct platform_device *pdev) 4266e0832faSShawn Lin { 4276e0832faSShawn Lin struct histb_pcie *hipcie = platform_get_drvdata(pdev); 4286e0832faSShawn Lin 4296e0832faSShawn Lin histb_pcie_host_disable(hipcie); 4306e0832faSShawn Lin 4316e0832faSShawn Lin if (hipcie->phy) 4326e0832faSShawn Lin phy_exit(hipcie->phy); 4336e0832faSShawn Lin 4346e0832faSShawn Lin return 0; 4356e0832faSShawn Lin } 4366e0832faSShawn Lin 4376e0832faSShawn Lin static const struct of_device_id histb_pcie_of_match[] = { 4386e0832faSShawn Lin { .compatible = "hisilicon,hi3798cv200-pcie", }, 4396e0832faSShawn Lin {}, 4406e0832faSShawn Lin }; 4416e0832faSShawn Lin MODULE_DEVICE_TABLE(of, histb_pcie_of_match); 4426e0832faSShawn Lin 4436e0832faSShawn Lin static struct platform_driver histb_pcie_platform_driver = { 4446e0832faSShawn Lin .probe = histb_pcie_probe, 4456e0832faSShawn Lin .remove = histb_pcie_remove, 4466e0832faSShawn Lin .driver = { 4476e0832faSShawn Lin .name = "histb-pcie", 4486e0832faSShawn Lin .of_match_table = histb_pcie_of_match, 4496e0832faSShawn Lin }, 4506e0832faSShawn Lin }; 4516e0832faSShawn Lin module_platform_driver(histb_pcie_platform_driver); 4526e0832faSShawn Lin 4536e0832faSShawn Lin MODULE_DESCRIPTION("HiSilicon STB PCIe host controller driver"); 4546e0832faSShawn Lin MODULE_LICENSE("GPL v2"); 455