diff options
Diffstat (limited to 'drivers/pci/controller/dwc/pcie-designware-host.c')
| -rw-r--r-- | drivers/pci/controller/dwc/pcie-designware-host.c | 30 | 
1 files changed, 24 insertions, 6 deletions
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index f93252d0da5b..0f36a926059a 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -323,6 +323,7 @@ int dw_pcie_host_init(struct pcie_port *pp)  	struct pci_bus *child;  	struct pci_host_bridge *bridge;  	struct resource *cfg_res; +	u32 hdr_type;  	int ret;  	raw_spin_lock_init(&pci->pp.lock); @@ -464,6 +465,21 @@ int dw_pcie_host_init(struct pcie_port *pp)  			goto err_free_msi;  	} +	ret = dw_pcie_rd_own_conf(pp, PCI_HEADER_TYPE, 1, &hdr_type); +	if (ret != PCIBIOS_SUCCESSFUL) { +		dev_err(pci->dev, "Failed reading PCI_HEADER_TYPE cfg space reg (ret: 0x%x)\n", +			ret); +		ret = pcibios_err_to_errno(ret); +		goto err_free_msi; +	} +	if (hdr_type != PCI_HEADER_TYPE_BRIDGE) { +		dev_err(pci->dev, +			"PCIe controller is not set to bridge type (hdr_type: 0x%x)!\n", +			hdr_type); +		ret = -EIO; +		goto err_free_msi; +	} +  	pp->root_bus_nr = pp->busn->start;  	bridge->dev.parent = dev; @@ -628,6 +644,12 @@ void dw_pcie_setup_rc(struct pcie_port *pp)  	u32 val, ctrl, num_ctrls;  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp); +	/* +	 * Enable DBI read-only registers for writing/updating configuration. +	 * Write permission gets disabled towards the end of this function. +	 */ +	dw_pcie_dbi_ro_wr_en(pci); +  	dw_pcie_setup(pci);  	if (!pp->ops->msi_host_init) { @@ -650,12 +672,10 @@ void dw_pcie_setup_rc(struct pcie_port *pp)  	dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_1, 0x00000000);  	/* Setup interrupt pins */ -	dw_pcie_dbi_ro_wr_en(pci);  	val = dw_pcie_readl_dbi(pci, PCI_INTERRUPT_LINE);  	val &= 0xffff00ff;  	val |= 0x00000100;  	dw_pcie_writel_dbi(pci, PCI_INTERRUPT_LINE, val); -	dw_pcie_dbi_ro_wr_dis(pci);  	/* Setup bus numbers */  	val = dw_pcie_readl_dbi(pci, PCI_PRIMARY_BUS); @@ -687,15 +707,13 @@ void dw_pcie_setup_rc(struct pcie_port *pp)  	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0); -	/* Enable write permission for the DBI read-only register */ -	dw_pcie_dbi_ro_wr_en(pci);  	/* Program correct class for RC */  	dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2, PCI_CLASS_BRIDGE_PCI); -	/* Better disable write permission right after the update */ -	dw_pcie_dbi_ro_wr_dis(pci);  	dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, &val);  	val |= PORT_LOGIC_SPEED_CHANGE;  	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val); + +	dw_pcie_dbi_ro_wr_dis(pci);  }  EXPORT_SYMBOL_GPL(dw_pcie_setup_rc);  |