[PATCH 1/2] pci/layercape: disable all iATUs before initialization
Bjorn Helgaas
helgaas at kernel.org
Wed Sep 14 14:10:53 PDT 2016
On Thu, Sep 08, 2016 at 02:25:49PM +0800, Minghuan Lian wrote:
> Layerscape PCIe has 6 outbound iATUs. The bootloader such as
> u-boot uses 4 iATUs for CFG0 CFG1 IO and MEM separately. But
> Designware driver only uses two outbound iATUs. To avoid
> conflict between enabled but unused iATUs with used iATUs
> under Linux and unexpected behavior, the patch disables all
> iATUs before initialization.
Do we need similar changes in other DesignWare-based drivers?
> Signed-off-by: Minghuan Lian <Minghuan.Lian at nxp.com>
> ---
> drivers/pci/host/pci-layerscape.c | 17 +++++++++++++++--
> drivers/pci/host/pcie-designware.c | 7 +++++++
> drivers/pci/host/pcie-designware.h | 1 +
> 3 files changed, 23 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c
> index 114ba81..cf783ad 100644
> --- a/drivers/pci/host/pci-layerscape.c
> +++ b/drivers/pci/host/pci-layerscape.c
> @@ -38,6 +38,8 @@
> /* PEX LUT registers */
> #define PCIE_LUT_DBG 0x7FC /* PEX LUT Debug Register */
>
> +#define PCIE_IATU_NUM 6
> +
> struct ls_pcie_drvdata {
> u32 lut_offset;
> u32 ltssm_shift;
> @@ -55,6 +57,8 @@ struct ls_pcie {
>
> #define to_ls_pcie(x) container_of(x, struct ls_pcie, pp)
>
> +static void ls_pcie_host_init(struct pcie_port *pp);
I would prefer to reorder the function definitions so the forward
declaration is not necessary. This would be two patches:
1) Reorder functions (no functional change)
2) Disable iATUs
> static bool ls_pcie_is_bridge(struct ls_pcie *pcie)
> {
> u32 header_type;
> @@ -87,6 +91,14 @@ static void ls_pcie_drop_msg_tlp(struct ls_pcie *pcie)
> iowrite32(val, pcie->dbi + 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_outbound_atu(&pcie->pp, i);
It looks like maybe the DesignWare ATUs are generic enough that we could
move the loop into the generic code, e.g.,
void dw_pcie_disable_outbound_atu(struct pcie_port *pp, int count)
{
int i;
for (i = 0; i < count; i++) {
dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | i, PCIE_ATU_VIEWPORT);
dw_pcie_writel_rc(pp, 0, PCIE_ATU_CR2);
}
}
> +}
> +
> static int ls1021_pcie_link_up(struct pcie_port *pp)
> {
> u32 state;
> @@ -124,9 +136,8 @@ static void ls1021_pcie_host_init(struct pcie_port *pp)
> }
> pcie->index = index[1];
>
> + ls_pcie_host_init(pp);
> dw_pcie_setup_rc(pp);
> -
> - ls_pcie_drop_msg_tlp(pcie);
Can you split this to a separate patch? This hunk changes
ls1021_pcie_host_init() so it does several things in addition to
ls_pcie_drop_msg_tlp(), and it is unrelated to the "disable iATU" change.
> }
>
> static int ls_pcie_link_up(struct pcie_port *pp)
> @@ -153,6 +164,8 @@ static void ls_pcie_host_init(struct pcie_port *pp)
> ls_pcie_clear_multifunction(pcie);
> ls_pcie_drop_msg_tlp(pcie);
> iowrite32(0, pcie->dbi + PCIE_DBI_RO_WR_EN);
> +
> + ls_pcie_disable_outbound_atus(pcie);
> }
>
> static int ls_pcie_msi_host_init(struct pcie_port *pp,
> diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
> index 12afce1..e4d1203 100644
> --- a/drivers/pci/host/pcie-designware.c
> +++ b/drivers/pci/host/pcie-designware.c
> @@ -172,6 +172,13 @@ static void dw_pcie_prog_outbound_atu(struct pcie_port *pp, int index,
> dw_pcie_readl_rc(pp, PCIE_ATU_CR2, &val);
> }
>
> +void dw_pcie_disable_outbound_atu(struct pcie_port *pp, int index)
> +{
> + dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | index,
> + PCIE_ATU_VIEWPORT);
> + dw_pcie_writel_rc(pp, 0, PCIE_ATU_CR2);
> +}
> +
> static struct irq_chip dw_msi_irq_chip = {
> .name = "PCI-MSI",
> .irq_enable = pci_msi_unmask_irq,
> diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
> index f437f9b..e998bfc 100644
> --- a/drivers/pci/host/pcie-designware.h
> +++ b/drivers/pci/host/pcie-designware.h
> @@ -85,5 +85,6 @@ int dw_pcie_wait_for_link(struct pcie_port *pp);
> int dw_pcie_link_up(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_disable_outbound_atu(struct pcie_port *pp, int index);
>
> #endif /* _PCIE_DESIGNWARE_H */
> --
> 1.9.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
More information about the linux-arm-kernel
mailing list