diff options
Diffstat (limited to 'drivers/pci/controller/dwc')
25 files changed, 658 insertions, 1297 deletions
diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig index bc049865f8e0..22c5529e9a65 100644 --- a/drivers/pci/controller/dwc/Kconfig +++ b/drivers/pci/controller/dwc/Kconfig @@ -83,10 +83,15 @@ config PCIE_DW_PLAT_EP  	  selected.  config PCI_EXYNOS -	bool "Samsung Exynos PCIe controller" -	depends on SOC_EXYNOS5440 || COMPILE_TEST +	tristate "Samsung Exynos PCIe controller" +	depends on ARCH_EXYNOS || COMPILE_TEST  	depends on PCI_MSI_IRQ_DOMAIN  	select PCIE_DW_HOST +	help +	  Enables support for the PCIe controller in the Samsung Exynos SoCs +	  to work in host mode. The PCI controller is based on the DesignWare +	  hardware and therefore the driver re-uses the DesignWare core +	  functions to implement the driver.  config PCI_IMX6  	bool "Freescale i.MX6/7/8 PCIe controller" @@ -107,7 +112,7 @@ config PCI_KEYSTONE  config PCI_KEYSTONE_HOST  	bool "PCI Keystone Host Mode" -	depends on ARCH_KEYSTONE || ARCH_K3 || ((ARM || ARM64) && COMPILE_TEST) +	depends on ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST  	depends on PCI_MSI_IRQ_DOMAIN  	select PCIE_DW_HOST  	select PCI_KEYSTONE @@ -119,7 +124,7 @@ config PCI_KEYSTONE_HOST  config PCI_KEYSTONE_EP  	bool "PCI Keystone Endpoint Mode" -	depends on ARCH_KEYSTONE || ARCH_K3 || ((ARM || ARM64) && COMPILE_TEST) +	depends on ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST  	depends on PCI_ENDPOINT  	select PCIE_DW_EP  	select PCI_KEYSTONE @@ -169,6 +174,7 @@ config PCIE_QCOM  	depends on OF && (ARCH_QCOM || COMPILE_TEST)  	depends on PCI_MSI_IRQ_DOMAIN  	select PCIE_DW_HOST +	select CRC8  	help  	  Say Y here to enable PCIe controller support on Qualcomm SoCs. The  	  PCIe controller uses the DesignWare core plus Qualcomm-specific diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c index 6d012d2b1e90..b105af63854a 100644 --- a/drivers/pci/controller/dwc/pci-dra7xx.c +++ b/drivers/pci/controller/dwc/pci-dra7xx.c @@ -181,11 +181,6 @@ static int dra7xx_pcie_host_init(struct pcie_port *pp)  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);  	struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci); -	dw_pcie_setup_rc(pp); - -	dra7xx_pcie_establish_link(pci); -	dw_pcie_wait_for_link(pci); -	dw_pcie_msi_init(pp);  	dra7xx_pcie_enable_interrupts(dra7xx);  	return 0; @@ -377,133 +372,8 @@ static int dra7xx_pcie_init_irq_domain(struct pcie_port *pp)  	return 0;  } -static void dra7xx_pcie_setup_msi_msg(struct irq_data *d, struct msi_msg *msg) -{ -	struct pcie_port *pp = irq_data_get_irq_chip_data(d); -	struct dw_pcie *pci = to_dw_pcie_from_pp(pp); -	u64 msi_target; - -	msi_target = (u64)pp->msi_data; - -	msg->address_lo = lower_32_bits(msi_target); -	msg->address_hi = upper_32_bits(msi_target); - -	msg->data = d->hwirq; - -	dev_dbg(pci->dev, "msi#%d address_hi %#x address_lo %#x\n", -		(int)d->hwirq, msg->address_hi, msg->address_lo); -} - -static int dra7xx_pcie_msi_set_affinity(struct irq_data *d, -					const struct cpumask *mask, -					bool force) -{ -	return -EINVAL; -} - -static void dra7xx_pcie_bottom_mask(struct irq_data *d) -{ -	struct pcie_port *pp = irq_data_get_irq_chip_data(d); -	struct dw_pcie *pci = to_dw_pcie_from_pp(pp); -	unsigned int res, bit, ctrl; -	unsigned long flags; - -	raw_spin_lock_irqsave(&pp->lock, flags); - -	ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL; -	res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; -	bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; - -	pp->irq_mask[ctrl] |= BIT(bit); -	dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_MASK + res, -			   pp->irq_mask[ctrl]); - -	raw_spin_unlock_irqrestore(&pp->lock, flags); -} - -static void dra7xx_pcie_bottom_unmask(struct irq_data *d) -{ -	struct pcie_port *pp = irq_data_get_irq_chip_data(d); -	struct dw_pcie *pci = to_dw_pcie_from_pp(pp); -	unsigned int res, bit, ctrl; -	unsigned long flags; - -	raw_spin_lock_irqsave(&pp->lock, flags); - -	ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL; -	res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; -	bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; - -	pp->irq_mask[ctrl] &= ~BIT(bit); -	dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_MASK + res, -			   pp->irq_mask[ctrl]); - -	raw_spin_unlock_irqrestore(&pp->lock, flags); -} - -static void dra7xx_pcie_bottom_ack(struct irq_data *d) -{ -	struct pcie_port *pp  = irq_data_get_irq_chip_data(d); -	struct dw_pcie *pci = to_dw_pcie_from_pp(pp); -	unsigned int res, bit, ctrl; - -	ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL; -	res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; -	bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; - -	dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_STATUS + res, BIT(bit)); -} - -static struct irq_chip dra7xx_pci_msi_bottom_irq_chip = { -	.name = "DRA7XX-PCI-MSI", -	.irq_ack = dra7xx_pcie_bottom_ack, -	.irq_compose_msi_msg = dra7xx_pcie_setup_msi_msg, -	.irq_set_affinity = dra7xx_pcie_msi_set_affinity, -	.irq_mask = dra7xx_pcie_bottom_mask, -	.irq_unmask = dra7xx_pcie_bottom_unmask, -}; - -static int dra7xx_pcie_msi_host_init(struct pcie_port *pp) -{ -	struct dw_pcie *pci = to_dw_pcie_from_pp(pp); -	struct device *dev = pci->dev; -	u32 ctrl, num_ctrls; -	int ret; - -	pp->msi_irq_chip = &dra7xx_pci_msi_bottom_irq_chip; - -	num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL; -	/* Initialize IRQ Status array */ -	for (ctrl = 0; ctrl < num_ctrls; ctrl++) { -		pp->irq_mask[ctrl] = ~0; -		dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_MASK + -				    (ctrl * MSI_REG_CTRL_BLOCK_SIZE), -				    pp->irq_mask[ctrl]); -		dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_ENABLE + -				    (ctrl * MSI_REG_CTRL_BLOCK_SIZE), -				    ~0); -	} - -	ret = dw_pcie_allocate_domains(pp); -	if (ret) -		return ret; - -	pp->msi_data = dma_map_single_attrs(dev, &pp->msi_msg, -					   sizeof(pp->msi_msg), -					   DMA_FROM_DEVICE, -					   DMA_ATTR_SKIP_CPU_SYNC); -	ret = dma_mapping_error(dev, pp->msi_data); -	if (ret) { -		dev_err(dev, "Failed to map MSI data\n"); -		pp->msi_data = 0; -		dw_pcie_free_msi(pp); -	} -	return ret; -} -  static const struct dw_pcie_host_ops dra7xx_pcie_host_ops = {  	.host_init = dra7xx_pcie_host_init, -	.msi_host_init = dra7xx_pcie_msi_host_init,  };  static void dra7xx_pcie_ep_init(struct dw_pcie_ep *ep) @@ -578,7 +448,6 @@ static int __init dra7xx_add_pcie_ep(struct dra7xx_pcie *dra7xx,  {  	int ret;  	struct dw_pcie_ep *ep; -	struct resource *res;  	struct device *dev = &pdev->dev;  	struct dw_pcie *pci = dra7xx->pci; @@ -594,13 +463,6 @@ static int __init dra7xx_add_pcie_ep(struct dra7xx_pcie *dra7xx,  	if (IS_ERR(pci->dbi_base2))  		return PTR_ERR(pci->dbi_base2); -	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space"); -	if (!res) -		return -EINVAL; - -	ep->phys_base = res->start; -	ep->addr_size = resource_size(res); -  	ret = dw_pcie_ep_init(ep);  	if (ret) {  		dev_err(dev, "failed to initialize endpoint\n"); @@ -622,6 +484,9 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,  	if (pp->irq < 0)  		return pp->irq; +	/* MSI IRQ is muxed */ +	pp->msi_irq = -ENODEV; +  	ret = dra7xx_pcie_init_irq_domain(pp);  	if (ret < 0)  		return ret; diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c index 242683cde04a..c24dab383654 100644 --- a/drivers/pci/controller/dwc/pci-exynos.c +++ b/drivers/pci/controller/dwc/pci-exynos.c @@ -2,26 +2,23 @@  /*   * PCIe host controller driver for Samsung Exynos SoCs   * - * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Copyright (C) 2013-2020 Samsung Electronics Co., Ltd.   *		https://www.samsung.com   *   * Author: Jingoo Han <[email protected]> + *	   Jaehoon Chung <[email protected]>   */  #include <linux/clk.h>  #include <linux/delay.h> -#include <linux/gpio.h>  #include <linux/interrupt.h>  #include <linux/kernel.h>  #include <linux/init.h>  #include <linux/of_device.h> -#include <linux/of_gpio.h>  #include <linux/pci.h>  #include <linux/platform_device.h>  #include <linux/phy/phy.h> -#include <linux/resource.h> -#include <linux/signal.h> -#include <linux/types.h> +#include <linux/regulator/consumer.h>  #include "pcie-designware.h" @@ -37,102 +34,43 @@  #define PCIE_IRQ_SPECIAL		0x008  #define PCIE_IRQ_EN_PULSE		0x00c  #define PCIE_IRQ_EN_LEVEL		0x010 -#define IRQ_MSI_ENABLE			BIT(2)  #define PCIE_IRQ_EN_SPECIAL		0x014 -#define PCIE_PWR_RESET			0x018 +#define PCIE_SW_WAKE			0x018 +#define PCIE_BUS_EN			BIT(1)  #define PCIE_CORE_RESET			0x01c  #define PCIE_CORE_RESET_ENABLE		BIT(0)  #define PCIE_STICKY_RESET		0x020  #define PCIE_NONSTICKY_RESET		0x024  #define PCIE_APP_INIT_RESET		0x028  #define PCIE_APP_LTSSM_ENABLE		0x02c -#define PCIE_ELBI_RDLH_LINKUP		0x064 +#define PCIE_ELBI_RDLH_LINKUP		0x074 +#define PCIE_ELBI_XMLH_LINKUP		BIT(4)  #define PCIE_ELBI_LTSSM_ENABLE		0x1  #define PCIE_ELBI_SLV_AWMISC		0x11c  #define PCIE_ELBI_SLV_ARMISC		0x120  #define PCIE_ELBI_SLV_DBI_ENABLE	BIT(21) -struct exynos_pcie_mem_res { -	void __iomem *elbi_base;   /* DT 0th resource: PCIe CTRL */ -}; - -struct exynos_pcie_clk_res { -	struct clk *clk; -	struct clk *bus_clk; -}; -  struct exynos_pcie { -	struct dw_pcie			*pci; -	struct exynos_pcie_mem_res	*mem_res; -	struct exynos_pcie_clk_res	*clk_res; -	const struct exynos_pcie_ops	*ops; -	int				reset_gpio; - +	struct dw_pcie			pci; +	void __iomem			*elbi_base; +	struct clk			*clk; +	struct clk			*bus_clk;  	struct phy			*phy; +	struct regulator_bulk_data	supplies[2];  }; -struct exynos_pcie_ops { -	int (*get_mem_resources)(struct platform_device *pdev, -			struct exynos_pcie *ep); -	int (*get_clk_resources)(struct exynos_pcie *ep); -	int (*init_clk_resources)(struct exynos_pcie *ep); -	void (*deinit_clk_resources)(struct exynos_pcie *ep); -}; - -static int exynos5440_pcie_get_mem_resources(struct platform_device *pdev, -					     struct exynos_pcie *ep) -{ -	struct dw_pcie *pci = ep->pci; -	struct device *dev = pci->dev; - -	ep->mem_res = devm_kzalloc(dev, sizeof(*ep->mem_res), GFP_KERNEL); -	if (!ep->mem_res) -		return -ENOMEM; - -	ep->mem_res->elbi_base = devm_platform_ioremap_resource(pdev, 0); -	if (IS_ERR(ep->mem_res->elbi_base)) -		return PTR_ERR(ep->mem_res->elbi_base); - -	return 0; -} - -static int exynos5440_pcie_get_clk_resources(struct exynos_pcie *ep) +static int exynos_pcie_init_clk_resources(struct exynos_pcie *ep)  { -	struct dw_pcie *pci = ep->pci; -	struct device *dev = pci->dev; - -	ep->clk_res = devm_kzalloc(dev, sizeof(*ep->clk_res), GFP_KERNEL); -	if (!ep->clk_res) -		return -ENOMEM; - -	ep->clk_res->clk = devm_clk_get(dev, "pcie"); -	if (IS_ERR(ep->clk_res->clk)) { -		dev_err(dev, "Failed to get pcie rc clock\n"); -		return PTR_ERR(ep->clk_res->clk); -	} - -	ep->clk_res->bus_clk = devm_clk_get(dev, "pcie_bus"); -	if (IS_ERR(ep->clk_res->bus_clk)) { -		dev_err(dev, "Failed to get pcie bus clock\n"); -		return PTR_ERR(ep->clk_res->bus_clk); -	} - -	return 0; -} - -static int exynos5440_pcie_init_clk_resources(struct exynos_pcie *ep) -{ -	struct dw_pcie *pci = ep->pci; -	struct device *dev = pci->dev; +	struct device *dev = ep->pci.dev;  	int ret; -	ret = clk_prepare_enable(ep->clk_res->clk); +	ret = clk_prepare_enable(ep->clk);  	if (ret) {  		dev_err(dev, "cannot enable pcie rc clock");  		return ret;  	} -	ret = clk_prepare_enable(ep->clk_res->bus_clk); +	ret = clk_prepare_enable(ep->bus_clk);  	if (ret) {  		dev_err(dev, "cannot enable pcie bus clock");  		goto err_bus_clk; @@ -141,24 +79,17 @@ static int exynos5440_pcie_init_clk_resources(struct exynos_pcie *ep)  	return 0;  err_bus_clk: -	clk_disable_unprepare(ep->clk_res->clk); +	clk_disable_unprepare(ep->clk);  	return ret;  } -static void exynos5440_pcie_deinit_clk_resources(struct exynos_pcie *ep) +static void exynos_pcie_deinit_clk_resources(struct exynos_pcie *ep)  { -	clk_disable_unprepare(ep->clk_res->bus_clk); -	clk_disable_unprepare(ep->clk_res->clk); +	clk_disable_unprepare(ep->bus_clk); +	clk_disable_unprepare(ep->clk);  } -static const struct exynos_pcie_ops exynos5440_pcie_ops = { -	.get_mem_resources	= exynos5440_pcie_get_mem_resources, -	.get_clk_resources	= exynos5440_pcie_get_clk_resources, -	.init_clk_resources	= exynos5440_pcie_init_clk_resources, -	.deinit_clk_resources	= exynos5440_pcie_deinit_clk_resources, -}; -  static void exynos_pcie_writel(void __iomem *base, u32 val, u32 reg)  {  	writel(val, base + reg); @@ -173,115 +104,71 @@ static void exynos_pcie_sideband_dbi_w_mode(struct exynos_pcie *ep, bool on)  {  	u32 val; -	val = exynos_pcie_readl(ep->mem_res->elbi_base, PCIE_ELBI_SLV_AWMISC); +	val = exynos_pcie_readl(ep->elbi_base, PCIE_ELBI_SLV_AWMISC);  	if (on)  		val |= PCIE_ELBI_SLV_DBI_ENABLE;  	else  		val &= ~PCIE_ELBI_SLV_DBI_ENABLE; -	exynos_pcie_writel(ep->mem_res->elbi_base, val, PCIE_ELBI_SLV_AWMISC); +	exynos_pcie_writel(ep->elbi_base, val, PCIE_ELBI_SLV_AWMISC);  }  static void exynos_pcie_sideband_dbi_r_mode(struct exynos_pcie *ep, bool on)  {  	u32 val; -	val = exynos_pcie_readl(ep->mem_res->elbi_base, PCIE_ELBI_SLV_ARMISC); +	val = exynos_pcie_readl(ep->elbi_base, PCIE_ELBI_SLV_ARMISC);  	if (on)  		val |= PCIE_ELBI_SLV_DBI_ENABLE;  	else  		val &= ~PCIE_ELBI_SLV_DBI_ENABLE; -	exynos_pcie_writel(ep->mem_res->elbi_base, val, PCIE_ELBI_SLV_ARMISC); +	exynos_pcie_writel(ep->elbi_base, val, PCIE_ELBI_SLV_ARMISC);  }  static void exynos_pcie_assert_core_reset(struct exynos_pcie *ep)  {  	u32 val; -	val = exynos_pcie_readl(ep->mem_res->elbi_base, PCIE_CORE_RESET); +	val = exynos_pcie_readl(ep->elbi_base, PCIE_CORE_RESET);  	val &= ~PCIE_CORE_RESET_ENABLE; -	exynos_pcie_writel(ep->mem_res->elbi_base, val, PCIE_CORE_RESET); -	exynos_pcie_writel(ep->mem_res->elbi_base, 0, PCIE_PWR_RESET); -	exynos_pcie_writel(ep->mem_res->elbi_base, 0, PCIE_STICKY_RESET); -	exynos_pcie_writel(ep->mem_res->elbi_base, 0, PCIE_NONSTICKY_RESET); +	exynos_pcie_writel(ep->elbi_base, val, PCIE_CORE_RESET); +	exynos_pcie_writel(ep->elbi_base, 0, PCIE_STICKY_RESET); +	exynos_pcie_writel(ep->elbi_base, 0, PCIE_NONSTICKY_RESET);  }  static void exynos_pcie_deassert_core_reset(struct exynos_pcie *ep)  {  	u32 val; -	val = exynos_pcie_readl(ep->mem_res->elbi_base, PCIE_CORE_RESET); +	val = exynos_pcie_readl(ep->elbi_base, PCIE_CORE_RESET);  	val |= PCIE_CORE_RESET_ENABLE; -	exynos_pcie_writel(ep->mem_res->elbi_base, val, PCIE_CORE_RESET); -	exynos_pcie_writel(ep->mem_res->elbi_base, 1, PCIE_STICKY_RESET); -	exynos_pcie_writel(ep->mem_res->elbi_base, 1, PCIE_NONSTICKY_RESET); -	exynos_pcie_writel(ep->mem_res->elbi_base, 1, PCIE_APP_INIT_RESET); -	exynos_pcie_writel(ep->mem_res->elbi_base, 0, PCIE_APP_INIT_RESET); -} - -static void exynos_pcie_assert_reset(struct exynos_pcie *ep) -{ -	struct dw_pcie *pci = ep->pci; -	struct device *dev = pci->dev; - -	if (ep->reset_gpio >= 0) -		devm_gpio_request_one(dev, ep->reset_gpio, -				GPIOF_OUT_INIT_HIGH, "RESET"); +	exynos_pcie_writel(ep->elbi_base, val, PCIE_CORE_RESET); +	exynos_pcie_writel(ep->elbi_base, 1, PCIE_STICKY_RESET); +	exynos_pcie_writel(ep->elbi_base, 1, PCIE_NONSTICKY_RESET); +	exynos_pcie_writel(ep->elbi_base, 1, PCIE_APP_INIT_RESET); +	exynos_pcie_writel(ep->elbi_base, 0, PCIE_APP_INIT_RESET);  } -static int exynos_pcie_establish_link(struct exynos_pcie *ep) +static int exynos_pcie_start_link(struct dw_pcie *pci)  { -	struct dw_pcie *pci = ep->pci; -	struct pcie_port *pp = &pci->pp; -	struct device *dev = pci->dev; - -	if (dw_pcie_link_up(pci)) { -		dev_err(dev, "Link already up\n"); -		return 0; -	} - -	exynos_pcie_assert_core_reset(ep); - -	phy_reset(ep->phy); - -	exynos_pcie_writel(ep->mem_res->elbi_base, 1, -			PCIE_PWR_RESET); +	struct exynos_pcie *ep = to_exynos_pcie(pci); +	u32 val; -	phy_power_on(ep->phy); -	phy_init(ep->phy); - -	exynos_pcie_deassert_core_reset(ep); -	dw_pcie_setup_rc(pp); -	exynos_pcie_assert_reset(ep); +	val = exynos_pcie_readl(ep->elbi_base, PCIE_SW_WAKE); +	val &= ~PCIE_BUS_EN; +	exynos_pcie_writel(ep->elbi_base, val, PCIE_SW_WAKE);  	/* assert LTSSM enable */ -	exynos_pcie_writel(ep->mem_res->elbi_base, PCIE_ELBI_LTSSM_ENABLE, +	exynos_pcie_writel(ep->elbi_base, PCIE_ELBI_LTSSM_ENABLE,  			  PCIE_APP_LTSSM_ENABLE); - -	/* check if the link is up or not */ -	if (!dw_pcie_wait_for_link(pci)) -		return 0; - -	phy_power_off(ep->phy); -	return -ETIMEDOUT; +	return 0;  }  static void exynos_pcie_clear_irq_pulse(struct exynos_pcie *ep)  { -	u32 val; +	u32 val = exynos_pcie_readl(ep->elbi_base, PCIE_IRQ_PULSE); -	val = exynos_pcie_readl(ep->mem_res->elbi_base, PCIE_IRQ_PULSE); -	exynos_pcie_writel(ep->mem_res->elbi_base, val, PCIE_IRQ_PULSE); -} - -static void exynos_pcie_enable_irq_pulse(struct exynos_pcie *ep) -{ -	u32 val; - -	/* enable INTX interrupt */ -	val = IRQ_INTA_ASSERT | IRQ_INTB_ASSERT | -		IRQ_INTC_ASSERT | IRQ_INTD_ASSERT; -	exynos_pcie_writel(ep->mem_res->elbi_base, val, PCIE_IRQ_EN_PULSE); +	exynos_pcie_writel(ep->elbi_base, val, PCIE_IRQ_PULSE);  }  static irqreturn_t exynos_pcie_irq_handler(int irq, void *arg) @@ -292,26 +179,14 @@ static irqreturn_t exynos_pcie_irq_handler(int irq, void *arg)  	return IRQ_HANDLED;  } -static void exynos_pcie_msi_init(struct exynos_pcie *ep) -{ -	struct dw_pcie *pci = ep->pci; -	struct pcie_port *pp = &pci->pp; -	u32 val; - -	dw_pcie_msi_init(pp); - -	/* enable MSI interrupt */ -	val = exynos_pcie_readl(ep->mem_res->elbi_base, PCIE_IRQ_EN_LEVEL); -	val |= IRQ_MSI_ENABLE; -	exynos_pcie_writel(ep->mem_res->elbi_base, val, PCIE_IRQ_EN_LEVEL); -} - -static void exynos_pcie_enable_interrupts(struct exynos_pcie *ep) +static void exynos_pcie_enable_irq_pulse(struct exynos_pcie *ep)  { -	exynos_pcie_enable_irq_pulse(ep); +	u32 val = IRQ_INTA_ASSERT | IRQ_INTB_ASSERT | +		  IRQ_INTC_ASSERT | IRQ_INTD_ASSERT; -	if (IS_ENABLED(CONFIG_PCI_MSI)) -		exynos_pcie_msi_init(ep); +	exynos_pcie_writel(ep->elbi_base, val, PCIE_IRQ_EN_PULSE); +	exynos_pcie_writel(ep->elbi_base, 0, PCIE_IRQ_EN_LEVEL); +	exynos_pcie_writel(ep->elbi_base, 0, PCIE_IRQ_EN_SPECIAL);  }  static u32 exynos_pcie_read_dbi(struct dw_pcie *pci, void __iomem *base, @@ -370,13 +245,9 @@ static struct pci_ops exynos_pci_ops = {  static int exynos_pcie_link_up(struct dw_pcie *pci)  {  	struct exynos_pcie *ep = to_exynos_pcie(pci); -	u32 val; +	u32 val = exynos_pcie_readl(ep->elbi_base, PCIE_ELBI_RDLH_LINKUP); -	val = exynos_pcie_readl(ep->mem_res->elbi_base, PCIE_ELBI_RDLH_LINKUP); -	if (val == PCIE_ELBI_LTSSM_ENABLE) -		return 1; - -	return 0; +	return (val & PCIE_ELBI_XMLH_LINKUP);  }  static int exynos_pcie_host_init(struct pcie_port *pp) @@ -386,8 +257,14 @@ static int exynos_pcie_host_init(struct pcie_port *pp)  	pp->bridge->ops = &exynos_pci_ops; -	exynos_pcie_establish_link(ep); -	exynos_pcie_enable_interrupts(ep); +	exynos_pcie_assert_core_reset(ep); + +	phy_reset(ep->phy); +	phy_power_on(ep->phy); +	phy_init(ep->phy); + +	exynos_pcie_deassert_core_reset(ep); +	exynos_pcie_enable_irq_pulse(ep);  	return 0;  } @@ -396,32 +273,27 @@ static const struct dw_pcie_host_ops exynos_pcie_host_ops = {  	.host_init = exynos_pcie_host_init,  }; -static int __init exynos_add_pcie_port(struct exynos_pcie *ep, +static int exynos_add_pcie_port(struct exynos_pcie *ep,  				       struct platform_device *pdev)  { -	struct dw_pcie *pci = ep->pci; +	struct dw_pcie *pci = &ep->pci;  	struct pcie_port *pp = &pci->pp;  	struct device *dev = &pdev->dev;  	int ret; -	pp->irq = platform_get_irq(pdev, 1); +	pp->irq = platform_get_irq(pdev, 0);  	if (pp->irq < 0)  		return pp->irq;  	ret = devm_request_irq(dev, pp->irq, exynos_pcie_irq_handler, -				IRQF_SHARED, "exynos-pcie", ep); +			       IRQF_SHARED, "exynos-pcie", ep);  	if (ret) {  		dev_err(dev, "failed to request irq\n");  		return ret;  	} -	if (IS_ENABLED(CONFIG_PCI_MSI)) { -		pp->msi_irq = platform_get_irq(pdev, 0); -		if (pp->msi_irq < 0) -			return pp->msi_irq; -	} -  	pp->ops = &exynos_pcie_host_ops; +	pp->msi_irq = -ENODEV;  	ret = dw_pcie_host_init(pp);  	if (ret) { @@ -436,12 +308,12 @@ static const struct dw_pcie_ops dw_pcie_ops = {  	.read_dbi = exynos_pcie_read_dbi,  	.write_dbi = exynos_pcie_write_dbi,  	.link_up = exynos_pcie_link_up, +	.start_link = exynos_pcie_start_link,  }; -static int __init exynos_pcie_probe(struct platform_device *pdev) +static int exynos_pcie_probe(struct platform_device *pdev)  {  	struct device *dev = &pdev->dev; -	struct dw_pcie *pci;  	struct exynos_pcie *ep;  	struct device_node *np = dev->of_node;  	int ret; @@ -450,43 +322,45 @@ static int __init exynos_pcie_probe(struct platform_device *pdev)  	if (!ep)  		return -ENOMEM; -	pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL); -	if (!pci) -		return -ENOMEM; - -	pci->dev = dev; -	pci->ops = &dw_pcie_ops; - -	ep->pci = pci; -	ep->ops = (const struct exynos_pcie_ops *) -		of_device_get_match_data(dev); - -	ep->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0); +	ep->pci.dev = dev; +	ep->pci.ops = &dw_pcie_ops;  	ep->phy = devm_of_phy_get(dev, np, NULL); -	if (IS_ERR(ep->phy)) { -		if (PTR_ERR(ep->phy) != -ENODEV) -			return PTR_ERR(ep->phy); +	if (IS_ERR(ep->phy)) +		return PTR_ERR(ep->phy); -		ep->phy = NULL; -	} +	/* External Local Bus interface (ELBI) registers */ +	ep->elbi_base = devm_platform_ioremap_resource_byname(pdev, "elbi"); +	if (IS_ERR(ep->elbi_base)) +		return PTR_ERR(ep->elbi_base); -	if (ep->ops && ep->ops->get_mem_resources) { -		ret = ep->ops->get_mem_resources(pdev, ep); -		if (ret) -			return ret; +	ep->clk = devm_clk_get(dev, "pcie"); +	if (IS_ERR(ep->clk)) { +		dev_err(dev, "Failed to get pcie rc clock\n"); +		return PTR_ERR(ep->clk);  	} -	if (ep->ops && ep->ops->get_clk_resources && -			ep->ops->init_clk_resources) { -		ret = ep->ops->get_clk_resources(ep); -		if (ret) -			return ret; -		ret = ep->ops->init_clk_resources(ep); -		if (ret) -			return ret; +	ep->bus_clk = devm_clk_get(dev, "pcie_bus"); +	if (IS_ERR(ep->bus_clk)) { +		dev_err(dev, "Failed to get pcie bus clock\n"); +		return PTR_ERR(ep->bus_clk);  	} +	ep->supplies[0].supply = "vdd18"; +	ep->supplies[1].supply = "vdd10"; +	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ep->supplies), +				      ep->supplies); +	if (ret) +		return ret; + +	ret = exynos_pcie_init_clk_resources(ep); +	if (ret) +		return ret; + +	ret = regulator_bulk_enable(ARRAY_SIZE(ep->supplies), ep->supplies); +	if (ret) +		return ret; +  	platform_set_drvdata(pdev, ep);  	ret = exynos_add_pcie_port(ep, pdev); @@ -497,9 +371,9 @@ static int __init exynos_pcie_probe(struct platform_device *pdev)  fail_probe:  	phy_exit(ep->phy); +	exynos_pcie_deinit_clk_resources(ep); +	regulator_bulk_disable(ARRAY_SIZE(ep->supplies), ep->supplies); -	if (ep->ops && ep->ops->deinit_clk_resources) -		ep->ops->deinit_clk_resources(ep);  	return ret;  } @@ -507,32 +381,65 @@ static int __exit exynos_pcie_remove(struct platform_device *pdev)  {  	struct exynos_pcie *ep = platform_get_drvdata(pdev); -	if (ep->ops && ep->ops->deinit_clk_resources) -		ep->ops->deinit_clk_resources(ep); +	dw_pcie_host_deinit(&ep->pci.pp); +	exynos_pcie_assert_core_reset(ep); +	phy_power_off(ep->phy); +	phy_exit(ep->phy); +	exynos_pcie_deinit_clk_resources(ep); +	regulator_bulk_disable(ARRAY_SIZE(ep->supplies), ep->supplies);  	return 0;  } +static int __maybe_unused exynos_pcie_suspend_noirq(struct device *dev) +{ +	struct exynos_pcie *ep = dev_get_drvdata(dev); + +	exynos_pcie_assert_core_reset(ep); +	phy_power_off(ep->phy); +	phy_exit(ep->phy); +	regulator_bulk_disable(ARRAY_SIZE(ep->supplies), ep->supplies); + +	return 0; +} + +static int __maybe_unused exynos_pcie_resume_noirq(struct device *dev) +{ +	struct exynos_pcie *ep = dev_get_drvdata(dev); +	struct dw_pcie *pci = &ep->pci; +	struct pcie_port *pp = &pci->pp; +	int ret; + +	ret = regulator_bulk_enable(ARRAY_SIZE(ep->supplies), ep->supplies); +	if (ret) +		return ret; + +	/* exynos_pcie_host_init controls ep->phy */ +	exynos_pcie_host_init(pp); +	dw_pcie_setup_rc(pp); +	exynos_pcie_start_link(pci); +	return dw_pcie_wait_for_link(pci); +} + +static const struct dev_pm_ops exynos_pcie_pm_ops = { +	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(exynos_pcie_suspend_noirq, +				      exynos_pcie_resume_noirq) +}; +  static const struct of_device_id exynos_pcie_of_match[] = { -	{ -		.compatible = "samsung,exynos5440-pcie", -		.data = &exynos5440_pcie_ops -	}, -	{}, +	{ .compatible = "samsung,exynos5433-pcie", }, +	{ },  };  static struct platform_driver exynos_pcie_driver = { +	.probe		= exynos_pcie_probe,  	.remove		= __exit_p(exynos_pcie_remove),  	.driver = {  		.name	= "exynos-pcie",  		.of_match_table = exynos_pcie_of_match, +		.pm		= &exynos_pcie_pm_ops,  	},  }; - -/* Exynos PCIe driver does not allow module unload */ - -static int __init exynos_pcie_init(void) -{ -	return platform_driver_probe(&exynos_pcie_driver, exynos_pcie_probe); -} -subsys_initcall(exynos_pcie_init); +module_platform_driver(exynos_pcie_driver); +MODULE_LICENSE("GPL v2"); +MODULE_DEVICE_TABLE(of, exynos_pcie_of_match); diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 5cf1ef12fb9b..0cf1333c0440 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -745,9 +745,9 @@ static void imx6_pcie_ltssm_enable(struct device *dev)  	}  } -static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie) +static int imx6_pcie_start_link(struct dw_pcie *pci)  { -	struct dw_pcie *pci = imx6_pcie->pci; +	struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);  	struct device *dev = pci->dev;  	u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);  	u32 tmp; @@ -834,9 +834,6 @@ static int imx6_pcie_host_init(struct pcie_port *pp)  	imx6_pcie_init_phy(imx6_pcie);  	imx6_pcie_deassert_core_reset(imx6_pcie);  	imx6_setup_phy_mpll(imx6_pcie); -	dw_pcie_setup_rc(pp); -	imx6_pcie_establish_link(imx6_pcie); -	dw_pcie_msi_init(pp);  	return 0;  } @@ -845,33 +842,8 @@ static const struct dw_pcie_host_ops imx6_pcie_host_ops = {  	.host_init = imx6_pcie_host_init,  }; -static int imx6_add_pcie_port(struct imx6_pcie *imx6_pcie, -			      struct platform_device *pdev) -{ -	struct dw_pcie *pci = imx6_pcie->pci; -	struct pcie_port *pp = &pci->pp; -	struct device *dev = &pdev->dev; -	int ret; - -	if (IS_ENABLED(CONFIG_PCI_MSI)) { -		pp->msi_irq = platform_get_irq_byname(pdev, "msi"); -		if (pp->msi_irq < 0) -			return pp->msi_irq; -	} - -	pp->ops = &imx6_pcie_host_ops; - -	ret = dw_pcie_host_init(pp); -	if (ret) { -		dev_err(dev, "failed to initialize host\n"); -		return ret; -	} - -	return 0; -} -  static const struct dw_pcie_ops dw_pcie_ops = { -	/* No special ops needed, but pcie-designware still expects this struct */ +	.start_link = imx6_pcie_start_link,  };  #ifdef CONFIG_PM_SLEEP @@ -980,7 +952,7 @@ static int imx6_pcie_resume_noirq(struct device *dev)  	imx6_pcie_deassert_core_reset(imx6_pcie);  	dw_pcie_setup_rc(pp); -	ret = imx6_pcie_establish_link(imx6_pcie); +	ret = imx6_pcie_start_link(imx6_pcie->pci);  	if (ret < 0)  		dev_info(dev, "pcie link is down after resume.\n"); @@ -1014,6 +986,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)  	pci->dev = dev;  	pci->ops = &dw_pcie_ops; +	pci->pp.ops = &imx6_pcie_host_ops;  	imx6_pcie->pci = pci;  	imx6_pcie->drvdata = of_device_get_match_data(dev); @@ -1163,7 +1136,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)  	if (ret)  		return ret; -	ret = imx6_add_pcie_port(imx6_pcie, pdev); +	ret = dw_pcie_host_init(&pci->pp);  	if (ret < 0)  		return ret; diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c index a222728238ca..53aa35cb3a49 100644 --- a/drivers/pci/controller/dwc/pci-keystone.c +++ b/drivers/pci/controller/dwc/pci-keystone.c @@ -121,6 +121,7 @@ struct keystone_pcie {  	int			msi_host_irq;  	int			num_lanes; +	u32			num_viewport;  	struct phy		**phy;  	struct device_link	**link;  	struct			device_node *msi_intc_np; @@ -272,14 +273,6 @@ static void ks_pcie_handle_legacy_irq(struct keystone_pcie *ks_pcie,  	ks_pcie_app_writel(ks_pcie, IRQ_EOI, offset);  } -/* - * Dummy function so that DW core doesn't configure MSI - */ -static int ks_pcie_am654_msi_host_init(struct pcie_port *pp) -{ -	return 0; -} -  static void ks_pcie_enable_error_irq(struct keystone_pcie *ks_pcie)  {  	ks_pcie_app_writel(ks_pcie, ERR_IRQ_ENABLE_SET, ERR_IRQ_ALL); @@ -394,9 +387,9 @@ static void ks_pcie_clear_dbi_mode(struct keystone_pcie *ks_pcie)  static void ks_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)  {  	u32 val; +	u32 num_viewport = ks_pcie->num_viewport;  	struct dw_pcie *pci = ks_pcie->pci;  	struct pcie_port *pp = &pci->pp; -	u32 num_viewport = pci->num_viewport;  	u64 start, end;  	struct resource *mem;  	int i; @@ -519,14 +512,8 @@ static void ks_pcie_stop_link(struct dw_pcie *pci)  static int ks_pcie_start_link(struct dw_pcie *pci)  {  	struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); -	struct device *dev = pci->dev;  	u32 val; -	if (dw_pcie_link_up(pci)) { -		dev_dbg(dev, "link is already up\n"); -		return 0; -	} -  	/* Initiate Link Training */  	val = ks_pcie_app_readl(ks_pcie, CMD_STATUS);  	ks_pcie_app_writel(ks_pcie, CMD_STATUS, LTSSM_EN_VAL | val); @@ -821,8 +808,6 @@ static int __init ks_pcie_host_init(struct pcie_port *pp)  	if (ret)  		return ret; -	dw_pcie_setup_rc(pp); -  	ks_pcie_stop_link(pci);  	ks_pcie_setup_rc_app_regs(ks_pcie);  	writew(PCI_IO_RANGE_TYPE_32 | (PCI_IO_RANGE_TYPE_32 << 8), @@ -841,9 +826,6 @@ static int __init ks_pcie_host_init(struct pcie_port *pp)  			"Asynchronous external abort");  #endif -	ks_pcie_start_link(pci); -	dw_pcie_wait_for_link(pci); -  	return 0;  } @@ -854,7 +836,6 @@ static const struct dw_pcie_host_ops ks_pcie_host_ops = {  static const struct dw_pcie_host_ops ks_pcie_am654_host_ops = {  	.host_init = ks_pcie_host_init, -	.msi_host_init = ks_pcie_am654_msi_host_init,  };  static irqreturn_t ks_pcie_err_irq_handler(int irq, void *priv) @@ -864,23 +845,6 @@ static irqreturn_t ks_pcie_err_irq_handler(int irq, void *priv)  	return ks_pcie_handle_error_irq(ks_pcie);  } -static int __init ks_pcie_add_pcie_port(struct keystone_pcie *ks_pcie, -					struct platform_device *pdev) -{ -	struct dw_pcie *pci = ks_pcie->pci; -	struct pcie_port *pp = &pci->pp; -	struct device *dev = &pdev->dev; -	int ret; - -	ret = dw_pcie_host_init(pp); -	if (ret) { -		dev_err(dev, "failed to initialize host\n"); -		return ret; -	} - -	return 0; -} -  static void ks_pcie_am654_write_dbi2(struct dw_pcie *pci, void __iomem *base,  				     u32 reg, size_t size, u32 val)  { @@ -977,33 +941,6 @@ static const struct dw_pcie_ep_ops ks_pcie_am654_ep_ops = {  	.get_features = &ks_pcie_am654_get_features,  }; -static int __init ks_pcie_add_pcie_ep(struct keystone_pcie *ks_pcie, -				      struct platform_device *pdev) -{ -	int ret; -	struct dw_pcie_ep *ep; -	struct resource *res; -	struct device *dev = &pdev->dev; -	struct dw_pcie *pci = ks_pcie->pci; - -	ep = &pci->ep; - -	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space"); -	if (!res) -		return -EINVAL; - -	ep->phys_base = res->start; -	ep->addr_size = resource_size(res); - -	ret = dw_pcie_ep_init(ep); -	if (ret) { -		dev_err(dev, "failed to initialize endpoint\n"); -		return ret; -	} - -	return 0; -} -  static void ks_pcie_disable_phy(struct keystone_pcie *ks_pcie)  {  	int num_lanes = ks_pcie->num_lanes; @@ -1157,6 +1094,7 @@ static int __init ks_pcie_probe(struct platform_device *pdev)  	struct resource *res;  	unsigned int version;  	void __iomem *base; +	u32 num_viewport;  	struct phy **phy;  	u32 num_lanes;  	char name[10]; @@ -1288,6 +1226,12 @@ static int __init ks_pcie_probe(struct platform_device *pdev)  			goto err_get_sync;  		} +		ret = of_property_read_u32(np, "num-viewport", &num_viewport); +		if (ret < 0) { +			dev_err(dev, "unable to read *num-viewport* property\n"); +			goto err_get_sync; +		} +  		/*  		 * "Power Sequencing and Reset Signal Timings" table in  		 * PCI EXPRESS CARD ELECTROMECHANICAL SPECIFICATION, REV. 2.0 @@ -1301,8 +1245,9 @@ static int __init ks_pcie_probe(struct platform_device *pdev)  			gpiod_set_value_cansleep(gpiod, 1);  		} +		ks_pcie->num_viewport = num_viewport;  		pci->pp.ops = host_ops; -		ret = ks_pcie_add_pcie_port(ks_pcie, pdev); +		ret = dw_pcie_host_init(&pci->pp);  		if (ret < 0)  			goto err_get_sync;  		break; @@ -1313,7 +1258,7 @@ static int __init ks_pcie_probe(struct platform_device *pdev)  		}  		pci->ep.ops = ep_ops; -		ret = ks_pcie_add_pcie_ep(ks_pcie, pdev); +		ret = dw_pcie_ep_init(&pci->ep);  		if (ret < 0)  			goto err_get_sync;  		break; diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c index 84206f265e54..4d12efdacd2f 100644 --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c @@ -18,8 +18,6 @@  #include "pcie-designware.h" -#define PCIE_DBI2_OFFSET		0x1000	/* DBI2 base address*/ -  #define to_ls_pcie_ep(x)	dev_get_drvdata((x)->dev)  struct ls_pcie_ep_drvdata { @@ -124,34 +122,6 @@ static const struct of_device_id ls_pcie_ep_of_match[] = {  	{ },  }; -static int __init ls_add_pcie_ep(struct ls_pcie_ep *pcie, -				 struct platform_device *pdev) -{ -	struct dw_pcie *pci = pcie->pci; -	struct device *dev = pci->dev; -	struct dw_pcie_ep *ep; -	struct resource *res; -	int ret; - -	ep = &pci->ep; -	ep->ops = pcie->drvdata->ops; - -	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space"); -	if (!res) -		return -EINVAL; - -	ep->phys_base = res->start; -	ep->addr_size = resource_size(res); - -	ret = dw_pcie_ep_init(ep); -	if (ret) { -		dev_err(dev, "failed to initialize endpoint\n"); -		return ret; -	} - -	return 0; -} -  static int __init ls_pcie_ep_probe(struct platform_device *pdev)  {  	struct device *dev = &pdev->dev; @@ -159,7 +129,6 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)  	struct ls_pcie_ep *pcie;  	struct pci_epc_features *ls_epc;  	struct resource *dbi_base; -	int ret;  	pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);  	if (!pcie) @@ -188,13 +157,11 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)  	if (IS_ERR(pci->dbi_base))  		return PTR_ERR(pci->dbi_base); -	pci->dbi_base2 = pci->dbi_base + PCIE_DBI2_OFFSET; +	pci->ep.ops = &ls_pcie_ep_ops;  	platform_set_drvdata(pdev, pcie); -	ret = ls_add_pcie_ep(pcie, pdev); - -	return ret; +	return dw_pcie_ep_init(&pci->ep);  }  static struct platform_driver ls_pcie_ep_driver = { diff --git a/drivers/pci/controller/dwc/pci-layerscape.c b/drivers/pci/controller/dwc/pci-layerscape.c index f24f79a70d9a..44ad34cdc3bc 100644 --- a/drivers/pci/controller/dwc/pci-layerscape.c +++ b/drivers/pci/controller/dwc/pci-layerscape.c @@ -83,14 +83,6 @@ static void ls_pcie_drop_msg_tlp(struct ls_pcie *pcie)  	iowrite32(val, pci->dbi_base + PCIE_STRFMR1);  } -static void ls_pcie_disable_outbound_atus(struct ls_pcie *pcie) -{ -	int i; - -	for (i = 0; i < PCIE_IATU_NUM; i++) -		dw_pcie_disable_atu(pcie->pci, i, DW_PCIE_REGION_OUTBOUND); -} -  static int ls1021_pcie_link_up(struct dw_pcie *pci)  {  	u32 state; @@ -136,12 +128,6 @@ static int ls_pcie_host_init(struct pcie_port *pp)  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);  	struct ls_pcie *pcie = to_ls_pcie(pci); -	/* -	 * Disable outbound windows configured by the bootloader to avoid -	 * one transaction hitting multiple outbound windows. -	 * dw_pcie_setup_rc() will reconfigure the outbound windows. -	 */ -	ls_pcie_disable_outbound_atus(pcie);  	ls_pcie_fix_error_response(pcie);  	dw_pcie_dbi_ro_wr_en(pci); @@ -150,8 +136,6 @@ static int ls_pcie_host_init(struct pcie_port *pp)  	ls_pcie_drop_msg_tlp(pcie); -	dw_pcie_setup_rc(pp); -  	return 0;  } @@ -182,37 +166,12 @@ static int ls1021_pcie_host_init(struct pcie_port *pp)  	return ls_pcie_host_init(pp);  } -static int ls_pcie_msi_host_init(struct pcie_port *pp) -{ -	struct dw_pcie *pci = to_dw_pcie_from_pp(pp); -	struct device *dev = pci->dev; -	struct device_node *np = dev->of_node; -	struct device_node *msi_node; - -	/* -	 * The MSI domain is set by the generic of_msi_configure().  This -	 * .msi_host_init() function keeps us from doing the default MSI -	 * domain setup in dw_pcie_host_init() and also enforces the -	 * requirement that "msi-parent" exists. -	 */ -	msi_node = of_parse_phandle(np, "msi-parent", 0); -	if (!msi_node) { -		dev_err(dev, "failed to find msi-parent\n"); -		return -EINVAL; -	} - -	of_node_put(msi_node); -	return 0; -} -  static const struct dw_pcie_host_ops ls1021_pcie_host_ops = {  	.host_init = ls1021_pcie_host_init, -	.msi_host_init = ls_pcie_msi_host_init,  };  static const struct dw_pcie_host_ops ls_pcie_host_ops = {  	.host_init = ls_pcie_host_init, -	.msi_host_init = ls_pcie_msi_host_init,  };  static const struct dw_pcie_ops dw_ls1021_pcie_ops = { @@ -273,31 +232,12 @@ static const struct of_device_id ls_pcie_of_match[] = {  	{ },  }; -static int __init ls_add_pcie_port(struct ls_pcie *pcie) -{ -	struct dw_pcie *pci = pcie->pci; -	struct pcie_port *pp = &pci->pp; -	struct device *dev = pci->dev; -	int ret; - -	pp->ops = pcie->drvdata->ops; - -	ret = dw_pcie_host_init(pp); -	if (ret) { -		dev_err(dev, "failed to initialize host\n"); -		return ret; -	} - -	return 0; -} -  static int __init ls_pcie_probe(struct platform_device *pdev)  {  	struct device *dev = &pdev->dev;  	struct dw_pcie *pci;  	struct ls_pcie *pcie;  	struct resource *dbi_base; -	int ret;  	pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);  	if (!pcie) @@ -311,6 +251,7 @@ static int __init ls_pcie_probe(struct platform_device *pdev)  	pci->dev = dev;  	pci->ops = pcie->drvdata->dw_pcie_ops; +	pci->pp.ops = pcie->drvdata->ops;  	pcie->pci = pci; @@ -326,11 +267,7 @@ static int __init ls_pcie_probe(struct platform_device *pdev)  	platform_set_drvdata(pdev, pcie); -	ret = ls_add_pcie_port(pcie); -	if (ret < 0) -		return ret; - -	return 0; +	return dw_pcie_host_init(&pci->pp);  }  static struct platform_driver ls_pcie_driver = { diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c index 1913dc2c8fa0..686ded034f22 100644 --- a/drivers/pci/controller/dwc/pci-meson.c +++ b/drivers/pci/controller/dwc/pci-meson.c @@ -231,7 +231,7 @@ static void meson_pcie_assert_reset(struct meson_pcie *mp)  	gpiod_set_value_cansleep(mp->reset_gpio, 0);  } -static void meson_pcie_init_dw(struct meson_pcie *mp) +static void meson_pcie_ltssm_enable(struct meson_pcie *mp)  {  	u32 val; @@ -289,20 +289,14 @@ static void meson_set_max_rd_req_size(struct meson_pcie *mp, int size)  	dw_pcie_writel_dbi(pci, offset + PCI_EXP_DEVCTL, val);  } -static int meson_pcie_establish_link(struct meson_pcie *mp) +static int meson_pcie_start_link(struct dw_pcie *pci)  { -	struct dw_pcie *pci = &mp->pci; -	struct pcie_port *pp = &pci->pp; - -	meson_pcie_init_dw(mp); -	meson_set_max_payload(mp, MAX_PAYLOAD_SIZE); -	meson_set_max_rd_req_size(mp, MAX_READ_REQ_SIZE); - -	dw_pcie_setup_rc(pp); +	struct meson_pcie *mp = to_meson_pcie(pci); +	meson_pcie_ltssm_enable(mp);  	meson_pcie_assert_reset(mp); -	return dw_pcie_wait_for_link(pci); +	return 0;  }  static int meson_pcie_rd_own_conf(struct pci_bus *bus, u32 devfn, @@ -380,15 +374,11 @@ static int meson_pcie_host_init(struct pcie_port *pp)  {  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);  	struct meson_pcie *mp = to_meson_pcie(pci); -	int ret;  	pp->bridge->ops = &meson_pci_ops; -	ret = meson_pcie_establish_link(mp); -	if (ret) -		return ret; - -	dw_pcie_msi_init(pp); +	meson_set_max_payload(mp, MAX_PAYLOAD_SIZE); +	meson_set_max_rd_req_size(mp, MAX_READ_REQ_SIZE);  	return 0;  } @@ -397,33 +387,9 @@ static const struct dw_pcie_host_ops meson_pcie_host_ops = {  	.host_init = meson_pcie_host_init,  }; -static int meson_add_pcie_port(struct meson_pcie *mp, -			       struct platform_device *pdev) -{ -	struct dw_pcie *pci = &mp->pci; -	struct pcie_port *pp = &pci->pp; -	struct device *dev = &pdev->dev; -	int ret; - -	if (IS_ENABLED(CONFIG_PCI_MSI)) { -		pp->msi_irq = platform_get_irq(pdev, 0); -		if (pp->msi_irq < 0) -			return pp->msi_irq; -	} - -	pp->ops = &meson_pcie_host_ops; - -	ret = dw_pcie_host_init(pp); -	if (ret) { -		dev_err(dev, "failed to initialize host\n"); -		return ret; -	} - -	return 0; -} -  static const struct dw_pcie_ops dw_pcie_ops = {  	.link_up = meson_pcie_link_up, +	.start_link = meson_pcie_start_link,  };  static int meson_pcie_probe(struct platform_device *pdev) @@ -440,6 +406,7 @@ static int meson_pcie_probe(struct platform_device *pdev)  	pci = &mp->pci;  	pci->dev = dev;  	pci->ops = &dw_pcie_ops; +	pci->pp.ops = &meson_pcie_host_ops;  	pci->num_lanes = 1;  	mp->phy = devm_phy_get(dev, "pcie"); @@ -486,7 +453,7 @@ static int meson_pcie_probe(struct platform_device *pdev)  	platform_set_drvdata(pdev, mp); -	ret = meson_add_pcie_port(mp, pdev); +	ret = dw_pcie_host_init(&pci->pp);  	if (ret < 0) {  		dev_err(dev, "Add PCIe port failed, %d\n", ret);  		goto err_phy; diff --git a/drivers/pci/controller/dwc/pcie-al.c b/drivers/pci/controller/dwc/pcie-al.c index f973fbca90cf..abf37aa68e51 100644 --- a/drivers/pci/controller/dwc/pcie-al.c +++ b/drivers/pci/controller/dwc/pcie-al.c @@ -76,7 +76,6 @@ static int al_pcie_init(struct pci_config_window *cfg)  }  const struct pci_ecam_ops al_pcie_ops = { -	.bus_shift    = 20,  	.init         =  al_pcie_init,  	.pci_ops      = {  		.map_bus    = al_pcie_map_bus, @@ -138,8 +137,6 @@ struct al_pcie {  	struct al_pcie_target_bus_cfg target_bus_cfg;  }; -#define PCIE_ECAM_DEVFN(x)		(((x) & 0xff) << 12) -  #define to_al_pcie(x)		dev_get_drvdata((x)->dev)  static inline u32 al_pcie_controller_readl(struct al_pcie *pcie, u32 offset) @@ -226,11 +223,6 @@ static void __iomem *al_pcie_conf_addr_map_bus(struct pci_bus *bus,  	struct al_pcie_target_bus_cfg *target_bus_cfg = &pcie->target_bus_cfg;  	unsigned int busnr_ecam = busnr & target_bus_cfg->ecam_mask;  	unsigned int busnr_reg = busnr & target_bus_cfg->reg_mask; -	void __iomem *pci_base_addr; - -	pci_base_addr = (void __iomem *)((uintptr_t)pp->va_cfg0_base + -					 (busnr_ecam << 20) + -					 PCIE_ECAM_DEVFN(devfn));  	if (busnr_reg != target_bus_cfg->reg_val) {  		dev_dbg(pcie->pci->dev, "Changing target bus busnum val from 0x%x to 0x%x\n", @@ -241,7 +233,7 @@ static void __iomem *al_pcie_conf_addr_map_bus(struct pci_bus *bus,  				       target_bus_cfg->reg_mask);  	} -	return pci_base_addr + where; +	return pp->va_cfg0_base + PCIE_ECAM_OFFSET(busnr_ecam, devfn, where);  }  static struct pci_ops al_child_pci_ops = { @@ -264,7 +256,7 @@ static void al_pcie_config_prepare(struct al_pcie *pcie)  	target_bus_cfg = &pcie->target_bus_cfg; -	ecam_bus_mask = (pcie->ecam_size >> 20) - 1; +	ecam_bus_mask = (pcie->ecam_size >> PCIE_ECAM_BUS_SHIFT) - 1;  	if (ecam_bus_mask > 255) {  		dev_warn(pcie->dev, "ECAM window size is larger than 256MB. Cutting off at 256\n");  		ecam_bus_mask = 255; @@ -322,23 +314,6 @@ static const struct dw_pcie_host_ops al_pcie_host_ops = {  	.host_init = al_pcie_host_init,  }; -static int al_add_pcie_port(struct pcie_port *pp, -			    struct platform_device *pdev) -{ -	struct device *dev = &pdev->dev; -	int ret; - -	pp->ops = &al_pcie_host_ops; - -	ret = dw_pcie_host_init(pp); -	if (ret) { -		dev_err(dev, "failed to initialize host\n"); -		return ret; -	} - -	return 0; -} -  static const struct dw_pcie_ops dw_pcie_ops = {  }; @@ -347,7 +322,6 @@ static int al_pcie_probe(struct platform_device *pdev)  	struct device *dev = &pdev->dev;  	struct resource *controller_res;  	struct resource *ecam_res; -	struct resource *dbi_res;  	struct al_pcie *al_pcie;  	struct dw_pcie *pci; @@ -361,15 +335,11 @@ static int al_pcie_probe(struct platform_device *pdev)  	pci->dev = dev;  	pci->ops = &dw_pcie_ops; +	pci->pp.ops = &al_pcie_host_ops;  	al_pcie->pci = pci;  	al_pcie->dev = dev; -	dbi_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); -	pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_res); -	if (IS_ERR(pci->dbi_base)) -		return PTR_ERR(pci->dbi_base); -  	ecam_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");  	if (!ecam_res) {  		dev_err(dev, "couldn't find 'config' reg in DT\n"); @@ -386,12 +356,11 @@ static int al_pcie_probe(struct platform_device *pdev)  		return PTR_ERR(al_pcie->controller_base);  	} -	dev_dbg(dev, "From DT: dbi_base: %pR, controller_base: %pR\n", -		dbi_res, controller_res); +	dev_dbg(dev, "From DT: controller_base: %pR\n", controller_res);  	platform_set_drvdata(pdev, al_pcie); -	return al_add_pcie_port(&pci->pp, pdev); +	return dw_pcie_host_init(&pci->pp);  }  static const struct of_device_id al_pcie_of_match[] = { diff --git a/drivers/pci/controller/dwc/pcie-armada8k.c b/drivers/pci/controller/dwc/pcie-armada8k.c index 13901f359a41..4e2552dcf982 100644 --- a/drivers/pci/controller/dwc/pcie-armada8k.c +++ b/drivers/pci/controller/dwc/pcie-armada8k.c @@ -154,10 +154,22 @@ static int armada8k_pcie_link_up(struct dw_pcie *pci)  	return 0;  } -static void armada8k_pcie_establish_link(struct armada8k_pcie *pcie) +static int armada8k_pcie_start_link(struct dw_pcie *pci) +{ +	u32 reg; + +	/* Start LTSSM */ +	reg = dw_pcie_readl_dbi(pci, PCIE_GLOBAL_CONTROL_REG); +	reg |= PCIE_APP_LTSSM_EN; +	dw_pcie_writel_dbi(pci, PCIE_GLOBAL_CONTROL_REG, reg); + +	return 0; +} + +static int armada8k_pcie_host_init(struct pcie_port *pp)  { -	struct dw_pcie *pci = pcie->pci;  	u32 reg; +	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);  	if (!dw_pcie_link_up(pci)) {  		/* Disable LTSSM state machine to enable configuration */ @@ -193,26 +205,6 @@ static void armada8k_pcie_establish_link(struct armada8k_pcie *pcie)  	       PCIE_INT_C_ASSERT_MASK | PCIE_INT_D_ASSERT_MASK;  	dw_pcie_writel_dbi(pci, PCIE_GLOBAL_INT_MASK1_REG, reg); -	if (!dw_pcie_link_up(pci)) { -		/* Configuration done. Start LTSSM */ -		reg = dw_pcie_readl_dbi(pci, PCIE_GLOBAL_CONTROL_REG); -		reg |= PCIE_APP_LTSSM_EN; -		dw_pcie_writel_dbi(pci, PCIE_GLOBAL_CONTROL_REG, reg); -	} - -	/* Wait until the link becomes active again */ -	if (dw_pcie_wait_for_link(pci)) -		dev_err(pci->dev, "Link not up after reconfiguration\n"); -} - -static int armada8k_pcie_host_init(struct pcie_port *pp) -{ -	struct dw_pcie *pci = to_dw_pcie_from_pp(pp); -	struct armada8k_pcie *pcie = to_armada8k_pcie(pci); - -	dw_pcie_setup_rc(pp); -	armada8k_pcie_establish_link(pcie); -  	return 0;  } @@ -269,6 +261,7 @@ static int armada8k_add_pcie_port(struct armada8k_pcie *pcie,  static const struct dw_pcie_ops dw_pcie_ops = {  	.link_up = armada8k_pcie_link_up, +	.start_link = armada8k_pcie_start_link,  };  static int armada8k_pcie_probe(struct platform_device *pdev) diff --git a/drivers/pci/controller/dwc/pcie-artpec6.c b/drivers/pci/controller/dwc/pcie-artpec6.c index 929448e9e0bc..597c282f586c 100644 --- a/drivers/pci/controller/dwc/pcie-artpec6.c +++ b/drivers/pci/controller/dwc/pcie-artpec6.c @@ -328,10 +328,6 @@ static int artpec6_pcie_host_init(struct pcie_port *pp)  	artpec6_pcie_init_phy(artpec6_pcie);  	artpec6_pcie_deassert_core_reset(artpec6_pcie);  	artpec6_pcie_wait_for_phy(artpec6_pcie); -	dw_pcie_setup_rc(pp); -	artpec6_pcie_establish_link(pci); -	dw_pcie_wait_for_link(pci); -	dw_pcie_msi_init(pp);  	return 0;  } @@ -340,31 +336,6 @@ static const struct dw_pcie_host_ops artpec6_pcie_host_ops = {  	.host_init = artpec6_pcie_host_init,  }; -static int artpec6_add_pcie_port(struct artpec6_pcie *artpec6_pcie, -				 struct platform_device *pdev) -{ -	struct dw_pcie *pci = artpec6_pcie->pci; -	struct pcie_port *pp = &pci->pp; -	struct device *dev = pci->dev; -	int ret; - -	if (IS_ENABLED(CONFIG_PCI_MSI)) { -		pp->msi_irq = platform_get_irq_byname(pdev, "msi"); -		if (pp->msi_irq < 0) -			return pp->msi_irq; -	} - -	pp->ops = &artpec6_pcie_host_ops; - -	ret = dw_pcie_host_init(pp); -	if (ret) { -		dev_err(dev, "failed to initialize host\n"); -		return ret; -	} - -	return 0; -} -  static void artpec6_pcie_ep_init(struct dw_pcie_ep *ep)  {  	struct dw_pcie *pci = to_dw_pcie_from_ep(ep); @@ -403,38 +374,6 @@ static const struct dw_pcie_ep_ops pcie_ep_ops = {  	.raise_irq = artpec6_pcie_raise_irq,  }; -static int artpec6_add_pcie_ep(struct artpec6_pcie *artpec6_pcie, -			       struct platform_device *pdev) -{ -	int ret; -	struct dw_pcie_ep *ep; -	struct resource *res; -	struct device *dev = &pdev->dev; -	struct dw_pcie *pci = artpec6_pcie->pci; - -	ep = &pci->ep; -	ep->ops = &pcie_ep_ops; - -	pci->dbi_base2 = devm_platform_ioremap_resource_byname(pdev, "dbi2"); -	if (IS_ERR(pci->dbi_base2)) -		return PTR_ERR(pci->dbi_base2); - -	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space"); -	if (!res) -		return -EINVAL; - -	ep->phys_base = res->start; -	ep->addr_size = resource_size(res); - -	ret = dw_pcie_ep_init(ep); -	if (ret) { -		dev_err(dev, "failed to initialize endpoint\n"); -		return ret; -	} - -	return 0; -} -  static int artpec6_pcie_probe(struct platform_device *pdev)  {  	struct device *dev = &pdev->dev; @@ -469,10 +408,6 @@ static int artpec6_pcie_probe(struct platform_device *pdev)  	artpec6_pcie->variant = variant;  	artpec6_pcie->mode = mode; -	pci->dbi_base = devm_platform_ioremap_resource_byname(pdev, "dbi"); -	if (IS_ERR(pci->dbi_base)) -		return PTR_ERR(pci->dbi_base); -  	artpec6_pcie->phy_base =  		devm_platform_ioremap_resource_byname(pdev, "phy");  	if (IS_ERR(artpec6_pcie->phy_base)) @@ -491,7 +426,9 @@ static int artpec6_pcie_probe(struct platform_device *pdev)  		if (!IS_ENABLED(CONFIG_PCIE_ARTPEC6_HOST))  			return -ENODEV; -		ret = artpec6_add_pcie_port(artpec6_pcie, pdev); +		pci->pp.ops = &artpec6_pcie_host_ops; + +		ret = dw_pcie_host_init(&pci->pp);  		if (ret < 0)  			return ret;  		break; @@ -504,9 +441,10 @@ static int artpec6_pcie_probe(struct platform_device *pdev)  		val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);  		val &= ~PCIECFG_DEVICE_TYPE_MASK;  		artpec6_pcie_writel(artpec6_pcie, PCIECFG, val); -		ret = artpec6_add_pcie_ep(artpec6_pcie, pdev); -		if (ret < 0) -			return ret; + +		pci->ep.ops = &pcie_ep_ops; + +		return dw_pcie_ep_init(&pci->ep);  		break;  	}  	default: diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c index ad7da4ea43a5..bcd1cd9ba8c8 100644 --- a/drivers/pci/controller/dwc/pcie-designware-ep.c +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c @@ -7,6 +7,7 @@   */  #include <linux/of.h> +#include <linux/platform_device.h>  #include "pcie-designware.h"  #include <linux/pci-epc.h> @@ -160,8 +161,8 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, u8 func_no,  	u32 free_win;  	struct dw_pcie *pci = to_dw_pcie_from_ep(ep); -	free_win = find_first_zero_bit(ep->ib_window_map, ep->num_ib_windows); -	if (free_win >= ep->num_ib_windows) { +	free_win = find_first_zero_bit(ep->ib_window_map, pci->num_ib_windows); +	if (free_win >= pci->num_ib_windows) {  		dev_err(pci->dev, "No free inbound window\n");  		return -EINVAL;  	} @@ -186,8 +187,8 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, u8 func_no,  	u32 free_win;  	struct dw_pcie *pci = to_dw_pcie_from_ep(ep); -	free_win = find_first_zero_bit(ep->ob_window_map, ep->num_ob_windows); -	if (free_win >= ep->num_ob_windows) { +	free_win = find_first_zero_bit(ep->ob_window_map, pci->num_ob_windows); +	if (free_win >= pci->num_ob_windows) {  		dev_err(pci->dev, "No free outbound window\n");  		return -EINVAL;  	} @@ -263,8 +264,9 @@ static int dw_pcie_find_index(struct dw_pcie_ep *ep, phys_addr_t addr,  			      u32 *atu_index)  {  	u32 index; +	struct dw_pcie *pci = to_dw_pcie_from_ep(ep); -	for (index = 0; index < ep->num_ob_windows; index++) { +	for (index = 0; index < pci->num_ob_windows; index++) {  		if (ep->outbound_addr[index] != addr)  			continue;  		*atu_index = index; @@ -676,55 +678,57 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)  	int ret;  	void *addr;  	u8 func_no; +	struct resource *res;  	struct pci_epc *epc;  	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);  	struct device *dev = pci->dev; +	struct platform_device *pdev = to_platform_device(dev);  	struct device_node *np = dev->of_node;  	const struct pci_epc_features *epc_features;  	struct dw_pcie_ep_func *ep_func;  	INIT_LIST_HEAD(&ep->func_list); -	if (!pci->dbi_base || !pci->dbi_base2) { -		dev_err(dev, "dbi_base/dbi_base2 is not populated\n"); -		return -EINVAL; +	if (!pci->dbi_base) { +		res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); +		pci->dbi_base = devm_pci_remap_cfg_resource(dev, res); +		if (IS_ERR(pci->dbi_base)) +			return PTR_ERR(pci->dbi_base);  	} -	ret = of_property_read_u32(np, "num-ib-windows", &ep->num_ib_windows); -	if (ret < 0) { -		dev_err(dev, "Unable to read *num-ib-windows* property\n"); -		return ret; -	} -	if (ep->num_ib_windows > MAX_IATU_IN) { -		dev_err(dev, "Invalid *num-ib-windows*\n"); -		return -EINVAL; +	if (!pci->dbi_base2) { +		res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi2"); +		if (!res) +			pci->dbi_base2 = pci->dbi_base + SZ_4K; +		else { +			pci->dbi_base2 = devm_pci_remap_cfg_resource(dev, res); +			if (IS_ERR(pci->dbi_base2)) +				return PTR_ERR(pci->dbi_base2); +		}  	} -	ret = of_property_read_u32(np, "num-ob-windows", &ep->num_ob_windows); -	if (ret < 0) { -		dev_err(dev, "Unable to read *num-ob-windows* property\n"); -		return ret; -	} -	if (ep->num_ob_windows > MAX_IATU_OUT) { -		dev_err(dev, "Invalid *num-ob-windows*\n"); +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space"); +	if (!res)  		return -EINVAL; -	} + +	ep->phys_base = res->start; +	ep->addr_size = resource_size(res);  	ep->ib_window_map = devm_kcalloc(dev, -					 BITS_TO_LONGS(ep->num_ib_windows), +					 BITS_TO_LONGS(pci->num_ib_windows),  					 sizeof(long),  					 GFP_KERNEL);  	if (!ep->ib_window_map)  		return -ENOMEM;  	ep->ob_window_map = devm_kcalloc(dev, -					 BITS_TO_LONGS(ep->num_ob_windows), +					 BITS_TO_LONGS(pci->num_ob_windows),  					 sizeof(long),  					 GFP_KERNEL);  	if (!ep->ob_window_map)  		return -ENOMEM; -	addr = devm_kcalloc(dev, ep->num_ob_windows, sizeof(phys_addr_t), +	addr = devm_kcalloc(dev, pci->num_ob_windows, sizeof(phys_addr_t),  			    GFP_KERNEL);  	if (!addr)  		return -ENOMEM; diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index 44c2a6572199..516b151e0ef3 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -256,7 +256,7 @@ int dw_pcie_allocate_domains(struct pcie_port *pp)  	return 0;  } -void dw_pcie_free_msi(struct pcie_port *pp) +static void dw_pcie_free_msi(struct pcie_port *pp)  {  	if (pp->msi_irq) {  		irq_set_chained_handler(pp->msi_irq, NULL); @@ -275,19 +275,18 @@ void dw_pcie_free_msi(struct pcie_port *pp)  	}  } -void dw_pcie_msi_init(struct pcie_port *pp) +static void dw_pcie_msi_init(struct pcie_port *pp)  {  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);  	u64 msi_target = (u64)pp->msi_data; -	if (!IS_ENABLED(CONFIG_PCI_MSI)) +	if (!pci_msi_enabled() || !pp->has_msi_ctrl)  		return;  	/* Program the msi_data */  	dw_pcie_writel_dbi(pci, PCIE_MSI_ADDR_LO, lower_32_bits(msi_target));  	dw_pcie_writel_dbi(pci, PCIE_MSI_ADDR_HI, upper_32_bits(msi_target));  } -EXPORT_SYMBOL_GPL(dw_pcie_msi_init);  int dw_pcie_host_init(struct pcie_port *pp)  { @@ -310,6 +309,13 @@ int dw_pcie_host_init(struct pcie_port *pp)  		dev_err(dev, "Missing *config* reg space\n");  	} +	if (!pci->dbi_base) { +		struct resource *dbi_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); +		pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_res); +		if (IS_ERR(pci->dbi_base)) +			return PTR_ERR(pci->dbi_base); +	} +  	bridge = devm_pci_alloc_host_bridge(dev, 0);  	if (!bridge)  		return -ENOMEM; @@ -350,44 +356,54 @@ int dw_pcie_host_init(struct pcie_port *pp)  		}  	} -	ret = of_property_read_u32(np, "num-viewport", &pci->num_viewport); -	if (ret) -		pci->num_viewport = 2; -  	if (pci->link_gen < 1)  		pci->link_gen = of_pci_get_max_link_speed(np);  	if (pci_msi_enabled()) { -		/* -		 * If a specific SoC driver needs to change the -		 * default number of vectors, it needs to implement -		 * the set_num_vectors callback. -		 */ -		if (!pp->ops->set_num_vectors) { +		pp->has_msi_ctrl = !(pp->ops->msi_host_init || +				     of_property_read_bool(np, "msi-parent") || +				     of_property_read_bool(np, "msi-map")); + +		if (!pp->num_vectors) {  			pp->num_vectors = MSI_DEF_NUM_VECTORS; -		} else { -			pp->ops->set_num_vectors(pp); - -			if (pp->num_vectors > MAX_MSI_IRQS || -			    pp->num_vectors == 0) { -				dev_err(dev, -					"Invalid number of vectors\n"); -				return -EINVAL; -			} +		} else if (pp->num_vectors > MAX_MSI_IRQS) { +			dev_err(dev, "Invalid number of vectors\n"); +			return -EINVAL;  		} -		if (!pp->ops->msi_host_init) { +		if (pp->ops->msi_host_init) { +			ret = pp->ops->msi_host_init(pp); +			if (ret < 0) +				return ret; +		} else if (pp->has_msi_ctrl) { +			if (!pp->msi_irq) { +				pp->msi_irq = platform_get_irq_byname_optional(pdev, "msi"); +				if (pp->msi_irq < 0) { +					pp->msi_irq = platform_get_irq(pdev, 0); +					if (pp->msi_irq < 0) +						return pp->msi_irq; +				} +			} +  			pp->msi_irq_chip = &dw_pci_msi_bottom_irq_chip;  			ret = dw_pcie_allocate_domains(pp);  			if (ret)  				return ret; -			if (pp->msi_irq) +			if (pp->msi_irq > 0)  				irq_set_chained_handler_and_data(pp->msi_irq,  							    dw_chained_msi_isr,  							    pp); +			ret = dma_set_mask(pci->dev, DMA_BIT_MASK(32)); +			if (!ret) { +				dev_warn(pci->dev, +					 "Failed to set DMA mask to 32-bit. " +					 "Devices with only 32-bit MSI support" +					 " may not work properly\n"); +			} +  			pp->msi_data = dma_map_single_attrs(pci->dev, &pp->msi_msg,  						      sizeof(pp->msi_msg),  						      DMA_FROM_DEVICE, @@ -397,10 +413,6 @@ int dw_pcie_host_init(struct pcie_port *pp)  				pp->msi_data = 0;  				goto err_free_msi;  			} -		} else { -			ret = pp->ops->msi_host_init(pp); -			if (ret < 0) -				return ret;  		}  	} @@ -414,6 +426,18 @@ int dw_pcie_host_init(struct pcie_port *pp)  			goto err_free_msi;  	} +	dw_pcie_setup_rc(pp); +	dw_pcie_msi_init(pp); + +	if (!dw_pcie_link_up(pci) && pci->ops->start_link) { +		ret = pci->ops->start_link(pci); +		if (ret) +			goto err_free_msi; +	} + +	/* Ignore errors, the link may come up later */ +	dw_pcie_wait_for_link(pci); +  	bridge->sysdata = pp;  	ret = pci_host_probe(bridge); @@ -421,7 +445,7 @@ int dw_pcie_host_init(struct pcie_port *pp)  		return 0;  err_free_msi: -	if (pci_msi_enabled() && !pp->ops->msi_host_init) +	if (pp->has_msi_ctrl)  		dw_pcie_free_msi(pp);  	return ret;  } @@ -431,7 +455,7 @@ void dw_pcie_host_deinit(struct pcie_port *pp)  {  	pci_stop_root_bus(pp->bridge->bus);  	pci_remove_root_bus(pp->bridge->bus); -	if (pci_msi_enabled() && !pp->ops->msi_host_init) +	if (pp->has_msi_ctrl)  		dw_pcie_free_msi(pp);  }  EXPORT_SYMBOL_GPL(dw_pcie_host_deinit); @@ -464,9 +488,7 @@ static void __iomem *dw_pcie_other_conf_map_bus(struct pci_bus *bus,  		type = PCIE_ATU_TYPE_CFG1; -	dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, -				  type, pp->cfg0_base, -				  busdev, pp->cfg0_size); +	dw_pcie_prog_outbound_atu(pci, 0, type, pp->cfg0_base, busdev, pp->cfg0_size);  	return pp->va_cfg0_base + where;  } @@ -480,9 +502,8 @@ static int dw_pcie_rd_other_conf(struct pci_bus *bus, unsigned int devfn,  	ret = pci_generic_config_read(bus, devfn, where, size, val); -	if (!ret && pci->num_viewport <= 2) -		dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, -					  PCIE_ATU_TYPE_IO, pp->io_base, +	if (!ret && pci->io_cfg_atu_shared) +		dw_pcie_prog_outbound_atu(pci, 0, PCIE_ATU_TYPE_IO, pp->io_base,  					  pp->io_bus_addr, pp->io_size);  	return ret; @@ -497,9 +518,8 @@ static int dw_pcie_wr_other_conf(struct pci_bus *bus, unsigned int devfn,  	ret = pci_generic_config_write(bus, devfn, where, size, val); -	if (!ret && pci->num_viewport <= 2) -		dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, -					  PCIE_ATU_TYPE_IO, pp->io_base, +	if (!ret && pci->io_cfg_atu_shared) +		dw_pcie_prog_outbound_atu(pci, 0, PCIE_ATU_TYPE_IO, pp->io_base,  					  pp->io_bus_addr, pp->io_size);  	return ret; @@ -531,6 +551,7 @@ static struct pci_ops dw_pcie_ops = {  void dw_pcie_setup_rc(struct pcie_port *pp)  { +	int i;  	u32 val, ctrl, num_ctrls;  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp); @@ -542,7 +563,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp)  	dw_pcie_setup(pci); -	if (pci_msi_enabled() && !pp->ops->msi_host_init) { +	if (pp->has_msi_ctrl) {  		num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL;  		/* Initialize IRQ Status array */ @@ -580,27 +601,45 @@ void dw_pcie_setup_rc(struct pcie_port *pp)  		PCI_COMMAND_MASTER | PCI_COMMAND_SERR;  	dw_pcie_writel_dbi(pci, PCI_COMMAND, val); +	/* Ensure all outbound windows are disabled so there are multiple matches */ +	for (i = 0; i < pci->num_ob_windows; i++) +		dw_pcie_disable_atu(pci, i, DW_PCIE_REGION_OUTBOUND); +  	/*  	 * If the platform provides its own child bus config accesses, it means  	 * the platform uses its own address translation component rather than  	 * ATU, so we should not program the ATU here.  	 */  	if (pp->bridge->child_ops == &dw_child_pcie_ops) { -		struct resource_entry *tmp, *entry = NULL; +		int atu_idx = 0; +		struct resource_entry *entry;  		/* Get last memory resource entry */ -		resource_list_for_each_entry(tmp, &pp->bridge->windows) -			if (resource_type(tmp->res) == IORESOURCE_MEM) -				entry = tmp; - -		dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX0, -					  PCIE_ATU_TYPE_MEM, entry->res->start, -					  entry->res->start - entry->offset, -					  resource_size(entry->res)); -		if (pci->num_viewport > 2) -			dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX2, -						  PCIE_ATU_TYPE_IO, pp->io_base, -						  pp->io_bus_addr, pp->io_size); +		resource_list_for_each_entry(entry, &pp->bridge->windows) { +			if (resource_type(entry->res) != IORESOURCE_MEM) +				continue; + +			if (pci->num_ob_windows <= ++atu_idx) +				break; + +			dw_pcie_prog_outbound_atu(pci, atu_idx, +						  PCIE_ATU_TYPE_MEM, entry->res->start, +						  entry->res->start - entry->offset, +						  resource_size(entry->res)); +		} + +		if (pp->io_size) { +			if (pci->num_ob_windows > ++atu_idx) +				dw_pcie_prog_outbound_atu(pci, atu_idx, +							  PCIE_ATU_TYPE_IO, pp->io_base, +							  pp->io_bus_addr, pp->io_size); +			else +				pci->io_cfg_atu_shared = true; +		} + +		if (pci->num_ob_windows <= atu_idx) +			dev_warn(pci->dev, "Resources exceed number of ATU entries (%d)", +				 pci->num_ob_windows);  	}  	dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, 0); diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c b/drivers/pci/controller/dwc/pcie-designware-plat.c index e3e300669ed5..9b397c807261 100644 --- a/drivers/pci/controller/dwc/pcie-designware-plat.c +++ b/drivers/pci/controller/dwc/pcie-designware-plat.c @@ -33,25 +33,7 @@ struct dw_plat_pcie_of_data {  static const struct of_device_id dw_plat_pcie_of_match[]; -static int dw_plat_pcie_host_init(struct pcie_port *pp) -{ -	struct dw_pcie *pci = to_dw_pcie_from_pp(pp); - -	dw_pcie_setup_rc(pp); -	dw_pcie_wait_for_link(pci); -	dw_pcie_msi_init(pp); - -	return 0; -} - -static void dw_plat_set_num_vectors(struct pcie_port *pp) -{ -	pp->num_vectors = MAX_MSI_IRQS; -} -  static const struct dw_pcie_host_ops dw_plat_pcie_host_ops = { -	.host_init = dw_plat_pcie_host_init, -	.set_num_vectors = dw_plat_set_num_vectors,  };  static int dw_plat_pcie_establish_link(struct dw_pcie *pci) @@ -122,12 +104,7 @@ static int dw_plat_add_pcie_port(struct dw_plat_pcie *dw_plat_pcie,  	if (pp->irq < 0)  		return pp->irq; -	if (IS_ENABLED(CONFIG_PCI_MSI)) { -		pp->msi_irq = platform_get_irq(pdev, 0); -		if (pp->msi_irq < 0) -			return pp->msi_irq; -	} - +	pp->num_vectors = MAX_MSI_IRQS;  	pp->ops = &dw_plat_pcie_host_ops;  	ret = dw_pcie_host_init(pp); @@ -139,43 +116,11 @@ static int dw_plat_add_pcie_port(struct dw_plat_pcie *dw_plat_pcie,  	return 0;  } -static int dw_plat_add_pcie_ep(struct dw_plat_pcie *dw_plat_pcie, -			       struct platform_device *pdev) -{ -	int ret; -	struct dw_pcie_ep *ep; -	struct resource *res; -	struct device *dev = &pdev->dev; -	struct dw_pcie *pci = dw_plat_pcie->pci; - -	ep = &pci->ep; -	ep->ops = &pcie_ep_ops; - -	pci->dbi_base2 = devm_platform_ioremap_resource_byname(pdev, "dbi2"); -	if (IS_ERR(pci->dbi_base2)) -		return PTR_ERR(pci->dbi_base2); - -	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space"); -	if (!res) -		return -EINVAL; - -	ep->phys_base = res->start; -	ep->addr_size = resource_size(res); - -	ret = dw_pcie_ep_init(ep); -	if (ret) { -		dev_err(dev, "Failed to initialize endpoint\n"); -		return ret; -	} -	return 0; -} -  static int dw_plat_pcie_probe(struct platform_device *pdev)  {  	struct device *dev = &pdev->dev;  	struct dw_plat_pcie *dw_plat_pcie;  	struct dw_pcie *pci; -	struct resource *res;  /* Resource from DT */  	int ret;  	const struct of_device_id *match;  	const struct dw_plat_pcie_of_data *data; @@ -202,14 +147,6 @@ static int dw_plat_pcie_probe(struct platform_device *pdev)  	dw_plat_pcie->pci = pci;  	dw_plat_pcie->mode = mode; -	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); -	if (!res) -		res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - -	pci->dbi_base = devm_ioremap_resource(dev, res); -	if (IS_ERR(pci->dbi_base)) -		return PTR_ERR(pci->dbi_base); -  	platform_set_drvdata(pdev, dw_plat_pcie);  	switch (dw_plat_pcie->mode) { @@ -225,9 +162,8 @@ static int dw_plat_pcie_probe(struct platform_device *pdev)  		if (!IS_ENABLED(CONFIG_PCIE_DW_PLAT_EP))  			return -ENODEV; -		ret = dw_plat_add_pcie_ep(dw_plat_pcie, pdev); -		if (ret < 0) -			return ret; +		pci->ep.ops = &pcie_ep_ops; +		return dw_pcie_ep_init(&pci->ep);  		break;  	default:  		dev_err(dev, "INVALID device type %d\n", dw_plat_pcie->mode); diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c index c2dea8fc97c8..645fa1892375 100644 --- a/drivers/pci/controller/dwc/pcie-designware.c +++ b/drivers/pci/controller/dwc/pcie-designware.c @@ -228,7 +228,7 @@ static void dw_pcie_writel_ob_unroll(struct dw_pcie *pci, u32 index, u32 reg,  static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, u8 func_no,  					     int index, int type,  					     u64 cpu_addr, u64 pci_addr, -					     u32 size) +					     u64 size)  {  	u32 retries, val;  	u64 limit_addr = cpu_addr + size - 1; @@ -245,8 +245,10 @@ static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, u8 func_no,  				 lower_32_bits(pci_addr));  	dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_UPPER_TARGET,  				 upper_32_bits(pci_addr)); -	dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL1, -				 type | PCIE_ATU_FUNC_NUM(func_no)); +	val = type | PCIE_ATU_FUNC_NUM(func_no); +	val = upper_32_bits(size - 1) ? +		val | PCIE_ATU_INCREASE_REGION_SIZE : val; +	dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL1, val);  	dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2,  				 PCIE_ATU_ENABLE); @@ -267,7 +269,7 @@ static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, u8 func_no,  static void __dw_pcie_prog_outbound_atu(struct dw_pcie *pci, u8 func_no,  					int index, int type, u64 cpu_addr, -					u64 pci_addr, u32 size) +					u64 pci_addr, u64 size)  {  	u32 retries, val; @@ -311,7 +313,7 @@ static void __dw_pcie_prog_outbound_atu(struct dw_pcie *pci, u8 func_no,  }  void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type, -			       u64 cpu_addr, u64 pci_addr, u32 size) +			       u64 cpu_addr, u64 pci_addr, u64 size)  {  	__dw_pcie_prog_outbound_atu(pci, 0, index, type,  				    cpu_addr, pci_addr, size); @@ -544,6 +546,70 @@ static u8 dw_pcie_iatu_unroll_enabled(struct dw_pcie *pci)  	return 0;  } +static void dw_pcie_iatu_detect_regions_unroll(struct dw_pcie *pci) +{ +	int max_region, i, ob = 0, ib = 0; +	u32 val; + +	max_region = min((int)pci->atu_size / 512, 256); + +	for (i = 0; i < max_region; i++) { +		dw_pcie_writel_ob_unroll(pci, i, PCIE_ATU_UNR_LOWER_TARGET, +					0x11110000); + +		val = dw_pcie_readl_ob_unroll(pci, i, PCIE_ATU_UNR_LOWER_TARGET); +		if (val == 0x11110000) +			ob++; +		else +			break; +	} + +	for (i = 0; i < max_region; i++) { +		dw_pcie_writel_ib_unroll(pci, i, PCIE_ATU_UNR_LOWER_TARGET, +					0x11110000); + +		val = dw_pcie_readl_ib_unroll(pci, i, PCIE_ATU_UNR_LOWER_TARGET); +		if (val == 0x11110000) +			ib++; +		else +			break; +	} +	pci->num_ib_windows = ib; +	pci->num_ob_windows = ob; +} + +static void dw_pcie_iatu_detect_regions(struct dw_pcie *pci) +{ +	int max_region, i, ob = 0, ib = 0; +	u32 val; + +	dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT, 0xFF); +	max_region = dw_pcie_readl_dbi(pci, PCIE_ATU_VIEWPORT) + 1; + +	for (i = 0; i < max_region; i++) { +		dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT, PCIE_ATU_REGION_OUTBOUND | i); +		dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_TARGET, 0x11110000); +		val = dw_pcie_readl_dbi(pci, PCIE_ATU_LOWER_TARGET); +		if (val == 0x11110000) +			ob++; +		else +			break; +	} + +	for (i = 0; i < max_region; i++) { +		dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT, PCIE_ATU_REGION_INBOUND | i); +		dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_TARGET, 0x11110000); +		val = dw_pcie_readl_dbi(pci, PCIE_ATU_LOWER_TARGET); +		if (val == 0x11110000) +			ib++; +		else +			break; +	} + +	pci->num_ib_windows = ib; +	pci->num_ob_windows = ob; +} +  void dw_pcie_setup(struct dw_pcie *pci)  {  	u32 val; @@ -554,15 +620,30 @@ void dw_pcie_setup(struct dw_pcie *pci)  	if (pci->version >= 0x480A || (!pci->version &&  				       dw_pcie_iatu_unroll_enabled(pci))) {  		pci->iatu_unroll_enabled = true; -		if (!pci->atu_base) -			pci->atu_base = -			    devm_platform_ioremap_resource_byname(pdev, "atu"); -		if (IS_ERR(pci->atu_base)) -			pci->atu_base = pci->dbi_base + DEFAULT_DBI_ATU_OFFSET; -	} -	dev_dbg(pci->dev, "iATU unroll: %s\n", pci->iatu_unroll_enabled ? +		if (!pci->atu_base) { +			struct resource *res = +				platform_get_resource_byname(pdev, IORESOURCE_MEM, "atu"); +			if (res) +				pci->atu_size = resource_size(res); +			pci->atu_base = devm_ioremap_resource(dev, res); +			if (IS_ERR(pci->atu_base)) +				pci->atu_base = pci->dbi_base + DEFAULT_DBI_ATU_OFFSET; +		} + +		if (!pci->atu_size) +			/* Pick a minimal default, enough for 8 in and 8 out windows */ +			pci->atu_size = SZ_4K; + +		dw_pcie_iatu_detect_regions_unroll(pci); +	} else +		dw_pcie_iatu_detect_regions(pci); + +	dev_info(pci->dev, "iATU unroll: %s\n", pci->iatu_unroll_enabled ?  		"enabled" : "disabled"); +	dev_info(pci->dev, "Detected iATU regions: %u outbound, %u inbound", +		 pci->num_ob_windows, pci->num_ib_windows); +  	if (pci->link_gen > 0)  		dw_pcie_link_set_max_speed(pci, pci->link_gen); diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index 9d2f511f13fa..0207840756c4 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h @@ -80,10 +80,8 @@  #define PCIE_ATU_VIEWPORT		0x900  #define PCIE_ATU_REGION_INBOUND		BIT(31)  #define PCIE_ATU_REGION_OUTBOUND	0 -#define PCIE_ATU_REGION_INDEX2		0x2 -#define PCIE_ATU_REGION_INDEX1		0x1 -#define PCIE_ATU_REGION_INDEX0		0x0  #define PCIE_ATU_CR1			0x904 +#define PCIE_ATU_INCREASE_REGION_SIZE	BIT(13)  #define PCIE_ATU_TYPE_MEM		0x0  #define PCIE_ATU_TYPE_IO		0x2  #define PCIE_ATU_TYPE_CFG0		0x4 @@ -174,11 +172,11 @@ enum dw_pcie_device_mode {  struct dw_pcie_host_ops {  	int (*host_init)(struct pcie_port *pp); -	void (*set_num_vectors)(struct pcie_port *pp);  	int (*msi_host_init)(struct pcie_port *pp);  };  struct pcie_port { +	bool			has_msi_ctrl:1;  	u64			cfg0_base;  	void __iomem		*va_cfg0_base;  	u32			cfg0_size; @@ -239,8 +237,6 @@ struct dw_pcie_ep {  	phys_addr_t		*outbound_addr;  	unsigned long		*ib_window_map;  	unsigned long		*ob_window_map; -	u32			num_ib_windows; -	u32			num_ob_windows;  	void __iomem		*msi_mem;  	phys_addr_t		msi_mem_phys;  	struct pci_epf_bar	*epf_bar[PCI_STD_NUM_BARS]; @@ -265,8 +261,9 @@ struct dw_pcie {  	void __iomem		*dbi_base2;  	/* Used when iatu_unroll_enabled is true */  	void __iomem		*atu_base; -	u32			num_viewport; -	u8			iatu_unroll_enabled; +	size_t			atu_size; +	u32			num_ib_windows; +	u32			num_ob_windows;  	struct pcie_port	pp;  	struct dw_pcie_ep	ep;  	const struct dw_pcie_ops *ops; @@ -274,6 +271,8 @@ struct dw_pcie {  	int			num_lanes;  	int			link_gen;  	u8			n_fts[2]; +	bool			iatu_unroll_enabled: 1; +	bool			io_cfg_atu_shared: 1;  };  #define to_dw_pcie_from_pp(port) container_of((port), struct dw_pcie, pp) @@ -295,7 +294,7 @@ void dw_pcie_upconfig_setup(struct dw_pcie *pci);  int dw_pcie_wait_for_link(struct dw_pcie *pci);  void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,  			       int type, u64 cpu_addr, u64 pci_addr, -			       u32 size); +			       u64 size);  void dw_pcie_prog_ep_outbound_atu(struct dw_pcie *pci, u8 func_no, int index,  				  int type, u64 cpu_addr, u64 pci_addr,  				  u32 size); @@ -365,8 +364,6 @@ static inline void dw_pcie_dbi_ro_wr_dis(struct dw_pcie *pci)  #ifdef CONFIG_PCIE_DW_HOST  irqreturn_t dw_handle_msi_irq(struct pcie_port *pp); -void dw_pcie_msi_init(struct pcie_port *pp); -void dw_pcie_free_msi(struct pcie_port *pp);  void dw_pcie_setup_rc(struct pcie_port *pp);  int dw_pcie_host_init(struct pcie_port *pp);  void dw_pcie_host_deinit(struct pcie_port *pp); @@ -379,14 +376,6 @@ static inline irqreturn_t dw_handle_msi_irq(struct pcie_port *pp)  	return IRQ_NONE;  } -static inline void dw_pcie_msi_init(struct pcie_port *pp) -{ -} - -static inline void dw_pcie_free_msi(struct pcie_port *pp) -{ -} -  static inline void dw_pcie_setup_rc(struct pcie_port *pp)  {  } diff --git a/drivers/pci/controller/dwc/pcie-hisi.c b/drivers/pci/controller/dwc/pcie-hisi.c index 5ca86796d43a..8fc5960faf28 100644 --- a/drivers/pci/controller/dwc/pcie-hisi.c +++ b/drivers/pci/controller/dwc/pcie-hisi.c @@ -100,7 +100,6 @@ static int hisi_pcie_init(struct pci_config_window *cfg)  }  const struct pci_ecam_ops hisi_pcie_ops = { -	.bus_shift    = 20,  	.init         =  hisi_pcie_init,  	.pci_ops      = {  		.map_bus    = hisi_pcie_map_bus, @@ -135,7 +134,6 @@ static int hisi_pcie_platform_init(struct pci_config_window *cfg)  }  static const struct pci_ecam_ops hisi_pcie_platform_ops = { -	.bus_shift    = 20,  	.init         =  hisi_pcie_platform_init,  	.pci_ops      = {  		.map_bus    = hisi_pcie_map_bus, diff --git a/drivers/pci/controller/dwc/pcie-histb.c b/drivers/pci/controller/dwc/pcie-histb.c index afc1abbe49aa..86f9d16c50d7 100644 --- a/drivers/pci/controller/dwc/pcie-histb.c +++ b/drivers/pci/controller/dwc/pcie-histb.c @@ -169,40 +169,32 @@ static int histb_pcie_link_up(struct dw_pcie *pci)  	return 0;  } -static int histb_pcie_establish_link(struct pcie_port *pp) +static int histb_pcie_start_link(struct dw_pcie *pci)  { -	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);  	struct histb_pcie *hipcie = to_histb_pcie(pci);  	u32 regval; -	if (dw_pcie_link_up(pci)) { -		dev_info(pci->dev, "Link already up\n"); -		return 0; -	} - -	/* PCIe RC work mode */ -	regval = histb_pcie_readl(hipcie, PCIE_SYS_CTRL0); -	regval &= ~PCIE_DEVICE_TYPE_MASK; -	regval |= PCIE_WM_RC; -	histb_pcie_writel(hipcie, PCIE_SYS_CTRL0, regval); - -	/* setup root complex */ -	dw_pcie_setup_rc(pp); -  	/* assert LTSSM enable */  	regval = histb_pcie_readl(hipcie, PCIE_SYS_CTRL7);  	regval |= PCIE_APP_LTSSM_ENABLE;  	histb_pcie_writel(hipcie, PCIE_SYS_CTRL7, regval); -	return dw_pcie_wait_for_link(pci); +	return 0;  }  static int histb_pcie_host_init(struct pcie_port *pp)  { +	struct dw_pcie *pci = to_dw_pcie_from_pp(pp); +	struct histb_pcie *hipcie = to_histb_pcie(pci); +	u32 regval; +  	pp->bridge->ops = &histb_pci_ops; -	histb_pcie_establish_link(pp); -	dw_pcie_msi_init(pp); +	/* PCIe RC work mode */ +	regval = histb_pcie_readl(hipcie, PCIE_SYS_CTRL0); +	regval &= ~PCIE_DEVICE_TYPE_MASK; +	regval |= PCIE_WM_RC; +	histb_pcie_writel(hipcie, PCIE_SYS_CTRL0, regval);  	return 0;  } @@ -300,6 +292,7 @@ static const struct dw_pcie_ops dw_pcie_ops = {  	.read_dbi = histb_pcie_read_dbi,  	.write_dbi = histb_pcie_write_dbi,  	.link_up = histb_pcie_link_up, +	.start_link = histb_pcie_start_link,  };  static int histb_pcie_probe(struct platform_device *pdev) @@ -400,12 +393,6 @@ static int histb_pcie_probe(struct platform_device *pdev)  		return PTR_ERR(hipcie->bus_reset);  	} -	if (IS_ENABLED(CONFIG_PCI_MSI)) { -		pp->msi_irq = platform_get_irq_byname(pdev, "msi"); -		if (pp->msi_irq < 0) -			return pp->msi_irq; -	} -  	hipcie->phy = devm_phy_get(dev, "phy");  	if (IS_ERR(hipcie->phy)) {  		dev_info(dev, "no pcie-phy found\n"); diff --git a/drivers/pci/controller/dwc/pcie-intel-gw.c b/drivers/pci/controller/dwc/pcie-intel-gw.c index 5650cb78acba..0cedd1f95f37 100644 --- a/drivers/pci/controller/dwc/pcie-intel-gw.c +++ b/drivers/pci/controller/dwc/pcie-intel-gw.c @@ -58,8 +58,6 @@  struct intel_pcie_soc {  	unsigned int	pcie_ver; -	unsigned int	pcie_atu_offset; -	u32		num_viewport;  };  struct intel_pcie_port { @@ -153,15 +151,6 @@ static void intel_pcie_init_n_fts(struct dw_pcie *pci)  	pci->n_fts[0] = PORT_AFR_N_FTS_GEN12_DFT;  } -static void intel_pcie_rc_setup(struct intel_pcie_port *lpp) -{ -	intel_pcie_ltssm_disable(lpp); -	intel_pcie_link_setup(lpp); -	intel_pcie_init_n_fts(&lpp->pci); -	dw_pcie_setup_rc(&lpp->pci.pp); -	dw_pcie_upconfig_setup(&lpp->pci); -} -  static int intel_pcie_ep_rst_init(struct intel_pcie_port *lpp)  {  	struct device *dev = lpp->pci.dev; @@ -213,14 +202,6 @@ static void intel_pcie_device_rst_deassert(struct intel_pcie_port *lpp)  	gpiod_set_value_cansleep(lpp->reset_gpio, 0);  } -static int intel_pcie_app_logic_setup(struct intel_pcie_port *lpp) -{ -	intel_pcie_device_rst_deassert(lpp); -	intel_pcie_ltssm_enable(lpp); - -	return dw_pcie_wait_for_link(&lpp->pci); -} -  static void intel_pcie_core_irq_disable(struct intel_pcie_port *lpp)  {  	pcie_app_wr(lpp, PCIE_APP_IRNEN, 0); @@ -234,10 +215,6 @@ static int intel_pcie_get_resources(struct platform_device *pdev)  	struct device *dev = pci->dev;  	int ret; -	pci->dbi_base = devm_platform_ioremap_resource_byname(pdev, "dbi"); -	if (IS_ERR(pci->dbi_base)) -		return PTR_ERR(pci->dbi_base); -  	lpp->core_clk = devm_clk_get(dev, NULL);  	if (IS_ERR(lpp->core_clk)) {  		ret = PTR_ERR(lpp->core_clk); @@ -274,11 +251,6 @@ static int intel_pcie_get_resources(struct platform_device *pdev)  	return 0;  } -static void intel_pcie_deinit_phy(struct intel_pcie_port *lpp) -{ -	phy_exit(lpp->phy); -} -  static int intel_pcie_wait_l2(struct intel_pcie_port *lpp)  {  	u32 value; @@ -315,6 +287,7 @@ static void intel_pcie_turn_off(struct intel_pcie_port *lpp)  static int intel_pcie_host_setup(struct intel_pcie_port *lpp)  {  	int ret; +	struct dw_pcie *pci = &lpp->pci;  	intel_pcie_core_rst_assert(lpp);  	intel_pcie_device_rst_assert(lpp); @@ -331,8 +304,18 @@ static int intel_pcie_host_setup(struct intel_pcie_port *lpp)  		goto clk_err;  	} -	intel_pcie_rc_setup(lpp); -	ret = intel_pcie_app_logic_setup(lpp); +	pci->atu_base = pci->dbi_base + 0xC0000; + +	intel_pcie_ltssm_disable(lpp); +	intel_pcie_link_setup(lpp); +	intel_pcie_init_n_fts(pci); +	dw_pcie_setup_rc(&pci->pp); +	dw_pcie_upconfig_setup(pci); + +	intel_pcie_device_rst_deassert(lpp); +	intel_pcie_ltssm_enable(lpp); + +	ret = dw_pcie_wait_for_link(pci);  	if (ret)  		goto app_init_err; @@ -346,7 +329,7 @@ app_init_err:  	clk_disable_unprepare(lpp->core_clk);  clk_err:  	intel_pcie_core_rst_assert(lpp); -	intel_pcie_deinit_phy(lpp); +	phy_exit(lpp->phy);  	return ret;  } @@ -357,7 +340,7 @@ static void __intel_pcie_remove(struct intel_pcie_port *lpp)  	intel_pcie_turn_off(lpp);  	clk_disable_unprepare(lpp->core_clk);  	intel_pcie_core_rst_assert(lpp); -	intel_pcie_deinit_phy(lpp); +	phy_exit(lpp->phy);  }  static int intel_pcie_remove(struct platform_device *pdev) @@ -381,7 +364,7 @@ static int __maybe_unused intel_pcie_suspend_noirq(struct device *dev)  	if (ret)  		return ret; -	intel_pcie_deinit_phy(lpp); +	phy_exit(lpp->phy);  	clk_disable_unprepare(lpp->core_clk);  	return ret;  } @@ -401,14 +384,6 @@ static int intel_pcie_rc_init(struct pcie_port *pp)  	return intel_pcie_host_setup(lpp);  } -/* - * Dummy function so that DW core doesn't configure MSI - */ -static int intel_pcie_msi_init(struct pcie_port *pp) -{ -	return 0; -} -  static u64 intel_pcie_cpu_addr(struct dw_pcie *pcie, u64 cpu_addr)  {  	return cpu_addr + BUS_IATU_OFFSET; @@ -420,13 +395,10 @@ static const struct dw_pcie_ops intel_pcie_ops = {  static const struct dw_pcie_host_ops intel_pcie_dw_ops = {  	.host_init =		intel_pcie_rc_init, -	.msi_host_init =	intel_pcie_msi_init,  };  static const struct intel_pcie_soc pcie_data = {  	.pcie_ver =		0x520A, -	.pcie_atu_offset =	0xC0000, -	.num_viewport =		3,  };  static int intel_pcie_probe(struct platform_device *pdev) @@ -461,7 +433,6 @@ static int intel_pcie_probe(struct platform_device *pdev)  	pci->ops = &intel_pcie_ops;  	pci->version = data->pcie_ver; -	pci->atu_base = pci->dbi_base + data->pcie_atu_offset;  	pp->ops = &intel_pcie_dw_ops;  	ret = dw_pcie_host_init(pp); @@ -470,12 +441,6 @@ static int intel_pcie_probe(struct platform_device *pdev)  		return ret;  	} -	/* -	 * Intel PCIe doesn't configure IO region, so set viewport -	 * to not perform IO region access. -	 */ -	pci->num_viewport = data->num_viewport; -  	return 0;  } diff --git a/drivers/pci/controller/dwc/pcie-kirin.c b/drivers/pci/controller/dwc/pcie-kirin.c index d0a6a2dee6f5..026fd1e42a55 100644 --- a/drivers/pci/controller/dwc/pcie-kirin.c +++ b/drivers/pci/controller/dwc/pcie-kirin.c @@ -157,11 +157,6 @@ static long kirin_pcie_get_resource(struct kirin_pcie *kirin_pcie,  	if (IS_ERR(kirin_pcie->phy_base))  		return PTR_ERR(kirin_pcie->phy_base); -	kirin_pcie->pci->dbi_base = -		devm_platform_ioremap_resource_byname(pdev, "dbi"); -	if (IS_ERR(kirin_pcie->pci->dbi_base)) -		return PTR_ERR(kirin_pcie->pci->dbi_base); -  	kirin_pcie->crgctrl =  		syscon_regmap_lookup_by_compatible("hisilicon,hi3660-crgctrl");  	if (IS_ERR(kirin_pcie->crgctrl)) @@ -395,32 +390,14 @@ static int kirin_pcie_link_up(struct dw_pcie *pci)  	return 0;  } -static int kirin_pcie_establish_link(struct pcie_port *pp) +static int kirin_pcie_start_link(struct dw_pcie *pci)  { -	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);  	struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci); -	struct device *dev = kirin_pcie->pci->dev; -	int count = 0; - -	if (kirin_pcie_link_up(pci)) -		return 0; - -	dw_pcie_setup_rc(pp);  	/* assert LTSSM enable */  	kirin_apb_ctrl_writel(kirin_pcie, PCIE_LTSSM_ENABLE_BIT,  			      PCIE_APP_LTSSM_ENABLE); -	/* check if the link is up or not */ -	while (!kirin_pcie_link_up(pci)) { -		usleep_range(LINK_WAIT_MIN, LINK_WAIT_MAX); -		count++; -		if (count == 1000) { -			dev_err(dev, "Link Fail\n"); -			return -EINVAL; -		} -	} -  	return 0;  } @@ -428,9 +405,6 @@ static int kirin_pcie_host_init(struct pcie_port *pp)  {  	pp->bridge->ops = &kirin_pci_ops; -	kirin_pcie_establish_link(pp); -	dw_pcie_msi_init(pp); -  	return 0;  } @@ -438,42 +412,13 @@ static const struct dw_pcie_ops kirin_dw_pcie_ops = {  	.read_dbi = kirin_pcie_read_dbi,  	.write_dbi = kirin_pcie_write_dbi,  	.link_up = kirin_pcie_link_up, +	.start_link = kirin_pcie_start_link,  };  static const struct dw_pcie_host_ops kirin_pcie_host_ops = {  	.host_init = kirin_pcie_host_init,  }; -static int kirin_pcie_add_msi(struct dw_pcie *pci, -				struct platform_device *pdev) -{ -	int irq; - -	if (IS_ENABLED(CONFIG_PCI_MSI)) { -		irq = platform_get_irq(pdev, 0); -		if (irq < 0) -			return irq; - -		pci->pp.msi_irq = irq; -	} - -	return 0; -} - -static int kirin_add_pcie_port(struct dw_pcie *pci, -			       struct platform_device *pdev) -{ -	int ret; - -	ret = kirin_pcie_add_msi(pci, pdev); -	if (ret) -		return ret; - -	pci->pp.ops = &kirin_pcie_host_ops; - -	return dw_pcie_host_init(&pci->pp); -} -  static int kirin_pcie_probe(struct platform_device *pdev)  {  	struct device *dev = &pdev->dev; @@ -496,6 +441,7 @@ static int kirin_pcie_probe(struct platform_device *pdev)  	pci->dev = dev;  	pci->ops = &kirin_dw_pcie_ops; +	pci->pp.ops = &kirin_pcie_host_ops;  	kirin_pcie->pci = pci;  	ret = kirin_pcie_get_clk(kirin_pcie, pdev); @@ -521,7 +467,7 @@ static int kirin_pcie_probe(struct platform_device *pdev)  	platform_set_drvdata(pdev, kirin_pcie); -	return kirin_add_pcie_port(pci, pdev); +	return dw_pcie_host_init(&pci->pp);  }  static const struct of_device_id kirin_pcie_match[] = { diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index b4761640ffd9..affa2713bf80 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -9,6 +9,7 @@   */  #include <linux/clk.h> +#include <linux/crc8.h>  #include <linux/delay.h>  #include <linux/gpio/consumer.h>  #include <linux/interrupt.h> @@ -57,6 +58,7 @@  #define PCIE20_PARF_SID_OFFSET			0x234  #define PCIE20_PARF_BDF_TRANSLATE_CFG		0x24C  #define PCIE20_PARF_DEVICE_TYPE			0x1000 +#define PCIE20_PARF_BDF_TO_SID_TABLE_N		0x2000  #define PCIE20_ELBI_SYS_CTRL			0x04  #define PCIE20_ELBI_SYS_CTRL_LT_ENABLE		BIT(0) @@ -97,6 +99,9 @@  #define QCOM_PCIE_2_1_0_MAX_SUPPLY	3  #define QCOM_PCIE_2_1_0_MAX_CLOCKS	5 + +#define QCOM_PCIE_CRC8_POLYNOMIAL (BIT(2) | BIT(1) | BIT(0)) +  struct qcom_pcie_resources_2_1_0 {  	struct clk_bulk_data clks[QCOM_PCIE_2_1_0_MAX_CLOCKS];  	struct reset_control *pci_reset; @@ -179,6 +184,7 @@ struct qcom_pcie_ops {  	void (*deinit)(struct qcom_pcie *pcie);  	void (*post_deinit)(struct qcom_pcie *pcie);  	void (*ltssm_enable)(struct qcom_pcie *pcie); +	int (*config_sid)(struct qcom_pcie *pcie);  };  struct qcom_pcie { @@ -207,18 +213,15 @@ static void qcom_ep_reset_deassert(struct qcom_pcie *pcie)  	usleep_range(PERST_DELAY_US, PERST_DELAY_US + 500);  } -static int qcom_pcie_establish_link(struct qcom_pcie *pcie) +static int qcom_pcie_start_link(struct dw_pcie *pci)  { -	struct dw_pcie *pci = pcie->pci; - -	if (dw_pcie_link_up(pci)) -		return 0; +	struct qcom_pcie *pcie = to_qcom_pcie(pci);  	/* Enable Link Training state machine */  	if (pcie->ops->ltssm_enable)  		pcie->ops->ltssm_enable(pcie); -	return dw_pcie_wait_for_link(pci); +	return 0;  }  static void qcom_pcie_2_1_0_ltssm_enable(struct qcom_pcie *pcie) @@ -1261,6 +1264,77 @@ static int qcom_pcie_link_up(struct dw_pcie *pci)  	return !!(val & PCI_EXP_LNKSTA_DLLLA);  } +static int qcom_pcie_config_sid_sm8250(struct qcom_pcie *pcie) +{ +	/* iommu map structure */ +	struct { +		u32 bdf; +		u32 phandle; +		u32 smmu_sid; +		u32 smmu_sid_len; +	} *map; +	void __iomem *bdf_to_sid_base = pcie->parf + PCIE20_PARF_BDF_TO_SID_TABLE_N; +	struct device *dev = pcie->pci->dev; +	u8 qcom_pcie_crc8_table[CRC8_TABLE_SIZE]; +	int i, nr_map, size = 0; +	u32 smmu_sid_base; + +	of_get_property(dev->of_node, "iommu-map", &size); +	if (!size) +		return 0; + +	map = kzalloc(size, GFP_KERNEL); +	if (!map) +		return -ENOMEM; + +	of_property_read_u32_array(dev->of_node, +		"iommu-map", (u32 *)map, size / sizeof(u32)); + +	nr_map = size / (sizeof(*map)); + +	crc8_populate_msb(qcom_pcie_crc8_table, QCOM_PCIE_CRC8_POLYNOMIAL); + +	/* Registers need to be zero out first */ +	memset_io(bdf_to_sid_base, 0, CRC8_TABLE_SIZE * sizeof(u32)); + +	/* Extract the SMMU SID base from the first entry of iommu-map */ +	smmu_sid_base = map[0].smmu_sid; + +	/* Look for an available entry to hold the mapping */ +	for (i = 0; i < nr_map; i++) { +		u16 bdf_be = cpu_to_be16(map[i].bdf); +		u32 val; +		u8 hash; + +		hash = crc8(qcom_pcie_crc8_table, (u8 *)&bdf_be, sizeof(bdf_be), +			0); + +		val = readl(bdf_to_sid_base + hash * sizeof(u32)); + +		/* If the register is already populated, look for next available entry */ +		while (val) { +			u8 current_hash = hash++; +			u8 next_mask = 0xff; + +			/* If NEXT field is NULL then update it with next hash */ +			if (!(val & next_mask)) { +				val |= (u32)hash; +				writel(val, bdf_to_sid_base + current_hash * sizeof(u32)); +			} + +			val = readl(bdf_to_sid_base + hash * sizeof(u32)); +		} + +		/* BDF [31:16] | SID [15:8] | NEXT [7:0] */ +		val = map[i].bdf << 16 | (map[i].smmu_sid - smmu_sid_base) << 8 | 0; +		writel(val, bdf_to_sid_base + hash * sizeof(u32)); +	} + +	kfree(map); + +	return 0; +} +  static int qcom_pcie_host_init(struct pcie_port *pp)  {  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp); @@ -1283,16 +1357,16 @@ static int qcom_pcie_host_init(struct pcie_port *pp)  			goto err_disable_phy;  	} -	dw_pcie_setup_rc(pp); -	dw_pcie_msi_init(pp); -  	qcom_ep_reset_deassert(pcie); -	ret = qcom_pcie_establish_link(pcie); -	if (ret) -		goto err; +	if (pcie->ops->config_sid) { +		ret = pcie->ops->config_sid(pcie); +		if (ret) +			goto err; +	}  	return 0; +  err:  	qcom_ep_reset_assert(pcie);  	if (pcie->ops->post_deinit) @@ -1361,14 +1435,25 @@ static const struct qcom_pcie_ops ops_2_7_0 = {  	.post_deinit = qcom_pcie_post_deinit_2_7_0,  }; +/* Qcom IP rev.: 1.9.0 */ +static const struct qcom_pcie_ops ops_1_9_0 = { +	.get_resources = qcom_pcie_get_resources_2_7_0, +	.init = qcom_pcie_init_2_7_0, +	.deinit = qcom_pcie_deinit_2_7_0, +	.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable, +	.post_init = qcom_pcie_post_init_2_7_0, +	.post_deinit = qcom_pcie_post_deinit_2_7_0, +	.config_sid = qcom_pcie_config_sid_sm8250, +}; +  static const struct dw_pcie_ops dw_pcie_ops = {  	.link_up = qcom_pcie_link_up, +	.start_link = qcom_pcie_start_link,  };  static int qcom_pcie_probe(struct platform_device *pdev)  {  	struct device *dev = &pdev->dev; -	struct resource *res;  	struct pcie_port *pp;  	struct dw_pcie *pci;  	struct qcom_pcie *pcie; @@ -1407,13 +1492,6 @@ static int qcom_pcie_probe(struct platform_device *pdev)  		goto err_pm_runtime_put;  	} -	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); -	pci->dbi_base = devm_pci_remap_cfg_resource(dev, res); -	if (IS_ERR(pci->dbi_base)) { -		ret = PTR_ERR(pci->dbi_base); -		goto err_pm_runtime_put; -	} -  	pcie->elbi = devm_platform_ioremap_resource_byname(pdev, "elbi");  	if (IS_ERR(pcie->elbi)) {  		ret = PTR_ERR(pcie->elbi); @@ -1432,14 +1510,6 @@ static int qcom_pcie_probe(struct platform_device *pdev)  	pp->ops = &qcom_pcie_dw_ops; -	if (IS_ENABLED(CONFIG_PCI_MSI)) { -		pp->msi_irq = platform_get_irq_byname(pdev, "msi"); -		if (pp->msi_irq < 0) { -			ret = pp->msi_irq; -			goto err_pm_runtime_put; -		} -	} -  	ret = phy_init(pcie->phy);  	if (ret) {  		pm_runtime_disable(&pdev->dev); @@ -1474,6 +1544,7 @@ static const struct of_device_id qcom_pcie_match[] = {  	{ .compatible = "qcom,pcie-ipq4019", .data = &ops_2_4_0 },  	{ .compatible = "qcom,pcie-qcs404", .data = &ops_2_4_0 },  	{ .compatible = "qcom,pcie-sdm845", .data = &ops_2_7_0 }, +	{ .compatible = "qcom,pcie-sm8250", .data = &ops_1_9_0 },  	{ }  }; diff --git a/drivers/pci/controller/dwc/pcie-spear13xx.c b/drivers/pci/controller/dwc/pcie-spear13xx.c index e348225f651f..1a9e353bef55 100644 --- a/drivers/pci/controller/dwc/pcie-spear13xx.c +++ b/drivers/pci/controller/dwc/pcie-spear13xx.c @@ -66,32 +66,10 @@ struct pcie_app_reg {  #define to_spear13xx_pcie(x)	dev_get_drvdata((x)->dev) -static int spear13xx_pcie_establish_link(struct spear13xx_pcie *spear13xx_pcie) +static int spear13xx_pcie_start_link(struct dw_pcie *pci)  { -	struct dw_pcie *pci = spear13xx_pcie->pci; -	struct pcie_port *pp = &pci->pp; +	struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pci);  	struct pcie_app_reg *app_reg = spear13xx_pcie->app_base; -	u32 val; -	u32 exp_cap_off = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); - -	if (dw_pcie_link_up(pci)) { -		dev_err(pci->dev, "link already up\n"); -		return 0; -	} - -	dw_pcie_setup_rc(pp); - -	/* -	 * this controller support only 128 bytes read size, however its -	 * default value in capability register is 512 bytes. So force -	 * it to 128 here. -	 */ -	val = dw_pcie_readw_dbi(pci, exp_cap_off + PCI_EXP_DEVCTL); -	val &= ~PCI_EXP_DEVCTL_READRQ; -	dw_pcie_writew_dbi(pci, exp_cap_off + PCI_EXP_DEVCTL, val); - -	dw_pcie_writew_dbi(pci, PCI_VENDOR_ID, 0x104A); -	dw_pcie_writew_dbi(pci, PCI_DEVICE_ID, 0xCD80);  	/* enable ltssm */  	writel(DEVICE_TYPE_RC | (1 << MISCTRL_EN_ID) @@ -99,7 +77,7 @@ static int spear13xx_pcie_establish_link(struct spear13xx_pcie *spear13xx_pcie)  			| ((u32)1 << REG_TRANSLATION_ENABLE),  			&app_reg->app_ctrl_0); -	return dw_pcie_wait_for_link(pci); +	return 0;  }  static irqreturn_t spear13xx_pcie_irq_handler(int irq, void *arg) @@ -124,16 +102,12 @@ static irqreturn_t spear13xx_pcie_irq_handler(int irq, void *arg)  static void spear13xx_pcie_enable_interrupts(struct spear13xx_pcie *spear13xx_pcie)  { -	struct dw_pcie *pci = spear13xx_pcie->pci; -	struct pcie_port *pp = &pci->pp;  	struct pcie_app_reg *app_reg = spear13xx_pcie->app_base;  	/* Enable MSI interrupt */ -	if (IS_ENABLED(CONFIG_PCI_MSI)) { -		dw_pcie_msi_init(pp); +	if (IS_ENABLED(CONFIG_PCI_MSI))  		writel(readl(&app_reg->int_mask) |  				MSI_CTRL_INT, &app_reg->int_mask); -	}  }  static int spear13xx_pcie_link_up(struct dw_pcie *pci) @@ -151,8 +125,23 @@ static int spear13xx_pcie_host_init(struct pcie_port *pp)  {  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);  	struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pci); +	u32 exp_cap_off = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); +	u32 val; + +	spear13xx_pcie->app_base = pci->dbi_base + 0x2000; + +	/* +	 * this controller support only 128 bytes read size, however its +	 * default value in capability register is 512 bytes. So force +	 * it to 128 here. +	 */ +	val = dw_pcie_readw_dbi(pci, exp_cap_off + PCI_EXP_DEVCTL); +	val &= ~PCI_EXP_DEVCTL_READRQ; +	dw_pcie_writew_dbi(pci, exp_cap_off + PCI_EXP_DEVCTL, val); + +	dw_pcie_writew_dbi(pci, PCI_VENDOR_ID, 0x104A); +	dw_pcie_writew_dbi(pci, PCI_DEVICE_ID, 0xCD80); -	spear13xx_pcie_establish_link(spear13xx_pcie);  	spear13xx_pcie_enable_interrupts(spear13xx_pcie);  	return 0; @@ -183,6 +172,7 @@ static int spear13xx_add_pcie_port(struct spear13xx_pcie *spear13xx_pcie,  	}  	pp->ops = &spear13xx_pcie_host_ops; +	pp->msi_irq = -ENODEV;  	ret = dw_pcie_host_init(pp);  	if (ret) { @@ -195,6 +185,7 @@ static int spear13xx_add_pcie_port(struct spear13xx_pcie *spear13xx_pcie,  static const struct dw_pcie_ops dw_pcie_ops = {  	.link_up = spear13xx_pcie_link_up, +	.start_link = spear13xx_pcie_start_link,  };  static int spear13xx_pcie_probe(struct platform_device *pdev) @@ -203,7 +194,6 @@ static int spear13xx_pcie_probe(struct platform_device *pdev)  	struct dw_pcie *pci;  	struct spear13xx_pcie *spear13xx_pcie;  	struct device_node *np = dev->of_node; -	struct resource *dbi_base;  	int ret;  	spear13xx_pcie = devm_kzalloc(dev, sizeof(*spear13xx_pcie), GFP_KERNEL); @@ -242,14 +232,6 @@ static int spear13xx_pcie_probe(struct platform_device *pdev)  		return ret;  	} -	dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); -	pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_base); -	if (IS_ERR(pci->dbi_base)) { -		ret = PTR_ERR(pci->dbi_base); -		goto fail_clk; -	} -	spear13xx_pcie->app_base = pci->dbi_base + 0x2000; -  	if (of_property_read_bool(np, "st,pcie-is-gen1"))  		pci->link_gen = 1; diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c index f920e7efe118..5597b2a49598 100644 --- a/drivers/pci/controller/dwc/pcie-tegra194.c +++ b/drivers/pci/controller/dwc/pcie-tegra194.c @@ -765,8 +765,6 @@ static void tegra_pcie_enable_msi_interrupts(struct pcie_port *pp)  	struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);  	u32 val; -	dw_pcie_msi_init(pp); -  	/* Enable MSI interrupt generation */  	val = appl_readl(pcie, APPL_INTR_EN_L0_0);  	val |= APPL_INTR_EN_L0_0_SYS_MSI_INTR_EN; @@ -861,6 +859,10 @@ static void tegra_pcie_prepare_host(struct pcie_port *pp)  	struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);  	u32 val; +	if (!pcie->pcie_cap_base) +		pcie->pcie_cap_base = dw_pcie_find_capability(&pcie->pci, +							      PCI_CAP_ID_EXP); +  	val = dw_pcie_readl_dbi(pci, PCI_IO_BASE);  	val &= ~(IO_BASE_IO_DECODE | IO_BASE_IO_DECODE_BIT8);  	dw_pcie_writel_dbi(pci, PCI_IO_BASE, val); @@ -889,6 +891,12 @@ static void tegra_pcie_prepare_host(struct pcie_port *pp)  	init_host_aspm(pcie); +	/* Disable ASPM-L1SS advertisement if there is no CLKREQ routing */ +	if (!pcie->supports_clkreq) { +		disable_aspm_l11(pcie); +		disable_aspm_l12(pcie); +	} +  	val = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF);  	val &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL;  	dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, val); @@ -990,11 +998,6 @@ static int tegra_pcie_dw_link_up(struct dw_pcie *pci)  	return !!(val & PCI_EXP_LNKSTA_DLLLA);  } -static void tegra_pcie_set_msi_vec_num(struct pcie_port *pp) -{ -	pp->num_vectors = MAX_MSI_IRQS; -} -  static int tegra_pcie_dw_start_link(struct dw_pcie *pci)  {  	struct tegra_pcie_dw *pcie = to_tegra_pcie(pci); @@ -1019,7 +1022,6 @@ static const struct dw_pcie_ops tegra_dw_pcie_ops = {  static struct dw_pcie_host_ops tegra_pcie_dw_host_ops = {  	.host_init = tegra_pcie_dw_host_init, -	.set_num_vectors = tegra_pcie_set_msi_vec_num,  };  static void tegra_pcie_disable_phy(struct tegra_pcie_dw *pcie) @@ -1061,9 +1063,16 @@ phy_exit:  static int tegra_pcie_dw_parse_dt(struct tegra_pcie_dw *pcie)  { +	struct platform_device *pdev = to_platform_device(pcie->dev);  	struct device_node *np = pcie->dev->of_node;  	int ret; +	pcie->dbi_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); +	if (!pcie->dbi_res) { +		dev_err(pcie->dev, "Failed to find \"dbi\" region\n"); +		return -ENODEV; +	} +  	ret = of_property_read_u32(np, "nvidia,aspm-cmrt-us", &pcie->aspm_cmrt);  	if (ret < 0) {  		dev_info(pcie->dev, "Failed to read ASPM T_cmrt: %d\n", ret); @@ -1390,15 +1399,6 @@ static int tegra_pcie_config_controller(struct tegra_pcie_dw *pcie,  	reset_control_deassert(pcie->core_rst); -	pcie->pcie_cap_base = dw_pcie_find_capability(&pcie->pci, -						      PCI_CAP_ID_EXP); - -	/* Disable ASPM-L1SS advertisement as there is no CLKREQ routing */ -	if (!pcie->supports_clkreq) { -		disable_aspm_l11(pcie); -		disable_aspm_l12(pcie); -	} -  	return ret;  fail_phy: @@ -1415,43 +1415,32 @@ fail_slot_reg_en:  	return ret;  } -static int __deinit_controller(struct tegra_pcie_dw *pcie) +static void tegra_pcie_unconfig_controller(struct tegra_pcie_dw *pcie)  {  	int ret;  	ret = reset_control_assert(pcie->core_rst); -	if (ret) { -		dev_err(pcie->dev, "Failed to assert \"core\" reset: %d\n", -			ret); -		return ret; -	} +	if (ret) +		dev_err(pcie->dev, "Failed to assert \"core\" reset: %d\n", ret);  	tegra_pcie_disable_phy(pcie);  	ret = reset_control_assert(pcie->core_apb_rst); -	if (ret) { +	if (ret)  		dev_err(pcie->dev, "Failed to assert APB reset: %d\n", ret); -		return ret; -	}  	clk_disable_unprepare(pcie->core_clk);  	ret = regulator_disable(pcie->pex_ctl_supply); -	if (ret) { +	if (ret)  		dev_err(pcie->dev, "Failed to disable regulator: %d\n", ret); -		return ret; -	}  	tegra_pcie_disable_slot_regulators(pcie);  	ret = tegra_pcie_bpmp_set_ctrl_state(pcie, false); -	if (ret) { +	if (ret)  		dev_err(pcie->dev, "Failed to disable controller %d: %d\n",  			pcie->cid, ret); -		return ret; -	} - -	return ret;  }  static int tegra_pcie_init_controller(struct tegra_pcie_dw *pcie) @@ -1475,7 +1464,8 @@ static int tegra_pcie_init_controller(struct tegra_pcie_dw *pcie)  	return 0;  fail_host_init: -	return __deinit_controller(pcie); +	tegra_pcie_unconfig_controller(pcie); +	return ret;  }  static int tegra_pcie_try_link_l2(struct tegra_pcie_dw *pcie) @@ -1516,6 +1506,14 @@ static void tegra_pcie_dw_pme_turnoff(struct tegra_pcie_dw *pcie)  		data &= ~APPL_PINMUX_PEX_RST;  		appl_writel(pcie, data, APPL_PINMUX); +		/* +		 * Some cards do not go to detect state even after de-asserting +		 * PERST#. So, de-assert LTSSM to bring link to detect state. +		 */ +		data = readl(pcie->appl_base + APPL_CTRL); +		data &= ~APPL_CTRL_LTSSM_EN; +		writel(data, pcie->appl_base + APPL_CTRL); +  		err = readl_poll_timeout_atomic(pcie->appl_base + APPL_DEBUG,  						data,  						((data & @@ -1523,14 +1521,8 @@ static void tegra_pcie_dw_pme_turnoff(struct tegra_pcie_dw *pcie)  						APPL_DEBUG_LTSSM_STATE_SHIFT) ==  						LTSSM_STATE_PRE_DETECT,  						1, LTSSM_TIMEOUT); -		if (err) { +		if (err)  			dev_info(pcie->dev, "Link didn't go to detect state\n"); -		} else { -			/* Disable LTSSM after link is in detect state */ -			data = appl_readl(pcie, APPL_CTRL); -			data &= ~APPL_CTRL_LTSSM_EN; -			appl_writel(pcie, data, APPL_CTRL); -		}  	}  	/*  	 * DBI registers may not be accessible after this as PLL-E would be @@ -1544,30 +1536,20 @@ static void tegra_pcie_dw_pme_turnoff(struct tegra_pcie_dw *pcie)  	appl_writel(pcie, data, APPL_PINMUX);  } -static int tegra_pcie_deinit_controller(struct tegra_pcie_dw *pcie) +static void tegra_pcie_deinit_controller(struct tegra_pcie_dw *pcie)  {  	tegra_pcie_downstream_dev_to_D0(pcie);  	dw_pcie_host_deinit(&pcie->pci.pp);  	tegra_pcie_dw_pme_turnoff(pcie); - -	return __deinit_controller(pcie); +	tegra_pcie_unconfig_controller(pcie);  }  static int tegra_pcie_config_rp(struct tegra_pcie_dw *pcie)  { -	struct pcie_port *pp = &pcie->pci.pp;  	struct device *dev = pcie->dev;  	char *name;  	int ret; -	if (IS_ENABLED(CONFIG_PCI_MSI)) { -		pp->msi_irq = of_irq_get_byname(dev->of_node, "msi"); -		if (!pp->msi_irq) { -			dev_err(dev, "Failed to get MSI interrupt\n"); -			return -ENODEV; -		} -	} -  	pm_runtime_enable(dev);  	ret = pm_runtime_get_sync(dev); @@ -1583,7 +1565,11 @@ static int tegra_pcie_config_rp(struct tegra_pcie_dw *pcie)  		goto fail_pm_get_sync;  	} -	tegra_pcie_init_controller(pcie); +	ret = tegra_pcie_init_controller(pcie); +	if (ret < 0) { +		dev_err(dev, "Failed to initialize controller: %d\n", ret); +		goto fail_pm_get_sync; +	}  	pcie->link_state = tegra_pcie_dw_link_up(&pcie->pci);  	if (!pcie->link_state) { @@ -1907,19 +1893,12 @@ static int tegra_pcie_config_ep(struct tegra_pcie_dw *pcie,  	struct dw_pcie *pci = &pcie->pci;  	struct device *dev = pcie->dev;  	struct dw_pcie_ep *ep; -	struct resource *res;  	char *name;  	int ret;  	ep = &pci->ep;  	ep->ops = &pcie_ep_ops; -	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space"); -	if (!res) -		return -EINVAL; - -	ep->phys_base = res->start; -	ep->addr_size = resource_size(res);  	ep->page_size = SZ_64K;  	ret = gpiod_set_debounce(pcie->pex_rst_gpiod, PERST_DEBOUNCE_TIME); @@ -1982,7 +1961,6 @@ static int tegra_pcie_dw_probe(struct platform_device *pdev)  	struct device *dev = &pdev->dev;  	struct resource *atu_dma_res;  	struct tegra_pcie_dw *pcie; -	struct resource *dbi_res;  	struct pcie_port *pp;  	struct dw_pcie *pci;  	struct phy **phys; @@ -2001,8 +1979,10 @@ static int tegra_pcie_dw_probe(struct platform_device *pdev)  	pci->ops = &tegra_dw_pcie_ops;  	pci->n_fts[0] = N_FTS_VAL;  	pci->n_fts[1] = FTS_VAL; +	pci->version = 0x490A;  	pp = &pci->pp; +	pp->num_vectors = MAX_MSI_IRQS;  	pcie->dev = &pdev->dev;  	pcie->mode = (enum dw_pcie_device_mode)data->mode; @@ -2091,20 +2071,6 @@ static int tegra_pcie_dw_probe(struct platform_device *pdev)  	pcie->phys = phys; -	dbi_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); -	if (!dbi_res) { -		dev_err(dev, "Failed to find \"dbi\" region\n"); -		return -ENODEV; -	} -	pcie->dbi_res = dbi_res; - -	pci->dbi_base = devm_ioremap_resource(dev, dbi_res); -	if (IS_ERR(pci->dbi_base)) -		return PTR_ERR(pci->dbi_base); - -	/* Tegra HW locates DBI2 at a fixed offset from DBI */ -	pci->dbi_base2 = pci->dbi_base + 0x1000; -  	atu_dma_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,  						   "atu_dma");  	if (!atu_dma_res) { @@ -2113,6 +2079,7 @@ static int tegra_pcie_dw_probe(struct platform_device *pdev)  	}  	pcie->atu_dma_res = atu_dma_res; +	pci->atu_size = resource_size(atu_dma_res);  	pci->atu_base = devm_ioremap_resource(dev, atu_dma_res);  	if (IS_ERR(pci->atu_base))  		return PTR_ERR(pci->atu_base); @@ -2225,8 +2192,9 @@ static int tegra_pcie_dw_suspend_noirq(struct device *dev)  					       PORT_LOGIC_MSI_CTRL_INT_0_EN);  	tegra_pcie_downstream_dev_to_D0(pcie);  	tegra_pcie_dw_pme_turnoff(pcie); +	tegra_pcie_unconfig_controller(pcie); -	return __deinit_controller(pcie); +	return 0;  }  static int tegra_pcie_dw_resume_noirq(struct device *dev) @@ -2254,7 +2222,8 @@ static int tegra_pcie_dw_resume_noirq(struct device *dev)  	return 0;  fail_host_init: -	return __deinit_controller(pcie); +	tegra_pcie_unconfig_controller(pcie); +	return ret;  }  static int tegra_pcie_dw_resume_early(struct device *dev) @@ -2292,7 +2261,7 @@ static void tegra_pcie_dw_shutdown(struct platform_device *pdev)  		disable_irq(pcie->pci.pp.msi_irq);  	tegra_pcie_dw_pme_turnoff(pcie); -	__deinit_controller(pcie); +	tegra_pcie_unconfig_controller(pcie);  }  static const struct tegra_pcie_dw_of_data tegra_pcie_dw_rc_of_data = { diff --git a/drivers/pci/controller/dwc/pcie-uniphier-ep.c b/drivers/pci/controller/dwc/pcie-uniphier-ep.c index 148355960061..69810c6b0d58 100644 --- a/drivers/pci/controller/dwc/pcie-uniphier-ep.c +++ b/drivers/pci/controller/dwc/pcie-uniphier-ep.c @@ -218,35 +218,6 @@ static const struct dw_pcie_ep_ops uniphier_pcie_ep_ops = {  	.get_features = uniphier_pcie_get_features,  }; -static int uniphier_add_pcie_ep(struct uniphier_pcie_ep_priv *priv, -				struct platform_device *pdev) -{ -	struct dw_pcie *pci = &priv->pci; -	struct dw_pcie_ep *ep = &pci->ep; -	struct device *dev = &pdev->dev; -	struct resource *res; -	int ret; - -	ep->ops = &uniphier_pcie_ep_ops; - -	pci->dbi_base2 = devm_platform_ioremap_resource_byname(pdev, "dbi2"); -	if (IS_ERR(pci->dbi_base2)) -		return PTR_ERR(pci->dbi_base2); - -	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space"); -	if (!res) -		return -EINVAL; - -	ep->phys_base = res->start; -	ep->addr_size = resource_size(res); - -	ret = dw_pcie_ep_init(ep); -	if (ret) -		dev_err(dev, "Failed to initialize endpoint (%d)\n", ret); - -	return ret; -} -  static int uniphier_pcie_ep_enable(struct uniphier_pcie_ep_priv *priv)  {  	int ret; @@ -300,7 +271,6 @@ static int uniphier_pcie_ep_probe(struct platform_device *pdev)  {  	struct device *dev = &pdev->dev;  	struct uniphier_pcie_ep_priv *priv; -	struct resource *res;  	int ret;  	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); @@ -314,11 +284,6 @@ static int uniphier_pcie_ep_probe(struct platform_device *pdev)  	priv->pci.dev = dev;  	priv->pci.ops = &dw_pcie_ops; -	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); -	priv->pci.dbi_base = devm_pci_remap_cfg_resource(dev, res); -	if (IS_ERR(priv->pci.dbi_base)) -		return PTR_ERR(priv->pci.dbi_base); -  	priv->base = devm_platform_ioremap_resource_byname(pdev, "link");  	if (IS_ERR(priv->base))  		return PTR_ERR(priv->base); @@ -352,7 +317,8 @@ static int uniphier_pcie_ep_probe(struct platform_device *pdev)  	if (ret)  		return ret; -	return uniphier_add_pcie_ep(priv, pdev); +	priv->pci.ep.ops = &uniphier_pcie_ep_ops; +	return dw_pcie_ep_init(&priv->pci.ep);  }  static const struct pci_epc_features uniphier_pro5_data = { diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c index 48176265c867..7e8bad326770 100644 --- a/drivers/pci/controller/dwc/pcie-uniphier.c +++ b/drivers/pci/controller/dwc/pcie-uniphier.c @@ -146,16 +146,13 @@ static int uniphier_pcie_link_up(struct dw_pcie *pci)  	return (val & mask) == mask;  } -static int uniphier_pcie_establish_link(struct dw_pcie *pci) +static int uniphier_pcie_start_link(struct dw_pcie *pci)  {  	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci); -	if (dw_pcie_link_up(pci)) -		return 0; -  	uniphier_pcie_ltssm_enable(priv, true); -	return dw_pcie_wait_for_link(pci); +	return 0;  }  static void uniphier_pcie_stop_link(struct dw_pcie *pci) @@ -317,13 +314,6 @@ static int uniphier_pcie_host_init(struct pcie_port *pp)  	uniphier_pcie_irq_enable(priv); -	dw_pcie_setup_rc(pp); -	ret = uniphier_pcie_establish_link(pci); -	if (ret) -		return ret; - -	dw_pcie_msi_init(pp); -  	return 0;  } @@ -331,31 +321,6 @@ static const struct dw_pcie_host_ops uniphier_pcie_host_ops = {  	.host_init = uniphier_pcie_host_init,  }; -static int uniphier_add_pcie_port(struct uniphier_pcie_priv *priv, -				  struct platform_device *pdev) -{ -	struct dw_pcie *pci = &priv->pci; -	struct pcie_port *pp = &pci->pp; -	struct device *dev = &pdev->dev; -	int ret; - -	pp->ops = &uniphier_pcie_host_ops; - -	if (IS_ENABLED(CONFIG_PCI_MSI)) { -		pp->msi_irq = platform_get_irq_byname(pdev, "msi"); -		if (pp->msi_irq < 0) -			return pp->msi_irq; -	} - -	ret = dw_pcie_host_init(pp); -	if (ret) { -		dev_err(dev, "Failed to initialize host (%d)\n", ret); -		return ret; -	} - -	return 0; -} -  static int uniphier_pcie_host_enable(struct uniphier_pcie_priv *priv)  {  	int ret; @@ -391,7 +356,7 @@ out_clk_disable:  }  static const struct dw_pcie_ops dw_pcie_ops = { -	.start_link = uniphier_pcie_establish_link, +	.start_link = uniphier_pcie_start_link,  	.stop_link = uniphier_pcie_stop_link,  	.link_up = uniphier_pcie_link_up,  }; @@ -400,7 +365,6 @@ static int uniphier_pcie_probe(struct platform_device *pdev)  {  	struct device *dev = &pdev->dev;  	struct uniphier_pcie_priv *priv; -	struct resource *res;  	int ret;  	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); @@ -410,11 +374,6 @@ static int uniphier_pcie_probe(struct platform_device *pdev)  	priv->pci.dev = dev;  	priv->pci.ops = &dw_pcie_ops; -	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); -	priv->pci.dbi_base = devm_pci_remap_cfg_resource(dev, res); -	if (IS_ERR(priv->pci.dbi_base)) -		return PTR_ERR(priv->pci.dbi_base); -  	priv->base = devm_platform_ioremap_resource_byname(pdev, "link");  	if (IS_ERR(priv->base))  		return PTR_ERR(priv->base); @@ -437,7 +396,9 @@ static int uniphier_pcie_probe(struct platform_device *pdev)  	if (ret)  		return ret; -	return uniphier_add_pcie_port(priv, pdev); +	priv->pci.pp.ops = &uniphier_pcie_host_ops; + +	return dw_pcie_host_init(&priv->pci.pp);  }  static const struct of_device_id uniphier_pcie_match[] = {  |