diff mbox

[v2,1/2] pcie-designware: add iATU Unroll feature

Message ID 0ce5678ac78d082afa3df7ad284111afcc03b2a1.1469193895.git.jpinto@synopsys.com
State Changes Requested
Headers show

Commit Message

Joao Pinto July 22, 2016, 1:29 p.m. UTC
This patch adds the support to the new iATU mechanism that will be used
from Core version 4.80, which is called iATU Unroll.
The new Cores can support the iATU Unroll or support the "old" iATU 
method now called Legacy Mode. The driver is perfectly capable of
performing well for both.

In order to make sure that the iATU is really enabled a for loop was
introduced in dw_pcie_prog_outbound_atu() to improve reliability.

This patch also moves the sleep definitions to the *.c file like
suggested by Jisheng Zhang in a previous patch.

Signed-off-by: Joao Pinto <jpinto@synopsys.com>
---
changes v1->v2:
- Patch was breaking kernel build due to bad definition in macro funtion.
- Rebased on top of pci/next.

 drivers/pci/host/pcie-designware.c | 157 +++++++++++++++++++++++++++++++++----
 drivers/pci/host/pcie-designware.h |   6 +-
 2 files changed, 144 insertions(+), 19 deletions(-)

Comments

Bjorn Helgaas July 25, 2016, 8:44 p.m. UTC | #1
On Fri, Jul 22, 2016 at 02:29:38PM +0100, Joao Pinto wrote:
> This patch adds the support to the new iATU mechanism that will be used
> from Core version 4.80, which is called iATU Unroll.
> The new Cores can support the iATU Unroll or support the "old" iATU 
> method now called Legacy Mode. The driver is perfectly capable of
> performing well for both.
> 
> In order to make sure that the iATU is really enabled a for loop was
> introduced in dw_pcie_prog_outbound_atu() to improve reliability.
> 
> This patch also moves the sleep definitions to the *.c file like
> suggested by Jisheng Zhang in a previous patch.
> 
> Signed-off-by: Joao Pinto <jpinto@synopsys.com>
> ---
> changes v1->v2:
> - Patch was breaking kernel build due to bad definition in macro funtion.
> - Rebased on top of pci/next.
> 
>  drivers/pci/host/pcie-designware.c | 157 +++++++++++++++++++++++++++++++++----
>  drivers/pci/host/pcie-designware.h |   6 +-
>  2 files changed, 144 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
> index 12afce1..9135725 100644
> --- a/drivers/pci/host/pcie-designware.c
> +++ b/drivers/pci/host/pcie-designware.c
> @@ -26,7 +26,15 @@
>  
>  #include "pcie-designware.h"
>  
> -/* Synopsis specific PCIE configuration registers */
> +/* Parameters for the waiting for link up routine */
> +#define LINK_WAIT_MAX_RETRIES		10
> +#define LINK_WAIT_MAX_ATU_RETRIES	5
> +#define LINK_WAIT_USLEEP_MIN		90000
> +#define LINK_WAIT_USLEEP_MAX		100000
> +#define LINK_WAIT_IATU_MIN		9000
> +#define LINK_WAIT_IATU_MAX		10000

Add an introductory patch that moves definitions from
drivers/pci/host/pcie-designware.h to here, then add the new
ATU/unroll-related things in this patch.

> +/* Synopsys specific PCIE configuration registers */
>  #define PCIE_PORT_LINK_CONTROL		0x710
>  #define PORT_LINK_MODE_MASK		(0x3f << 16)
>  #define PORT_LINK_MODE_1_LANES		(0x1 << 16)
> @@ -58,6 +66,7 @@
>  #define PCIE_ATU_TYPE_IO		(0x2 << 0)
>  #define PCIE_ATU_TYPE_CFG0		(0x4 << 0)
>  #define PCIE_ATU_TYPE_CFG1		(0x5 << 0)
> +
>  #define PCIE_ATU_CR2			0x908
>  #define PCIE_ATU_ENABLE			(0x1 << 31)
>  #define PCIE_ATU_BAR_MODE_ENABLE	(0x1 << 30)
> @@ -75,6 +84,37 @@
>  #define PCIE_PHY_DEBUG_R1		(PLR_OFFSET + 0x2c)
>  #define PCIE_PHY_DEBUG_R1_LINK_UP	0x00000010
>  
> +/*
> + * iatu unroll specific registers and definitions
> + * From 4.80 Core version the address translation will be made by unroll
> + */
> +
> +/* Registers */
> +#define PCIE_ATU_UNR_REGION_CTRL1	0x00
> +#define PCIE_ATU_UNR_REGION_CTRL2	0x01
> +#define PCIE_ATU_UNR_LOWER_BASE		0x02
> +#define PCIE_ATU_UNR_UPPER_BASE		0x03
> +#define PCIE_ATU_UNR_LIMIT		0x04
> +#define PCIE_ATU_UNR_LOWER_TARGET	0x05
> +#define PCIE_ATU_UNR_UPPER_TARGET	0x06
> +#define PCIE_ATU_UNR_REGION_CTRL3	0x07
> +#define PCIE_ATU_UNR_UPPR_LIMIT		0x08

Last two items aren't used.

> +/* register address builder */
> +#define PCIE_GET_ATU_INB_UNR_REG_ADDR(region, register)		\
> +					((0x3 << 20) | (region << 9) |	\
> +					(0x1 << 8) | (register << 2))
> +
> +#define PCIE_GET_ATU_OUTB_UNR_REG_ADDR(region, register)		\
> +					((0x3 << 20) | (region << 9) |	\
> +					(register << 2))
> +
> +/* translation types */
> +#define PCIE_TRANSL_INB			0x1
> +#define PCIE_TRANSL_OUTB		0x2
> +
> +/* end of Unroll specific */
> +
>  static struct pci_ops dw_pcie_ops;
>  
>  int dw_pcie_cfg_read(void __iomem *addr, int size, u32 *val)
> @@ -131,6 +171,38 @@ static inline void dw_pcie_writel_rc(struct pcie_port *pp, u32 val, u32 reg)
>  		writel(val, pp->dbi_base + reg);
>  }
>  
> +static inline void dw_pcie_readl_unroll(struct pcie_port *pp, u32 type,
> +						u32 index, u32 reg, u32 *val)
> +{
> +	u32 reg_addr = 0;
> +
> +	if (type == PCIE_TRANSL_OUTB)
> +		reg_addr = PCIE_GET_ATU_OUTB_UNR_REG_ADDR(index, reg);
> +	else if  (type == PCIE_TRANSL_INB)
> +		reg_addr = PCIE_GET_ATU_INB_UNR_REG_ADDR(index, reg);

PCIE_TRANSL_INB is never used.  In fact, dw_pcie_readl_unroll() is
*always* called with PCIE_TRANSL_OUTB, so it's not clear what the
value of passing it as an argument is.

> +
> +	if (pp->ops->readl_rc)
> +		pp->ops->readl_rc(pp, pp->dbi_base + reg_addr, val);
> +	else
> +		*val = readl(pp->dbi_base + reg_addr);
> +}
> +
> +static inline void dw_pcie_writel_unroll(struct pcie_port *pp, u32 type,
> +						u32 index, u32 val, u32 reg)
> +{
> +	u32 reg_addr = 0;
> +
> +	if (type == PCIE_TRANSL_OUTB)
> +		reg_addr = PCIE_GET_ATU_OUTB_UNR_REG_ADDR(index, reg);
> +	else if  (type == PCIE_TRANSL_INB)
> +		reg_addr = PCIE_GET_ATU_INB_UNR_REG_ADDR(index, reg);
> +
> +	if (pp->ops->writel_rc)
> +		pp->ops->writel_rc(pp, val, pp->dbi_base + reg_addr);
> +	else
> +		writel(val, pp->dbi_base + reg_addr);
> +}
> +
>  static int dw_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
>  			       u32 *val)
>  {
> @@ -152,24 +224,66 @@ static int dw_pcie_wr_own_conf(struct pcie_port *pp, int where, int size,
>  static void dw_pcie_prog_outbound_atu(struct pcie_port *pp, int index,
>  		int type, u64 cpu_addr, u64 pci_addr, u32 size)
>  {
> -	u32 val;
> -
> -	dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | index,
> -			  PCIE_ATU_VIEWPORT);
> -	dw_pcie_writel_rc(pp, lower_32_bits(cpu_addr), PCIE_ATU_LOWER_BASE);
> -	dw_pcie_writel_rc(pp, upper_32_bits(cpu_addr), PCIE_ATU_UPPER_BASE);
> -	dw_pcie_writel_rc(pp, lower_32_bits(cpu_addr + size - 1),
> -			  PCIE_ATU_LIMIT);
> -	dw_pcie_writel_rc(pp, lower_32_bits(pci_addr), PCIE_ATU_LOWER_TARGET);
> -	dw_pcie_writel_rc(pp, upper_32_bits(pci_addr), PCIE_ATU_UPPER_TARGET);
> -	dw_pcie_writel_rc(pp, type, PCIE_ATU_CR1);
> -	dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
> +	u32 val = 0;
> +	u32 retries = 0;
> +
> +	if (pp->iatu_unroll_status) {
> +		/* outbound translation using Unroll feature*/
> +		dw_pcie_writel_unroll(pp, PCIE_TRANSL_OUTB, index,
> +			lower_32_bits(cpu_addr), PCIE_ATU_UNR_LOWER_BASE);
> +		dw_pcie_writel_unroll(pp, PCIE_TRANSL_OUTB, index,
> +			upper_32_bits(cpu_addr), PCIE_ATU_UNR_UPPER_BASE);
> +		dw_pcie_writel_unroll(pp, PCIE_TRANSL_OUTB, index,
> +			lower_32_bits(cpu_addr + size - 1), PCIE_ATU_UNR_LIMIT);
> +		dw_pcie_writel_unroll(pp, PCIE_TRANSL_OUTB, index,
> +			lower_32_bits(pci_addr), PCIE_ATU_UNR_LOWER_TARGET);
> +		dw_pcie_writel_unroll(pp, PCIE_TRANSL_OUTB, index,
> +			upper_32_bits(pci_addr), PCIE_ATU_UNR_UPPER_TARGET);
> +		dw_pcie_writel_unroll(pp, PCIE_TRANSL_OUTB, index,
> +			type, PCIE_ATU_UNR_REGION_CTRL1);
> +		dw_pcie_writel_unroll(pp, PCIE_TRANSL_OUTB, index,
> +			PCIE_ATU_ENABLE, PCIE_ATU_UNR_REGION_CTRL2);
> +		dw_pcie_readl_unroll(pp, PCIE_TRANSL_OUTB, index,
> +			PCIE_ATU_UNR_REGION_CTRL2, &val);
> +	} else {
> +		/* outbound translation using legacy mechanism */
> +		dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | index,
> +						PCIE_ATU_VIEWPORT);
> +		dw_pcie_writel_rc(pp, lower_32_bits(cpu_addr),
> +						PCIE_ATU_LOWER_BASE);
> +		dw_pcie_writel_rc(pp, upper_32_bits(cpu_addr),
> +						PCIE_ATU_UPPER_BASE);
> +		dw_pcie_writel_rc(pp, lower_32_bits(cpu_addr + size - 1),
> +						PCIE_ATU_LIMIT);
> +		dw_pcie_writel_rc(pp, lower_32_bits(pci_addr),
> +						PCIE_ATU_LOWER_TARGET);
> +		dw_pcie_writel_rc(pp, upper_32_bits(pci_addr),
> +						PCIE_ATU_UPPER_TARGET);
> +		dw_pcie_writel_rc(pp, type, PCIE_ATU_CR1);
> +		dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
> +		dw_pcie_readl_rc(pp, PCIE_ATU_CR2, &val);
> +	}
>  
>  	/*
>  	 * Make sure ATU enable takes effect before any subsequent config
>  	 * and I/O accesses.
>  	 */

Move the PCIE_ATU_UNR_REGION_CTRL2 and PCIE_ATU_CR2 reads down here so
everything related to the retry loop is right here.  You can probably
even restructure the loop so there's only one call without having to
repeat it above then again inside the loop.

> -	dw_pcie_readl_rc(pp, PCIE_ATU_CR2, &val);
> +	for (retries = 0; retries < LINK_WAIT_MAX_ATU_RETRIES; retries++) {
> +
> +		if (val == PCIE_ATU_ENABLE)
> +			break;
> +
> +		usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX);
> +
> +		if (pp->iatu_unroll_status) {
> +			dw_pcie_readl_unroll(pp, PCIE_TRANSL_OUTB, index,
> +				PCIE_ATU_UNR_REGION_CTRL2, &val);
> +		} else {
> +			dw_pcie_readl_rc(pp, PCIE_ATU_CR2, &val);
> +		}
> +	}

This retry loop is not strictly related to unroll, so it could be done
in a separate patch.

> +	dev_dbg(pp->dev, "iATU is not being enabled\n");
>  }
>  
>  static struct irq_chip dw_msi_irq_chip = {
> @@ -428,6 +542,18 @@ static const struct irq_domain_ops msi_domain_ops = {
>  	.map = dw_pcie_msi_map,
>  };
>  
> +static void dw_pcie_get_atu_mode(struct pcie_port *pp)
> +{
> +	u32 val = 0;
> +
> +	/* Check if the iATU unroll is enabled or not */

Refer to "iATU" consistently in comments.  Several occurrences above
are "iatu", and below there's "ATU".

> +	dw_pcie_readl_rc(pp, PCIE_ATU_VIEWPORT, &val);
> +
> +	pp->iatu_unroll_status = 0; /* disabled - legacy is used */
> +	if (val == 0xFFFFFFFF)
> +		pp->iatu_unroll_status = 1; /* enabled */
> +}
> +
>  int dw_pcie_host_init(struct pcie_port *pp)
>  {
>  	struct device_node *np = pp->dev->of_node;
> @@ -544,6 +670,9 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  		}
>  	}
>  
> +	/* get ATU mode */
> +	dw_pcie_get_atu_mode(pp);

Comment is superfluous since it only repeats the function name.  I
prefer the style of:

  pp->iatu_unroll = dw_pcie_iatu_unroll_supported(pp);

so the assignment isn't buried inside the function.

>  	if (pp->ops->host_init)
>  		pp->ops->host_init(pp);
>  
> diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
> index f437f9b..354a981 100644
> --- a/drivers/pci/host/pcie-designware.h
> +++ b/drivers/pci/host/pcie-designware.h
> @@ -22,11 +22,6 @@
>  #define MAX_MSI_IRQS			32
>  #define MAX_MSI_CTRLS			(MAX_MSI_IRQS / 32)
>  
> -/* Parameters for the waiting for link up routine */
> -#define LINK_WAIT_MAX_RETRIES		10
> -#define LINK_WAIT_USLEEP_MIN		90000
> -#define LINK_WAIT_USLEEP_MAX		100000
> -
>  struct pcie_port {
>  	struct device		*dev;
>  	u8			root_bus_nr;
> @@ -53,6 +48,7 @@ struct pcie_port {
>  	int			msi_irq;
>  	struct irq_domain	*irq_domain;
>  	unsigned long		msi_data;
> +	u8			iatu_unroll_status;
>  	DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS);
>  };
>  
> -- 
> 1.8.1.5
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Joao Pinto Aug. 2, 2016, 10:27 a.m. UTC | #2
On 7/25/2016 9:44 PM, Bjorn Helgaas wrote:
> On Fri, Jul 22, 2016 at 02:29:38PM +0100, Joao Pinto wrote:
>> This patch adds the support to the new iATU mechanism that will be used
>> from Core version 4.80, which is called iATU Unroll.
>> The new Cores can support the iATU Unroll or support the "old" iATU 
>> method now called Legacy Mode. The driver is perfectly capable of
>> performing well for both.
>>
>> In order to make sure that the iATU is really enabled a for loop was
>> introduced in dw_pcie_prog_outbound_atu() to improve reliability.
>>
>> This patch also moves the sleep definitions to the *.c file like
>> suggested by Jisheng Zhang in a previous patch.
>>
>> Signed-off-by: Joao Pinto <jpinto@synopsys.com>
>> ---
>> changes v1->v2:
>> - Patch was breaking kernel build due to bad definition in macro funtion.
>> - Rebased on top of pci/next.
>>
>>  drivers/pci/host/pcie-designware.c | 157 +++++++++++++++++++++++++++++++++----
>>  drivers/pci/host/pcie-designware.h |   6 +-
>>  2 files changed, 144 insertions(+), 19 deletions(-)
>>
>> diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
>> index 12afce1..9135725 100644
>> --- a/drivers/pci/host/pcie-designware.c
>> +++ b/drivers/pci/host/pcie-designware.c
>> @@ -26,7 +26,15 @@
>>  
>>  #include "pcie-designware.h"
>>  
>> -/* Synopsis specific PCIE configuration registers */
>> +/* Parameters for the waiting for link up routine */
>> +#define LINK_WAIT_MAX_RETRIES		10
>> +#define LINK_WAIT_MAX_ATU_RETRIES	5
>> +#define LINK_WAIT_USLEEP_MIN		90000
>> +#define LINK_WAIT_USLEEP_MAX		100000
>> +#define LINK_WAIT_IATU_MIN		9000
>> +#define LINK_WAIT_IATU_MAX		10000
> 
> Add an introductory patch that moves definitions from
> drivers/pci/host/pcie-designware.h to here, then add the new
> ATU/unroll-related things in this patch.

Makes sense! I will do that!

> 
>> +/* Synopsys specific PCIE configuration registers */
>>  #define PCIE_PORT_LINK_CONTROL		0x710
>>  #define PORT_LINK_MODE_MASK		(0x3f << 16)
>>  #define PORT_LINK_MODE_1_LANES		(0x1 << 16)
>> @@ -58,6 +66,7 @@
>>  #define PCIE_ATU_TYPE_IO		(0x2 << 0)
>>  #define PCIE_ATU_TYPE_CFG0		(0x4 << 0)
>>  #define PCIE_ATU_TYPE_CFG1		(0x5 << 0)
>> +
>>  #define PCIE_ATU_CR2			0x908
>>  #define PCIE_ATU_ENABLE			(0x1 << 31)
>>  #define PCIE_ATU_BAR_MODE_ENABLE	(0x1 << 30)
>> @@ -75,6 +84,37 @@
>>  #define PCIE_PHY_DEBUG_R1		(PLR_OFFSET + 0x2c)
>>  #define PCIE_PHY_DEBUG_R1_LINK_UP	0x00000010
>>  
>> +/*
>> + * iatu unroll specific registers and definitions
>> + * From 4.80 Core version the address translation will be made by unroll
>> + */
>> +
>> +/* Registers */
>> +#define PCIE_ATU_UNR_REGION_CTRL1	0x00
>> +#define PCIE_ATU_UNR_REGION_CTRL2	0x01
>> +#define PCIE_ATU_UNR_LOWER_BASE		0x02
>> +#define PCIE_ATU_UNR_UPPER_BASE		0x03
>> +#define PCIE_ATU_UNR_LIMIT		0x04
>> +#define PCIE_ATU_UNR_LOWER_TARGET	0x05
>> +#define PCIE_ATU_UNR_UPPER_TARGET	0x06
>> +#define PCIE_ATU_UNR_REGION_CTRL3	0x07
>> +#define PCIE_ATU_UNR_UPPR_LIMIT		0x08
> 
> Last two items aren't used.

I can take them off, but don't you think it is useful to include them for future
applications?

> 
>> +/* register address builder */
>> +#define PCIE_GET_ATU_INB_UNR_REG_ADDR(region, register)		\
>> +					((0x3 << 20) | (region << 9) |	\
>> +					(0x1 << 8) | (register << 2))
>> +
>> +#define PCIE_GET_ATU_OUTB_UNR_REG_ADDR(region, register)		\
>> +					((0x3 << 20) | (region << 9) |	\
>> +					(register << 2))
>> +
>> +/* translation types */
>> +#define PCIE_TRANSL_INB			0x1
>> +#define PCIE_TRANSL_OUTB		0x2
>> +
>> +/* end of Unroll specific */
>> +
>>  static struct pci_ops dw_pcie_ops;
>>  
>>  int dw_pcie_cfg_read(void __iomem *addr, int size, u32 *val)
>> @@ -131,6 +171,38 @@ static inline void dw_pcie_writel_rc(struct pcie_port *pp, u32 val, u32 reg)
>>  		writel(val, pp->dbi_base + reg);
>>  }
>>  
>> +static inline void dw_pcie_readl_unroll(struct pcie_port *pp, u32 type,
>> +						u32 index, u32 reg, u32 *val)
>> +{
>> +	u32 reg_addr = 0;
>> +
>> +	if (type == PCIE_TRANSL_OUTB)
>> +		reg_addr = PCIE_GET_ATU_OUTB_UNR_REG_ADDR(index, reg);
>> +	else if  (type == PCIE_TRANSL_INB)
>> +		reg_addr = PCIE_GET_ATU_INB_UNR_REG_ADDR(index, reg);
> 
> PCIE_TRANSL_INB is never used.  In fact, dw_pcie_readl_unroll() is
> *always* called with PCIE_TRANSL_OUTB, so it's not clear what the
> value of passing it as an argument is.

I included The Inbound translation mechanism because you can have Inbound or
Outbound translation in the iATU. The old mechanism also had Inbound properties
that are not used in the code. I suggest we keep the Inbound mechanism to avoid
future rework. Agree?

> 
>> +
>> +	if (pp->ops->readl_rc)
>> +		pp->ops->readl_rc(pp, pp->dbi_base + reg_addr, val);
>> +	else
>> +		*val = readl(pp->dbi_base + reg_addr);
>> +}
>> +
>> +static inline void dw_pcie_writel_unroll(struct pcie_port *pp, u32 type,
>> +						u32 index, u32 val, u32 reg)
>> +{
>> +	u32 reg_addr = 0;
>> +
>> +	if (type == PCIE_TRANSL_OUTB)
>> +		reg_addr = PCIE_GET_ATU_OUTB_UNR_REG_ADDR(index, reg);
>> +	else if  (type == PCIE_TRANSL_INB)
>> +		reg_addr = PCIE_GET_ATU_INB_UNR_REG_ADDR(index, reg);
>> +
>> +	if (pp->ops->writel_rc)
>> +		pp->ops->writel_rc(pp, val, pp->dbi_base + reg_addr);
>> +	else
>> +		writel(val, pp->dbi_base + reg_addr);
>> +}
>> +
>>  static int dw_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
>>  			       u32 *val)
>>  {
>> @@ -152,24 +224,66 @@ static int dw_pcie_wr_own_conf(struct pcie_port *pp, int where, int size,
>>  static void dw_pcie_prog_outbound_atu(struct pcie_port *pp, int index,
>>  		int type, u64 cpu_addr, u64 pci_addr, u32 size)
>>  {
>> -	u32 val;
>> -
>> -	dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | index,
>> -			  PCIE_ATU_VIEWPORT);
>> -	dw_pcie_writel_rc(pp, lower_32_bits(cpu_addr), PCIE_ATU_LOWER_BASE);
>> -	dw_pcie_writel_rc(pp, upper_32_bits(cpu_addr), PCIE_ATU_UPPER_BASE);
>> -	dw_pcie_writel_rc(pp, lower_32_bits(cpu_addr + size - 1),
>> -			  PCIE_ATU_LIMIT);
>> -	dw_pcie_writel_rc(pp, lower_32_bits(pci_addr), PCIE_ATU_LOWER_TARGET);
>> -	dw_pcie_writel_rc(pp, upper_32_bits(pci_addr), PCIE_ATU_UPPER_TARGET);
>> -	dw_pcie_writel_rc(pp, type, PCIE_ATU_CR1);
>> -	dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
>> +	u32 val = 0;
>> +	u32 retries = 0;
>> +
>> +	if (pp->iatu_unroll_status) {
>> +		/* outbound translation using Unroll feature*/
>> +		dw_pcie_writel_unroll(pp, PCIE_TRANSL_OUTB, index,
>> +			lower_32_bits(cpu_addr), PCIE_ATU_UNR_LOWER_BASE);
>> +		dw_pcie_writel_unroll(pp, PCIE_TRANSL_OUTB, index,
>> +			upper_32_bits(cpu_addr), PCIE_ATU_UNR_UPPER_BASE);
>> +		dw_pcie_writel_unroll(pp, PCIE_TRANSL_OUTB, index,
>> +			lower_32_bits(cpu_addr + size - 1), PCIE_ATU_UNR_LIMIT);
>> +		dw_pcie_writel_unroll(pp, PCIE_TRANSL_OUTB, index,
>> +			lower_32_bits(pci_addr), PCIE_ATU_UNR_LOWER_TARGET);
>> +		dw_pcie_writel_unroll(pp, PCIE_TRANSL_OUTB, index,
>> +			upper_32_bits(pci_addr), PCIE_ATU_UNR_UPPER_TARGET);
>> +		dw_pcie_writel_unroll(pp, PCIE_TRANSL_OUTB, index,
>> +			type, PCIE_ATU_UNR_REGION_CTRL1);
>> +		dw_pcie_writel_unroll(pp, PCIE_TRANSL_OUTB, index,
>> +			PCIE_ATU_ENABLE, PCIE_ATU_UNR_REGION_CTRL2);
>> +		dw_pcie_readl_unroll(pp, PCIE_TRANSL_OUTB, index,
>> +			PCIE_ATU_UNR_REGION_CTRL2, &val);
>> +	} else {
>> +		/* outbound translation using legacy mechanism */
>> +		dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | index,
>> +						PCIE_ATU_VIEWPORT);
>> +		dw_pcie_writel_rc(pp, lower_32_bits(cpu_addr),
>> +						PCIE_ATU_LOWER_BASE);
>> +		dw_pcie_writel_rc(pp, upper_32_bits(cpu_addr),
>> +						PCIE_ATU_UPPER_BASE);
>> +		dw_pcie_writel_rc(pp, lower_32_bits(cpu_addr + size - 1),
>> +						PCIE_ATU_LIMIT);
>> +		dw_pcie_writel_rc(pp, lower_32_bits(pci_addr),
>> +						PCIE_ATU_LOWER_TARGET);
>> +		dw_pcie_writel_rc(pp, upper_32_bits(pci_addr),
>> +						PCIE_ATU_UPPER_TARGET);
>> +		dw_pcie_writel_rc(pp, type, PCIE_ATU_CR1);
>> +		dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
>> +		dw_pcie_readl_rc(pp, PCIE_ATU_CR2, &val);
>> +	}
>>  
>>  	/*
>>  	 * Make sure ATU enable takes effect before any subsequent config
>>  	 * and I/O accesses.
>>  	 */
> 
> Move the PCIE_ATU_UNR_REGION_CTRL2 and PCIE_ATU_CR2 reads down here so
> everything related to the retry loop is right here.  You can probably
> even restructure the loop so there's only one call without having to
> repeat it above then again inside the loop.

Right. I will do that!

> 
>> -	dw_pcie_readl_rc(pp, PCIE_ATU_CR2, &val);
>> +	for (retries = 0; retries < LINK_WAIT_MAX_ATU_RETRIES; retries++) {
>> +
>> +		if (val == PCIE_ATU_ENABLE)
>> +			break;
>> +
>> +		usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX);
>> +
>> +		if (pp->iatu_unroll_status) {
>> +			dw_pcie_readl_unroll(pp, PCIE_TRANSL_OUTB, index,
>> +				PCIE_ATU_UNR_REGION_CTRL2, &val);
>> +		} else {
>> +			dw_pcie_readl_rc(pp, PCIE_ATU_CR2, &val);
>> +		}
>> +	}
> 
> This retry loop is not strictly related to unroll, so it could be done
> in a separate patch.

Right. I will do that!

> 
>> +	dev_dbg(pp->dev, "iATU is not being enabled\n");
>>  }
>>  
>>  static struct irq_chip dw_msi_irq_chip = {
>> @@ -428,6 +542,18 @@ static const struct irq_domain_ops msi_domain_ops = {
>>  	.map = dw_pcie_msi_map,
>>  };
>>  
>> +static void dw_pcie_get_atu_mode(struct pcie_port *pp)
>> +{
>> +	u32 val = 0;
>> +
>> +	/* Check if the iATU unroll is enabled or not */
> 
> Refer to "iATU" consistently in comments.  Several occurrences above
> are "iatu", and below there's "ATU".

Right. I will do that!

> 
>> +	dw_pcie_readl_rc(pp, PCIE_ATU_VIEWPORT, &val);
>> +
>> +	pp->iatu_unroll_status = 0; /* disabled - legacy is used */
>> +	if (val == 0xFFFFFFFF)
>> +		pp->iatu_unroll_status = 1; /* enabled */
>> +}
>> +
>>  int dw_pcie_host_init(struct pcie_port *pp)
>>  {
>>  	struct device_node *np = pp->dev->of_node;
>> @@ -544,6 +670,9 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>  		}
>>  	}
>>  
>> +	/* get ATU mode */
>> +	dw_pcie_get_atu_mode(pp);
> 
> Comment is superfluous since it only repeats the function name.  I
> prefer the style of:
> 
>   pp->iatu_unroll = dw_pcie_iatu_unroll_supported(pp);
> 
> so the assignment isn't buried inside the function.
> 

Makes sense.

>>  	if (pp->ops->host_init)
>>  		pp->ops->host_init(pp);
>>  
>> diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
>> index f437f9b..354a981 100644
>> --- a/drivers/pci/host/pcie-designware.h
>> +++ b/drivers/pci/host/pcie-designware.h
>> @@ -22,11 +22,6 @@
>>  #define MAX_MSI_IRQS			32
>>  #define MAX_MSI_CTRLS			(MAX_MSI_IRQS / 32)
>>  
>> -/* Parameters for the waiting for link up routine */
>> -#define LINK_WAIT_MAX_RETRIES		10
>> -#define LINK_WAIT_USLEEP_MIN		90000
>> -#define LINK_WAIT_USLEEP_MAX		100000
>> -
>>  struct pcie_port {
>>  	struct device		*dev;
>>  	u8			root_bus_nr;
>> @@ -53,6 +48,7 @@ struct pcie_port {
>>  	int			msi_irq;
>>  	struct irq_domain	*irq_domain;
>>  	unsigned long		msi_data;
>> +	u8			iatu_unroll_status;
>>  	DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS);
>>  };
>>  
>> -- 
>> 1.8.1.5
>>

Thanks for the review!

Joao

--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Bjorn Helgaas Aug. 2, 2016, 12:53 p.m. UTC | #3
On Tue, Aug 02, 2016 at 11:27:45AM +0100, Joao Pinto wrote:
> On 7/25/2016 9:44 PM, Bjorn Helgaas wrote:
> > On Fri, Jul 22, 2016 at 02:29:38PM +0100, Joao Pinto wrote:
> >> This patch adds the support to the new iATU mechanism that will be used
> >> from Core version 4.80, which is called iATU Unroll.
> >> The new Cores can support the iATU Unroll or support the "old" iATU 
> >> method now called Legacy Mode. The driver is perfectly capable of
> >> performing well for both.
> >>
> >> In order to make sure that the iATU is really enabled a for loop was
> >> introduced in dw_pcie_prog_outbound_atu() to improve reliability.
> >>
> >> This patch also moves the sleep definitions to the *.c file like
> >> suggested by Jisheng Zhang in a previous patch.
> >>
> >> Signed-off-by: Joao Pinto <jpinto@synopsys.com>
> ...

> >> +/* Registers */
> >> +#define PCIE_ATU_UNR_REGION_CTRL1	0x00
> >> +#define PCIE_ATU_UNR_REGION_CTRL2	0x01
> >> +#define PCIE_ATU_UNR_LOWER_BASE		0x02
> >> +#define PCIE_ATU_UNR_UPPER_BASE		0x03
> >> +#define PCIE_ATU_UNR_LIMIT		0x04
> >> +#define PCIE_ATU_UNR_LOWER_TARGET	0x05
> >> +#define PCIE_ATU_UNR_UPPER_TARGET	0x06
> >> +#define PCIE_ATU_UNR_REGION_CTRL3	0x07
> >> +#define PCIE_ATU_UNR_UPPR_LIMIT		0x08
> > 
> > Last two items aren't used.
> 
> I can take them off, but don't you think it is useful to include them for future
> applications?

This isn't a huge deal either way.  Personally I wouldn't include them
because if they're not used, they haven't been tested, and there's
always the possibility of transcription errors.  If you need to use
them in the future, it makes perfect sense to add the register
definition in the same patch that uses the register.

> ...
> >> +static inline void dw_pcie_readl_unroll(struct pcie_port *pp, u32 type,
> >> +						u32 index, u32 reg, u32 *val)
> >> +{
> >> +	u32 reg_addr = 0;
> >> +
> >> +	if (type == PCIE_TRANSL_OUTB)
> >> +		reg_addr = PCIE_GET_ATU_OUTB_UNR_REG_ADDR(index, reg);
> >> +	else if  (type == PCIE_TRANSL_INB)
> >> +		reg_addr = PCIE_GET_ATU_INB_UNR_REG_ADDR(index, reg);
> > 
> > PCIE_TRANSL_INB is never used.  In fact, dw_pcie_readl_unroll() is
> > *always* called with PCIE_TRANSL_OUTB, so it's not clear what the
> > value of passing it as an argument is.
> 
> I included The Inbound translation mechanism because you can have Inbound or
> Outbound translation in the iATU. The old mechanism also had Inbound properties
> that are not used in the code. I suggest we keep the Inbound mechanism to avoid
> future rework. Agree?

Again, not a huge deal, but since PCIE_TRANSL_INB is not used, it
makes life harder for the reader, and the related code is not tested.
So personally, I would remove it and add it back if/when it is needed.

Bjorn
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Joao Pinto Aug. 2, 2016, 2:27 p.m. UTC | #4
On 8/2/2016 1:53 PM, Bjorn Helgaas wrote:
> On Tue, Aug 02, 2016 at 11:27:45AM +0100, Joao Pinto wrote:
>> On 7/25/2016 9:44 PM, Bjorn Helgaas wrote:
>>> On Fri, Jul 22, 2016 at 02:29:38PM +0100, Joao Pinto wrote:
>>>> This patch adds the support to the new iATU mechanism that will be used
>>>> from Core version 4.80, which is called iATU Unroll.
>>>> The new Cores can support the iATU Unroll or support the "old" iATU 
>>>> method now called Legacy Mode. The driver is perfectly capable of
>>>> performing well for both.
>>>>
>>>> In order to make sure that the iATU is really enabled a for loop was
>>>> introduced in dw_pcie_prog_outbound_atu() to improve reliability.
>>>>

(snip...)

>> ...
>>>> +static inline void dw_pcie_readl_unroll(struct pcie_port *pp, u32 type,
>>>> +						u32 index, u32 reg, u32 *val)
>>>> +{
>>>> +	u32 reg_addr = 0;
>>>> +
>>>> +	if (type == PCIE_TRANSL_OUTB)
>>>> +		reg_addr = PCIE_GET_ATU_OUTB_UNR_REG_ADDR(index, reg);
>>>> +	else if  (type == PCIE_TRANSL_INB)
>>>> +		reg_addr = PCIE_GET_ATU_INB_UNR_REG_ADDR(index, reg);
>>>
>>> PCIE_TRANSL_INB is never used.  In fact, dw_pcie_readl_unroll() is
>>> *always* called with PCIE_TRANSL_OUTB, so it's not clear what the
>>> value of passing it as an argument is.
>>
>> I included The Inbound translation mechanism because you can have Inbound or
>> Outbound translation in the iATU. The old mechanism also had Inbound properties
>> that are not used in the code. I suggest we keep the Inbound mechanism to avoid
>> future rework. Agree?
> 
> Again, not a huge deal, but since PCIE_TRANSL_INB is not used, it
> makes life harder for the reader, and the related code is not tested.
> So personally, I would remove it and add it back if/when it is needed.
> 
> Bjorn
> 

Ok, I will do that and send a new version soon. Thanks!

Joao
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index 12afce1..9135725 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -26,7 +26,15 @@ 
 
 #include "pcie-designware.h"
 
-/* Synopsis specific PCIE configuration registers */
+/* Parameters for the waiting for link up routine */
+#define LINK_WAIT_MAX_RETRIES		10
+#define LINK_WAIT_MAX_ATU_RETRIES	5
+#define LINK_WAIT_USLEEP_MIN		90000
+#define LINK_WAIT_USLEEP_MAX		100000
+#define LINK_WAIT_IATU_MIN		9000
+#define LINK_WAIT_IATU_MAX		10000
+
+/* Synopsys specific PCIE configuration registers */
 #define PCIE_PORT_LINK_CONTROL		0x710
 #define PORT_LINK_MODE_MASK		(0x3f << 16)
 #define PORT_LINK_MODE_1_LANES		(0x1 << 16)
@@ -58,6 +66,7 @@ 
 #define PCIE_ATU_TYPE_IO		(0x2 << 0)
 #define PCIE_ATU_TYPE_CFG0		(0x4 << 0)
 #define PCIE_ATU_TYPE_CFG1		(0x5 << 0)
+
 #define PCIE_ATU_CR2			0x908
 #define PCIE_ATU_ENABLE			(0x1 << 31)
 #define PCIE_ATU_BAR_MODE_ENABLE	(0x1 << 30)
@@ -75,6 +84,37 @@ 
 #define PCIE_PHY_DEBUG_R1		(PLR_OFFSET + 0x2c)
 #define PCIE_PHY_DEBUG_R1_LINK_UP	0x00000010
 
+/*
+ * iatu unroll specific registers and definitions
+ * From 4.80 Core version the address translation will be made by unroll
+ */
+
+/* Registers */
+#define PCIE_ATU_UNR_REGION_CTRL1	0x00
+#define PCIE_ATU_UNR_REGION_CTRL2	0x01
+#define PCIE_ATU_UNR_LOWER_BASE		0x02
+#define PCIE_ATU_UNR_UPPER_BASE		0x03
+#define PCIE_ATU_UNR_LIMIT		0x04
+#define PCIE_ATU_UNR_LOWER_TARGET	0x05
+#define PCIE_ATU_UNR_UPPER_TARGET	0x06
+#define PCIE_ATU_UNR_REGION_CTRL3	0x07
+#define PCIE_ATU_UNR_UPPR_LIMIT		0x08
+
+/* register address builder */
+#define PCIE_GET_ATU_INB_UNR_REG_ADDR(region, register)		\
+					((0x3 << 20) | (region << 9) |	\
+					(0x1 << 8) | (register << 2))
+
+#define PCIE_GET_ATU_OUTB_UNR_REG_ADDR(region, register)		\
+					((0x3 << 20) | (region << 9) |	\
+					(register << 2))
+
+/* translation types */
+#define PCIE_TRANSL_INB			0x1
+#define PCIE_TRANSL_OUTB		0x2
+
+/* end of Unroll specific */
+
 static struct pci_ops dw_pcie_ops;
 
 int dw_pcie_cfg_read(void __iomem *addr, int size, u32 *val)
@@ -131,6 +171,38 @@  static inline void dw_pcie_writel_rc(struct pcie_port *pp, u32 val, u32 reg)
 		writel(val, pp->dbi_base + reg);
 }
 
+static inline void dw_pcie_readl_unroll(struct pcie_port *pp, u32 type,
+						u32 index, u32 reg, u32 *val)
+{
+	u32 reg_addr = 0;
+
+	if (type == PCIE_TRANSL_OUTB)
+		reg_addr = PCIE_GET_ATU_OUTB_UNR_REG_ADDR(index, reg);
+	else if  (type == PCIE_TRANSL_INB)
+		reg_addr = PCIE_GET_ATU_INB_UNR_REG_ADDR(index, reg);
+
+	if (pp->ops->readl_rc)
+		pp->ops->readl_rc(pp, pp->dbi_base + reg_addr, val);
+	else
+		*val = readl(pp->dbi_base + reg_addr);
+}
+
+static inline void dw_pcie_writel_unroll(struct pcie_port *pp, u32 type,
+						u32 index, u32 val, u32 reg)
+{
+	u32 reg_addr = 0;
+
+	if (type == PCIE_TRANSL_OUTB)
+		reg_addr = PCIE_GET_ATU_OUTB_UNR_REG_ADDR(index, reg);
+	else if  (type == PCIE_TRANSL_INB)
+		reg_addr = PCIE_GET_ATU_INB_UNR_REG_ADDR(index, reg);
+
+	if (pp->ops->writel_rc)
+		pp->ops->writel_rc(pp, val, pp->dbi_base + reg_addr);
+	else
+		writel(val, pp->dbi_base + reg_addr);
+}
+
 static int dw_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
 			       u32 *val)
 {
@@ -152,24 +224,66 @@  static int dw_pcie_wr_own_conf(struct pcie_port *pp, int where, int size,
 static void dw_pcie_prog_outbound_atu(struct pcie_port *pp, int index,
 		int type, u64 cpu_addr, u64 pci_addr, u32 size)
 {
-	u32 val;
-
-	dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | index,
-			  PCIE_ATU_VIEWPORT);
-	dw_pcie_writel_rc(pp, lower_32_bits(cpu_addr), PCIE_ATU_LOWER_BASE);
-	dw_pcie_writel_rc(pp, upper_32_bits(cpu_addr), PCIE_ATU_UPPER_BASE);
-	dw_pcie_writel_rc(pp, lower_32_bits(cpu_addr + size - 1),
-			  PCIE_ATU_LIMIT);
-	dw_pcie_writel_rc(pp, lower_32_bits(pci_addr), PCIE_ATU_LOWER_TARGET);
-	dw_pcie_writel_rc(pp, upper_32_bits(pci_addr), PCIE_ATU_UPPER_TARGET);
-	dw_pcie_writel_rc(pp, type, PCIE_ATU_CR1);
-	dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
+	u32 val = 0;
+	u32 retries = 0;
+
+	if (pp->iatu_unroll_status) {
+		/* outbound translation using Unroll feature*/
+		dw_pcie_writel_unroll(pp, PCIE_TRANSL_OUTB, index,
+			lower_32_bits(cpu_addr), PCIE_ATU_UNR_LOWER_BASE);
+		dw_pcie_writel_unroll(pp, PCIE_TRANSL_OUTB, index,
+			upper_32_bits(cpu_addr), PCIE_ATU_UNR_UPPER_BASE);
+		dw_pcie_writel_unroll(pp, PCIE_TRANSL_OUTB, index,
+			lower_32_bits(cpu_addr + size - 1), PCIE_ATU_UNR_LIMIT);
+		dw_pcie_writel_unroll(pp, PCIE_TRANSL_OUTB, index,
+			lower_32_bits(pci_addr), PCIE_ATU_UNR_LOWER_TARGET);
+		dw_pcie_writel_unroll(pp, PCIE_TRANSL_OUTB, index,
+			upper_32_bits(pci_addr), PCIE_ATU_UNR_UPPER_TARGET);
+		dw_pcie_writel_unroll(pp, PCIE_TRANSL_OUTB, index,
+			type, PCIE_ATU_UNR_REGION_CTRL1);
+		dw_pcie_writel_unroll(pp, PCIE_TRANSL_OUTB, index,
+			PCIE_ATU_ENABLE, PCIE_ATU_UNR_REGION_CTRL2);
+		dw_pcie_readl_unroll(pp, PCIE_TRANSL_OUTB, index,
+			PCIE_ATU_UNR_REGION_CTRL2, &val);
+	} else {
+		/* outbound translation using legacy mechanism */
+		dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | index,
+						PCIE_ATU_VIEWPORT);
+		dw_pcie_writel_rc(pp, lower_32_bits(cpu_addr),
+						PCIE_ATU_LOWER_BASE);
+		dw_pcie_writel_rc(pp, upper_32_bits(cpu_addr),
+						PCIE_ATU_UPPER_BASE);
+		dw_pcie_writel_rc(pp, lower_32_bits(cpu_addr + size - 1),
+						PCIE_ATU_LIMIT);
+		dw_pcie_writel_rc(pp, lower_32_bits(pci_addr),
+						PCIE_ATU_LOWER_TARGET);
+		dw_pcie_writel_rc(pp, upper_32_bits(pci_addr),
+						PCIE_ATU_UPPER_TARGET);
+		dw_pcie_writel_rc(pp, type, PCIE_ATU_CR1);
+		dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
+		dw_pcie_readl_rc(pp, PCIE_ATU_CR2, &val);
+	}
 
 	/*
 	 * Make sure ATU enable takes effect before any subsequent config
 	 * and I/O accesses.
 	 */
-	dw_pcie_readl_rc(pp, PCIE_ATU_CR2, &val);
+	for (retries = 0; retries < LINK_WAIT_MAX_ATU_RETRIES; retries++) {
+
+		if (val == PCIE_ATU_ENABLE)
+			break;
+
+		usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX);
+
+		if (pp->iatu_unroll_status) {
+			dw_pcie_readl_unroll(pp, PCIE_TRANSL_OUTB, index,
+				PCIE_ATU_UNR_REGION_CTRL2, &val);
+		} else {
+			dw_pcie_readl_rc(pp, PCIE_ATU_CR2, &val);
+		}
+	}
+
+	dev_dbg(pp->dev, "iATU is not being enabled\n");
 }
 
 static struct irq_chip dw_msi_irq_chip = {
@@ -428,6 +542,18 @@  static const struct irq_domain_ops msi_domain_ops = {
 	.map = dw_pcie_msi_map,
 };
 
+static void dw_pcie_get_atu_mode(struct pcie_port *pp)
+{
+	u32 val = 0;
+
+	/* Check if the iATU unroll is enabled or not */
+	dw_pcie_readl_rc(pp, PCIE_ATU_VIEWPORT, &val);
+
+	pp->iatu_unroll_status = 0; /* disabled - legacy is used */
+	if (val == 0xFFFFFFFF)
+		pp->iatu_unroll_status = 1; /* enabled */
+}
+
 int dw_pcie_host_init(struct pcie_port *pp)
 {
 	struct device_node *np = pp->dev->of_node;
@@ -544,6 +670,9 @@  int dw_pcie_host_init(struct pcie_port *pp)
 		}
 	}
 
+	/* get ATU mode */
+	dw_pcie_get_atu_mode(pp);
+
 	if (pp->ops->host_init)
 		pp->ops->host_init(pp);
 
diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
index f437f9b..354a981 100644
--- a/drivers/pci/host/pcie-designware.h
+++ b/drivers/pci/host/pcie-designware.h
@@ -22,11 +22,6 @@ 
 #define MAX_MSI_IRQS			32
 #define MAX_MSI_CTRLS			(MAX_MSI_IRQS / 32)
 
-/* Parameters for the waiting for link up routine */
-#define LINK_WAIT_MAX_RETRIES		10
-#define LINK_WAIT_USLEEP_MIN		90000
-#define LINK_WAIT_USLEEP_MAX		100000
-
 struct pcie_port {
 	struct device		*dev;
 	u8			root_bus_nr;
@@ -53,6 +48,7 @@  struct pcie_port {
 	int			msi_irq;
 	struct irq_domain	*irq_domain;
 	unsigned long		msi_data;
+	u8			iatu_unroll_status;
 	DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS);
 };