brintos

brintos / linux-shallow public Read only

0
0
Text · 18.5 KiB · 85a2c77 Raw
785 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * PCIe host controller driver for Kirin Phone SoCs4 *5 * Copyright (C) 2017 HiSilicon Electronics Co., Ltd.6 *		https://www.huawei.com7 *8 * Author: Xiaowei Song <songxiaowei@huawei.com>9 */10 11#include <linux/clk.h>12#include <linux/compiler.h>13#include <linux/delay.h>14#include <linux/err.h>15#include <linux/gpio/consumer.h>16#include <linux/interrupt.h>17#include <linux/mfd/syscon.h>18#include <linux/of.h>19#include <linux/of_pci.h>20#include <linux/phy/phy.h>21#include <linux/pci.h>22#include <linux/pci_regs.h>23#include <linux/platform_device.h>24#include <linux/regmap.h>25#include <linux/resource.h>26#include <linux/types.h>27#include "pcie-designware.h"28 29#define to_kirin_pcie(x) dev_get_drvdata((x)->dev)30 31/* PCIe ELBI registers */32#define SOC_PCIECTRL_CTRL0_ADDR		0x00033#define SOC_PCIECTRL_CTRL1_ADDR		0x00434#define PCIE_ELBI_SLV_DBI_ENABLE	(0x1 << 21)35 36/* info located in APB */37#define PCIE_APP_LTSSM_ENABLE	0x01c38#define PCIE_APB_PHY_STATUS0	0x40039#define PCIE_LINKUP_ENABLE	(0x8020)40#define PCIE_LTSSM_ENABLE_BIT	(0x1 << 11)41 42/* info located in sysctrl */43#define SCTRL_PCIE_CMOS_OFFSET	0x6044#define SCTRL_PCIE_CMOS_BIT	0x1045#define SCTRL_PCIE_ISO_OFFSET	0x4446#define SCTRL_PCIE_ISO_BIT	0x3047#define SCTRL_PCIE_HPCLK_OFFSET	0x19048#define SCTRL_PCIE_HPCLK_BIT	0x18400049#define SCTRL_PCIE_OE_OFFSET	0x14a50#define PCIE_DEBOUNCE_PARAM	0xF0F40051#define PCIE_OE_BYPASS		(0x3 << 28)52 53/*54 * Max number of connected PCI slots at an external PCI bridge55 *56 * This is used on HiKey 970, which has a PEX 8606 bridge with 4 connected57 * lanes (lane 0 upstream, and the other three lanes, one connected to an58 * in-board Ethernet adapter and the other two connected to M.2 and mini59 * PCI slots.60 *61 * Each slot has a different clock source and uses a separate PERST# pin.62 */63#define MAX_PCI_SLOTS		364 65enum pcie_kirin_phy_type {66	PCIE_KIRIN_INTERNAL_PHY,67	PCIE_KIRIN_EXTERNAL_PHY68};69 70struct kirin_pcie {71	enum pcie_kirin_phy_type	type;72 73	struct dw_pcie	*pci;74	struct regmap   *apb;75	struct phy	*phy;76	void		*phy_priv;	/* only for PCIE_KIRIN_INTERNAL_PHY */77 78	/* DWC PERST# */79	struct gpio_desc *id_dwc_perst_gpio;80 81	/* Per-slot PERST# */82	int		num_slots;83	struct gpio_desc *id_reset_gpio[MAX_PCI_SLOTS];84	const char	*reset_names[MAX_PCI_SLOTS];85 86	/* Per-slot clkreq */87	int		n_gpio_clkreq;88	struct gpio_desc *id_clkreq_gpio[MAX_PCI_SLOTS];89	const char	*clkreq_names[MAX_PCI_SLOTS];90};91 92/*93 * Kirin 960 PHY. Can't be split into a PHY driver without changing the94 * DT schema.95 */96 97#define REF_CLK_FREQ			10000000098 99/* PHY info located in APB */100#define PCIE_APB_PHY_CTRL0	0x0101#define PCIE_APB_PHY_CTRL1	0x4102#define PCIE_APB_PHY_STATUS0   0x400103#define PIPE_CLK_STABLE		BIT(19)104#define PHY_REF_PAD_BIT		BIT(8)105#define PHY_PWR_DOWN_BIT	BIT(22)106#define PHY_RST_ACK_BIT		BIT(16)107 108/* peri_crg ctrl */109#define CRGCTRL_PCIE_ASSERT_OFFSET	0x88110#define CRGCTRL_PCIE_ASSERT_BIT		0x8c000000111 112/* Time for delay */113#define REF_2_PERST_MIN		21000114#define REF_2_PERST_MAX		25000115#define PERST_2_ACCESS_MIN	10000116#define PERST_2_ACCESS_MAX	12000117#define PIPE_CLK_WAIT_MIN	550118#define PIPE_CLK_WAIT_MAX	600119#define TIME_CMOS_MIN		100120#define TIME_CMOS_MAX		105121#define TIME_PHY_PD_MIN		10122#define TIME_PHY_PD_MAX		11123 124struct hi3660_pcie_phy {125	struct device	*dev;126	void __iomem	*base;127	struct regmap	*crgctrl;128	struct regmap	*sysctrl;129	struct clk	*apb_sys_clk;130	struct clk	*apb_phy_clk;131	struct clk	*phy_ref_clk;132	struct clk	*aclk;133	struct clk	*aux_clk;134};135 136/* Registers in PCIePHY */137static inline void kirin_apb_phy_writel(struct hi3660_pcie_phy *hi3660_pcie_phy,138					u32 val, u32 reg)139{140	writel(val, hi3660_pcie_phy->base + reg);141}142 143static inline u32 kirin_apb_phy_readl(struct hi3660_pcie_phy *hi3660_pcie_phy,144				      u32 reg)145{146	return readl(hi3660_pcie_phy->base + reg);147}148 149static int hi3660_pcie_phy_get_clk(struct hi3660_pcie_phy *phy)150{151	struct device *dev = phy->dev;152 153	phy->phy_ref_clk = devm_clk_get(dev, "pcie_phy_ref");154	if (IS_ERR(phy->phy_ref_clk))155		return PTR_ERR(phy->phy_ref_clk);156 157	phy->aux_clk = devm_clk_get(dev, "pcie_aux");158	if (IS_ERR(phy->aux_clk))159		return PTR_ERR(phy->aux_clk);160 161	phy->apb_phy_clk = devm_clk_get(dev, "pcie_apb_phy");162	if (IS_ERR(phy->apb_phy_clk))163		return PTR_ERR(phy->apb_phy_clk);164 165	phy->apb_sys_clk = devm_clk_get(dev, "pcie_apb_sys");166	if (IS_ERR(phy->apb_sys_clk))167		return PTR_ERR(phy->apb_sys_clk);168 169	phy->aclk = devm_clk_get(dev, "pcie_aclk");170	if (IS_ERR(phy->aclk))171		return PTR_ERR(phy->aclk);172 173	return 0;174}175 176static int hi3660_pcie_phy_get_resource(struct hi3660_pcie_phy *phy)177{178	struct device *dev = phy->dev;179	struct platform_device *pdev;180 181	/* registers */182	pdev = container_of(dev, struct platform_device, dev);183 184	phy->base = devm_platform_ioremap_resource_byname(pdev, "phy");185	if (IS_ERR(phy->base))186		return PTR_ERR(phy->base);187 188	phy->crgctrl = syscon_regmap_lookup_by_compatible("hisilicon,hi3660-crgctrl");189	if (IS_ERR(phy->crgctrl))190		return PTR_ERR(phy->crgctrl);191 192	phy->sysctrl = syscon_regmap_lookup_by_compatible("hisilicon,hi3660-sctrl");193	if (IS_ERR(phy->sysctrl))194		return PTR_ERR(phy->sysctrl);195 196	return 0;197}198 199static int hi3660_pcie_phy_start(struct hi3660_pcie_phy *phy)200{201	struct device *dev = phy->dev;202	u32 reg_val;203 204	reg_val = kirin_apb_phy_readl(phy, PCIE_APB_PHY_CTRL1);205	reg_val &= ~PHY_REF_PAD_BIT;206	kirin_apb_phy_writel(phy, reg_val, PCIE_APB_PHY_CTRL1);207 208	reg_val = kirin_apb_phy_readl(phy, PCIE_APB_PHY_CTRL0);209	reg_val &= ~PHY_PWR_DOWN_BIT;210	kirin_apb_phy_writel(phy, reg_val, PCIE_APB_PHY_CTRL0);211	usleep_range(TIME_PHY_PD_MIN, TIME_PHY_PD_MAX);212 213	reg_val = kirin_apb_phy_readl(phy, PCIE_APB_PHY_CTRL1);214	reg_val &= ~PHY_RST_ACK_BIT;215	kirin_apb_phy_writel(phy, reg_val, PCIE_APB_PHY_CTRL1);216 217	usleep_range(PIPE_CLK_WAIT_MIN, PIPE_CLK_WAIT_MAX);218	reg_val = kirin_apb_phy_readl(phy, PCIE_APB_PHY_STATUS0);219	if (reg_val & PIPE_CLK_STABLE) {220		dev_err(dev, "PIPE clk is not stable\n");221		return -EINVAL;222	}223 224	return 0;225}226 227static void hi3660_pcie_phy_oe_enable(struct hi3660_pcie_phy *phy)228{229	u32 val;230 231	regmap_read(phy->sysctrl, SCTRL_PCIE_OE_OFFSET, &val);232	val |= PCIE_DEBOUNCE_PARAM;233	val &= ~PCIE_OE_BYPASS;234	regmap_write(phy->sysctrl, SCTRL_PCIE_OE_OFFSET, val);235}236 237static int hi3660_pcie_phy_clk_ctrl(struct hi3660_pcie_phy *phy, bool enable)238{239	int ret = 0;240 241	if (!enable)242		goto close_clk;243 244	ret = clk_set_rate(phy->phy_ref_clk, REF_CLK_FREQ);245	if (ret)246		return ret;247 248	ret = clk_prepare_enable(phy->phy_ref_clk);249	if (ret)250		return ret;251 252	ret = clk_prepare_enable(phy->apb_sys_clk);253	if (ret)254		goto apb_sys_fail;255 256	ret = clk_prepare_enable(phy->apb_phy_clk);257	if (ret)258		goto apb_phy_fail;259 260	ret = clk_prepare_enable(phy->aclk);261	if (ret)262		goto aclk_fail;263 264	ret = clk_prepare_enable(phy->aux_clk);265	if (ret)266		goto aux_clk_fail;267 268	return 0;269 270close_clk:271	clk_disable_unprepare(phy->aux_clk);272aux_clk_fail:273	clk_disable_unprepare(phy->aclk);274aclk_fail:275	clk_disable_unprepare(phy->apb_phy_clk);276apb_phy_fail:277	clk_disable_unprepare(phy->apb_sys_clk);278apb_sys_fail:279	clk_disable_unprepare(phy->phy_ref_clk);280 281	return ret;282}283 284static int hi3660_pcie_phy_power_on(struct kirin_pcie *pcie)285{286	struct hi3660_pcie_phy *phy = pcie->phy_priv;287	int ret;288 289	/* Power supply for Host */290	regmap_write(phy->sysctrl,291		     SCTRL_PCIE_CMOS_OFFSET, SCTRL_PCIE_CMOS_BIT);292	usleep_range(TIME_CMOS_MIN, TIME_CMOS_MAX);293 294	hi3660_pcie_phy_oe_enable(phy);295 296	ret = hi3660_pcie_phy_clk_ctrl(phy, true);297	if (ret)298		return ret;299 300	/* ISO disable, PCIeCtrl, PHY assert and clk gate clear */301	regmap_write(phy->sysctrl,302		     SCTRL_PCIE_ISO_OFFSET, SCTRL_PCIE_ISO_BIT);303	regmap_write(phy->crgctrl,304		     CRGCTRL_PCIE_ASSERT_OFFSET, CRGCTRL_PCIE_ASSERT_BIT);305	regmap_write(phy->sysctrl,306		     SCTRL_PCIE_HPCLK_OFFSET, SCTRL_PCIE_HPCLK_BIT);307 308	ret = hi3660_pcie_phy_start(phy);309	if (ret)310		goto disable_clks;311 312	return 0;313 314disable_clks:315	hi3660_pcie_phy_clk_ctrl(phy, false);316	return ret;317}318 319static int hi3660_pcie_phy_init(struct platform_device *pdev,320				struct kirin_pcie *pcie)321{322	struct device *dev = &pdev->dev;323	struct hi3660_pcie_phy *phy;324	int ret;325 326	phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);327	if (!phy)328		return -ENOMEM;329 330	pcie->phy_priv = phy;331	phy->dev = dev;332 333	ret = hi3660_pcie_phy_get_clk(phy);334	if (ret)335		return ret;336 337	return hi3660_pcie_phy_get_resource(phy);338}339 340static int hi3660_pcie_phy_power_off(struct kirin_pcie *pcie)341{342	struct hi3660_pcie_phy *phy = pcie->phy_priv;343 344	/* Drop power supply for Host */345	regmap_write(phy->sysctrl, SCTRL_PCIE_CMOS_OFFSET, 0x00);346 347	hi3660_pcie_phy_clk_ctrl(phy, false);348 349	return 0;350}351 352/*353 * The non-PHY part starts here354 */355 356static const struct regmap_config pcie_kirin_regmap_conf = {357	.name = "kirin_pcie_apb",358	.reg_bits = 32,359	.val_bits = 32,360	.reg_stride = 4,361};362 363static int kirin_pcie_get_gpio_enable(struct kirin_pcie *pcie,364				      struct platform_device *pdev)365{366	struct device *dev = &pdev->dev;367	int ret, i;368 369	/* This is an optional property */370	ret = gpiod_count(dev, "hisilicon,clken");371	if (ret < 0)372		return 0;373 374	if (ret > MAX_PCI_SLOTS) {375		dev_err(dev, "Too many GPIO clock requests!\n");376		return -EINVAL;377	}378 379	pcie->n_gpio_clkreq = ret;380 381	for (i = 0; i < pcie->n_gpio_clkreq; i++) {382		pcie->id_clkreq_gpio[i] = devm_gpiod_get_index(dev,383							"hisilicon,clken", i,384							GPIOD_OUT_LOW);385		if (IS_ERR(pcie->id_clkreq_gpio[i]))386			return dev_err_probe(dev, PTR_ERR(pcie->id_clkreq_gpio[i]),387					     "unable to get a valid clken gpio\n");388 389		pcie->clkreq_names[i] = devm_kasprintf(dev, GFP_KERNEL,390						       "pcie_clkreq_%d", i);391		if (!pcie->clkreq_names[i])392			return -ENOMEM;393 394		gpiod_set_consumer_name(pcie->id_clkreq_gpio[i],395					pcie->clkreq_names[i]);396	}397 398	return 0;399}400 401static int kirin_pcie_parse_port(struct kirin_pcie *pcie,402				 struct platform_device *pdev,403				 struct device_node *node)404{405	struct device *dev = &pdev->dev;406	int ret, slot, i;407 408	for_each_available_child_of_node_scoped(node, parent) {409		for_each_available_child_of_node_scoped(parent, child) {410			i = pcie->num_slots;411 412			pcie->id_reset_gpio[i] = devm_fwnode_gpiod_get_index(dev,413							 of_fwnode_handle(child),414							 "reset", 0, GPIOD_OUT_LOW,415							 NULL);416			if (IS_ERR(pcie->id_reset_gpio[i])) {417				if (PTR_ERR(pcie->id_reset_gpio[i]) == -ENOENT)418					continue;419				return dev_err_probe(dev, PTR_ERR(pcie->id_reset_gpio[i]),420						     "unable to get a valid reset gpio\n");421			}422 423			if (pcie->num_slots + 1 >= MAX_PCI_SLOTS) {424				dev_err(dev, "Too many PCI slots!\n");425				return -EINVAL;426			}427			pcie->num_slots++;428 429			ret = of_pci_get_devfn(child);430			if (ret < 0) {431				dev_err(dev, "failed to parse devfn: %d\n", ret);432				return ret;433			}434 435			slot = PCI_SLOT(ret);436 437			pcie->reset_names[i] = devm_kasprintf(dev, GFP_KERNEL,438							      "pcie_perst_%d",439							      slot);440			if (!pcie->reset_names[i])441				return -ENOMEM;442 443			gpiod_set_consumer_name(pcie->id_reset_gpio[i],444						pcie->reset_names[i]);445		}446	}447 448	return 0;449}450 451static long kirin_pcie_get_resource(struct kirin_pcie *kirin_pcie,452				    struct platform_device *pdev)453{454	struct device *dev = &pdev->dev;455	struct device_node *child, *node = dev->of_node;456	void __iomem *apb_base;457	int ret;458 459	apb_base = devm_platform_ioremap_resource_byname(pdev, "apb");460	if (IS_ERR(apb_base))461		return PTR_ERR(apb_base);462 463	kirin_pcie->apb = devm_regmap_init_mmio(dev, apb_base,464						&pcie_kirin_regmap_conf);465	if (IS_ERR(kirin_pcie->apb))466		return PTR_ERR(kirin_pcie->apb);467 468	/* pcie internal PERST# gpio */469	kirin_pcie->id_dwc_perst_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);470	if (IS_ERR(kirin_pcie->id_dwc_perst_gpio))471		return dev_err_probe(dev, PTR_ERR(kirin_pcie->id_dwc_perst_gpio),472				     "unable to get a valid gpio pin\n");473	gpiod_set_consumer_name(kirin_pcie->id_dwc_perst_gpio, "pcie_perst_bridge");474 475	ret = kirin_pcie_get_gpio_enable(kirin_pcie, pdev);476	if (ret)477		return ret;478 479	/* Parse OF children */480	for_each_available_child_of_node(node, child) {481		ret = kirin_pcie_parse_port(kirin_pcie, pdev, child);482		if (ret)483			goto put_node;484	}485 486	return 0;487 488put_node:489	of_node_put(child);490	return ret;491}492 493static void kirin_pcie_sideband_dbi_w_mode(struct kirin_pcie *kirin_pcie,494					   bool on)495{496	u32 val;497 498	regmap_read(kirin_pcie->apb, SOC_PCIECTRL_CTRL0_ADDR, &val);499	if (on)500		val = val | PCIE_ELBI_SLV_DBI_ENABLE;501	else502		val = val & ~PCIE_ELBI_SLV_DBI_ENABLE;503 504	regmap_write(kirin_pcie->apb, SOC_PCIECTRL_CTRL0_ADDR, val);505}506 507static void kirin_pcie_sideband_dbi_r_mode(struct kirin_pcie *kirin_pcie,508					   bool on)509{510	u32 val;511 512	regmap_read(kirin_pcie->apb, SOC_PCIECTRL_CTRL1_ADDR, &val);513	if (on)514		val = val | PCIE_ELBI_SLV_DBI_ENABLE;515	else516		val = val & ~PCIE_ELBI_SLV_DBI_ENABLE;517 518	regmap_write(kirin_pcie->apb, SOC_PCIECTRL_CTRL1_ADDR, val);519}520 521static int kirin_pcie_rd_own_conf(struct pci_bus *bus, unsigned int devfn,522				  int where, int size, u32 *val)523{524	struct dw_pcie *pci = to_dw_pcie_from_pp(bus->sysdata);525 526	if (PCI_SLOT(devfn))527		return PCIBIOS_DEVICE_NOT_FOUND;528 529	*val = dw_pcie_read_dbi(pci, where, size);530	return PCIBIOS_SUCCESSFUL;531}532 533static int kirin_pcie_wr_own_conf(struct pci_bus *bus, unsigned int devfn,534				  int where, int size, u32 val)535{536	struct dw_pcie *pci = to_dw_pcie_from_pp(bus->sysdata);537 538	if (PCI_SLOT(devfn))539		return PCIBIOS_DEVICE_NOT_FOUND;540 541	dw_pcie_write_dbi(pci, where, size, val);542	return PCIBIOS_SUCCESSFUL;543}544 545static int kirin_pcie_add_bus(struct pci_bus *bus)546{547	struct dw_pcie *pci = to_dw_pcie_from_pp(bus->sysdata);548	struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci);549	int i, ret;550 551	if (!kirin_pcie->num_slots)552		return 0;553 554	/* Send PERST# to each slot */555	for (i = 0; i < kirin_pcie->num_slots; i++) {556		ret = gpiod_direction_output_raw(kirin_pcie->id_reset_gpio[i], 1);557		if (ret) {558			dev_err(pci->dev, "PERST# %s error: %d\n",559				kirin_pcie->reset_names[i], ret);560		}561	}562	usleep_range(PERST_2_ACCESS_MIN, PERST_2_ACCESS_MAX);563 564	return 0;565}566 567static struct pci_ops kirin_pci_ops = {568	.read = kirin_pcie_rd_own_conf,569	.write = kirin_pcie_wr_own_conf,570	.add_bus = kirin_pcie_add_bus,571};572 573static u32 kirin_pcie_read_dbi(struct dw_pcie *pci, void __iomem *base,574			       u32 reg, size_t size)575{576	struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci);577	u32 ret;578 579	kirin_pcie_sideband_dbi_r_mode(kirin_pcie, true);580	dw_pcie_read(base + reg, size, &ret);581	kirin_pcie_sideband_dbi_r_mode(kirin_pcie, false);582 583	return ret;584}585 586static void kirin_pcie_write_dbi(struct dw_pcie *pci, void __iomem *base,587				 u32 reg, size_t size, u32 val)588{589	struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci);590 591	kirin_pcie_sideband_dbi_w_mode(kirin_pcie, true);592	dw_pcie_write(base + reg, size, val);593	kirin_pcie_sideband_dbi_w_mode(kirin_pcie, false);594}595 596static int kirin_pcie_link_up(struct dw_pcie *pci)597{598	struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci);599	u32 val;600 601	regmap_read(kirin_pcie->apb, PCIE_APB_PHY_STATUS0, &val);602	if ((val & PCIE_LINKUP_ENABLE) == PCIE_LINKUP_ENABLE)603		return 1;604 605	return 0;606}607 608static int kirin_pcie_start_link(struct dw_pcie *pci)609{610	struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci);611 612	/* assert LTSSM enable */613	regmap_write(kirin_pcie->apb, PCIE_APP_LTSSM_ENABLE,614		     PCIE_LTSSM_ENABLE_BIT);615 616	return 0;617}618 619static int kirin_pcie_host_init(struct dw_pcie_rp *pp)620{621	pp->bridge->ops = &kirin_pci_ops;622 623	return 0;624}625 626static const struct dw_pcie_ops kirin_dw_pcie_ops = {627	.read_dbi = kirin_pcie_read_dbi,628	.write_dbi = kirin_pcie_write_dbi,629	.link_up = kirin_pcie_link_up,630	.start_link = kirin_pcie_start_link,631};632 633static const struct dw_pcie_host_ops kirin_pcie_host_ops = {634	.init = kirin_pcie_host_init,635};636 637static int kirin_pcie_power_off(struct kirin_pcie *kirin_pcie)638{639	int i;640 641	if (kirin_pcie->type == PCIE_KIRIN_INTERNAL_PHY)642		return hi3660_pcie_phy_power_off(kirin_pcie);643 644	for (i = 0; i < kirin_pcie->n_gpio_clkreq; i++)645		gpiod_direction_output_raw(kirin_pcie->id_clkreq_gpio[i], 1);646 647	phy_power_off(kirin_pcie->phy);648	phy_exit(kirin_pcie->phy);649 650	return 0;651}652 653static int kirin_pcie_power_on(struct platform_device *pdev,654			       struct kirin_pcie *kirin_pcie)655{656	struct device *dev = &pdev->dev;657	int ret;658 659	if (kirin_pcie->type == PCIE_KIRIN_INTERNAL_PHY) {660		ret = hi3660_pcie_phy_init(pdev, kirin_pcie);661		if (ret)662			return ret;663 664		ret = hi3660_pcie_phy_power_on(kirin_pcie);665		if (ret)666			return ret;667	} else {668		kirin_pcie->phy = devm_of_phy_get(dev, dev->of_node, NULL);669		if (IS_ERR(kirin_pcie->phy))670			return PTR_ERR(kirin_pcie->phy);671 672		ret = phy_init(kirin_pcie->phy);673		if (ret)674			goto err;675 676		ret = phy_power_on(kirin_pcie->phy);677		if (ret)678			goto err;679	}680 681	/* perst assert Endpoint */682	usleep_range(REF_2_PERST_MIN, REF_2_PERST_MAX);683 684	ret = gpiod_direction_output_raw(kirin_pcie->id_dwc_perst_gpio, 1);685	if (ret)686		goto err;687 688	usleep_range(PERST_2_ACCESS_MIN, PERST_2_ACCESS_MAX);689 690	return 0;691err:692	kirin_pcie_power_off(kirin_pcie);693 694	return ret;695}696 697static void kirin_pcie_remove(struct platform_device *pdev)698{699	struct kirin_pcie *kirin_pcie = platform_get_drvdata(pdev);700 701	dw_pcie_host_deinit(&kirin_pcie->pci->pp);702 703	kirin_pcie_power_off(kirin_pcie);704}705 706struct kirin_pcie_data {707	enum pcie_kirin_phy_type	phy_type;708};709 710static const struct kirin_pcie_data kirin_960_data = {711	.phy_type = PCIE_KIRIN_INTERNAL_PHY,712};713 714static const struct kirin_pcie_data kirin_970_data = {715	.phy_type = PCIE_KIRIN_EXTERNAL_PHY,716};717 718static const struct of_device_id kirin_pcie_match[] = {719	{ .compatible = "hisilicon,kirin960-pcie", .data = &kirin_960_data },720	{ .compatible = "hisilicon,kirin970-pcie", .data = &kirin_970_data },721	{},722};723 724static int kirin_pcie_probe(struct platform_device *pdev)725{726	struct device *dev = &pdev->dev;727	const struct kirin_pcie_data *data;728	struct kirin_pcie *kirin_pcie;729	struct dw_pcie *pci;730	int ret;731 732	if (!dev->of_node) {733		dev_err(dev, "NULL node\n");734		return -EINVAL;735	}736 737	data = of_device_get_match_data(dev);738	if (!data) {739		dev_err(dev, "OF data missing\n");740		return -EINVAL;741	}742 743	kirin_pcie = devm_kzalloc(dev, sizeof(struct kirin_pcie), GFP_KERNEL);744	if (!kirin_pcie)745		return -ENOMEM;746 747	pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);748	if (!pci)749		return -ENOMEM;750 751	pci->dev = dev;752	pci->ops = &kirin_dw_pcie_ops;753	pci->pp.ops = &kirin_pcie_host_ops;754	kirin_pcie->pci = pci;755	kirin_pcie->type = data->phy_type;756 757	ret = kirin_pcie_get_resource(kirin_pcie, pdev);758	if (ret)759		return ret;760 761	platform_set_drvdata(pdev, kirin_pcie);762 763	ret = kirin_pcie_power_on(pdev, kirin_pcie);764	if (ret)765		return ret;766 767	return dw_pcie_host_init(&pci->pp);768}769 770static struct platform_driver kirin_pcie_driver = {771	.probe			= kirin_pcie_probe,772	.remove_new		= kirin_pcie_remove,773	.driver			= {774		.name			= "kirin-pcie",775		.of_match_table		= kirin_pcie_match,776		.suppress_bind_attrs	= true,777	},778};779module_platform_driver(kirin_pcie_driver);780 781MODULE_DEVICE_TABLE(of, kirin_pcie_match);782MODULE_DESCRIPTION("PCIe host controller driver for Kirin Phone SoCs");783MODULE_AUTHOR("Xiaowei Song <songxiaowei@huawei.com>");784MODULE_LICENSE("GPL v2");785