diff options
Diffstat (limited to 'drivers/pci/controller/dwc')
| -rw-r--r-- | drivers/pci/controller/dwc/pcie-designware-host.c | 28 | ||||
| -rw-r--r-- | drivers/pci/controller/dwc/pcie-qcom.c | 68 | 
2 files changed, 24 insertions, 72 deletions
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index 20c9333bcb1c..e92513c5bda5 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -23,6 +23,7 @@  #include "pcie-designware.h"  static struct pci_ops dw_pcie_ops; +static struct pci_ops dw_pcie_ecam_ops;  static struct pci_ops dw_child_pcie_ops;  #define DW_PCIE_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS		| \ @@ -471,9 +472,6 @@ static int dw_pcie_create_ecam_window(struct dw_pcie_rp *pp, struct resource *re  	if (IS_ERR(pp->cfg))  		return PTR_ERR(pp->cfg); -	pci->dbi_base = pp->cfg->win; -	pci->dbi_phys_addr = res->start; -  	return 0;  } @@ -529,7 +527,7 @@ static int dw_pcie_host_get_resources(struct dw_pcie_rp *pp)  		if (ret)  			return ret; -		pp->bridge->ops = (struct pci_ops *)&pci_generic_ecam_ops.pci_ops; +		pp->bridge->ops = &dw_pcie_ecam_ops;  		pp->bridge->sysdata = pp->cfg;  		pp->cfg->priv = pp;  	} else { @@ -842,12 +840,34 @@ void __iomem *dw_pcie_own_conf_map_bus(struct pci_bus *bus, unsigned int devfn,  }  EXPORT_SYMBOL_GPL(dw_pcie_own_conf_map_bus); +static void __iomem *dw_pcie_ecam_conf_map_bus(struct pci_bus *bus, unsigned int devfn, int where) +{ +	struct pci_config_window *cfg = bus->sysdata; +	struct dw_pcie_rp *pp = cfg->priv; +	struct dw_pcie *pci = to_dw_pcie_from_pp(pp); +	unsigned int busn = bus->number; + +	if (busn > 0) +		return pci_ecam_map_bus(bus, devfn, where); + +	if (PCI_SLOT(devfn) > 0) +		return NULL; + +	return pci->dbi_base + where; +} +  static struct pci_ops dw_pcie_ops = {  	.map_bus = dw_pcie_own_conf_map_bus,  	.read = pci_generic_config_read,  	.write = pci_generic_config_write,  }; +static struct pci_ops dw_pcie_ecam_ops = { +	.map_bus = dw_pcie_ecam_conf_map_bus, +	.read = pci_generic_config_read, +	.write = pci_generic_config_write, +}; +  static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)  {  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp); diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index 805edbbfe7eb..6948824642dc 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -55,7 +55,6 @@  #define PARF_AXI_MSTR_WR_ADDR_HALT_V2		0x1a8  #define PARF_Q2A_FLUSH				0x1ac  #define PARF_LTSSM				0x1b0 -#define PARF_SLV_DBI_ELBI			0x1b4  #define PARF_INT_ALL_STATUS			0x224  #define PARF_INT_ALL_CLEAR			0x228  #define PARF_INT_ALL_MASK			0x22c @@ -65,16 +64,6 @@  #define PARF_DBI_BASE_ADDR_V2_HI		0x354  #define PARF_SLV_ADDR_SPACE_SIZE_V2		0x358  #define PARF_SLV_ADDR_SPACE_SIZE_V2_HI		0x35c -#define PARF_BLOCK_SLV_AXI_WR_BASE		0x360 -#define PARF_BLOCK_SLV_AXI_WR_BASE_HI		0x364 -#define PARF_BLOCK_SLV_AXI_WR_LIMIT		0x368 -#define PARF_BLOCK_SLV_AXI_WR_LIMIT_HI		0x36c -#define PARF_BLOCK_SLV_AXI_RD_BASE		0x370 -#define PARF_BLOCK_SLV_AXI_RD_BASE_HI		0x374 -#define PARF_BLOCK_SLV_AXI_RD_LIMIT		0x378 -#define PARF_BLOCK_SLV_AXI_RD_LIMIT_HI		0x37c -#define PARF_ECAM_BASE				0x380 -#define PARF_ECAM_BASE_HI			0x384  #define PARF_NO_SNOOP_OVERRIDE			0x3d4  #define PARF_ATU_BASE_ADDR			0x634  #define PARF_ATU_BASE_ADDR_HI			0x638 @@ -98,7 +87,6 @@  /* PARF_SYS_CTRL register fields */  #define MAC_PHY_POWERDOWN_IN_P2_D_MUX_EN	BIT(29) -#define PCIE_ECAM_BLOCKER_EN			BIT(26)  #define MST_WAKEUP_EN				BIT(13)  #define SLV_WAKEUP_EN				BIT(12)  #define MSTR_ACLK_CGC_DIS			BIT(10) @@ -146,9 +134,6 @@  /* PARF_LTSSM register fields */  #define LTSSM_EN				BIT(8) -/* PARF_SLV_DBI_ELBI */ -#define SLV_DBI_ELBI_ADDR_BASE			GENMASK(11, 0) -  /* PARF_INT_ALL_{STATUS/CLEAR/MASK} register fields */  #define PARF_INT_ALL_LINK_UP			BIT(13)  #define PARF_INT_MSI_DEV_0_7			GENMASK(30, 23) @@ -326,47 +311,6 @@ static void qcom_ep_reset_deassert(struct qcom_pcie *pcie)  	qcom_perst_assert(pcie, false);  } -static void qcom_pci_config_ecam(struct dw_pcie_rp *pp) -{ -	struct dw_pcie *pci = to_dw_pcie_from_pp(pp); -	struct qcom_pcie *pcie = to_qcom_pcie(pci); -	u64 addr, addr_end; -	u32 val; - -	writel_relaxed(lower_32_bits(pci->dbi_phys_addr), pcie->parf + PARF_ECAM_BASE); -	writel_relaxed(upper_32_bits(pci->dbi_phys_addr), pcie->parf + PARF_ECAM_BASE_HI); - -	/* -	 * The only device on the root bus is a single Root Port. If we try to -	 * access any devices other than Device/Function 00.0 on Bus 0, the TLP -	 * will go outside of the controller to the PCI bus. But with CFG Shift -	 * Feature (ECAM) enabled in iATU, there is no guarantee that the -	 * response is going to be all F's. Hence, to make sure that the -	 * requester gets all F's response for accesses other than the Root -	 * Port, configure iATU to block the transactions starting from -	 * function 1 of the root bus to the end of the root bus (i.e., from -	 * dbi_base + 4KB to dbi_base + 1MB). -	 */ -	addr = pci->dbi_phys_addr + SZ_4K; -	writel_relaxed(lower_32_bits(addr), pcie->parf + PARF_BLOCK_SLV_AXI_WR_BASE); -	writel_relaxed(upper_32_bits(addr), pcie->parf + PARF_BLOCK_SLV_AXI_WR_BASE_HI); - -	writel_relaxed(lower_32_bits(addr), pcie->parf + PARF_BLOCK_SLV_AXI_RD_BASE); -	writel_relaxed(upper_32_bits(addr), pcie->parf + PARF_BLOCK_SLV_AXI_RD_BASE_HI); - -	addr_end = pci->dbi_phys_addr + SZ_1M - 1; - -	writel_relaxed(lower_32_bits(addr_end), pcie->parf + PARF_BLOCK_SLV_AXI_WR_LIMIT); -	writel_relaxed(upper_32_bits(addr_end), pcie->parf + PARF_BLOCK_SLV_AXI_WR_LIMIT_HI); - -	writel_relaxed(lower_32_bits(addr_end), pcie->parf + PARF_BLOCK_SLV_AXI_RD_LIMIT); -	writel_relaxed(upper_32_bits(addr_end), pcie->parf + PARF_BLOCK_SLV_AXI_RD_LIMIT_HI); - -	val = readl_relaxed(pcie->parf + PARF_SYS_CTRL); -	val |= PCIE_ECAM_BLOCKER_EN; -	writel_relaxed(val, pcie->parf + PARF_SYS_CTRL); -} -  static int qcom_pcie_start_link(struct dw_pcie *pci)  {  	struct qcom_pcie *pcie = to_qcom_pcie(pci); @@ -1320,7 +1264,6 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp)  {  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);  	struct qcom_pcie *pcie = to_qcom_pcie(pci); -	u16 offset;  	int ret;  	qcom_ep_reset_assert(pcie); @@ -1329,17 +1272,6 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp)  	if (ret)  		return ret; -	if (pp->ecam_enabled) { -		/* -		 * Override ELBI when ECAM is enabled, as when ECAM is enabled, -		 * ELBI moves under the 'config' space. -		 */ -		offset = FIELD_GET(SLV_DBI_ELBI_ADDR_BASE, readl(pcie->parf + PARF_SLV_DBI_ELBI)); -		pci->elbi_base = pci->dbi_base + offset; - -		qcom_pci_config_ecam(pp); -	} -  	ret = qcom_pcie_phy_power_on(pcie);  	if (ret)  		goto err_deinit;  | 
