diff options
Diffstat (limited to 'drivers/pci/controller/dwc/pcie-designware.c')
| -rw-r--r-- | drivers/pci/controller/dwc/pcie-designware.c | 64 | 
1 files changed, 55 insertions, 9 deletions
| diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c index 31f6331ca46f..9d7c51c32b3b 100644 --- a/drivers/pci/controller/dwc/pcie-designware.c +++ b/drivers/pci/controller/dwc/pcie-designware.c @@ -14,12 +14,6 @@  #include "pcie-designware.h" -/* PCIe Port Logic registers */ -#define PLR_OFFSET			0x700 -#define PCIE_PHY_DEBUG_R1		(PLR_OFFSET + 0x2c) -#define PCIE_PHY_DEBUG_R1_LINK_UP	(0x1 << 4) -#define PCIE_PHY_DEBUG_R1_LINK_IN_TRAINING	(0x1 << 29) -  int dw_pcie_read(void __iomem *addr, int size, u32 *val)  {  	if (!IS_ALIGNED((uintptr_t)addr, size)) { @@ -89,6 +83,37 @@ void __dw_pcie_write_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg,  		dev_err(pci->dev, "Write DBI address failed\n");  } +u32 __dw_pcie_read_dbi2(struct dw_pcie *pci, void __iomem *base, u32 reg, +			size_t size) +{ +	int ret; +	u32 val; + +	if (pci->ops->read_dbi2) +		return pci->ops->read_dbi2(pci, base, reg, size); + +	ret = dw_pcie_read(base + reg, size, &val); +	if (ret) +		dev_err(pci->dev, "read DBI address failed\n"); + +	return val; +} + +void __dw_pcie_write_dbi2(struct dw_pcie *pci, void __iomem *base, u32 reg, +			  size_t size, u32 val) +{ +	int ret; + +	if (pci->ops->write_dbi2) { +		pci->ops->write_dbi2(pci, base, reg, size, val); +		return; +	} + +	ret = dw_pcie_write(base + reg, size, val); +	if (ret) +		dev_err(pci->dev, "write DBI address failed\n"); +} +  static u32 dw_pcie_readl_ob_unroll(struct dw_pcie *pci, u32 index, u32 reg)  {  	u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index); @@ -334,9 +359,20 @@ int dw_pcie_link_up(struct dw_pcie *pci)  	if (pci->ops->link_up)  		return pci->ops->link_up(pci); -	val = readl(pci->dbi_base + PCIE_PHY_DEBUG_R1); -	return ((val & PCIE_PHY_DEBUG_R1_LINK_UP) && -		(!(val & PCIE_PHY_DEBUG_R1_LINK_IN_TRAINING))); +	val = readl(pci->dbi_base + PCIE_PORT_DEBUG1); +	return ((val & PCIE_PORT_DEBUG1_LINK_UP) && +		(!(val & PCIE_PORT_DEBUG1_LINK_IN_TRAINING))); +} + +static u8 dw_pcie_iatu_unroll_enabled(struct dw_pcie *pci) +{ +	u32 val; + +	val = dw_pcie_readl_dbi(pci, PCIE_ATU_VIEWPORT); +	if (val == 0xffffffff) +		return 1; + +	return 0;  }  void dw_pcie_setup(struct dw_pcie *pci) @@ -347,6 +383,16 @@ void dw_pcie_setup(struct dw_pcie *pci)  	struct device *dev = pci->dev;  	struct device_node *np = dev->of_node; +	if (pci->version >= 0x480A || (!pci->version && +				       dw_pcie_iatu_unroll_enabled(pci))) { +		pci->iatu_unroll_enabled = true; +		if (!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 ? +		"enabled" : "disabled"); + +  	ret = of_property_read_u32(np, "num-lanes", &lanes);  	if (ret)  		lanes = 0; |