* [PATCH v2 01/65] PCI: desginware: Remove bogus prototypes
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 02/65] PCI: designware: Consolidate outbound iATU programming functions Andrey Smirnov
` (64 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.h | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/pci/pcie-designware.h b/drivers/pci/pcie-designware.h
index 8d0330a5a..ba5752ec1 100644
--- a/drivers/pci/pcie-designware.h
+++ b/drivers/pci/pcie-designware.h
@@ -62,8 +62,6 @@ struct pcie_host_ops {
int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val);
int dw_pcie_cfg_write(void __iomem *addr, int where, int size, u32 val);
-irqreturn_t dw_handle_msi_irq(struct pcie_port *pp);
-void dw_pcie_msi_init(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);
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 02/65] PCI: designware: Consolidate outbound iATU programming functions
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 01/65] PCI: desginware: Remove bogus prototypes Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 03/65] PCI: designware: Use iATU0 for cfg and IO, iATU1 for MEM Andrey Smirnov
` (63 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 63503c87f06e0f2c8c951cada81221c5500188d8
Currently, the outbound iATU programming functions are similar: the only
difference is index, type, addr and size. Consolidate these functions into
one. This saves about 1700 bytes in text:
text data bss dec hex filename
9276 204 4 9484 250c pcie-designware.o-before
7532 204 4 7740 1e3c pcie-designware.o
Signed-off-by: Jisheng Zhang <jszhang@marvell.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Pratyush Anand <pratyush.anand@gmail.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 121 ++++++++++++----------------------
1 file changed, 43 insertions(+), 78 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index 4962a1964..d54e47074 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -148,6 +148,21 @@ static int dw_pcie_wr_own_conf(struct pcie_port *pp, int where, int size,
return ret;
}
+static void dw_pcie_prog_outbound_atu(struct pcie_port *pp, int index,
+ int type, u64 cpu_addr, u64 pci_addr, u32 size)
+{
+ 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);
+}
+
int dw_pcie_link_up(struct pcie_port *pp)
{
if (pp->ops->link_up)
@@ -288,68 +303,6 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
return 0;
}
-static void dw_pcie_prog_viewport_cfg0(struct pcie_port *pp, u32 busdev)
-{
- /* Program viewport 0 : OUTBOUND : CFG0 */
- dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0,
- PCIE_ATU_VIEWPORT);
- dw_pcie_writel_rc(pp, pp->cfg0_mod_base, PCIE_ATU_LOWER_BASE);
- dw_pcie_writel_rc(pp, (pp->cfg0_mod_base >> 32), PCIE_ATU_UPPER_BASE);
- dw_pcie_writel_rc(pp, pp->cfg0_mod_base + pp->cfg0_size - 1,
- PCIE_ATU_LIMIT);
- dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET);
- dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET);
- dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_CFG0, PCIE_ATU_CR1);
- dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
-}
-
-static void dw_pcie_prog_viewport_cfg1(struct pcie_port *pp, u32 busdev)
-{
- /* Program viewport 1 : OUTBOUND : CFG1 */
- dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
- PCIE_ATU_VIEWPORT);
- dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_CFG1, PCIE_ATU_CR1);
- dw_pcie_writel_rc(pp, pp->cfg1_mod_base, PCIE_ATU_LOWER_BASE);
- dw_pcie_writel_rc(pp, (pp->cfg1_mod_base >> 32), PCIE_ATU_UPPER_BASE);
- dw_pcie_writel_rc(pp, pp->cfg1_mod_base + pp->cfg1_size - 1,
- PCIE_ATU_LIMIT);
- dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET);
- dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET);
- dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
-}
-
-static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp)
-{
- /* Program viewport 0 : OUTBOUND : MEM */
- dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0,
- PCIE_ATU_VIEWPORT);
- dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_MEM, PCIE_ATU_CR1);
- dw_pcie_writel_rc(pp, pp->mem_mod_base, PCIE_ATU_LOWER_BASE);
- dw_pcie_writel_rc(pp, (pp->mem_mod_base >> 32), PCIE_ATU_UPPER_BASE);
- dw_pcie_writel_rc(pp, pp->mem_mod_base + pp->mem_size - 1,
- PCIE_ATU_LIMIT);
- dw_pcie_writel_rc(pp, pp->mem_bus_addr, PCIE_ATU_LOWER_TARGET);
- dw_pcie_writel_rc(pp, upper_32_bits(pp->mem_bus_addr),
- PCIE_ATU_UPPER_TARGET);
- dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
-}
-
-static void dw_pcie_prog_viewport_io_outbound(struct pcie_port *pp)
-{
- /* Program viewport 1 : OUTBOUND : IO */
- dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
- PCIE_ATU_VIEWPORT);
- dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_IO, PCIE_ATU_CR1);
- dw_pcie_writel_rc(pp, pp->io_mod_base, PCIE_ATU_LOWER_BASE);
- dw_pcie_writel_rc(pp, (pp->io_mod_base >> 32), PCIE_ATU_UPPER_BASE);
- dw_pcie_writel_rc(pp, pp->io_mod_base + pp->io_size - 1,
- PCIE_ATU_LIMIT);
- dw_pcie_writel_rc(pp, pp->io_bus_addr, PCIE_ATU_LOWER_TARGET);
- dw_pcie_writel_rc(pp, upper_32_bits(pp->io_bus_addr),
- PCIE_ATU_UPPER_TARGET);
- dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
-}
-
static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
u32 devfn, int where, int size, u32 *val)
{
@@ -361,15 +314,21 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
address = where & ~0x3;
if (bus->primary == pp->root_bus_nr) {
- dw_pcie_prog_viewport_cfg0(pp, busdev);
- ret = dw_pcie_cfg_read(pp->va_cfg0_base + address, where, size,
- val);
- dw_pcie_prog_viewport_mem_outbound(pp);
+ dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
+ PCIE_ATU_TYPE_CFG0, pp->cfg0_mod_base,
+ busdev, pp->cfg0_size);
+ ret = dw_pcie_cfg_read(pp->va_cfg0_base + address, where, size, val);
+ dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
+ PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
+ pp->mem_bus_addr, pp->mem_size);
} else {
- dw_pcie_prog_viewport_cfg1(pp, busdev);
- ret = dw_pcie_cfg_read(pp->va_cfg1_base + address, where, size,
- val);
- dw_pcie_prog_viewport_io_outbound(pp);
+ dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
+ PCIE_ATU_TYPE_CFG1, pp->cfg1_mod_base,
+ busdev, pp->cfg1_size);
+ ret = dw_pcie_cfg_read(pp->va_cfg1_base + address, where, size, val);
+ dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
+ PCIE_ATU_TYPE_IO, pp->io_mod_base,
+ pp->io_bus_addr, pp->io_size);
}
return ret;
@@ -386,15 +345,21 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
address = where & ~0x3;
if (bus->primary == pp->root_bus_nr) {
- dw_pcie_prog_viewport_cfg0(pp, busdev);
- ret = dw_pcie_cfg_write(pp->va_cfg0_base + address, where, size,
- val);
- dw_pcie_prog_viewport_mem_outbound(pp);
+ dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
+ PCIE_ATU_TYPE_CFG0, pp->cfg0_mod_base,
+ busdev, pp->cfg0_size);
+ ret = dw_pcie_cfg_write(pp->va_cfg0_base + address, where, size, val);
+ dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
+ PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
+ pp->mem_bus_addr, pp->mem_size);
} else {
- dw_pcie_prog_viewport_cfg1(pp, busdev);
- ret = dw_pcie_cfg_write(pp->va_cfg1_base + address, where, size,
- val);
- dw_pcie_prog_viewport_io_outbound(pp);
+ dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
+ PCIE_ATU_TYPE_CFG1, pp->cfg1_mod_base,
+ busdev, pp->cfg1_size);
+ ret = dw_pcie_cfg_write(pp->va_cfg1_base + address, where, size, val);
+ dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
+ PCIE_ATU_TYPE_IO, pp->io_mod_base,
+ pp->io_bus_addr, pp->io_size);
}
return ret;
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 03/65] PCI: designware: Use iATU0 for cfg and IO, iATU1 for MEM
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 01/65] PCI: desginware: Remove bogus prototypes Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 02/65] PCI: designware: Consolidate outbound iATU programming functions Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 04/65] PCI: designware: Fix PORT_LOGIC_LINK_WIDTH_MASK Andrey Smirnov
` (62 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 2d91b491d5be13602a73be789bb8a3c28d06b7f2
Most transactions' type are cfg0 and MEM, so the current iATU usage is not
balanced: iATU0 is hot while iATU1 is rarely used.
Refactor the iATU usage so we use iATU0 for cfg and IO and iATU1 for MEM.
This allocation idea comes from Minghuan Lian
<Minghuan.Lian@freescale.com>:
[bhelgaas: use link with Message-ID]
Link: http://lkml.kernel.org/r/1429091315-31891-3-git-send-email-Minghuan.Lian@freescale.com
Signed-off-by: Jisheng Zhang <jszhang@marvell.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Pratyush Anand <pratyush.anand@gmail.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 79 ++++++++++++++++++++---------------
1 file changed, 46 insertions(+), 33 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index d54e47074..1ef544c7b 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -283,6 +283,11 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
if (pp->ops->host_init)
pp->ops->host_init(pp);
+ if (!pp->ops->rd_other_conf)
+ dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
+ PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
+ pp->mem_bus_addr, pp->mem_size);
+
dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
/* program correct class for RC */
@@ -306,62 +311,70 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
u32 devfn, int where, int size, u32 *val)
{
- int ret = PCIBIOS_SUCCESSFUL;
- u32 address, busdev;
+ int ret, type;
+ u32 address, busdev, cfg_size;
+ u64 cpu_addr;
+ void __iomem *va_cfg_base;
busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) |
- PCIE_ATU_FUNC(PCI_FUNC(devfn));
+ PCIE_ATU_FUNC(PCI_FUNC(devfn));
address = where & ~0x3;
if (bus->primary == pp->root_bus_nr) {
- dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
- PCIE_ATU_TYPE_CFG0, pp->cfg0_mod_base,
- busdev, pp->cfg0_size);
- ret = dw_pcie_cfg_read(pp->va_cfg0_base + address, where, size, val);
- dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
- PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
- pp->mem_bus_addr, pp->mem_size);
+ type = PCIE_ATU_TYPE_CFG0;
+ cpu_addr = pp->cfg0_mod_base;
+ cfg_size = pp->cfg0_size;
+ va_cfg_base = pp->va_cfg0_base;
} else {
- dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
- PCIE_ATU_TYPE_CFG1, pp->cfg1_mod_base,
- busdev, pp->cfg1_size);
- ret = dw_pcie_cfg_read(pp->va_cfg1_base + address, where, size, val);
- dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
- PCIE_ATU_TYPE_IO, pp->io_mod_base,
- pp->io_bus_addr, pp->io_size);
+ type = PCIE_ATU_TYPE_CFG1;
+ cpu_addr = pp->cfg1_mod_base;
+ cfg_size = pp->cfg1_size;
+ va_cfg_base = pp->va_cfg1_base;
}
+ dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
+ type, cpu_addr,
+ busdev, cfg_size);
+ ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
+ dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
+ PCIE_ATU_TYPE_IO, pp->io_mod_base,
+ pp->io_bus_addr, pp->io_size);
+
return ret;
}
static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
u32 devfn, int where, int size, u32 val)
{
- int ret = PCIBIOS_SUCCESSFUL;
- u32 address, busdev;
+ int ret, type;
+ u32 address, busdev, cfg_size;
+ u64 cpu_addr;
+ void __iomem *va_cfg_base;
busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) |
PCIE_ATU_FUNC(PCI_FUNC(devfn));
address = where & ~0x3;
if (bus->primary == pp->root_bus_nr) {
- dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
- PCIE_ATU_TYPE_CFG0, pp->cfg0_mod_base,
- busdev, pp->cfg0_size);
- ret = dw_pcie_cfg_write(pp->va_cfg0_base + address, where, size, val);
- dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
- PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
- pp->mem_bus_addr, pp->mem_size);
+ type = PCIE_ATU_TYPE_CFG0;
+ cpu_addr = pp->cfg0_mod_base;
+ cfg_size = pp->cfg0_size;
+ va_cfg_base = pp->va_cfg0_base;
} else {
- dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
- PCIE_ATU_TYPE_CFG1, pp->cfg1_mod_base,
- busdev, pp->cfg1_size);
- ret = dw_pcie_cfg_write(pp->va_cfg1_base + address, where, size, val);
- dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
- PCIE_ATU_TYPE_IO, pp->io_mod_base,
- pp->io_bus_addr, pp->io_size);
+ type = PCIE_ATU_TYPE_CFG1;
+ cpu_addr = pp->cfg1_mod_base;
+ cfg_size = pp->cfg1_size;
+ va_cfg_base = pp->va_cfg1_base;
}
+ dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
+ type, cpu_addr,
+ busdev, cfg_size);
+ ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
+ dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
+ PCIE_ATU_TYPE_IO, pp->io_mod_base,
+ pp->io_bus_addr, pp->io_size);
+
return ret;
}
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 04/65] PCI: designware: Fix PORT_LOGIC_LINK_WIDTH_MASK
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (2 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 03/65] PCI: designware: Use iATU0 for cfg and IO, iATU1 for MEM Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 05/65] PCI: designware: Use exact access size in dw_pcie_cfg_read() Andrey Smirnov
` (61 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit ed8b472df44af6dc4cb18e828dc9bb2d57f14b9e
The value under PORT_LOGIC_LINK_WIDTH_MASK is 0x1, 0x2, 0x4, 0x8. In IP
v4.2, bits [16:8] are defined for NUM_OF_LANES. But in IP v4.4, bits[12:8]
are defined for NUM_OF_LANES, bits [16:13] are for other usages (bit 16 is
AUTO_LANE_FLIP_CTRL_EN, bits [15:13] are PRE_DET_LANE).
As there is no conflict about NUM_OF_LANES between v4.2 and v4.4, change
the mask value to avoid future problems.
Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Jingoo Han <jingoohan1@gmail.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index 1ef544c7b..547d402a7 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -39,7 +39,7 @@
#define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C
#define PORT_LOGIC_SPEED_CHANGE (0x1 << 17)
-#define PORT_LOGIC_LINK_WIDTH_MASK (0x1ff << 8)
+#define PORT_LOGIC_LINK_WIDTH_MASK (0x1f << 8)
#define PORT_LOGIC_LINK_WIDTH_1_LANES (0x1 << 8)
#define PORT_LOGIC_LINK_WIDTH_2_LANES (0x2 << 8)
#define PORT_LOGIC_LINK_WIDTH_4_LANES (0x4 << 8)
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 05/65] PCI: designware: Use exact access size in dw_pcie_cfg_read()
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (3 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 04/65] PCI: designware: Fix PORT_LOGIC_LINK_WIDTH_MASK Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 06/65] PCI: designware: Simplify dw_pcie_cfg_read/write() interfaces Andrey Smirnov
` (60 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit c003ca99632e1783466f459033874a0e1e31457b
dw_pcie_cfg_write() uses the exact 8-, 16-, or 32-bit access size
requested, but dw_pcie_cfg_read() previously performed a 32-bit read and
masked out the bits requested.
Use the exact access size in dw_pcie_cfg_read(). For example, if we want
an 8-bit read, use readb() instead of using readl() and masking out the 8
bits we need. This makes it symmetric with dw_pcie_cfg_write().
[bhelgaas: split into separate patch, set *val = 0 in failure case]
Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
NOTE: Original Linux commit incorrectly handles the case of single
byte read by doing
else if (size == 1)
*val = readb(addr + (where & 1));
instead of
else if (size == 1)
*val = readb(addr + (where & 3));
which would be symmetric with what's done in dw_pcie_cfg_write(). This
was most likely overlooked since commit that follow change the
signature of the function, remove 'where' as argument completely,
inadvertenly fixing the problem.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index 547d402a7..bda85c30e 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -76,14 +76,16 @@ static unsigned long global_io_offset;
int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val)
{
- *val = readl(addr);
-
- if (size == 1)
- *val = (*val >> (8 * (where & 3))) & 0xff;
+ if (size == 4)
+ *val = readl(addr);
else if (size == 2)
- *val = (*val >> (8 * (where & 3))) & 0xffff;
- else if (size != 4)
+ *val = readw(addr + (where & 2));
+ else if (size == 1)
+ *val = readb(addr + (where & 3));
+ else {
+ *val = 0;
return PCIBIOS_BAD_REGISTER_NUMBER;
+ }
return PCIBIOS_SUCCESSFUL;
}
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 06/65] PCI: designware: Simplify dw_pcie_cfg_read/write() interfaces
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (4 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 05/65] PCI: designware: Use exact access size in dw_pcie_cfg_read() Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 07/65] PCI: designware: Require config accesses to be naturally aligned Andrey Smirnov
` (59 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 4c45852f494dab827291c656ee9e12f3f4ee64d6
Callers of dw_pcie_cfg_read() and dw_pcie_cfg_write() previously had to
split the address into "addr" and "where". The callees assumed "addr" was
32-bit aligned (with zeros in the low two bits) and they used only the low
two bits of "where".
Accept the entire address in "addr" and drop the now-redundant "where"
argument. As an example, this replaces this:
int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val)
*val = readb(addr + (where & 1));
with this:
int dw_pcie_cfg_read(void __iomem *addr, int size, u32 *val)
*val = readb(addr):
[bhelgaas: changelog, split access size change to separate patch]
Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
TODO: Fixup the pcie-designware.h
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 27 +++++++++++++--------------
drivers/pci/pcie-designware.h | 4 ++--
2 files changed, 15 insertions(+), 16 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index bda85c30e..f46d33265 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -74,14 +74,14 @@
static unsigned long global_io_offset;
-int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val)
+int dw_pcie_cfg_read(void __iomem *addr, int size, u32 *val)
{
if (size == 4)
*val = readl(addr);
else if (size == 2)
- *val = readw(addr + (where & 2));
+ *val = readw(addr);
else if (size == 1)
- *val = readb(addr + (where & 3));
+ *val = readb(addr);
else {
*val = 0;
return PCIBIOS_BAD_REGISTER_NUMBER;
@@ -90,14 +90,14 @@ int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val)
return PCIBIOS_SUCCESSFUL;
}
-int dw_pcie_cfg_write(void __iomem *addr, int where, int size, u32 val)
+int dw_pcie_cfg_write(void __iomem *addr, int size, u32 val)
{
if (size == 4)
writel(val, addr);
else if (size == 2)
- writew(val, addr + (where & 2));
+ writew(val, addr);
else if (size == 1)
- writeb(val, addr + (where & 3));
+ writeb(val, addr);
else
return PCIBIOS_BAD_REGISTER_NUMBER;
@@ -130,8 +130,8 @@ static int dw_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
if (pp->ops->rd_own_conf)
ret = pp->ops->rd_own_conf(pp, where, size, val);
else
- ret = dw_pcie_cfg_read(pp->dbi_base + (where & ~0x3), where,
- size, val);
+ ret = dw_pcie_cfg_read(pp->dbi_base + where,
+ size, val);
return ret;
}
@@ -144,8 +144,8 @@ static int dw_pcie_wr_own_conf(struct pcie_port *pp, int where, int size,
if (pp->ops->wr_own_conf)
ret = pp->ops->wr_own_conf(pp, where, size, val);
else
- ret = dw_pcie_cfg_write(pp->dbi_base + (where & ~0x3), where,
- size, val);
+ ret = dw_pcie_cfg_write(pp->dbi_base + where,
+ size, val);
return ret;
}
@@ -337,7 +337,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
type, cpu_addr,
busdev, cfg_size);
- ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
+ ret = dw_pcie_cfg_read(va_cfg_base + where, size, val);
dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
PCIE_ATU_TYPE_IO, pp->io_mod_base,
pp->io_bus_addr, pp->io_size);
@@ -349,13 +349,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
u32 devfn, int where, int size, u32 val)
{
int ret, type;
- u32 address, busdev, cfg_size;
+ u32 busdev, cfg_size;
u64 cpu_addr;
void __iomem *va_cfg_base;
busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) |
PCIE_ATU_FUNC(PCI_FUNC(devfn));
- address = where & ~0x3;
if (bus->primary == pp->root_bus_nr) {
type = PCIE_ATU_TYPE_CFG0;
@@ -372,7 +371,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
type, cpu_addr,
busdev, cfg_size);
- ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
+ ret = dw_pcie_cfg_write(va_cfg_base + where, size, val);
dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
PCIE_ATU_TYPE_IO, pp->io_mod_base,
pp->io_bus_addr, pp->io_size);
diff --git a/drivers/pci/pcie-designware.h b/drivers/pci/pcie-designware.h
index ba5752ec1..b8b85c575 100644
--- a/drivers/pci/pcie-designware.h
+++ b/drivers/pci/pcie-designware.h
@@ -60,8 +60,8 @@ struct pcie_host_ops {
void (*scan_bus)(struct pcie_port *pp);
};
-int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val);
-int dw_pcie_cfg_write(void __iomem *addr, int where, int size, u32 val);
+int dw_pcie_cfg_read(void __iomem *addr, int size, u32 *val);
+int dw_pcie_cfg_write(void __iomem *addr, int size, u32 val);
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);
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 07/65] PCI: designware: Require config accesses to be naturally aligned
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (5 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 06/65] PCI: designware: Simplify dw_pcie_cfg_read/write() interfaces Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 08/65] PCI: designware: Make "num-lanes" an optional DT property Andrey Smirnov
` (58 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit b6b18f589e1ddbfbc31f72ea7fb8a723a2d10058
Add sanity checks on "addr" input parameter in dw_pcie_cfg_read() and
dw_pcie_cfg_write(). These checks make sure that accesses are aligned on
their size, e.g., a 4-byte config access is aligned on a 4-byte boundary.
[bhelgaas: changelog, set *val = 0 in failure case]
Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Pratyush Anand <pratyush.anand@gmail.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index f46d33265..f47e5eb1e 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -76,6 +76,11 @@ static unsigned long global_io_offset;
int dw_pcie_cfg_read(void __iomem *addr, int size, u32 *val)
{
+ if ((uintptr_t)addr & (size - 1)) {
+ *val = 0;
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ }
+
if (size == 4)
*val = readl(addr);
else if (size == 2)
@@ -92,6 +97,9 @@ int dw_pcie_cfg_read(void __iomem *addr, int size, u32 *val)
int dw_pcie_cfg_write(void __iomem *addr, int size, u32 val)
{
+ if ((uintptr_t)addr & (size - 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
if (size == 4)
writel(val, addr);
else if (size == 2)
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 08/65] PCI: designware: Make "num-lanes" an optional DT property
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (6 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 07/65] PCI: designware: Require config accesses to be naturally aligned Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 09/65] PCI: designware: Ensure ATU is enabled before IO/conf space accesses Andrey Smirnov
` (57 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 907fce0902539ecde609e485eb2ecd7119a7a623
Currently "num-lanes" is read in dw_pcie_host_init(), but it is only used
if we call dw_pcie_setup_rc() while bringing up the link. If the link has
already been brought up by firmware, we need not call dw_pcie_setup_rc(),
and "num-lanes" is unnecessary.
Only complain about "num-lanes" if we actually need it and we didn't find a
valid value.
[bhelgaas: changelog]
Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index f47e5eb1e..977548f01 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -203,7 +203,7 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
struct resource *cfg_res;
u32 val, na, ns;
const __be32 *addrp;
- int index;
+ int index, ret;
/* Find the address cell size and the number of cells in order to get
* the untranslated address.
@@ -285,10 +285,9 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
if (!pp->va_cfg1_base)
pp->va_cfg1_base = (void __force *)(u32)pp->cfg1_base;
- if (of_property_read_u32(np, "num-lanes", &pp->lanes)) {
- dev_err(pp->dev, "Failed to parse the number of lanes\n");
- return -EINVAL;
- }
+ ret = of_property_read_u32(np, "num-lanes", &pp->lanes);
+ if (ret)
+ pp->lanes = 0;
if (pp->ops->host_init)
pp->ops->host_init(pp);
@@ -496,6 +495,9 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
case 4:
val |= PORT_LINK_MODE_4_LANES;
break;
+ default:
+ dev_err(pp->dev, "num-lanes %u: invalid value\n", pp->lanes);
+ return;
}
dw_pcie_writel_rc(pp, val, PCIE_PORT_LINK_CONTROL);
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 09/65] PCI: designware: Ensure ATU is enabled before IO/conf space accesses
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (7 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 08/65] PCI: designware: Make "num-lanes" an optional DT property Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 10/65] PCI: designware: Simplify control flow Andrey Smirnov
` (56 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 17209dfb35a228e597a387bfc83b68093b247f78
Read back the ATU CR2 register to ensure ATU programming is effective
before any subsequent I/O or config space accesses.
Without this, PCI device enumeration is unreliable.
[bhelgaas: changelog, comment]
Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Pratyush Anand <pratyush.anand@gmail.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index 977548f01..f52b67f4f 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -161,6 +161,8 @@ 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);
@@ -171,6 +173,12 @@ static void dw_pcie_prog_outbound_atu(struct pcie_port *pp, int index,
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);
+
+ /*
+ * Make sure ATU enable takes effect before any subsequent config
+ * and I/O accesses.
+ */
+ dw_pcie_readl_rc(pp, PCIE_ATU_CR2, &val);
}
int dw_pcie_link_up(struct pcie_port *pp)
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 10/65] PCI: designware: Simplify control flow
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (8 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 09/65] PCI: designware: Ensure ATU is enabled before IO/conf space accesses Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 11/65] PCI: designware: Make config accessor override checking symmetric Andrey Smirnov
` (55 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 116a489d78b30862a2dd04961d3ba98fe4704220
Return values immediately when possible to simplify the control flow.
No functional change intended. Folded in unused variable removal as
pointed out by Fabio Estevam <fabio.estevam@nxp.com>, Arnd Bergmann
<arnd@arndb.de>, and Thierry Reding <thierry.reding@gmail.com>.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Pratyush Anand <pratyush.anand@gmail.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 53 ++++++++++++++---------------------
1 file changed, 21 insertions(+), 32 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index f52b67f4f..782da2626 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -133,29 +133,19 @@ static inline void dw_pcie_writel_rc(struct pcie_port *pp, u32 val, u32 reg)
static int dw_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
u32 *val)
{
- int ret;
-
if (pp->ops->rd_own_conf)
- ret = pp->ops->rd_own_conf(pp, where, size, val);
- else
- ret = dw_pcie_cfg_read(pp->dbi_base + where,
- size, val);
+ return pp->ops->rd_own_conf(pp, where, size, val);
- return ret;
+ return dw_pcie_cfg_read(pp->dbi_base + where, size, val);
}
static int dw_pcie_wr_own_conf(struct pcie_port *pp, int where, int size,
u32 val)
{
- int ret;
-
if (pp->ops->wr_own_conf)
- ret = pp->ops->wr_own_conf(pp, where, size, val);
- else
- ret = dw_pcie_cfg_write(pp->dbi_base + where,
- size, val);
+ return pp->ops->wr_own_conf(pp, where, size, val);
- return ret;
+ return dw_pcie_cfg_write(pp->dbi_base + where, size, val);
}
static void dw_pcie_prog_outbound_atu(struct pcie_port *pp, int index,
@@ -185,8 +175,8 @@ int dw_pcie_link_up(struct pcie_port *pp)
{
if (pp->ops->link_up)
return pp->ops->link_up(pp);
- else
- return 0;
+
+ return 0;
}
static inline struct pcie_port *host_to_pcie(struct pci_controller *host)
@@ -430,16 +420,16 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
data_abort_mask();
- if (bus->number != pp->root_bus_nr)
- if (pp->ops->rd_other_conf)
- ret = pp->ops->rd_other_conf(pp, bus, devfn,
- where, size, val);
- else
- ret = dw_pcie_rd_other_conf(pp, bus, devfn,
- where, size, val);
- else
+ if (bus->number == pp->root_bus_nr)
ret = dw_pcie_rd_own_conf(pp, where, size, val);
+ else if (pp->ops->rd_other_conf)
+ ret = pp->ops->rd_other_conf(pp, bus, devfn,
+ where, size, val);
+ else
+ ret = dw_pcie_rd_other_conf(pp, bus, devfn,
+ where, size, val);
+
if (data_abort_unmask())
return PCIBIOS_DEVICE_NOT_FOUND;
@@ -457,15 +447,14 @@ static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
data_abort_mask();
- if (bus->number != pp->root_bus_nr)
- if (pp->ops->wr_other_conf)
- ret = pp->ops->wr_other_conf(pp, bus, devfn,
- where, size, val);
- else
- ret = dw_pcie_wr_other_conf(pp, bus, devfn,
- where, size, val);
- else
+ if (bus->number == pp->root_bus_nr)
ret = dw_pcie_wr_own_conf(pp, where, size, val);
+ else if (pp->ops->wr_other_conf)
+ ret = pp->ops->wr_other_conf(pp, bus, devfn,
+ where, size, val);
+ else
+ ret = dw_pcie_wr_other_conf(pp, bus, devfn,
+ where, size, val);
if (data_abort_unmask())
return PCIBIOS_DEVICE_NOT_FOUND;
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 11/65] PCI: designware: Make config accessor override checking symmetric
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (9 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 10/65] PCI: designware: Simplify control flow Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 12/65] PCI: designware: Explain why we don't program ATU for some platforms Andrey Smirnov
` (54 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 67de2dc34cc30d334cb66ab4f466e80f04d5b618
Drivers based on the DesignWare core can override the config read accessors
by supplying rd_own_conf() and rd_other_conf() function pointers.
dw_pcie_rd_conf() calls dw_pcie_rd_own_conf() (for accesses to the root
bus) or dw_pcie_rd_other_conf():
dw_pcie_rd_conf
dw_pcie_rd_own_conf # if on root bus
dw_pcie_rd_other_conf # if not on root bus
Previously we checked for rd_other_conf() directly in dw_pcie_rd_conf(),
but we checked for rd_own_conf() in dw_pcie_rd_own_conf().
Check for rd_other_conf() in dw_pcie_rd_other_conf() to make this symmetric
with the rd_own_conf() checking, and similarly for the write path.
No functional change intended.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Pratyush Anand <pratyush.anand@gmail.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index 782da2626..28f57f9d2 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -323,6 +323,10 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
u64 cpu_addr;
void __iomem *va_cfg_base;
+ if (pp->ops->rd_other_conf)
+ return pp->ops->rd_other_conf(pp, bus, devfn,
+ where, size, val);
+
busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) |
PCIE_ATU_FUNC(PCI_FUNC(devfn));
address = where & ~0x3;
@@ -358,6 +362,10 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
u64 cpu_addr;
void __iomem *va_cfg_base;
+ if (pp->ops->wr_other_conf)
+ return pp->ops->wr_other_conf(pp, bus, devfn,
+ where, size, val);
+
busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) |
PCIE_ATU_FUNC(PCI_FUNC(devfn));
@@ -422,10 +430,6 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
if (bus->number == pp->root_bus_nr)
ret = dw_pcie_rd_own_conf(pp, where, size, val);
-
- else if (pp->ops->rd_other_conf)
- ret = pp->ops->rd_other_conf(pp, bus, devfn,
- where, size, val);
else
ret = dw_pcie_rd_other_conf(pp, bus, devfn,
where, size, val);
@@ -449,9 +453,6 @@ static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
if (bus->number == pp->root_bus_nr)
ret = dw_pcie_wr_own_conf(pp, where, size, val);
- else if (pp->ops->wr_other_conf)
- ret = pp->ops->wr_other_conf(pp, bus, devfn,
- where, size, val);
else
ret = dw_pcie_wr_other_conf(pp, bus, devfn,
where, size, val);
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 12/65] PCI: designware: Explain why we don't program ATU for some platforms
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (10 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 11/65] PCI: designware: Make config accessor override checking symmetric Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 13/65] PCI: imx6: Move link up check into imx6_pcie_wait_for_link() Andrey Smirnov
` (53 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit dd193929d91e1b44b90f81509feeff10c94ddc4d
Some platforms don't support ATU, e.g., pci-keystone.c. These platforms
use their own address translation component rather than ATU, and they
provide the rd_other_conf and wr_other_conf methods to program the
translation component and perform the access.
Add a comment to explain why we don't program the ATU for these platforms.
[bhelgaas: changelog]
Signed-off-by: Jisheng Zhang <jszhang@marvell.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index 28f57f9d2..34dba5898 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -290,6 +290,11 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
if (pp->ops->host_init)
pp->ops->host_init(pp);
+ /*
+ * If the platform provides ->rd_other_conf, it means the platform
+ * uses its own address translation component rather than ATU, so
+ * we should not program the ATU here.
+ */
if (!pp->ops->rd_other_conf)
dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 13/65] PCI: imx6: Move link up check into imx6_pcie_wait_for_link()
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (11 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 12/65] PCI: designware: Explain why we don't program ATU for some platforms Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 14/65] PCI: designware: Add generic dw_pcie_wait_for_link() Andrey Smirnov
` (52 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 4d107d3b5a686b5834e533a00b73bf7b1cf59df7
imx6_pcie_link_up() previously used usleep_range() to wait for the link to
come up. Since it may be called while holding the config spinlock, the
sleep causes a "BUG: scheduling while atomic" error.
Instead of waiting for the link to come up in imx6_pcie_link_up(), do the
waiting in imx6_pcie_wait_for_link(), where we're not holding a lock and
sleeping is allowed.
[bhelgaas: changelog, references to bugzilla and f95d3ae77191]
Link: https://bugzilla.kernel.org/show_bug.cgi?id=100031
Fixes: f95d3ae77191 ("PCI: imx6: Wait for retraining")
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pci-imx6.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/pci-imx6.c b/drivers/pci/pci-imx6.c
index fc56a0d14..53d767824 100644
--- a/drivers/pci/pci-imx6.c
+++ b/drivers/pci/pci-imx6.c
@@ -399,8 +399,26 @@ static int imx6_pcie_wait_for_link(struct pcie_port *pp)
{
uint64_t start = get_time_ns();
+ /*
+ * Test if the PHY reports that the link is up and also that the LTSSM
+ * training finished. There are three possible states of the link when
+ * this code is called:
+ * 1) The link is DOWN (unlikely)
+ * The link didn't come up yet for some reason. This usually means
+ * we have a real problem somewhere, if it happens with a peripheral
+ * connected. This state calls for inspection of the DEBUG registers.
+ * 2) The link is UP, but still in LTSSM training
+ * Wait for the training to finish, which should take a very short
+ * time. If the training does not finish, we have a problem and we
+ * need to inspect the DEBUG registers. If the training does finish,
+ * the link is up and operating correctly.
+ * 3) The link is UP and no longer in LTSSM training
+ * The link is up and operating correctly.
+ */
while (1) {
- if (dw_pcie_link_up(pp))
+ u32 reg = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1);
+ if ((reg & PCIE_PHY_DEBUG_R1_XMLH_LINK_UP) &&
+ !(reg & PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING))
return 0;
if (!is_timeout(start, SECOND))
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 14/65] PCI: designware: Add generic dw_pcie_wait_for_link()
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (12 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 13/65] PCI: imx6: Move link up check into imx6_pcie_wait_for_link() Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 15/65] PCI: designware: Add default link up check if sub-driver doesn't override Andrey Smirnov
` (51 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of Linux commit 886bc5ceb5cc3ad4b219502d72b277e3c3255a32
Several DesignWare-based drivers (dra7xx, exynos, imx6, keystone, qcom, and
spear13xx) had similar loops waiting for the link to come up.
Add a generic dw_pcie_wait_for_link() for use by all these drivers so the
waiting is done consistently, e.g., always using usleep_range() rather than
mdelay() and using similar timeouts and retry counts.
Note that this changes the Keystone link training/wait for link strategy,
so we initiate link training, then wait longer for the link to come up
before re-initiating link training.
[bhelgaas: changelog, split into its own patch, update pci-keystone.c, pcie-qcom.c]
Signed-off-by: Joao Pinto <jpinto@synopsys.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Pratyush Anand <pratyush.anand@gmail.com>
NOTE: For some reason, all of the changes to imx6_pcie_wait_for_link()
made in 4d107d3b5a686b5834e533a00b73bf7b1cf59df7 are actually not
present 886bc5ceb5cc3ad4b219502d72b277e3c3255a32. So there isn't
really a kernel commit corresponding to removal of the large comment
block or check for !(reg & PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING)
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pci-imx6.c | 30 +-----------------------------
drivers/pci/pcie-designware.c | 18 ++++++++++++++++++
drivers/pci/pcie-designware.h | 6 ++++++
3 files changed, 25 insertions(+), 29 deletions(-)
diff --git a/drivers/pci/pci-imx6.c b/drivers/pci/pci-imx6.c
index 53d767824..18965c7c3 100644
--- a/drivers/pci/pci-imx6.c
+++ b/drivers/pci/pci-imx6.c
@@ -397,35 +397,7 @@ static void imx6_pcie_init_phy(struct pcie_port *pp)
static int imx6_pcie_wait_for_link(struct pcie_port *pp)
{
- uint64_t start = get_time_ns();
-
- /*
- * Test if the PHY reports that the link is up and also that the LTSSM
- * training finished. There are three possible states of the link when
- * this code is called:
- * 1) The link is DOWN (unlikely)
- * The link didn't come up yet for some reason. This usually means
- * we have a real problem somewhere, if it happens with a peripheral
- * connected. This state calls for inspection of the DEBUG registers.
- * 2) The link is UP, but still in LTSSM training
- * Wait for the training to finish, which should take a very short
- * time. If the training does not finish, we have a problem and we
- * need to inspect the DEBUG registers. If the training does finish,
- * the link is up and operating correctly.
- * 3) The link is UP and no longer in LTSSM training
- * The link is up and operating correctly.
- */
- while (1) {
- u32 reg = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1);
- if ((reg & PCIE_PHY_DEBUG_R1_XMLH_LINK_UP) &&
- !(reg & PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING))
- return 0;
-
- if (!is_timeout(start, SECOND))
- continue;
-
- return -EINVAL;
- }
+ return dw_pcie_wait_for_link(pp);
}
static int imx6_pcie_wait_for_speed_change(struct pcie_port *pp)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index 34dba5898..ab6f1d289 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -171,6 +171,24 @@ static void dw_pcie_prog_outbound_atu(struct pcie_port *pp, int index,
dw_pcie_readl_rc(pp, PCIE_ATU_CR2, &val);
}
+int dw_pcie_wait_for_link(struct pcie_port *pp)
+{
+ int retries;
+
+ /* Check if the link is up or not */
+ for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
+ if (dw_pcie_link_up(pp)) {
+ dev_info(pp->dev, "Link up\n");
+ return 0;
+ }
+ udelay(LINK_WAIT_USLEEP_MAX);
+ }
+
+ dev_err(pp->dev, "Phy link never came up\n");
+
+ return -ETIMEDOUT;
+}
+
int dw_pcie_link_up(struct pcie_port *pp)
{
if (pp->ops->link_up)
diff --git a/drivers/pci/pcie-designware.h b/drivers/pci/pcie-designware.h
index b8b85c575..051511a26 100644
--- a/drivers/pci/pcie-designware.h
+++ b/drivers/pci/pcie-designware.h
@@ -14,6 +14,10 @@
#ifndef _PCIE_DESIGNWARE_H
#define _PCIE_DESIGNWARE_H
+/* Parameters for the waiting for link up routine */
+#define LINK_WAIT_MAX_RETRIES 10
+#define LINK_WAIT_USLEEP_MAX 100000
+
struct pcie_port {
struct device_d *dev;
u8 root_bus_nr;
@@ -66,4 +70,6 @@ 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);
+int dw_pcie_wait_for_link(struct pcie_port *pp);
+
#endif /* _PCIE_DESIGNWARE_H */
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 15/65] PCI: designware: Add default link up check if sub-driver doesn't override
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (13 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 14/65] PCI: designware: Add generic dw_pcie_wait_for_link() Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 16/65] PCI: designware: Move Root Complex setup code to dw_pcie_setup_rc() Andrey Smirnov
` (50 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit dac29e6c5460d05774e3e8c4fdf4d6e7bd481fab
Add a default DesignWare "link_up" test for use when a sub-driver doesn't
supply its own pcie_host_ops.link_up() method.
[bhelgaas: changelog, split into its own patch]
Signed-off-by: Joao Pinto <jpinto@synopsys.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Pratyush Anand <pratyush.anand@gmail.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index ab6f1d289..d1c2635d6 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -72,6 +72,11 @@
#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16)
#define PCIE_ATU_UPPER_TARGET 0x91C
+/* PCIe Port Logic registers */
+#define PLR_OFFSET 0x700
+#define PCIE_PHY_DEBUG_R1 (PLR_OFFSET + 0x2c)
+#define PCIE_PHY_DEBUG_R1_LINK_UP 0x00000010
+
static unsigned long global_io_offset;
int dw_pcie_cfg_read(void __iomem *addr, int size, u32 *val)
@@ -191,10 +196,13 @@ int dw_pcie_wait_for_link(struct pcie_port *pp)
int dw_pcie_link_up(struct pcie_port *pp)
{
+ u32 val;
+
if (pp->ops->link_up)
return pp->ops->link_up(pp);
- return 0;
+ val = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1);
+ return val & PCIE_PHY_DEBUG_R1_LINK_UP;
}
static inline struct pcie_port *host_to_pcie(struct pci_controller *host)
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 16/65] PCI: designware: Move Root Complex setup code to dw_pcie_setup_rc()
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (14 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 15/65] PCI: designware: Add default link up check if sub-driver doesn't override Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 17/65] PCI: designware: Remove incorrect RC memory base/limit configuration Andrey Smirnov
` (49 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 7e57fd1444bf8f4ba9179f826ed6817c56b801d4
dw_pcie_host_init() looks up host bridge resources, ioremaps them, creates
IRQ domains, and enumerates devices below the bridge. dw_pcie_setup_rc()
programs the Root Complex registers. The Root Complex may lose power
during suspend-to-RAM, and when we resume, we want to redo the latter but
not the former.
Move some Root Complex programming from dw_pcie_host_init() to
dw_pcie_setup_rc() where it belongs. DesignWare-based drivers can call
dw_pcie_setup_rc() in their resume paths.
[Niklas Cassel <niklas.cassel@axis.com>: This change moves outbound ATU
programming, which uses pp->mem_base, to dw_pcie_setup_rc(). Apply the
dra7xx pp->mem_base update before calling dw_pcie_setup_rc().]
[bhelgaas: changelog, fold in dra7xx fix from Niklas]
Signed-off-by: Jisheng Zhang <jszhang@marvell.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Pratyush Anand <pratyush.anand@gmail.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 40 +++++++++++++++++------------------
1 file changed, 20 insertions(+), 20 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index d1c2635d6..5e824cedc 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -225,7 +225,7 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
struct of_pci_range range;
struct of_pci_range_parser parser;
struct resource *cfg_res;
- u32 val, na, ns;
+ u32 na, ns;
const __be32 *addrp;
int index, ret;
@@ -316,25 +316,6 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
if (pp->ops->host_init)
pp->ops->host_init(pp);
- /*
- * If the platform provides ->rd_other_conf, it means the platform
- * uses its own address translation component rather than ATU, so
- * we should not program the ATU here.
- */
- if (!pp->ops->rd_other_conf)
- dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
- PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
- pp->mem_bus_addr, pp->mem_size);
-
- dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
-
- /* program correct class for RC */
- dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2, PCI_CLASS_BRIDGE_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);
-
pp->pci.parent = pp->dev;
pp->pci.pci_ops = &dw_pcie_ops;
pp->pci.set_busno = dw_pcie_set_local_bus_nr;
@@ -568,6 +549,25 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
dw_pcie_writel_rc(pp, val, PCI_COMMAND);
+
+ /*
+ * If the platform provides ->rd_other_conf, it means the platform
+ * uses its own address translation component rather than ATU, so
+ * we should not program the ATU here.
+ */
+ if (!pp->ops->rd_other_conf)
+ dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
+ PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
+ pp->mem_bus_addr, pp->mem_size);
+
+ dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
+
+ /* program correct class for RC */
+ dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2, PCI_CLASS_BRIDGE_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);
}
MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 17/65] PCI: designware: Remove incorrect RC memory base/limit configuration
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (15 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 16/65] PCI: designware: Move Root Complex setup code to dw_pcie_setup_rc() Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 18/65] PCI: designware: Return data directly from dw_pcie_readl_rc() Andrey Smirnov
` (48 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit a5cb903aef8c642e6f0f6810d46dacedf666b54a
Currently dw_pcie_setup_rc() configures memory base and memory limit in the
type1 configuration header for the root complex. In doing so it uses the
CPU address (pp->mem_base) rather than the bus address (pp->mem_bus_addr).
This is wrong and it is useless since the configuration is overwritten
later on when pci_bus_assign_resources() is called.
Remove this configuration from dw_pcie_setup_rc().
Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Pratyush Anand <pratyush.anand@gmail.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 8 --------
1 file changed, 8 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index 5e824cedc..e9058768d 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -489,8 +489,6 @@ static struct pci_ops dw_pcie_ops = {
void dw_pcie_setup_rc(struct pcie_port *pp)
{
u32 val;
- u32 membase;
- u32 memlimit;
/* set the number of lanes */
dw_pcie_readl_rc(pp, PCIE_PORT_LINK_CONTROL, &val);
@@ -537,12 +535,6 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
val |= 0x00010100;
dw_pcie_writel_rc(pp, val, PCI_PRIMARY_BUS);
- /* setup memory base, memory limit */
- membase = ((u32)pp->mem_base & 0xfff00000) >> 16;
- memlimit = (pp->mem_size + (u32)pp->mem_base) & 0xfff00000;
- val = memlimit | membase;
- dw_pcie_writel_rc(pp, val, PCI_MEMORY_BASE);
-
/* setup command register */
dw_pcie_readl_rc(pp, PCI_COMMAND, &val);
val &= 0xffff0000;
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 18/65] PCI: designware: Return data directly from dw_pcie_readl_rc()
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (16 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 17/65] PCI: designware: Remove incorrect RC memory base/limit configuration Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 19/65] PCI: designware: Move link wait definitions to .c file Andrey Smirnov
` (47 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 446fc23fb6f0cab15011d7daae856091856a65cc
dw_pcie_readl_rc() reads a u32 value. Previously we stored that value in
space supplied by the caller. Return the u32 value directly instead.
This makes the calling code read better and makes it obvious that the
caller need not initialize the storage. In the following example it isn't
clear whether "val" is initialized before being used:
dw_pcie_readl_rc(pp, PCI_COMMAND, &val);
if (val & PCI_COMMAND_MEMORY)
...
No functional change intended.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 18 +++++++++---------
drivers/pci/pcie-designware.h | 3 +--
2 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index e9058768d..995fe997e 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -117,12 +117,12 @@ int dw_pcie_cfg_write(void __iomem *addr, int size, u32 val)
return PCIBIOS_SUCCESSFUL;
}
-static inline void dw_pcie_readl_rc(struct pcie_port *pp, u32 reg, u32 *val)
+static inline u32 dw_pcie_readl_rc(struct pcie_port *pp, u32 reg)
{
if (pp->ops->readl_rc)
- pp->ops->readl_rc(pp, pp->dbi_base + reg, val);
- else
- *val = readl(pp->dbi_base + reg);
+ return pp->ops->readl_rc(pp, pp->dbi_base + reg);
+
+ return readl(pp->dbi_base + reg);
}
static inline void dw_pcie_writel_rc(struct pcie_port *pp, u32 val, u32 reg)
@@ -173,7 +173,7 @@ static void dw_pcie_prog_outbound_atu(struct pcie_port *pp, int index,
* Make sure ATU enable takes effect before any subsequent config
* and I/O accesses.
*/
- dw_pcie_readl_rc(pp, PCIE_ATU_CR2, &val);
+ dw_pcie_readl_rc(pp, PCIE_ATU_CR2);
}
int dw_pcie_wait_for_link(struct pcie_port *pp)
@@ -491,7 +491,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
u32 val;
/* set the number of lanes */
- dw_pcie_readl_rc(pp, PCIE_PORT_LINK_CONTROL, &val);
+ val = dw_pcie_readl_rc(pp, PCIE_PORT_LINK_CONTROL);
val &= ~PORT_LINK_MODE_MASK;
switch (pp->lanes) {
case 1:
@@ -510,7 +510,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
dw_pcie_writel_rc(pp, val, PCIE_PORT_LINK_CONTROL);
/* set link width speed control register */
- dw_pcie_readl_rc(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, &val);
+ val = dw_pcie_readl_rc(pp, PCIE_LINK_WIDTH_SPEED_CONTROL);
val &= ~PORT_LOGIC_LINK_WIDTH_MASK;
switch (pp->lanes) {
case 1:
@@ -530,13 +530,13 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
dw_pcie_writel_rc(pp, 0x00000000, PCI_BASE_ADDRESS_1);
/* setup bus numbers */
- dw_pcie_readl_rc(pp, PCI_PRIMARY_BUS, &val);
+ val = dw_pcie_readl_rc(pp, PCI_PRIMARY_BUS);
val &= 0xff000000;
val |= 0x00010100;
dw_pcie_writel_rc(pp, val, PCI_PRIMARY_BUS);
/* setup command register */
- dw_pcie_readl_rc(pp, PCI_COMMAND, &val);
+ val = dw_pcie_readl_rc(pp, PCI_COMMAND);
val &= 0xffff0000;
val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
diff --git a/drivers/pci/pcie-designware.h b/drivers/pci/pcie-designware.h
index 051511a26..547ab3151 100644
--- a/drivers/pci/pcie-designware.h
+++ b/drivers/pci/pcie-designware.h
@@ -49,8 +49,7 @@ struct pcie_port {
};
struct pcie_host_ops {
- void (*readl_rc)(struct pcie_port *pp,
- void __iomem *dbi_base, u32 *val);
+ u32 (*readl_rc)(struct pcie_port *pp, void __iomem *dbi_base);
void (*writel_rc)(struct pcie_port *pp,
u32 val, void __iomem *dbi_base);
int (*rd_own_conf)(struct pcie_port *pp, int where, int size, u32 *val);
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 19/65] PCI: designware: Move link wait definitions to .c file
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (17 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 18/65] PCI: designware: Return data directly from dw_pcie_readl_rc() Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 20/65] PCI: designware: Wait for iATU enable Andrey Smirnov
` (46 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit c388de1c4f0e5da3e96b49efb0388e2a0d34e079
Move the link wait sleep definitions to the .c file as suggested by
Jisheng Zhang in a previous patch.
Signed-off-by: Joao Pinto <jpinto@synopsys.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
CC: Jisheng Zhang <jszhang@marvell.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 4 ++++
drivers/pci/pcie-designware.h | 4 ----
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index 995fe997e..450885f07 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -30,6 +30,10 @@
#include "pcie-designware.h"
+/* Parameters for the waiting for link up routine */
+#define LINK_WAIT_MAX_RETRIES 10
+#define LINK_WAIT_USLEEP_MAX 100000
+
/* Synopsis specific PCIE configuration registers */
#define PCIE_PORT_LINK_CONTROL 0x710
#define PORT_LINK_MODE_MASK (0x3f << 16)
diff --git a/drivers/pci/pcie-designware.h b/drivers/pci/pcie-designware.h
index 547ab3151..0d777ce00 100644
--- a/drivers/pci/pcie-designware.h
+++ b/drivers/pci/pcie-designware.h
@@ -14,10 +14,6 @@
#ifndef _PCIE_DESIGNWARE_H
#define _PCIE_DESIGNWARE_H
-/* Parameters for the waiting for link up routine */
-#define LINK_WAIT_MAX_RETRIES 10
-#define LINK_WAIT_USLEEP_MAX 100000
-
struct pcie_port {
struct device_d *dev;
u8 root_bus_nr;
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 20/65] PCI: designware: Wait for iATU enable
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (18 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 19/65] PCI: designware: Move link wait definitions to .c file Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 21/65] PCI: designware: Add iATU Unroll feature Andrey Smirnov
` (45 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit d8bbeb39fbf3ff06b6adae9d336f44bee4e3f3ec
Add a loop with timeout to make sure the iATU is really enabled before
subsequent config and I/O accesses.
[bhelgaas: split to separate patch, use dev_err() instead of dev_dbg()]
Signed-off-by: Joao Pinto <jpinto@synopsys.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index 450885f07..b56c466fd 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -34,6 +34,10 @@
#define LINK_WAIT_MAX_RETRIES 10
#define LINK_WAIT_USLEEP_MAX 100000
+/* Parameters for the waiting for iATU enabled routine */
+#define LINK_WAIT_MAX_IATU_RETRIES 5
+#define LINK_WAIT_IATU_MAX 10000
+
/* Synopsis specific PCIE configuration registers */
#define PCIE_PORT_LINK_CONTROL 0x710
#define PORT_LINK_MODE_MASK (0x3f << 16)
@@ -160,7 +164,7 @@ 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;
+ u32 retries, val;
dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | index,
PCIE_ATU_VIEWPORT);
@@ -177,7 +181,14 @@ static void dw_pcie_prog_outbound_atu(struct pcie_port *pp, int index,
* Make sure ATU enable takes effect before any subsequent config
* and I/O accesses.
*/
- dw_pcie_readl_rc(pp, PCIE_ATU_CR2);
+ for (retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; retries++) {
+ val = dw_pcie_readl_rc(pp, PCIE_ATU_CR2);
+ if (val == PCIE_ATU_ENABLE)
+ return;
+
+ udelay(LINK_WAIT_IATU_MAX);
+ }
+ dev_err(pp->dev, "iATU is not being enabled\n");
}
int dw_pcie_wait_for_link(struct pcie_port *pp)
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 21/65] PCI: designware: Add iATU Unroll feature
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (19 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 20/65] PCI: designware: Wait for iATU enable Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 22/65] PCI: designware: Check LTSSM training bit before deciding link is up Andrey Smirnov
` (44 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit a0601a47053714eecec726aea5ebcd829f817497
Add support for the new iATU Unroll mechanism that will be used from Core
version 4.80. The new Cores can support either iATU Unroll or the "old"
iATU method, now called Legacy Mode. The driver is perfectly capable of
performing well for both.
[bhelgaas: split ATU enable timeout to separate patch]
Signed-off-by: Joao Pinto <jpinto@synopsys.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
To avoid breaking i.MX6 PCIE support commit
416379f9ebded501eda882e6af0a7aafc1866700 was squashed here as well
PCI: designware: Check for iATU unroll support after initializing host
dw_pcie_iatu_unroll_enabled() reads a dbi_base register. Reading any
dbi_base register before pp->ops->host_init has been called causes
"imprecise external abort" on platforms like ARTPEC-6, where the PCIe
module is disabled at boot and first enabled in pp->ops->host_init. Move
dw_pcie_iatu_unroll_enabled() to dw_pcie_setup_rc(), since it is after
pp->ops->host_init, but before pp->iatu_unroll_enabled is actually used.
Fixes: a0601a470537 ("PCI: designware: Add iATU Unroll feature")
Tested-by: James Le Cuirot <chewi@gentoo.org>
Signed-off-by: Niklas Cassel <niklas.cassel@axis.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Joao Pinto <jpinto@synopsys.com>
Acked-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 101 ++++++++++++++++++++++++++++++----
drivers/pci/pcie-designware.h | 1 +
2 files changed, 91 insertions(+), 11 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index b56c466fd..5d0f782f4 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -80,6 +80,21 @@
#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16)
#define PCIE_ATU_UPPER_TARGET 0x91C
+/*
+ * iATU Unroll-specific register definitions
+ * From 4.80 core version the address translation will be made by unroll
+ */
+#define PCIE_ATU_UNR_REGION_CTRL1 0x00
+#define PCIE_ATU_UNR_REGION_CTRL2 0x04
+#define PCIE_ATU_UNR_LOWER_BASE 0x08
+#define PCIE_ATU_UNR_UPPER_BASE 0x0C
+#define PCIE_ATU_UNR_LIMIT 0x10
+#define PCIE_ATU_UNR_LOWER_TARGET 0x14
+#define PCIE_ATU_UNR_UPPER_TARGET 0x18
+
+/* Register address builder */
+#define PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(region) ((0x3 << 20) | (region << 9))
+
/* PCIe Port Logic registers */
#define PLR_OFFSET 0x700
#define PCIE_PHY_DEBUG_R1 (PLR_OFFSET + 0x2c)
@@ -141,6 +156,27 @@ static inline void dw_pcie_writel_rc(struct pcie_port *pp, u32 val, u32 reg)
writel(val, pp->dbi_base + reg);
}
+static inline u32 dw_pcie_readl_unroll(struct pcie_port *pp, u32 index, u32 reg)
+{
+ u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);
+
+ if (pp->ops->readl_rc)
+ return pp->ops->readl_rc(pp, pp->dbi_base + offset + reg);
+
+ return readl(pp->dbi_base + offset + reg);
+}
+
+static inline void dw_pcie_writel_unroll(struct pcie_port *pp, u32 index,
+ u32 val, u32 reg)
+{
+ u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);
+
+ if (pp->ops->writel_rc)
+ pp->ops->writel_rc(pp, val, pp->dbi_base + offset + reg);
+ else
+ writel(val, pp->dbi_base + offset + reg);
+}
+
#include <abort.h>
static int dw_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
@@ -166,23 +202,49 @@ static void dw_pcie_prog_outbound_atu(struct pcie_port *pp, int index,
{
u32 retries, 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);
+ if (pp->iatu_unroll_enabled) {
+ dw_pcie_writel_unroll(pp, index,
+ lower_32_bits(cpu_addr), PCIE_ATU_UNR_LOWER_BASE);
+ dw_pcie_writel_unroll(pp, index,
+ upper_32_bits(cpu_addr), PCIE_ATU_UNR_UPPER_BASE);
+ dw_pcie_writel_unroll(pp, index,
+ lower_32_bits(cpu_addr + size - 1), PCIE_ATU_UNR_LIMIT);
+ dw_pcie_writel_unroll(pp, index,
+ lower_32_bits(pci_addr), PCIE_ATU_UNR_LOWER_TARGET);
+ dw_pcie_writel_unroll(pp, index,
+ upper_32_bits(pci_addr), PCIE_ATU_UNR_UPPER_TARGET);
+ dw_pcie_writel_unroll(pp, index,
+ type, PCIE_ATU_UNR_REGION_CTRL1);
+ dw_pcie_writel_unroll(pp, index,
+ PCIE_ATU_ENABLE, PCIE_ATU_UNR_REGION_CTRL2);
+ } else {
+ 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);
+ }
/*
* Make sure ATU enable takes effect before any subsequent config
* and I/O accesses.
*/
for (retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; retries++) {
- val = dw_pcie_readl_rc(pp, PCIE_ATU_CR2);
+ if (pp->iatu_unroll_enabled)
+ val = dw_pcie_readl_unroll(pp, index,
+ PCIE_ATU_UNR_REGION_CTRL2);
+ else
+ val = dw_pcie_readl_rc(pp, PCIE_ATU_CR2);
+
if (val == PCIE_ATU_ENABLE)
return;
@@ -234,6 +296,18 @@ static void dw_pcie_set_local_bus_nr(struct pci_controller *host, int busno)
static struct pci_ops dw_pcie_ops;
+static u8 dw_pcie_iatu_unroll_enabled(struct pcie_port *pp)
+{
+ u32 val;
+
+ val = dw_pcie_readl_rc(pp, PCIE_ATU_VIEWPORT);
+ if (val == 0xffffffff)
+ return 1;
+
+ return 0;
+}
+
+
int __init dw_pcie_host_init(struct pcie_port *pp)
{
struct device_node *np = pp->dev->device_node;
@@ -505,6 +579,11 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
{
u32 val;
+ /* get iATU unroll support */
+ pp->iatu_unroll_enabled = dw_pcie_iatu_unroll_enabled(pp);
+ dev_dbg(pp->dev, "iATU unroll: %s\n",
+ pp->iatu_unroll_enabled ? "enabled" : "disabled");
+
/* set the number of lanes */
val = dw_pcie_readl_rc(pp, PCIE_PORT_LINK_CONTROL);
val &= ~PORT_LINK_MODE_MASK;
diff --git a/drivers/pci/pcie-designware.h b/drivers/pci/pcie-designware.h
index 0d777ce00..b2f492a5d 100644
--- a/drivers/pci/pcie-designware.h
+++ b/drivers/pci/pcie-designware.h
@@ -42,6 +42,7 @@ struct pcie_port {
u32 lanes;
struct pcie_host_ops *ops;
struct pci_controller pci;
+ u8 iatu_unroll_enabled;
};
struct pcie_host_ops {
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 22/65] PCI: designware: Check LTSSM training bit before deciding link is up
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (20 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 21/65] PCI: designware: Add iATU Unroll feature Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 23/65] PCI: designware: Keep viewport fixed for IO transaction if num_viewport > 2 Andrey Smirnov
` (43 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 01c076732e8288485c22ef50f20949455a783ca9
The link may be up but still in link training. In this case, we can't
think the link is up and operating correctly. Teach dw_pcie_link_up() to
be aware of the PCIE_PHY_DEBUG_R1_LINK_IN_TRAINING bit.
Also rewrite PCIE_PHY_DEBUG_R1_LINK_UP definition so that it's consistent
with other macros.
Signed-off-by: Jisheng Zhang <jszhang@marvell.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Joao Pinto <jpinto@synopsys.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index 5d0f782f4..a6006201e 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -98,7 +98,8 @@
/* PCIe Port Logic registers */
#define PLR_OFFSET 0x700
#define PCIE_PHY_DEBUG_R1 (PLR_OFFSET + 0x2c)
-#define PCIE_PHY_DEBUG_R1_LINK_UP 0x00000010
+#define PCIE_PHY_DEBUG_R1_LINK_UP (0x1 << 4)
+#define PCIE_PHY_DEBUG_R1_LINK_IN_TRAINING (0x1 << 29)
static unsigned long global_io_offset;
@@ -279,7 +280,8 @@ int dw_pcie_link_up(struct pcie_port *pp)
return pp->ops->link_up(pp);
val = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1);
- return val & PCIE_PHY_DEBUG_R1_LINK_UP;
+ return ((val & PCIE_PHY_DEBUG_R1_LINK_UP) &&
+ !(val & PCIE_PHY_DEBUG_R1_LINK_IN_TRAINING));
}
static inline struct pcie_port *host_to_pcie(struct pci_controller *host)
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 23/65] PCI: designware: Keep viewport fixed for IO transaction if num_viewport > 2
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (21 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 22/65] PCI: designware: Check LTSSM training bit before deciding link is up Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 24/65] PCI: designware: Exchange viewport of `MEMORYs' and `CFGs/IOs' Andrey Smirnov
` (42 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit fe48cb8538421fbd16ecf8bf95829faf8d8c001e
Most of the platforms have 3 or more viewports. For such platforms, We do
not need to share viewports between IO and CFG. Assign viewport 2 to IO
transactions in such cases.
Tested-by: Dong Bo <dongbo4@huawei.com>
Signed-off-by: Pratyush Anand <pratyush.anand@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 26 +++++++++++++++++++-------
drivers/pci/pcie-designware.h | 1 +
2 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index a6006201e..a591ac7a9 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -61,6 +61,7 @@
#define PCIE_ATU_VIEWPORT 0x900
#define PCIE_ATU_REGION_INBOUND (0x1 << 31)
#define PCIE_ATU_REGION_OUTBOUND (0x0 << 31)
+#define PCIE_ATU_REGION_INDEX2 (0x2 << 0)
#define PCIE_ATU_REGION_INDEX1 (0x1 << 0)
#define PCIE_ATU_REGION_INDEX0 (0x0 << 0)
#define PCIE_ATU_CR1 0x904
@@ -404,6 +405,10 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
if (ret)
pp->lanes = 0;
+ ret = of_property_read_u32(np, "num-viewport", &pp->num_viewport);
+ if (ret)
+ pp->num_viewport = 2;
+
if (pp->ops->host_init)
pp->ops->host_init(pp);
@@ -450,9 +455,10 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
type, cpu_addr,
busdev, cfg_size);
ret = dw_pcie_cfg_read(va_cfg_base + where, size, val);
- dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
- PCIE_ATU_TYPE_IO, pp->io_mod_base,
- pp->io_bus_addr, pp->io_size);
+ if (pp->num_viewport <= 2)
+ dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
+ PCIE_ATU_TYPE_IO, pp->io_mod_base,
+ pp->io_bus_addr, pp->io_size);
return ret;
}
@@ -488,9 +494,10 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
type, cpu_addr,
busdev, cfg_size);
ret = dw_pcie_cfg_write(va_cfg_base + where, size, val);
- dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
- PCIE_ATU_TYPE_IO, pp->io_mod_base,
- pp->io_bus_addr, pp->io_size);
+ if (pp->num_viewport <= 2)
+ dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
+ PCIE_ATU_TYPE_IO, pp->io_mod_base,
+ pp->io_bus_addr, pp->io_size);
return ret;
}
@@ -643,10 +650,15 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
* uses its own address translation component rather than ATU, so
* we should not program the ATU here.
*/
- if (!pp->ops->rd_other_conf)
+ if (!pp->ops->rd_other_conf) {
dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
pp->mem_bus_addr, pp->mem_size);
+ if (pp->num_viewport > 2)
+ dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX2,
+ PCIE_ATU_TYPE_IO, pp->io_base,
+ pp->io_bus_addr, pp->io_size);
+ }
dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
diff --git a/drivers/pci/pcie-designware.h b/drivers/pci/pcie-designware.h
index b2f492a5d..62f04e69b 100644
--- a/drivers/pci/pcie-designware.h
+++ b/drivers/pci/pcie-designware.h
@@ -40,6 +40,7 @@ struct pcie_port {
struct resource busn;
int irq;
u32 lanes;
+ u32 num_viewport;
struct pcie_host_ops *ops;
struct pci_controller pci;
u8 iatu_unroll_enabled;
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 24/65] PCI: designware: Exchange viewport of `MEMORYs' and `CFGs/IOs'
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (22 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 23/65] PCI: designware: Keep viewport fixed for IO transaction if num_viewport > 2 Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 25/65] PCI: designware: Rename dw_pcie_valid_config() to dw_pcie_valid_device() Andrey Smirnov
` (41 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 68a0bfec72cb4f117198ae31df114dad4c5e405d
When we have only two view ports in a DesignWare PCIe platform, iatu0
is used for both CFG and IO accesses. When CFGs are sent to peripherals
(e.g., lspci), iatu0 frequently switches between CFG and IO.
For such scenarios, a MEMORY might be sent as an IOs by mistake.
Considering the following configurations:
MEMORY -> BASE_ADDR: 0xb4100000, LIMIT: 0xb4100FFF, TYPE=mem
CFG -> BASE_ADDR: 0xb4000000, LIMIT: 0xb4000FFF, TYPE=cfg
IO -> BASE_ADDR: 0xFFFFFFFF, LIMIT: 0xFFFFFFFE, TYPE=io
Suppose PCIe has just completed a CFG access. To switch back to IO, it
sets the BASE_ADDR to 0xFFFFFFFF, LIMIT 0xFFFFFFFE and TYPE to IO. When
another CFG comes, the BASE_ADDR is set to 0xb4000000 to switch to CFG. At
this moment, a MEMORY access shows up, since it matches with iatu0 (due to
0xb4000000 <= MEMORY BASE_ADDR <= MEMORY LIMIT <= 0xFFFFFFF), it is treated
as an IO access by mistake, then sent to perpheral.
This patch fixes the problem by exchanging the assignments of `MEMORYs' and
`CFGs/IOs', which assigning MEMORYs to iatu0, CFGs and IOs to iatu1.
We can still have issues with IO transfer, however memory transfer is used
predominantly therefore we are just minimizing the risk of failure.
Actually, we can not do much when we have only two viewports. We can
either not allow the less frequent IO transfers at all, or can live with a
remote possibility of getting it corrupted.
Signed-off-by: Dong Bo <dongbo4@huawei.com>
[pratyush.anand@gmail.com: Modified commit log to capture remote risk]
Signed-off-by: Pratyush Anand <pratyush.anand@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index a591ac7a9..2f868828b 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -451,12 +451,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
va_cfg_base = pp->va_cfg1_base;
}
- dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
+ dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
type, cpu_addr,
busdev, cfg_size);
ret = dw_pcie_cfg_read(va_cfg_base + where, size, val);
if (pp->num_viewport <= 2)
- dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
+ dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
PCIE_ATU_TYPE_IO, pp->io_mod_base,
pp->io_bus_addr, pp->io_size);
@@ -490,12 +490,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
va_cfg_base = pp->va_cfg1_base;
}
- dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
+ dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
type, cpu_addr,
busdev, cfg_size);
ret = dw_pcie_cfg_write(va_cfg_base + where, size, val);
if (pp->num_viewport <= 2)
- dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
+ dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
PCIE_ATU_TYPE_IO, pp->io_mod_base,
pp->io_bus_addr, pp->io_size);
@@ -651,7 +651,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
* we should not program the ATU here.
*/
if (!pp->ops->rd_other_conf) {
- dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
+ dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
pp->mem_bus_addr, pp->mem_size);
if (pp->num_viewport > 2)
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 25/65] PCI: designware: Rename dw_pcie_valid_config() to dw_pcie_valid_device()
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (23 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 24/65] PCI: designware: Exchange viewport of `MEMORYs' and `CFGs/IOs' Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 26/65] PCI: designware: Simplify dw_pcie_readl_unroll(), dw_pcie_writel_unroll() Andrey Smirnov
` (40 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 1034023606d0e971f4dee6f725e441b785a846b5
Rename dw_pcie_valid_config() to dw_pcie_valid_device() and use the result
directly as a boolean value instead of testing against 0. No functional
change intended.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index 2f868828b..c548ae87e 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -502,8 +502,8 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
return ret;
}
-static int dw_pcie_valid_config(struct pcie_port *pp,
- struct pci_bus *bus, int dev)
+static int dw_pcie_valid_device(struct pcie_port *pp, struct pci_bus *bus,
+ int dev)
{
/* If there is no link, then there is no device */
if (bus->number != pp->root_bus_nr) {
@@ -533,7 +533,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
*val = 0xffffffff;
- if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
+ if (!dw_pcie_valid_device(pp, bus, PCI_SLOT(devfn)))
return PCIBIOS_DEVICE_NOT_FOUND;
data_abort_mask();
@@ -556,7 +556,7 @@ static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
struct pcie_port *pp = host_to_pcie(bus->host);
int ret;
- if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
+ if (!dw_pcie_valid_device(pp, bus, PCI_SLOT(devfn)))
return PCIBIOS_DEVICE_NOT_FOUND;
data_abort_mask();
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 26/65] PCI: designware: Simplify dw_pcie_readl_unroll(), dw_pcie_writel_unroll()
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (24 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 25/65] PCI: designware: Rename dw_pcie_valid_config() to dw_pcie_valid_device() Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 27/65] PCI: designware: Simplify pcie_host_ops.readl_rc() and .writel_rc() interfaces Andrey Smirnov
` (39 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of Linux commit a26e0108b61d6e65c151af720f2c4248a38f000d
dw_pcie_readl_unroll() and dw_pcie_writel_unroll() duplicate what
dw_pcie_readl_rc() and dw_pcie_writel_rc() already do, so call them
directly.
[bhelgaas: reworked into patch series]
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index c548ae87e..fd529c114 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -162,10 +162,7 @@ static inline u32 dw_pcie_readl_unroll(struct pcie_port *pp, u32 index, u32 reg)
{
u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);
- if (pp->ops->readl_rc)
- return pp->ops->readl_rc(pp, pp->dbi_base + offset + reg);
-
- return readl(pp->dbi_base + offset + reg);
+ return dw_pcie_readl_rc(pp, offset + reg);
}
static inline void dw_pcie_writel_unroll(struct pcie_port *pp, u32 index,
@@ -173,10 +170,7 @@ static inline void dw_pcie_writel_unroll(struct pcie_port *pp, u32 index,
{
u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);
- if (pp->ops->writel_rc)
- pp->ops->writel_rc(pp, val, pp->dbi_base + offset + reg);
- else
- writel(val, pp->dbi_base + offset + reg);
+ dw_pcie_writel_rc(pp, val, offset + reg);
}
#include <abort.h>
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 27/65] PCI: designware: Simplify pcie_host_ops.readl_rc() and .writel_rc() interfaces
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (25 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 26/65] PCI: designware: Simplify dw_pcie_readl_unroll(), dw_pcie_writel_unroll() Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 28/65] PCI: designware: Swap order of dw_pcie_writel_rc() reg/val arguments Andrey Smirnov
` (38 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 7e00dfd0fbbb2fc276592613f76ded0b9a139a04
The struct pcie_host_ops.readl_rc() and .writel_rc() function pointers
allow a driver to override the default DesignWare register accessors.
Make the signature of the override functions the same as the default
accessors. This makes the default dw_pcie_readl_rc() and the corresponding
override more structurally similar: both will compute the final register
address with "pp->dbi_base + reg". Previously dw_pcie_readl_rc() computed
the address and passed it to the override.
No functional change intended.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 4 ++--
drivers/pci/pcie-designware.h | 5 ++---
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index fd529c114..4595167c4 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -145,7 +145,7 @@ int dw_pcie_cfg_write(void __iomem *addr, int size, u32 val)
static inline u32 dw_pcie_readl_rc(struct pcie_port *pp, u32 reg)
{
if (pp->ops->readl_rc)
- return pp->ops->readl_rc(pp, pp->dbi_base + reg);
+ return pp->ops->readl_rc(pp, reg);
return readl(pp->dbi_base + reg);
}
@@ -153,7 +153,7 @@ static inline u32 dw_pcie_readl_rc(struct pcie_port *pp, u32 reg)
static inline void dw_pcie_writel_rc(struct pcie_port *pp, u32 val, u32 reg)
{
if (pp->ops->writel_rc)
- pp->ops->writel_rc(pp, val, pp->dbi_base + reg);
+ pp->ops->writel_rc(pp, val, reg);
else
writel(val, pp->dbi_base + reg);
}
diff --git a/drivers/pci/pcie-designware.h b/drivers/pci/pcie-designware.h
index 62f04e69b..b7ce73718 100644
--- a/drivers/pci/pcie-designware.h
+++ b/drivers/pci/pcie-designware.h
@@ -47,9 +47,8 @@ struct pcie_port {
};
struct pcie_host_ops {
- u32 (*readl_rc)(struct pcie_port *pp, void __iomem *dbi_base);
- void (*writel_rc)(struct pcie_port *pp,
- u32 val, void __iomem *dbi_base);
+ u32 (*readl_rc)(struct pcie_port *pp, u32 reg);
+ void (*writel_rc)(struct pcie_port *pp, u32 val, u32 reg);
int (*rd_own_conf)(struct pcie_port *pp, int where, int size, u32 *val);
int (*wr_own_conf)(struct pcie_port *pp, int where, int size, u32 val);
int (*rd_other_conf)(struct pcie_port *pp, struct pci_bus *bus,
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 28/65] PCI: designware: Swap order of dw_pcie_writel_rc() reg/val arguments
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (26 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 27/65] PCI: designware: Simplify pcie_host_ops.readl_rc() and .writel_rc() interfaces Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 29/65] PCI: designware: Export dw_pcie_readl_rc(), dw_pcie_writel_rc() Andrey Smirnov
` (37 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit ad8802189426cf7b3a2ad0444f71981fb81312a8
Swap order of dw_pcie_writel_rc() arguments to match the "dev, pos, val"
order used by pci_write_config_word() and other drivers. No functional
change intended.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 46 +++++++++++++++++------------------
drivers/pci/pcie-designware.h | 2 +-
2 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index 4595167c4..1ac6a4aaf 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -150,10 +150,10 @@ static inline u32 dw_pcie_readl_rc(struct pcie_port *pp, u32 reg)
return readl(pp->dbi_base + reg);
}
-static inline void dw_pcie_writel_rc(struct pcie_port *pp, u32 val, u32 reg)
+static inline void dw_pcie_writel_rc(struct pcie_port *pp, u32 reg, u32 val)
{
if (pp->ops->writel_rc)
- pp->ops->writel_rc(pp, val, reg);
+ pp->ops->writel_rc(pp, reg, val);
else
writel(val, pp->dbi_base + reg);
}
@@ -170,7 +170,7 @@ static inline void dw_pcie_writel_unroll(struct pcie_port *pp, u32 index,
{
u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);
- dw_pcie_writel_rc(pp, val, offset + reg);
+ dw_pcie_writel_rc(pp, offset + reg, val);
}
#include <abort.h>
@@ -214,20 +214,20 @@ static void dw_pcie_prog_outbound_atu(struct pcie_port *pp, int index,
dw_pcie_writel_unroll(pp, index,
PCIE_ATU_ENABLE, PCIE_ATU_UNR_REGION_CTRL2);
} else {
- 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_writel_rc(pp, PCIE_ATU_VIEWPORT,
+ PCIE_ATU_REGION_OUTBOUND | index);
+ dw_pcie_writel_rc(pp, PCIE_ATU_LOWER_BASE,
+ lower_32_bits(cpu_addr));
+ dw_pcie_writel_rc(pp, PCIE_ATU_UPPER_BASE,
+ upper_32_bits(cpu_addr));
+ dw_pcie_writel_rc(pp, PCIE_ATU_LIMIT,
+ lower_32_bits(cpu_addr + size - 1));
+ dw_pcie_writel_rc(pp, PCIE_ATU_LOWER_TARGET,
+ lower_32_bits(pci_addr));
+ dw_pcie_writel_rc(pp, PCIE_ATU_UPPER_TARGET,
+ upper_32_bits(pci_addr));
+ dw_pcie_writel_rc(pp, PCIE_ATU_CR1, type);
+ dw_pcie_writel_rc(pp, PCIE_ATU_CR2, PCIE_ATU_ENABLE);
}
/*
@@ -604,7 +604,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
dev_err(pp->dev, "num-lanes %u: invalid value\n", pp->lanes);
return;
}
- dw_pcie_writel_rc(pp, val, PCIE_PORT_LINK_CONTROL);
+ dw_pcie_writel_rc(pp, PCIE_PORT_LINK_CONTROL, val);
/* set link width speed control register */
val = dw_pcie_readl_rc(pp, PCIE_LINK_WIDTH_SPEED_CONTROL);
@@ -620,24 +620,24 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
val |= PORT_LOGIC_LINK_WIDTH_4_LANES;
break;
}
- dw_pcie_writel_rc(pp, val, PCIE_LINK_WIDTH_SPEED_CONTROL);
+ dw_pcie_writel_rc(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, val);
/* setup RC BARs */
- dw_pcie_writel_rc(pp, 0x00000004, PCI_BASE_ADDRESS_0);
- dw_pcie_writel_rc(pp, 0x00000000, PCI_BASE_ADDRESS_1);
+ dw_pcie_writel_rc(pp, PCI_BASE_ADDRESS_0, 0x00000004);
+ dw_pcie_writel_rc(pp, PCI_BASE_ADDRESS_1, 0x00000000);
/* setup bus numbers */
val = dw_pcie_readl_rc(pp, PCI_PRIMARY_BUS);
val &= 0xff000000;
val |= 0x00010100;
- dw_pcie_writel_rc(pp, val, PCI_PRIMARY_BUS);
+ dw_pcie_writel_rc(pp, PCI_PRIMARY_BUS, val);
/* setup command register */
val = dw_pcie_readl_rc(pp, PCI_COMMAND);
val &= 0xffff0000;
val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
- dw_pcie_writel_rc(pp, val, PCI_COMMAND);
+ dw_pcie_writel_rc(pp, PCI_COMMAND, val);
/*
* If the platform provides ->rd_other_conf, it means the platform
diff --git a/drivers/pci/pcie-designware.h b/drivers/pci/pcie-designware.h
index b7ce73718..f2ca8aadf 100644
--- a/drivers/pci/pcie-designware.h
+++ b/drivers/pci/pcie-designware.h
@@ -48,7 +48,7 @@ struct pcie_port {
struct pcie_host_ops {
u32 (*readl_rc)(struct pcie_port *pp, u32 reg);
- void (*writel_rc)(struct pcie_port *pp, u32 val, u32 reg);
+ void (*writel_rc)(struct pcie_port *pp, u32 reg, u32 val);
int (*rd_own_conf)(struct pcie_port *pp, int where, int size, u32 *val);
int (*wr_own_conf)(struct pcie_port *pp, int where, int size, u32 val);
int (*rd_other_conf)(struct pcie_port *pp, struct pci_bus *bus,
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 29/65] PCI: designware: Export dw_pcie_readl_rc(), dw_pcie_writel_rc()
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (27 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 28/65] PCI: designware: Swap order of dw_pcie_writel_rc() reg/val arguments Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 30/65] PCI: designware: Uninline register accessors Andrey Smirnov
` (36 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Export dw_pcie_readl_rc() and dw_pcie_writel_rc(). Many other drivers can
use these instead of implementing their own versions. No functional change
intended.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 4 ++--
drivers/pci/pcie-designware.h | 2 ++
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index 1ac6a4aaf..e01621d03 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -142,7 +142,7 @@ int dw_pcie_cfg_write(void __iomem *addr, int size, u32 val)
return PCIBIOS_SUCCESSFUL;
}
-static inline u32 dw_pcie_readl_rc(struct pcie_port *pp, u32 reg)
+u32 dw_pcie_readl_rc(struct pcie_port *pp, u32 reg)
{
if (pp->ops->readl_rc)
return pp->ops->readl_rc(pp, reg);
@@ -150,7 +150,7 @@ static inline u32 dw_pcie_readl_rc(struct pcie_port *pp, u32 reg)
return readl(pp->dbi_base + reg);
}
-static inline void dw_pcie_writel_rc(struct pcie_port *pp, u32 reg, u32 val)
+void dw_pcie_writel_rc(struct pcie_port *pp, u32 reg, u32 val)
{
if (pp->ops->writel_rc)
pp->ops->writel_rc(pp, reg, val);
diff --git a/drivers/pci/pcie-designware.h b/drivers/pci/pcie-designware.h
index f2ca8aadf..bded13292 100644
--- a/drivers/pci/pcie-designware.h
+++ b/drivers/pci/pcie-designware.h
@@ -60,6 +60,8 @@ struct pcie_host_ops {
void (*scan_bus)(struct pcie_port *pp);
};
+u32 dw_pcie_readl_rc(struct pcie_port *pp, u32 reg);
+void dw_pcie_writel_rc(struct pcie_port *pp, u32 reg, u32 val);
int dw_pcie_cfg_read(void __iomem *addr, int size, u32 *val);
int dw_pcie_cfg_write(void __iomem *addr, int size, u32 val);
int dw_pcie_link_up(struct pcie_port *pp);
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 30/65] PCI: designware: Uninline register accessors
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (28 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 29/65] PCI: designware: Export dw_pcie_readl_rc(), dw_pcie_writel_rc() Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 31/65] PCI: designware: Swap order of dw_pcie_writel_unroll() reg/val arguments Andrey Smirnov
` (35 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 3d469939bcdf044d9f370be4f6bf21436afea310
The register accessors are not performance critical and small enough that
the compiler can inline them itself if it makes sense.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index e01621d03..3aa048779 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -158,14 +158,14 @@ void dw_pcie_writel_rc(struct pcie_port *pp, u32 reg, u32 val)
writel(val, pp->dbi_base + reg);
}
-static inline u32 dw_pcie_readl_unroll(struct pcie_port *pp, u32 index, u32 reg)
+static u32 dw_pcie_readl_unroll(struct pcie_port *pp, u32 index, u32 reg)
{
u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);
return dw_pcie_readl_rc(pp, offset + reg);
}
-static inline void dw_pcie_writel_unroll(struct pcie_port *pp, u32 index,
+static void dw_pcie_writel_unroll(struct pcie_port *pp, u32 index,
u32 val, u32 reg)
{
u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 31/65] PCI: designware: Swap order of dw_pcie_writel_unroll() reg/val arguments
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (29 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 30/65] PCI: designware: Uninline register accessors Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 32/65] PCI: designware: Check for iATU unroll only on platforms that use ATU Andrey Smirnov
` (34 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit f5acb5c51de2c073ee5f80d868354113ce0227ee
Swap order of dw_pcie_readl_unroll() arguments to match the "dev, pos, val"
order used by pci_write_config_word() and other drivers. No functional
change intended.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index 3aa048779..2b39e39e0 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -166,7 +166,7 @@ static u32 dw_pcie_readl_unroll(struct pcie_port *pp, u32 index, u32 reg)
}
static void dw_pcie_writel_unroll(struct pcie_port *pp, u32 index,
- u32 val, u32 reg)
+ u32 reg, u32 val)
{
u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);
@@ -199,20 +199,20 @@ static void dw_pcie_prog_outbound_atu(struct pcie_port *pp, int index,
u32 retries, val;
if (pp->iatu_unroll_enabled) {
- dw_pcie_writel_unroll(pp, index,
- lower_32_bits(cpu_addr), PCIE_ATU_UNR_LOWER_BASE);
- dw_pcie_writel_unroll(pp, index,
- upper_32_bits(cpu_addr), PCIE_ATU_UNR_UPPER_BASE);
- dw_pcie_writel_unroll(pp, index,
- lower_32_bits(cpu_addr + size - 1), PCIE_ATU_UNR_LIMIT);
- dw_pcie_writel_unroll(pp, index,
- lower_32_bits(pci_addr), PCIE_ATU_UNR_LOWER_TARGET);
- dw_pcie_writel_unroll(pp, index,
- upper_32_bits(pci_addr), PCIE_ATU_UNR_UPPER_TARGET);
- dw_pcie_writel_unroll(pp, index,
- type, PCIE_ATU_UNR_REGION_CTRL1);
- dw_pcie_writel_unroll(pp, index,
- PCIE_ATU_ENABLE, PCIE_ATU_UNR_REGION_CTRL2);
+ dw_pcie_writel_unroll(pp, index, PCIE_ATU_UNR_LOWER_BASE,
+ lower_32_bits(cpu_addr));
+ dw_pcie_writel_unroll(pp, index, PCIE_ATU_UNR_UPPER_BASE,
+ upper_32_bits(cpu_addr));
+ dw_pcie_writel_unroll(pp, index, PCIE_ATU_UNR_LIMIT,
+ lower_32_bits(cpu_addr + size - 1));
+ dw_pcie_writel_unroll(pp, index, PCIE_ATU_UNR_LOWER_TARGET,
+ lower_32_bits(pci_addr));
+ dw_pcie_writel_unroll(pp, index, PCIE_ATU_UNR_UPPER_TARGET,
+ upper_32_bits(pci_addr));
+ dw_pcie_writel_unroll(pp, index, PCIE_ATU_UNR_REGION_CTRL1,
+ type);
+ dw_pcie_writel_unroll(pp, index, PCIE_ATU_UNR_REGION_CTRL2,
+ PCIE_ATU_ENABLE);
} else {
dw_pcie_writel_rc(pp, PCIE_ATU_VIEWPORT,
PCIE_ATU_REGION_OUTBOUND | index);
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 32/65] PCI: designware: Check for iATU unroll only on platforms that use ATU
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (30 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 31/65] PCI: designware: Swap order of dw_pcie_writel_unroll() reg/val arguments Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 33/65] PCI: dwc: designware: Move register defines to designware header file Andrey Smirnov
` (33 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit a782b5f986c3fa1cfa7f2b57941200c6a5809242
Previously we checked for iATU unroll support by reading PCIE_ATU_VIEWPORT
even on platforms, e.g., Keystone, that do not have ATU ports. This can
cause bad behavior such as asynchronous external aborts:
OF: PCI: MEM 0x60000000..0x6fffffff -> 0x60000000
Unhandled fault: asynchronous external abort (0x1211) at 0x00000000
pgd = c0003000
[00000000] *pgd=80000800004003, *pmd=00000000
Internal error: : 1211 [#1] PREEMPT SMP ARM
Modules linked in:
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.9.0-00009-g6ff59d2-dirty #7
Hardware name: Keystone
task: eb878000 task.stack: eb866000
PC is at dw_pcie_setup_rc+0x24/0x380
LR is at ks_pcie_host_init+0x10/0x170
Move the dw_pcie_iatu_unroll_enabled() check so we only call it on
platforms that do not use the ATU. These platforms supply their own
->rd_other_conf() and ->wr_other_conf() methods.
[bhelgaas: changelog]
Fixes: a0601a470537 ("PCI: designware: Add iATU Unroll feature")
Fixes: 416379f9ebde ("PCI: designware: Check for iATU unroll support after initializing host")
Tested-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-By: Joao Pinto <jpinto@synopsys.com>
CC: stable@vger.kernel.org # v4.9+
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index 2b39e39e0..d42045088 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -582,11 +582,6 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
{
u32 val;
- /* get iATU unroll support */
- pp->iatu_unroll_enabled = dw_pcie_iatu_unroll_enabled(pp);
- dev_dbg(pp->dev, "iATU unroll: %s\n",
- pp->iatu_unroll_enabled ? "enabled" : "disabled");
-
/* set the number of lanes */
val = dw_pcie_readl_rc(pp, PCIE_PORT_LINK_CONTROL);
val &= ~PORT_LINK_MODE_MASK;
@@ -645,6 +640,11 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
* we should not program the ATU here.
*/
if (!pp->ops->rd_other_conf) {
+ /* get iATU unroll support */
+ pp->iatu_unroll_enabled = dw_pcie_iatu_unroll_enabled(pp);
+ dev_dbg(pp->dev, "iATU unroll: %s\n",
+ pp->iatu_unroll_enabled ? "enabled" : "disabled");
+
dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
pp->mem_bus_addr, pp->mem_size);
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 33/65] PCI: dwc: designware: Move register defines to designware header file
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (31 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 32/65] PCI: designware: Check for iATU unroll only on platforms that use ATU Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 34/65] PCI: dwc: all: Rename cfg_read/cfg_write to read/write Andrey Smirnov
` (32 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commmit b90dc392212d1153a12eea15cbc6eae352a3c989
No functional change. Move the register defines and other macros from
pcie-designware.c to pcie-designware.h. This is in preparation to split the
pcie-designware.c file into designware core file and host-specific file.
While at that also fix a checkpatch warning.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-By: Joao Pinto <jpinto@synopsys.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pci-imx6.c | 1 -
drivers/pci/pcie-designware.c | 72 --------------------------------
drivers/pci/pcie-designware.h | 78 +++++++++++++++++++++++++++++++++++
3 files changed, 78 insertions(+), 73 deletions(-)
diff --git a/drivers/pci/pci-imx6.c b/drivers/pci/pci-imx6.c
index 18965c7c3..c499f4c83 100644
--- a/drivers/pci/pci-imx6.c
+++ b/drivers/pci/pci-imx6.c
@@ -72,7 +72,6 @@ struct imx6_pcie {
#define PCIE_PL_PFLR_LINK_STATE_MASK (0x3f << 16)
#define PCIE_PL_PFLR_FORCE_LINK (1 << 15)
#define PCIE_PHY_DEBUG_R0 (PL_OFFSET + 0x28)
-#define PCIE_PHY_DEBUG_R1 (PL_OFFSET + 0x2c)
#define PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING (1 << 29)
#define PCIE_PHY_DEBUG_R1_XMLH_LINK_UP (1 << 4)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index d42045088..2ddda3192 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -30,78 +30,6 @@
#include "pcie-designware.h"
-/* Parameters for the waiting for link up routine */
-#define LINK_WAIT_MAX_RETRIES 10
-#define LINK_WAIT_USLEEP_MAX 100000
-
-/* Parameters for the waiting for iATU enabled routine */
-#define LINK_WAIT_MAX_IATU_RETRIES 5
-#define LINK_WAIT_IATU_MAX 10000
-
-/* Synopsis 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)
-#define PORT_LINK_MODE_2_LANES (0x3 << 16)
-#define PORT_LINK_MODE_4_LANES (0x7 << 16)
-
-#define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C
-#define PORT_LOGIC_SPEED_CHANGE (0x1 << 17)
-#define PORT_LOGIC_LINK_WIDTH_MASK (0x1f << 8)
-#define PORT_LOGIC_LINK_WIDTH_1_LANES (0x1 << 8)
-#define PORT_LOGIC_LINK_WIDTH_2_LANES (0x2 << 8)
-#define PORT_LOGIC_LINK_WIDTH_4_LANES (0x4 << 8)
-
-#define PCIE_MSI_ADDR_LO 0x820
-#define PCIE_MSI_ADDR_HI 0x824
-#define PCIE_MSI_INTR0_ENABLE 0x828
-#define PCIE_MSI_INTR0_MASK 0x82C
-#define PCIE_MSI_INTR0_STATUS 0x830
-
-#define PCIE_ATU_VIEWPORT 0x900
-#define PCIE_ATU_REGION_INBOUND (0x1 << 31)
-#define PCIE_ATU_REGION_OUTBOUND (0x0 << 31)
-#define PCIE_ATU_REGION_INDEX2 (0x2 << 0)
-#define PCIE_ATU_REGION_INDEX1 (0x1 << 0)
-#define PCIE_ATU_REGION_INDEX0 (0x0 << 0)
-#define PCIE_ATU_CR1 0x904
-#define PCIE_ATU_TYPE_MEM (0x0 << 0)
-#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)
-#define PCIE_ATU_LOWER_BASE 0x90C
-#define PCIE_ATU_UPPER_BASE 0x910
-#define PCIE_ATU_LIMIT 0x914
-#define PCIE_ATU_LOWER_TARGET 0x918
-#define PCIE_ATU_BUS(x) (((x) & 0xff) << 24)
-#define PCIE_ATU_DEV(x) (((x) & 0x1f) << 19)
-#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16)
-#define PCIE_ATU_UPPER_TARGET 0x91C
-
-/*
- * iATU Unroll-specific register definitions
- * From 4.80 core version the address translation will be made by unroll
- */
-#define PCIE_ATU_UNR_REGION_CTRL1 0x00
-#define PCIE_ATU_UNR_REGION_CTRL2 0x04
-#define PCIE_ATU_UNR_LOWER_BASE 0x08
-#define PCIE_ATU_UNR_UPPER_BASE 0x0C
-#define PCIE_ATU_UNR_LIMIT 0x10
-#define PCIE_ATU_UNR_LOWER_TARGET 0x14
-#define PCIE_ATU_UNR_UPPER_TARGET 0x18
-
-/* Register address builder */
-#define PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(region) ((0x3 << 20) | (region << 9))
-
-/* 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)
-
static unsigned long global_io_offset;
int dw_pcie_cfg_read(void __iomem *addr, int size, u32 *val)
diff --git a/drivers/pci/pcie-designware.h b/drivers/pci/pcie-designware.h
index bded13292..3171adfe7 100644
--- a/drivers/pci/pcie-designware.h
+++ b/drivers/pci/pcie-designware.h
@@ -14,6 +14,84 @@
#ifndef _PCIE_DESIGNWARE_H
#define _PCIE_DESIGNWARE_H
+/* Parameters for the waiting for link up routine */
+#define LINK_WAIT_MAX_RETRIES 10
+#define LINK_WAIT_USLEEP_MAX 100000
+
+/* Parameters for the waiting for iATU enabled routine */
+#define LINK_WAIT_MAX_IATU_RETRIES 5
+#define LINK_WAIT_IATU_MAX 10000
+
+/* Synopsis 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)
+#define PORT_LINK_MODE_2_LANES (0x3 << 16)
+#define PORT_LINK_MODE_4_LANES (0x7 << 16)
+
+#define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C
+#define PORT_LOGIC_SPEED_CHANGE (0x1 << 17)
+#define PORT_LOGIC_LINK_WIDTH_MASK (0x1f << 8)
+#define PORT_LOGIC_LINK_WIDTH_1_LANES (0x1 << 8)
+#define PORT_LOGIC_LINK_WIDTH_2_LANES (0x2 << 8)
+#define PORT_LOGIC_LINK_WIDTH_4_LANES (0x4 << 8)
+
+#define PCIE_MSI_ADDR_LO 0x820
+#define PCIE_MSI_ADDR_HI 0x824
+#define PCIE_MSI_INTR0_ENABLE 0x828
+#define PCIE_MSI_INTR0_MASK 0x82C
+#define PCIE_MSI_INTR0_STATUS 0x830
+
+#define PCIE_ATU_VIEWPORT 0x900
+#define PCIE_ATU_REGION_INBOUND (0x1 << 31)
+#define PCIE_ATU_REGION_OUTBOUND (0x0 << 31)
+#define PCIE_ATU_REGION_INDEX2 (0x2 << 0)
+#define PCIE_ATU_REGION_INDEX1 (0x1 << 0)
+#define PCIE_ATU_REGION_INDEX0 (0x0 << 0)
+#define PCIE_ATU_CR1 0x904
+#define PCIE_ATU_TYPE_MEM (0x0 << 0)
+#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)
+#define PCIE_ATU_LOWER_BASE 0x90C
+#define PCIE_ATU_UPPER_BASE 0x910
+#define PCIE_ATU_LIMIT 0x914
+#define PCIE_ATU_LOWER_TARGET 0x918
+#define PCIE_ATU_BUS(x) (((x) & 0xff) << 24)
+#define PCIE_ATU_DEV(x) (((x) & 0x1f) << 19)
+#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16)
+#define PCIE_ATU_UPPER_TARGET 0x91C
+
+/*
+ * iATU Unroll-specific register definitions
+ * From 4.80 core version the address translation will be made by unroll
+ */
+#define PCIE_ATU_UNR_REGION_CTRL1 0x00
+#define PCIE_ATU_UNR_REGION_CTRL2 0x04
+#define PCIE_ATU_UNR_LOWER_BASE 0x08
+#define PCIE_ATU_UNR_UPPER_BASE 0x0C
+#define PCIE_ATU_UNR_LIMIT 0x10
+#define PCIE_ATU_UNR_LOWER_TARGET 0x14
+#define PCIE_ATU_UNR_UPPER_TARGET 0x18
+
+/* Register address builder */
+#define PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(region) ((0x3 << 20) | (region << 9))
+
+/* 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)
+
+/* 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)
+
struct pcie_port {
struct device_d *dev;
u8 root_bus_nr;
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 34/65] PCI: dwc: all: Rename cfg_read/cfg_write to read/write
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (32 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 33/65] PCI: dwc: designware: Move register defines to designware header file Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 35/65] PCI: dwc: designware: Get device pointer at the start of dw_pcie_host_init() Andrey Smirnov
` (31 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
No functional change. dw_pcie_cfg_read()/dw_pcie_cfg_write() doesn't do
anything specific to access configuration space. It can be just renamed to
dw_pcie_read()/dw_pcie_write() and used to read/write data to dbi space.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-By: Joao Pinto <jpinto@synopsys.com>
CC: Jingoo Han <jingoohan1@gmail.com>
CC: Murali Karicheri <m-karicheri2@ti.com>
CC: Stanimir Varbanov <svarbanov@mm-sol.com>
CC: Pratyush Anand <pratyush.anand@gmail.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 12 ++++++------
drivers/pci/pcie-designware.h | 4 ++--
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index 2ddda3192..74769de7f 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -32,7 +32,7 @@
static unsigned long global_io_offset;
-int dw_pcie_cfg_read(void __iomem *addr, int size, u32 *val)
+int dw_pcie_read(void __iomem *addr, int size, u32 *val)
{
if ((uintptr_t)addr & (size - 1)) {
*val = 0;
@@ -53,7 +53,7 @@ int dw_pcie_cfg_read(void __iomem *addr, int size, u32 *val)
return PCIBIOS_SUCCESSFUL;
}
-int dw_pcie_cfg_write(void __iomem *addr, int size, u32 val)
+int dw_pcie_write(void __iomem *addr, int size, u32 val)
{
if ((uintptr_t)addr & (size - 1))
return PCIBIOS_BAD_REGISTER_NUMBER;
@@ -109,7 +109,7 @@ static int dw_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
if (pp->ops->rd_own_conf)
return pp->ops->rd_own_conf(pp, where, size, val);
- return dw_pcie_cfg_read(pp->dbi_base + where, size, val);
+ return dw_pcie_read(pp->dbi_base + where, size, val);
}
static int dw_pcie_wr_own_conf(struct pcie_port *pp, int where, int size,
@@ -118,7 +118,7 @@ static int dw_pcie_wr_own_conf(struct pcie_port *pp, int where, int size,
if (pp->ops->wr_own_conf)
return pp->ops->wr_own_conf(pp, where, size, val);
- return dw_pcie_cfg_write(pp->dbi_base + where, size, val);
+ return dw_pcie_write(pp->dbi_base + where, size, val);
}
static void dw_pcie_prog_outbound_atu(struct pcie_port *pp, int index,
@@ -376,7 +376,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
type, cpu_addr,
busdev, cfg_size);
- ret = dw_pcie_cfg_read(va_cfg_base + where, size, val);
+ ret = dw_pcie_read(va_cfg_base + where, size, val);
if (pp->num_viewport <= 2)
dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
PCIE_ATU_TYPE_IO, pp->io_mod_base,
@@ -415,7 +415,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
type, cpu_addr,
busdev, cfg_size);
- ret = dw_pcie_cfg_write(va_cfg_base + where, size, val);
+ ret = dw_pcie_write(va_cfg_base + where, size, val);
if (pp->num_viewport <= 2)
dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
PCIE_ATU_TYPE_IO, pp->io_mod_base,
diff --git a/drivers/pci/pcie-designware.h b/drivers/pci/pcie-designware.h
index 3171adfe7..fb9d2fdb6 100644
--- a/drivers/pci/pcie-designware.h
+++ b/drivers/pci/pcie-designware.h
@@ -140,8 +140,8 @@ struct pcie_host_ops {
u32 dw_pcie_readl_rc(struct pcie_port *pp, u32 reg);
void dw_pcie_writel_rc(struct pcie_port *pp, u32 reg, u32 val);
-int dw_pcie_cfg_read(void __iomem *addr, int size, u32 *val);
-int dw_pcie_cfg_write(void __iomem *addr, int size, u32 val);
+int dw_pcie_read(void __iomem *addr, int size, u32 *val);
+int dw_pcie_write(void __iomem *addr, int size, u32 val);
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);
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 35/65] PCI: dwc: designware: Get device pointer at the start of dw_pcie_host_init()
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (33 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 34/65] PCI: dwc: all: Rename cfg_read/cfg_write to read/write Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 36/65] PCI: imx6: Add local struct device pointers Andrey Smirnov
` (30 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 40f67fb2c384fe12741aa35010d62bfe8c98286c
No functional change. Get device pointer at the beginning of
dw_pcie_host_init() instead of getting it all over dw_pcie_host_init().
This is in preparation for splitting struct pcie_port into host and core
structures (once split pcie_port will not have device pointer).
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index 74769de7f..7e65b56b9 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -235,7 +235,8 @@ static u8 dw_pcie_iatu_unroll_enabled(struct pcie_port *pp)
int __init dw_pcie_host_init(struct pcie_port *pp)
{
- struct device_node *np = pp->dev->device_node;
+ struct device_d *dev = pp->dev;
+ struct device_node *np = dev->device_node;
struct of_pci_range range;
struct of_pci_range_parser parser;
struct resource *cfg_res;
@@ -249,7 +250,7 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
of_property_read_u32(np, "#address-cells", &na);
ns = of_n_size_cells(np);
- cfg_res = dev_get_resource_by_name(pp->dev, IORESOURCE_MEM, "config");
+ cfg_res = dev_get_resource_by_name(dev, IORESOURCE_MEM, "config");
if (cfg_res) {
pp->cfg0_size = resource_size(cfg_res)/2;
pp->cfg1_size = resource_size(cfg_res)/2;
@@ -262,11 +263,11 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
pp->cfg0_mod_base = of_read_number(addrp, ns);
pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
} else {
- dev_err(pp->dev, "missing *config* reg space\n");
+ dev_err(dev, "missing *config* reg space\n");
}
if (of_pci_range_parser_init(&parser, np)) {
- dev_err(pp->dev, "missing ranges property\n");
+ dev_err(dev, "missing ranges property\n");
return -EINVAL;
}
@@ -334,7 +335,7 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
if (pp->ops->host_init)
pp->ops->host_init(pp);
- pp->pci.parent = pp->dev;
+ pp->pci.parent = dev;
pp->pci.pci_ops = &dw_pcie_ops;
pp->pci.set_busno = dw_pcie_set_local_bus_nr;
pp->pci.mem_resource = &pp->mem;
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 36/65] PCI: imx6: Add local struct device pointers
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (34 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 35/65] PCI: dwc: designware: Get device pointer at the start of dw_pcie_host_init() Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 37/65] PCI: imx6: Removed unused struct imx6_pcie.mem_base Andrey Smirnov
` (29 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 13957652f7242a8cb02ffb8c96f412f62c486ee1
Use a local "struct device *dev" for brevity and consistency with other
drivers. No functional change intended.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pci-imx6.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/drivers/pci/pci-imx6.c b/drivers/pci/pci-imx6.c
index c499f4c83..0ede1abfa 100644
--- a/drivers/pci/pci-imx6.c
+++ b/drivers/pci/pci-imx6.c
@@ -401,6 +401,7 @@ static int imx6_pcie_wait_for_link(struct pcie_port *pp)
static int imx6_pcie_wait_for_speed_change(struct pcie_port *pp)
{
+ struct device_d *dev = pp->dev;
uint32_t tmp;
uint64_t start = get_time_ns();
@@ -411,7 +412,7 @@ static int imx6_pcie_wait_for_speed_change(struct pcie_port *pp)
return 0;
}
- dev_err(pp->dev, "Speed change timeout\n");
+ dev_err(dev, "Speed change timeout\n");
return -EINVAL;
}
@@ -419,6 +420,7 @@ static int imx6_pcie_wait_for_speed_change(struct pcie_port *pp)
static int imx6_pcie_establish_link(struct pcie_port *pp)
{
struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
+ struct device_d *dev = pp->dev;
uint32_t tmp;
int ret;
u32 gpr12;
@@ -440,7 +442,7 @@ static int imx6_pcie_establish_link(struct pcie_port *pp)
ret = imx6_pcie_wait_for_link(pp);
if (ret) {
- dev_info(pp->dev, "Link never came up\n");
+ dev_info(dev, "Link never came up\n");
goto err_reset_phy;
}
@@ -460,24 +462,24 @@ static int imx6_pcie_establish_link(struct pcie_port *pp)
ret = imx6_pcie_wait_for_speed_change(pp);
if (ret) {
- dev_err(pp->dev, "Failed to bring link up!\n");
+ dev_err(dev, "Failed to bring link up!\n");
goto err_reset_phy;
}
/* Make sure link training is finished as well! */
ret = imx6_pcie_wait_for_link(pp);
if (ret) {
- dev_err(pp->dev, "Failed to bring link up!\n");
+ dev_err(dev, "Failed to bring link up!\n");
goto err_reset_phy;
}
tmp = readl(pp->dbi_base + PCIE_RC_LCSR);
- dev_dbg(pp->dev, "Link up, Gen=%i\n", (tmp >> 16) & 0xf);
+ dev_dbg(dev, "Link up, Gen=%i\n", (tmp >> 16) & 0xf);
return 0;
err_reset_phy:
- dev_dbg(pp->dev, "PHY DEBUG_R0=0x%08x DEBUG_R1=0x%08x\n",
+ dev_dbg(dev, "PHY DEBUG_R0=0x%08x DEBUG_R1=0x%08x\n",
readl(pp->dbi_base + PCIE_PHY_DEBUG_R0),
readl(pp->dbi_base + PCIE_PHY_DEBUG_R1));
imx6_pcie_reset_phy(pp);
@@ -500,6 +502,7 @@ static void imx6_pcie_host_init(struct pcie_port *pp)
static int imx6_pcie_link_up(struct pcie_port *pp)
{
+ struct device_d *dev = pp->dev;
u32 rc;
int count = 5;
@@ -527,7 +530,7 @@ static int imx6_pcie_link_up(struct pcie_port *pp)
return 1;
if (!count--)
break;
- dev_dbg(pp->dev, "Link is up, but still in training\n");
+ dev_dbg(dev, "Link is up, but still in training\n");
/*
* Wait a little bit, then re-check if the link finished
* the training.
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 37/65] PCI: imx6: Removed unused struct imx6_pcie.mem_base
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (35 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 36/65] PCI: imx6: Add local struct device pointers Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 38/65] PCI: imx6: Pass struct imx6_pcie to PHY accessors Andrey Smirnov
` (28 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 51c84709b8c4065fe83b84a487fe7822c2271e77
PCI: imx6: Removed unused struct imx6_pcie.mem_base
Removed the unused struct imx6_pcie.mem_base member. No functional change
intended.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pci-imx6.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/pci/pci-imx6.c b/drivers/pci/pci-imx6.c
index 0ede1abfa..a3658844c 100644
--- a/drivers/pci/pci-imx6.c
+++ b/drivers/pci/pci-imx6.c
@@ -50,7 +50,6 @@ struct imx6_pcie {
struct pcie_port pp;
void __iomem *iomuxc_gpr;
enum imx6_pcie_variants variant;
- void __iomem *mem_base;
u32 tx_deemph_gen1;
u32 tx_deemph_gen2_3p5db;
u32 tx_deemph_gen2_6db;
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 38/65] PCI: imx6: Pass struct imx6_pcie to PHY accessors
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (36 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 37/65] PCI: imx6: Removed unused struct imx6_pcie.mem_base Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:18 ` [PATCH v2 39/65] PCI: imx6: Pass device-specific struct to internal functions Andrey Smirnov
` (27 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 8bad7f2fc3006d1752c426343ca77f1fbe61cf00
Pass the struct imx6_pcie pointer, not dbi_base address, to PHY accessors.
This enables future simplifications. No functional change intended.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pci-imx6.c | 41 +++++++++++++++++++++++------------------
1 file changed, 23 insertions(+), 18 deletions(-)
diff --git a/drivers/pci/pci-imx6.c b/drivers/pci/pci-imx6.c
index a3658844c..8b78f3ec1 100644
--- a/drivers/pci/pci-imx6.c
+++ b/drivers/pci/pci-imx6.c
@@ -94,8 +94,9 @@ struct imx6_pcie {
#define PHY_RX_OVRD_IN_LO_RX_DATA_EN (1 << 5)
#define PHY_RX_OVRD_IN_LO_RX_PLL_EN (1 << 3)
-static int pcie_phy_poll_ack(void __iomem *dbi_base, int exp_val)
+static int pcie_phy_poll_ack(struct imx6_pcie *imx6_pcie, int exp_val)
{
+ void __iomem *dbi_base = imx6_pcie->pp.dbi_base;
u32 val;
u32 max_iterations = 10;
u32 wait_counter = 0;
@@ -114,8 +115,9 @@ static int pcie_phy_poll_ack(void __iomem *dbi_base, int exp_val)
return -ETIMEDOUT;
}
-static int pcie_phy_wait_ack(void __iomem *dbi_base, int addr)
+static int pcie_phy_wait_ack(struct imx6_pcie *imx6_pcie, int addr)
{
+ void __iomem *dbi_base = imx6_pcie->pp.dbi_base;
u32 val;
int ret;
@@ -125,23 +127,24 @@ static int pcie_phy_wait_ack(void __iomem *dbi_base, int addr)
val |= (0x1 << PCIE_PHY_CTRL_CAP_ADR_LOC);
writel(val, dbi_base + PCIE_PHY_CTRL);
- ret = pcie_phy_poll_ack(dbi_base, 1);
+ ret = pcie_phy_poll_ack(imx6_pcie, 1);
if (ret)
return ret;
val = addr << PCIE_PHY_CTRL_DATA_LOC;
writel(val, dbi_base + PCIE_PHY_CTRL);
- return pcie_phy_poll_ack(dbi_base, 0);
+ return pcie_phy_poll_ack(imx6_pcie, 0);
}
/* Read from the 16-bit PCIe PHY control registers (not memory-mapped) */
-static int pcie_phy_read(void __iomem *dbi_base, int addr , int *data)
+static int pcie_phy_read(struct imx6_pcie *imx6_pcie, int addr , int *data)
{
+ void __iomem *dbi_base = imx6_pcie->pp.dbi_base;
u32 val, phy_ctl;
int ret;
- ret = pcie_phy_wait_ack(dbi_base, addr);
+ ret = pcie_phy_wait_ack(imx6_pcie, addr);
if (ret)
return ret;
@@ -149,7 +152,7 @@ static int pcie_phy_read(void __iomem *dbi_base, int addr , int *data)
phy_ctl = 0x1 << PCIE_PHY_CTRL_RD_LOC;
writel(phy_ctl, dbi_base + PCIE_PHY_CTRL);
- ret = pcie_phy_poll_ack(dbi_base, 1);
+ ret = pcie_phy_poll_ack(imx6_pcie, 1);
if (ret)
return ret;
@@ -159,17 +162,18 @@ static int pcie_phy_read(void __iomem *dbi_base, int addr , int *data)
/* deassert Read signal */
writel(0x00, dbi_base + PCIE_PHY_CTRL);
- return pcie_phy_poll_ack(dbi_base, 0);
+ return pcie_phy_poll_ack(imx6_pcie, 0);
}
-static int pcie_phy_write(void __iomem *dbi_base, int addr, int data)
+static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data)
{
+ void __iomem *dbi_base = imx6_pcie->pp.dbi_base;
u32 var;
int ret;
/* write addr */
/* cap addr */
- ret = pcie_phy_wait_ack(dbi_base, addr);
+ ret = pcie_phy_wait_ack(imx6_pcie, addr);
if (ret)
return ret;
@@ -180,7 +184,7 @@ static int pcie_phy_write(void __iomem *dbi_base, int addr, int data)
var |= (0x1 << PCIE_PHY_CTRL_CAP_DAT_LOC);
writel(var, dbi_base + PCIE_PHY_CTRL);
- ret = pcie_phy_poll_ack(dbi_base, 1);
+ ret = pcie_phy_poll_ack(imx6_pcie, 1);
if (ret)
return ret;
@@ -189,7 +193,7 @@ static int pcie_phy_write(void __iomem *dbi_base, int addr, int data)
writel(var, dbi_base + PCIE_PHY_CTRL);
/* wait for ack de-assertion */
- ret = pcie_phy_poll_ack(dbi_base, 0);
+ ret = pcie_phy_poll_ack(imx6_pcie, 0);
if (ret)
return ret;
@@ -198,7 +202,7 @@ static int pcie_phy_write(void __iomem *dbi_base, int addr, int data)
writel(var, dbi_base + PCIE_PHY_CTRL);
/* wait for ack */
- ret = pcie_phy_poll_ack(dbi_base, 1);
+ ret = pcie_phy_poll_ack(imx6_pcie, 1);
if (ret)
return ret;
@@ -207,7 +211,7 @@ static int pcie_phy_write(void __iomem *dbi_base, int addr, int data)
writel(var, dbi_base + PCIE_PHY_CTRL);
/* wait for ack de-assertion */
- ret = pcie_phy_poll_ack(dbi_base, 0);
+ ret = pcie_phy_poll_ack(imx6_pcie, 0);
if (ret)
return ret;
@@ -218,19 +222,20 @@ static int pcie_phy_write(void __iomem *dbi_base, int addr, int data)
static void imx6_pcie_reset_phy(struct pcie_port *pp)
{
+ struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
uint32_t temp;
- pcie_phy_read(pp->dbi_base, PHY_RX_OVRD_IN_LO, &temp);
+ pcie_phy_read(imx6_pcie, PHY_RX_OVRD_IN_LO, &temp);
temp |= (PHY_RX_OVRD_IN_LO_RX_DATA_EN |
PHY_RX_OVRD_IN_LO_RX_PLL_EN);
- pcie_phy_write(pp->dbi_base, PHY_RX_OVRD_IN_LO, temp);
+ pcie_phy_write(imx6_pcie, PHY_RX_OVRD_IN_LO, temp);
udelay(2000);
- pcie_phy_read(pp->dbi_base, PHY_RX_OVRD_IN_LO, &temp);
+ pcie_phy_read(imx6_pcie, PHY_RX_OVRD_IN_LO, &temp);
temp &= ~(PHY_RX_OVRD_IN_LO_RX_DATA_EN |
PHY_RX_OVRD_IN_LO_RX_PLL_EN);
- pcie_phy_write(pp->dbi_base, PHY_RX_OVRD_IN_LO, temp);
+ pcie_phy_write(imx6_pcie, PHY_RX_OVRD_IN_LO, temp);
}
static int imx6_pcie_assert_core_reset(struct pcie_port *pp)
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 39/65] PCI: imx6: Pass device-specific struct to internal functions
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (37 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 38/65] PCI: imx6: Pass struct imx6_pcie to PHY accessors Andrey Smirnov
@ 2018-12-17 5:18 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 40/65] PCI: imx6: Use generic DesignWare accessors Andrey Smirnov
` (26 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:18 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit e7d7705ace9494949863848ec77536d5a3287b0a
Only interfaces used from outside the driver, e.g., those called by
the DesignWare core, need to accept pointers to the generic struct
pcie_port. Internal interfaces can accept pointers to the
device-specific struct, which makes them more straightforward. No
functional change intended.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pci-imx6.c | 53 ++++++++++++++++++++----------------------
1 file changed, 25 insertions(+), 28 deletions(-)
diff --git a/drivers/pci/pci-imx6.c b/drivers/pci/pci-imx6.c
index 8b78f3ec1..4692dab5b 100644
--- a/drivers/pci/pci-imx6.c
+++ b/drivers/pci/pci-imx6.c
@@ -220,9 +220,8 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data)
return 0;
}
-static void imx6_pcie_reset_phy(struct pcie_port *pp)
+static void imx6_pcie_reset_phy(struct imx6_pcie *imx6_pcie)
{
- struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
uint32_t temp;
pcie_phy_read(imx6_pcie, PHY_RX_OVRD_IN_LO, &temp);
@@ -238,9 +237,9 @@ static void imx6_pcie_reset_phy(struct pcie_port *pp)
pcie_phy_write(imx6_pcie, PHY_RX_OVRD_IN_LO, temp);
}
-static int imx6_pcie_assert_core_reset(struct pcie_port *pp)
+static int imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
{
- struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
+ struct pcie_port *pp = &imx6_pcie->pp;
u32 val, gpr1, gpr12;
switch (imx6_pcie->variant) {
@@ -289,9 +288,8 @@ static int imx6_pcie_assert_core_reset(struct pcie_port *pp)
return 0;
}
-static int imx6_pcie_deassert_core_reset(struct pcie_port *pp)
+static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
{
- struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
int ret;
u32 gpr1;
@@ -358,9 +356,8 @@ err_pcie_phy:
}
-static void imx6_pcie_init_phy(struct pcie_port *pp)
+static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)
{
- struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
u32 gpr12, gpr8;
gpr12 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR12);
@@ -398,13 +395,14 @@ static void imx6_pcie_init_phy(struct pcie_port *pp)
writel(gpr8, imx6_pcie->iomuxc_gpr + IOMUXC_GPR8);
}
-static int imx6_pcie_wait_for_link(struct pcie_port *pp)
+static int imx6_pcie_wait_for_link(struct imx6_pcie *imx6_pcie)
{
- return dw_pcie_wait_for_link(pp);
+ return dw_pcie_wait_for_link(&imx6_pcie->pp);
}
-static int imx6_pcie_wait_for_speed_change(struct pcie_port *pp)
+static int imx6_pcie_wait_for_speed_change(struct imx6_pcie *imx6_pcie)
{
+ struct pcie_port *pp = &imx6_pcie->pp;
struct device_d *dev = pp->dev;
uint32_t tmp;
uint64_t start = get_time_ns();
@@ -421,9 +419,9 @@ static int imx6_pcie_wait_for_speed_change(struct pcie_port *pp)
}
-static int imx6_pcie_establish_link(struct pcie_port *pp)
+static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
{
- struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
+ struct pcie_port *pp = &imx6_pcie->pp;
struct device_d *dev = pp->dev;
uint32_t tmp;
int ret;
@@ -444,7 +442,7 @@ static int imx6_pcie_establish_link(struct pcie_port *pp)
gpr12 |= IMX6Q_GPR12_PCIE_CTL_2;
writel(gpr12, imx6_pcie->iomuxc_gpr + IOMUXC_GPR12);
- ret = imx6_pcie_wait_for_link(pp);
+ ret = imx6_pcie_wait_for_link(imx6_pcie);
if (ret) {
dev_info(dev, "Link never came up\n");
goto err_reset_phy;
@@ -464,14 +462,14 @@ static int imx6_pcie_establish_link(struct pcie_port *pp)
tmp |= PORT_LOGIC_SPEED_CHANGE;
writel(tmp, pp->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
- ret = imx6_pcie_wait_for_speed_change(pp);
+ ret = imx6_pcie_wait_for_speed_change(imx6_pcie);
if (ret) {
dev_err(dev, "Failed to bring link up!\n");
goto err_reset_phy;
}
/* Make sure link training is finished as well! */
- ret = imx6_pcie_wait_for_link(pp);
+ ret = imx6_pcie_wait_for_link(imx6_pcie);
if (ret) {
dev_err(dev, "Failed to bring link up!\n");
goto err_reset_phy;
@@ -486,22 +484,20 @@ err_reset_phy:
dev_dbg(dev, "PHY DEBUG_R0=0x%08x DEBUG_R1=0x%08x\n",
readl(pp->dbi_base + PCIE_PHY_DEBUG_R0),
readl(pp->dbi_base + PCIE_PHY_DEBUG_R1));
- imx6_pcie_reset_phy(pp);
+ imx6_pcie_reset_phy(imx6_pcie);
return ret;
}
static void imx6_pcie_host_init(struct pcie_port *pp)
{
- imx6_pcie_assert_core_reset(pp);
-
- imx6_pcie_init_phy(pp);
-
- imx6_pcie_deassert_core_reset(pp);
+ struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
+ imx6_pcie_assert_core_reset(imx6_pcie);
+ imx6_pcie_init_phy(imx6_pcie);
+ imx6_pcie_deassert_core_reset(imx6_pcie);
dw_pcie_setup_rc(pp);
-
- imx6_pcie_establish_link(pp);
+ imx6_pcie_establish_link(imx6_pcie);
}
static int imx6_pcie_link_up(struct pcie_port *pp)
@@ -550,9 +546,10 @@ static struct pcie_host_ops imx6_pcie_host_ops = {
.host_init = imx6_pcie_host_init,
};
-static int __init imx6_add_pcie_port(struct pcie_port *pp,
- struct device_d *dev)
+static int __init imx6_add_pcie_port(struct imx6_pcie *imx6_pcie,
+ struct device_d *dev)
{
+ struct pcie_port *pp = &imx6_pcie->pp;
int ret;
pp->root_bus_nr = -1;
@@ -642,7 +639,7 @@ static int __init imx6_pcie_probe(struct device_d *dev)
&imx6_pcie->tx_swing_low))
imx6_pcie->tx_swing_low = 127;
- ret = imx6_add_pcie_port(pp, dev);
+ ret = imx6_add_pcie_port(imx6_pcie, dev);
if (ret < 0)
return ret;
@@ -655,7 +652,7 @@ static void imx6_pcie_remove(struct device_d *dev)
{
struct imx6_pcie *imx6_pcie = dev->priv;
- imx6_pcie_assert_core_reset(&imx6_pcie->pp);
+ imx6_pcie_assert_core_reset(imx6_pcie);
}
static struct of_device_id imx6_pcie_of_match[] = {
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 40/65] PCI: imx6: Use generic DesignWare accessors
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (38 preceding siblings ...)
2018-12-17 5:18 ` [PATCH v2 39/65] PCI: imx6: Pass device-specific struct to internal functions Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 41/65] PCI: imx6: Reorder struct imx6_pcie Andrey Smirnov
` (25 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 2a6a85d5368e55e506abd7ca79f08131028bb0bc
The dw_pcie_readl_rc() and dw_pcie_writel_rc() interfaces already add in
pp->dbi_base, so use those instead of doing it ourselves in the imx6
driver. No functional change intended.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pci-imx6.c | 96 +++++++++++++-----------------------------
1 file changed, 30 insertions(+), 66 deletions(-)
diff --git a/drivers/pci/pci-imx6.c b/drivers/pci/pci-imx6.c
index 4692dab5b..f3e9ea31b 100644
--- a/drivers/pci/pci-imx6.c
+++ b/drivers/pci/pci-imx6.c
@@ -96,13 +96,13 @@ struct imx6_pcie {
static int pcie_phy_poll_ack(struct imx6_pcie *imx6_pcie, int exp_val)
{
- void __iomem *dbi_base = imx6_pcie->pp.dbi_base;
+ struct pcie_port *pp = &imx6_pcie->pp;
u32 val;
u32 max_iterations = 10;
u32 wait_counter = 0;
do {
- val = readl(dbi_base + PCIE_PHY_STAT);
+ val = dw_pcie_readl_rc(pp, PCIE_PHY_STAT);
val = (val >> PCIE_PHY_STAT_ACK_LOC) & 0x1;
wait_counter++;
@@ -117,22 +117,21 @@ static int pcie_phy_poll_ack(struct imx6_pcie *imx6_pcie, int exp_val)
static int pcie_phy_wait_ack(struct imx6_pcie *imx6_pcie, int addr)
{
- void __iomem *dbi_base = imx6_pcie->pp.dbi_base;
+ struct pcie_port *pp = &imx6_pcie->pp;
u32 val;
int ret;
val = addr << PCIE_PHY_CTRL_DATA_LOC;
- writel(val, dbi_base + PCIE_PHY_CTRL);
val |= (0x1 << PCIE_PHY_CTRL_CAP_ADR_LOC);
- writel(val, dbi_base + PCIE_PHY_CTRL);
+ dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, val);
ret = pcie_phy_poll_ack(imx6_pcie, 1);
if (ret)
return ret;
val = addr << PCIE_PHY_CTRL_DATA_LOC;
- writel(val, dbi_base + PCIE_PHY_CTRL);
+ dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, val);
return pcie_phy_poll_ack(imx6_pcie, 0);
}
@@ -140,7 +139,7 @@ static int pcie_phy_wait_ack(struct imx6_pcie *imx6_pcie, int addr)
/* Read from the 16-bit PCIe PHY control registers (not memory-mapped) */
static int pcie_phy_read(struct imx6_pcie *imx6_pcie, int addr , int *data)
{
- void __iomem *dbi_base = imx6_pcie->pp.dbi_base;
+ struct pcie_port *pp = &imx6_pcie->pp;
u32 val, phy_ctl;
int ret;
@@ -150,24 +149,24 @@ static int pcie_phy_read(struct imx6_pcie *imx6_pcie, int addr , int *data)
/* assert Read signal */
phy_ctl = 0x1 << PCIE_PHY_CTRL_RD_LOC;
- writel(phy_ctl, dbi_base + PCIE_PHY_CTRL);
+ dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, phy_ctl);
ret = pcie_phy_poll_ack(imx6_pcie, 1);
if (ret)
return ret;
- val = readl(dbi_base + PCIE_PHY_STAT);
+ val = dw_pcie_readl_rc(pp, PCIE_PHY_STAT);
*data = val & 0xffff;
/* deassert Read signal */
- writel(0x00, dbi_base + PCIE_PHY_CTRL);
+ dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, 0x00);
return pcie_phy_poll_ack(imx6_pcie, 0);
}
static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data)
{
- void __iomem *dbi_base = imx6_pcie->pp.dbi_base;
+ struct pcie_port *pp = &imx6_pcie->pp;
u32 var;
int ret;
@@ -178,11 +177,11 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data)
return ret;
var = data << PCIE_PHY_CTRL_DATA_LOC;
- writel(var, dbi_base + PCIE_PHY_CTRL);
+ dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, var);
/* capture data */
var |= (0x1 << PCIE_PHY_CTRL_CAP_DAT_LOC);
- writel(var, dbi_base + PCIE_PHY_CTRL);
+ dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, var);
ret = pcie_phy_poll_ack(imx6_pcie, 1);
if (ret)
@@ -190,7 +189,7 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data)
/* deassert cap data */
var = data << PCIE_PHY_CTRL_DATA_LOC;
- writel(var, dbi_base + PCIE_PHY_CTRL);
+ dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, var);
/* wait for ack de-assertion */
ret = pcie_phy_poll_ack(imx6_pcie, 0);
@@ -199,7 +198,7 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data)
/* assert wr signal */
var = 0x1 << PCIE_PHY_CTRL_WR_LOC;
- writel(var, dbi_base + PCIE_PHY_CTRL);
+ dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, var);
/* wait for ack */
ret = pcie_phy_poll_ack(imx6_pcie, 1);
@@ -208,14 +207,14 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data)
/* deassert wr signal */
var = data << PCIE_PHY_CTRL_DATA_LOC;
- writel(var, dbi_base + PCIE_PHY_CTRL);
+ dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, var);
/* wait for ack de-assertion */
ret = pcie_phy_poll_ack(imx6_pcie, 0);
if (ret)
return ret;
- writel(0x0, dbi_base + PCIE_PHY_CTRL);
+ dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, 0x0);
return 0;
}
@@ -265,12 +264,12 @@ static int imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
if ((gpr1 & IMX6Q_GPR1_PCIE_REF_CLK_EN) &&
(gpr12 & IMX6Q_GPR12_PCIE_CTL_2)) {
- val = readl(pp->dbi_base + PCIE_PL_PFLR);
+ val = dw_pcie_readl_rc(pp, PCIE_PL_PFLR);
val &= ~PCIE_PL_PFLR_LINK_STATE_MASK;
val |= PCIE_PL_PFLR_FORCE_LINK;
data_abort_mask();
- writel(val, pp->dbi_base + PCIE_PL_PFLR);
+ dw_pcie_writel_rc(pp, PCIE_PL_PFLR, val);
data_abort_unmask();
gpr12 &= ~IMX6Q_GPR12_PCIE_CTL_2;
@@ -408,7 +407,7 @@ static int imx6_pcie_wait_for_speed_change(struct imx6_pcie *imx6_pcie)
uint64_t start = get_time_ns();
while (!is_timeout(start, SECOND)) {
- tmp = readl(pp->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
+ tmp = dw_pcie_readl_rc(pp, PCIE_LINK_WIDTH_SPEED_CONTROL);
/* Test if the speed change finished. */
if (!(tmp & PORT_LOGIC_SPEED_CHANGE))
return 0;
@@ -432,10 +431,10 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
* started in Gen2 mode, there is a possibility the devices on the
* bus will not be detected at all. This happens with PCIe switches.
*/
- tmp = readl(pp->dbi_base + PCIE_RC_LCR);
+ tmp = dw_pcie_readl_rc(pp, PCIE_RC_LCR);
tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1;
- writel(tmp, pp->dbi_base + PCIE_RC_LCR);
+ dw_pcie_writel_rc(pp, PCIE_RC_LCR, tmp);
/* Start LTSSM. */
gpr12 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR12);
@@ -449,18 +448,18 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
}
/* Allow Gen2 mode after the link is up. */
- tmp = readl(pp->dbi_base + PCIE_RC_LCR);
+ tmp = dw_pcie_readl_rc(pp, PCIE_RC_LCR);
tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2;
- writel(tmp, pp->dbi_base + PCIE_RC_LCR);
+ dw_pcie_writel_rc(pp, PCIE_RC_LCR, tmp);
/*
* Start Directed Speed Change so the best possible speed both link
* partners support can be negotiated.
*/
- tmp = readl(pp->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
+ tmp = dw_pcie_readl_rc(pp, PCIE_LINK_WIDTH_SPEED_CONTROL);
tmp |= PORT_LOGIC_SPEED_CHANGE;
- writel(tmp, pp->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
+ dw_pcie_writel_rc(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, tmp);
ret = imx6_pcie_wait_for_speed_change(imx6_pcie);
if (ret) {
@@ -475,15 +474,15 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
goto err_reset_phy;
}
- tmp = readl(pp->dbi_base + PCIE_RC_LCSR);
+ tmp = dw_pcie_readl_rc(pp, PCIE_RC_LCSR);
dev_dbg(dev, "Link up, Gen=%i\n", (tmp >> 16) & 0xf);
return 0;
err_reset_phy:
dev_dbg(dev, "PHY DEBUG_R0=0x%08x DEBUG_R1=0x%08x\n",
- readl(pp->dbi_base + PCIE_PHY_DEBUG_R0),
- readl(pp->dbi_base + PCIE_PHY_DEBUG_R1));
+ dw_pcie_readl_rc(pp, PCIE_PHY_DEBUG_R0),
+ dw_pcie_readl_rc(pp, PCIE_PHY_DEBUG_R1));
imx6_pcie_reset_phy(imx6_pcie);
return ret;
@@ -502,43 +501,8 @@ static void imx6_pcie_host_init(struct pcie_port *pp)
static int imx6_pcie_link_up(struct pcie_port *pp)
{
- struct device_d *dev = pp->dev;
- u32 rc;
- int count = 5;
-
- /*
- * Test if the PHY reports that the link is up and also that the LTSSM
- * training finished. There are three possible states of the link when
- * this code is called:
- * 1) The link is DOWN (unlikely)
- * The link didn't come up yet for some reason. This usually means
- * we have a real problem somewhere. Reset the PHY and exit. This
- * state calls for inspection of the DEBUG registers.
- * 2) The link is UP, but still in LTSSM training
- * Wait for the training to finish, which should take a very short
- * time. If the training does not finish, we have a problem and we
- * need to inspect the DEBUG registers. If the training does finish,
- * the link is up and operating correctly.
- * 3) The link is UP and no longer in LTSSM training
- * The link is up and operating correctly.
- */
- while (1) {
- rc = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1);
- if (!(rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_UP))
- break;
- if (!(rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING))
- return 1;
- if (!count--)
- break;
- dev_dbg(dev, "Link is up, but still in training\n");
- /*
- * Wait a little bit, then re-check if the link finished
- * the training.
- */
- udelay(1000);
- }
-
- return 0;
+ return dw_pcie_readl_rc(pp, PCIE_PHY_DEBUG_R1) &
+ PCIE_PHY_DEBUG_R1_XMLH_LINK_UP;
}
static struct pcie_host_ops imx6_pcie_host_ops = {
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 41/65] PCI: imx6: Reorder struct imx6_pcie
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (39 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 40/65] PCI: imx6: Use generic DesignWare accessors Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 42/65] PCI: imx6: Port error messages for imx6_pcie_deassert_core_reset() Andrey Smirnov
` (24 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 916bf1cc6528618197cdaf05ad42a9a82e9dea04
Reorder struct imx6_pcie to put generic fields first. No functional change
intended.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pci-imx6.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pci/pci-imx6.c b/drivers/pci/pci-imx6.c
index f3e9ea31b..baa07447e 100644
--- a/drivers/pci/pci-imx6.c
+++ b/drivers/pci/pci-imx6.c
@@ -43,11 +43,11 @@ enum imx6_pcie_variants {
};
struct imx6_pcie {
+ struct pcie_port pp; /* pp.dbi_base is DT 0th resource */
int reset_gpio;
struct clk *pcie_bus;
struct clk *pcie_phy;
struct clk *pcie;
- struct pcie_port pp;
void __iomem *iomuxc_gpr;
enum imx6_pcie_variants variant;
u32 tx_deemph_gen1;
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 42/65] PCI: imx6: Port error messages for imx6_pcie_deassert_core_reset()
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (40 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 41/65] PCI: imx6: Reorder struct imx6_pcie Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 43/65] PCI: imx6: Remove unused return values Andrey Smirnov
` (23 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pci-imx6.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/pci-imx6.c b/drivers/pci/pci-imx6.c
index baa07447e..8e7bae258 100644
--- a/drivers/pci/pci-imx6.c
+++ b/drivers/pci/pci-imx6.c
@@ -289,20 +289,27 @@ static int imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
{
+ struct device_d *dev = imx6_pcie->pp.dev;
int ret;
u32 gpr1;
ret = clk_enable(imx6_pcie->pcie_phy);
- if (ret)
+ if (ret) {
+ dev_err(dev, "unable to enable pcie_phy clock\n");
goto err_pcie_phy;
+ }
ret = clk_enable(imx6_pcie->pcie_bus);
- if (ret)
+ if (ret) {
+ dev_err(dev, "unable to enable pcie_bus clock\n");
goto err_pcie_bus;
+ }
ret = clk_enable(imx6_pcie->pcie);
- if (ret)
+ if (ret) {
+ dev_err(dev, "unable to enable pcie clock\n");
goto err_pcie;
+ }
/* power up core phy and enable ref clock */
gpr1 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 43/65] PCI: imx6: Remove unused return values
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (41 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 42/65] PCI: imx6: Port error messages for imx6_pcie_deassert_core_reset() Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 44/65] PCI: imx6: Factor out ref clock enable Andrey Smirnov
` (22 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 9ab021b6cf8b5bfc40ea9333c9b64b554fe01cd4
Remove unused return values. No functional change intended.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pci-imx6.c | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/drivers/pci/pci-imx6.c b/drivers/pci/pci-imx6.c
index 8e7bae258..fa62aa3a4 100644
--- a/drivers/pci/pci-imx6.c
+++ b/drivers/pci/pci-imx6.c
@@ -236,7 +236,7 @@ static void imx6_pcie_reset_phy(struct imx6_pcie *imx6_pcie)
pcie_phy_write(imx6_pcie, PHY_RX_OVRD_IN_LO, temp);
}
-static int imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
+static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
{
struct pcie_port *pp = &imx6_pcie->pp;
u32 val, gpr1, gpr12;
@@ -283,11 +283,9 @@ static int imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
writel(gpr1, imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
break;
}
-
- return 0;
}
-static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
+static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
{
struct device_d *dev = imx6_pcie->pp.dev;
int ret;
@@ -296,7 +294,7 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
ret = clk_enable(imx6_pcie->pcie_phy);
if (ret) {
dev_err(dev, "unable to enable pcie_phy clock\n");
- goto err_pcie_phy;
+ return;
}
ret = clk_enable(imx6_pcie->pcie_bus);
@@ -351,15 +349,12 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
break;
}
- return 0;
+ return;
err_pcie:
clk_disable(imx6_pcie->pcie_bus);
err_pcie_bus:
clk_disable(imx6_pcie->pcie_phy);
-err_pcie_phy:
- return ret;
-
}
static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 44/65] PCI: imx6: Factor out ref clock enable
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (42 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 43/65] PCI: imx6: Remove unused return values Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 45/65] PCI: imx6: Add DT property for link gen, default to Gen1 Andrey Smirnov
` (21 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 4d1821e729b5d2060ef8c9825af1dacc2182da38
Factor out ref clock enable to make it cleaner to add imx6sx support. No
functional change intended.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Christoph Fritz <chf.fritz@googlemail.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pci-imx6.c | 43 ++++++++++++++++++++++++++++--------------
1 file changed, 29 insertions(+), 14 deletions(-)
diff --git a/drivers/pci/pci-imx6.c b/drivers/pci/pci-imx6.c
index fa62aa3a4..447bb72ad 100644
--- a/drivers/pci/pci-imx6.c
+++ b/drivers/pci/pci-imx6.c
@@ -285,6 +285,28 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
}
}
+static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
+{
+ u32 gpr1;
+
+ /* power up core phy and enable ref clock */
+ gpr1 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
+ gpr1 &= ~IMX6Q_GPR1_PCIE_TEST_PD;
+ writel(gpr1, imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
+ /*
+ * the async reset input need ref clock to sync internally,
+ * when the ref clock comes after reset, internal synced
+ * reset time is too short, cannot meet the requirement.
+ * add one ~10us delay here.
+ */
+ udelay(10);
+ gpr1 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
+ gpr1 |= IMX6Q_GPR1_PCIE_REF_CLK_EN;
+ writel(gpr1, imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
+
+ return 0;
+}
+
static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
{
struct device_d *dev = imx6_pcie->pp.dev;
@@ -309,20 +331,11 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
goto err_pcie;
}
- /* power up core phy and enable ref clock */
- gpr1 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
- gpr1 &= ~IMX6Q_GPR1_PCIE_TEST_PD;
- writel(gpr1, imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
- /*
- * the async reset input need ref clock to sync internally,
- * when the ref clock comes after reset, internal synced
- * reset time is too short, cannot meet the requirement.
- * add one ~10us delay here.
- */
- udelay(10);
- gpr1 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
- gpr1 |= IMX6Q_GPR1_PCIE_REF_CLK_EN;
- writel(gpr1, imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
+ ret = imx6_pcie_enable_ref_clk(imx6_pcie);
+ if (ret) {
+ dev_err(dev, "unable to enable pcie ref clock\n");
+ goto err_ref_clk;
+ }
/* allow the clocks to stabilize */
udelay(200);
@@ -351,6 +364,8 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
return;
+err_ref_clk:
+ clk_disable(imx6_pcie->pcie);
err_pcie:
clk_disable(imx6_pcie->pcie_bus);
err_pcie_bus:
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 45/65] PCI: imx6: Add DT property for link gen, default to Gen1
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (43 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 44/65] PCI: imx6: Factor out ref clock enable Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 46/65] PCI: imx6: Remove redundant "Link never came up" message Andrey Smirnov
` (20 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit a5fcec480f25eb5444c0b71ecdf9b18b09236b95
Freescale has stated [1] that the LVDS clock source of the IMX6 does not
pass the PCI Gen2 clock jitter test, therefore unless an external Gen2
compliant external clock source is present and supplied back to the IMX6
PCIe core via LVDS CLK1/CLK2 you can not claim Gen2 compliance.
Add a DT property to specify Gen1 vs Gen2 and check this before allowing a
Gen2 link.
We default to Gen1 if the property is not present because at this time
there are no IMX6 boards in mainline that 'input' a clock on LVDS
CLK1/CLK2.
In order to be Gen2 compliant on IMX6 you need to:
- Have a Gen2 compliant external clock generator and route that clock back
to either LVDS CLK1 or LVDS CLK2 as an input (see IMX6SX-SabreSD
reference design).
- Specify this clock in the PCIe node in the DT (i.e.,
IMX6QDL_CLK_LVDS1_IN or IMX6QDL_CLK_LVDS2_IN instead of
IMX6QDL_CLK_LVDS1_GATE which configures it as a CLK output).
[1] https://community.freescale.com/message/453209
Signed-off-by: Tim Harvey <tharvey@gateworks.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
CC: Fabio Estevam <fabio.estevam@freescale.com>
CC: Zhu Richard <Richard.Zhu@freescale.com>
CC: Akshay Bhat <akshay.bhat@timesys.com>
CC: Rob Herring <robh+dt@kernel.org>
CC: Shawn Guo <shawnguo@kernel.org>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pci-imx6.c | 25 ++++++++++++++++++-------
1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/drivers/pci/pci-imx6.c b/drivers/pci/pci-imx6.c
index 447bb72ad..d72abe3a3 100644
--- a/drivers/pci/pci-imx6.c
+++ b/drivers/pci/pci-imx6.c
@@ -55,6 +55,7 @@ struct imx6_pcie {
u32 tx_deemph_gen2_6db;
u32 tx_swing_full;
u32 tx_swing_low;
+ int link_gen;
};
/* PCIe Root Complex registers (memory-mapped) */
@@ -464,11 +465,16 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
goto err_reset_phy;
}
- /* Allow Gen2 mode after the link is up. */
- tmp = dw_pcie_readl_rc(pp, PCIE_RC_LCR);
- tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
- tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2;
- dw_pcie_writel_rc(pp, PCIE_RC_LCR, tmp);
+
+ if (imx6_pcie->link_gen == 2) {
+ /* Allow Gen2 mode after the link is up. */
+ tmp = dw_pcie_readl_rc(pp, PCIE_RC_LCR);
+ tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
+ tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2;
+ dw_pcie_writel_rc(pp, PCIE_RC_LCR, tmp);
+ } else {
+ dev_info(dev, "Link: Gen2 disabled\n");
+ }
/*
* Start Directed Speed Change so the best possible speed both link
@@ -492,8 +498,7 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
}
tmp = dw_pcie_readl_rc(pp, PCIE_RC_LCSR);
- dev_dbg(dev, "Link up, Gen=%i\n", (tmp >> 16) & 0xf);
-
+ dev_info(dev, "Link up, Gen%i\n", (tmp >> 16) & 0xf);
return 0;
err_reset_phy:
@@ -620,6 +625,12 @@ static int __init imx6_pcie_probe(struct device_d *dev)
&imx6_pcie->tx_swing_low))
imx6_pcie->tx_swing_low = 127;
+ /* Limit link speed */
+ ret = of_property_read_u32(np, "fsl,max-link-speed",
+ &imx6_pcie->link_gen);
+ if (ret)
+ imx6_pcie->link_gen = 1;
+
ret = imx6_add_pcie_port(imx6_pcie, dev);
if (ret < 0)
return ret;
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 46/65] PCI: imx6: Remove redundant "Link never came up" message
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (44 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 45/65] PCI: imx6: Add DT property for link gen, default to Gen1 Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 47/65] PCI: imx6: Remove LTSSM disable workaround Andrey Smirnov
` (19 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit caf3f562e1161a86bd48a4c4c33af89d3693c658
When a PCI card is not connected, the following messages are seen on mx6:
imx6q-pcie 1ffc000.pcie: phy link never came up
imx6q-pcie 1ffc000.pcie: Link never came up
The first one comes from the pcie-designware.c core file, so remove
the redundant one from the imx6 driver.
Signed-off-by: Fabio Estevam <fabio.estevam@nxp.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pci-imx6.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/pci/pci-imx6.c b/drivers/pci/pci-imx6.c
index d72abe3a3..a9a4be927 100644
--- a/drivers/pci/pci-imx6.c
+++ b/drivers/pci/pci-imx6.c
@@ -460,10 +460,8 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
writel(gpr12, imx6_pcie->iomuxc_gpr + IOMUXC_GPR12);
ret = imx6_pcie_wait_for_link(imx6_pcie);
- if (ret) {
- dev_info(dev, "Link never came up\n");
+ if (ret)
goto err_reset_phy;
- }
if (imx6_pcie->link_gen == 2) {
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 47/65] PCI: imx6: Remove LTSSM disable workaround
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (45 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 46/65] PCI: imx6: Remove redundant "Link never came up" message Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 48/65] PCI: dwc: all: Split struct pcie_port into host-only and core structures Andrey Smirnov
` (18 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit a71280722eeba8f1afa51ad6656028dcb96e110b
This causes CPU hangs when the system is reset by the watchdog, as the GPRs
aren't cleared, but the clocks are back to disabled state.
If the bootloader uses PCIe, it must take care to bring it down into a safe
state, before passing control to the Linux kernel. This is the only way to
get a properly operating system at all times and circumstances.
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
LTSSM disable workaround still needs to be performed before passing
control to Linux. However, in order to avoid the hang described above,
we move it to imx6_pcie_remove() and apply it without relying on
values in GPR.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pci-imx6.c | 57 +++++++++++++++++++++---------------------
1 file changed, 28 insertions(+), 29 deletions(-)
diff --git a/drivers/pci/pci-imx6.c b/drivers/pci/pci-imx6.c
index a9a4be927..023e6f07f 100644
--- a/drivers/pci/pci-imx6.c
+++ b/drivers/pci/pci-imx6.c
@@ -239,8 +239,7 @@ static void imx6_pcie_reset_phy(struct imx6_pcie *imx6_pcie)
static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
{
- struct pcie_port *pp = &imx6_pcie->pp;
- u32 val, gpr1, gpr12;
+ u32 gpr1;
switch (imx6_pcie->variant) {
case IMX6QP:
@@ -249,34 +248,7 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
writel(gpr1, imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
break;
case IMX6Q:
- /*
- * If the bootloader already enabled the link we need some special
- * handling to get the core back into a state where it is safe to
- * touch it for configuration. As there is no dedicated reset signal
- * wired up for MX6QDL, we need to manually force LTSSM into "detect"
- * state before completely disabling LTSSM, which is a prerequisite
- * for core configuration.
- *
- * If both LTSSM_ENABLE and REF_SSP_ENABLE are active we have a strong
- * indication that the bootloader activated the link.
- */
gpr1 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
- gpr12 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR12);
-
- if ((gpr1 & IMX6Q_GPR1_PCIE_REF_CLK_EN) &&
- (gpr12 & IMX6Q_GPR12_PCIE_CTL_2)) {
- val = dw_pcie_readl_rc(pp, PCIE_PL_PFLR);
- val &= ~PCIE_PL_PFLR_LINK_STATE_MASK;
- val |= PCIE_PL_PFLR_FORCE_LINK;
-
- data_abort_mask();
- dw_pcie_writel_rc(pp, PCIE_PL_PFLR, val);
- data_abort_unmask();
-
- gpr12 &= ~IMX6Q_GPR12_PCIE_CTL_2;
- writel(gpr12, imx6_pcie->iomuxc_gpr + IOMUXC_GPR12);
- }
-
gpr1 |= IMX6Q_GPR1_PCIE_TEST_PD;
writel(gpr1, imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
@@ -642,6 +614,33 @@ static void imx6_pcie_remove(struct device_d *dev)
{
struct imx6_pcie *imx6_pcie = dev->priv;
+ if (imx6_pcie->variant == IMX6Q) {
+ /*
+ * If the bootloader already enabled the link we need
+ * some special handling to get the core back into a
+ * state where it is safe to touch it for
+ * configuration. As there is no dedicated reset
+ * signal wired up for MX6QDL, we need to manually
+ * force LTSSM into "detect" state before completely
+ * disabling LTSSM, which is a prerequisite for core
+ * configuration.
+ */
+ struct pcie_port *pp = &imx6_pcie->pp;
+ u32 gpr12, val;
+
+ val = dw_pcie_readl_rc(pp, PCIE_PL_PFLR);
+ val &= ~PCIE_PL_PFLR_LINK_STATE_MASK;
+ val |= PCIE_PL_PFLR_FORCE_LINK;
+
+ data_abort_mask();
+ dw_pcie_writel_rc(pp, PCIE_PL_PFLR, val);
+ data_abort_unmask();
+
+ gpr12 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR12);
+ gpr12 &= ~IMX6Q_GPR12_PCIE_CTL_2;
+ writel(gpr12, imx6_pcie->iomuxc_gpr + IOMUXC_GPR12);
+ }
+
imx6_pcie_assert_core_reset(imx6_pcie);
}
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 48/65] PCI: dwc: all: Split struct pcie_port into host-only and core structures
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (46 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 47/65] PCI: imx6: Remove LTSSM disable workaround Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 49/65] PCI: dwc: designware: Parse "num-lanes" property in dw_pcie_setup_rc() Andrey Smirnov
` (17 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 442ec4c04d1235f8c664a74004dae54a7a574d18
Keep only the host-specific members in struct pcie_port and move the common
members (i.e common to both host and endpoint) to struct dw_pcie. This is
in preparation for adding endpoint mode support to designware driver.
While at that also fix checkpatch warnings.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
CC: Jingoo Han <jingoohan1@gmail.com>
CC: Richard Zhu <hongxing.zhu@nxp.com>
CC: Lucas Stach <l.stach@pengutronix.de>
CC: Murali Karicheri <m-karicheri2@ti.com>
CC: Minghuan Lian <minghuan.Lian@freescale.com>
CC: Mingkai Hu <mingkai.hu@freescale.com>
CC: Roy Zang <tie-fei.zang@freescale.com>
CC: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
CC: Niklas Cassel <niklas.cassel@axis.com>
CC: Jesper Nilsson <jesper.nilsson@axis.com>
CC: Joao Pinto <Joao.Pinto@synopsys.com>
CC: Zhou Wang <wangzhou1@hisilicon.com>
CC: Gabriele Paoloni <gabriele.paoloni@huawei.com>
CC: Stanimir Varbanov <svarbanov@mm-sol.com>
CC: Pratyush Anand <pratyush.anand@gmail.com>
For convenience sake, commit c0464062bfea9cd2ef6643d93429eafe8f6c2a4a
PCI: dwc: Fix crashes seen due to missing assignments
Fix the following crash, seen in dwc/pci-imx6.
Unable to handle kernel NULL pointer dereference at virtual address 00000070
pgd = c0004000
[00000070] *pgd=00000000
Internal error: Oops: 805 [#1] SMP ARM
Modules linked in:
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.10.0-09686-g9e31489 #1
Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
task: cb850000 task.stack: cb84e000
PC is at imx6_pcie_probe+0x2f4/0x414
...
While at it, fix the same problem in various drivers instead of waiting for
individual crash reports.
The change in the imx6 driver was tested with qemu. The changes in other
drivers are based on code inspection and have been compile tested only.
Fixes: 442ec4c04d12 ("PCI: dwc: all: Split struct pcie_port into host-only and core structures")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Vivek Gautam <vivek.gautam@codeaurora.org> # designware-plat
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Kishon Vijay Abraham I <kishon@ti.com>
was squashed into this one as well.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pci-imx6.c | 105 +++++++++---------
drivers/pci/pcie-designware.c | 197 ++++++++++++++++++----------------
drivers/pci/pcie-designware.h | 57 ++++++----
3 files changed, 196 insertions(+), 163 deletions(-)
diff --git a/drivers/pci/pci-imx6.c b/drivers/pci/pci-imx6.c
index 023e6f07f..67ef47db9 100644
--- a/drivers/pci/pci-imx6.c
+++ b/drivers/pci/pci-imx6.c
@@ -35,7 +35,7 @@
#include "pcie-designware.h"
-#define to_imx6_pcie(x) container_of(x, struct imx6_pcie, pp)
+#define to_imx6_pcie(x) ((x)->dev->priv)
enum imx6_pcie_variants {
IMX6Q,
@@ -43,7 +43,7 @@ enum imx6_pcie_variants {
};
struct imx6_pcie {
- struct pcie_port pp; /* pp.dbi_base is DT 0th resource */
+ struct dw_pcie *pci;
int reset_gpio;
struct clk *pcie_bus;
struct clk *pcie_phy;
@@ -97,13 +97,13 @@ struct imx6_pcie {
static int pcie_phy_poll_ack(struct imx6_pcie *imx6_pcie, int exp_val)
{
- struct pcie_port *pp = &imx6_pcie->pp;
+ struct dw_pcie *pci = imx6_pcie->pci;
u32 val;
u32 max_iterations = 10;
u32 wait_counter = 0;
do {
- val = dw_pcie_readl_rc(pp, PCIE_PHY_STAT);
+ val = dw_pcie_readl_dbi(pci, PCIE_PHY_STAT);
val = (val >> PCIE_PHY_STAT_ACK_LOC) & 0x1;
wait_counter++;
@@ -118,21 +118,21 @@ static int pcie_phy_poll_ack(struct imx6_pcie *imx6_pcie, int exp_val)
static int pcie_phy_wait_ack(struct imx6_pcie *imx6_pcie, int addr)
{
- struct pcie_port *pp = &imx6_pcie->pp;
+ struct dw_pcie *pci = imx6_pcie->pci;
u32 val;
int ret;
val = addr << PCIE_PHY_CTRL_DATA_LOC;
val |= (0x1 << PCIE_PHY_CTRL_CAP_ADR_LOC);
- dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, val);
+ dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, val);
ret = pcie_phy_poll_ack(imx6_pcie, 1);
if (ret)
return ret;
val = addr << PCIE_PHY_CTRL_DATA_LOC;
- dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, val);
+ dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, val);
return pcie_phy_poll_ack(imx6_pcie, 0);
}
@@ -140,7 +140,7 @@ static int pcie_phy_wait_ack(struct imx6_pcie *imx6_pcie, int addr)
/* Read from the 16-bit PCIe PHY control registers (not memory-mapped) */
static int pcie_phy_read(struct imx6_pcie *imx6_pcie, int addr , int *data)
{
- struct pcie_port *pp = &imx6_pcie->pp;
+ struct dw_pcie *pci = imx6_pcie->pci;
u32 val, phy_ctl;
int ret;
@@ -150,24 +150,24 @@ static int pcie_phy_read(struct imx6_pcie *imx6_pcie, int addr , int *data)
/* assert Read signal */
phy_ctl = 0x1 << PCIE_PHY_CTRL_RD_LOC;
- dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, phy_ctl);
+ dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, phy_ctl);
ret = pcie_phy_poll_ack(imx6_pcie, 1);
if (ret)
return ret;
- val = dw_pcie_readl_rc(pp, PCIE_PHY_STAT);
+ val = dw_pcie_readl_dbi(pci, PCIE_PHY_STAT);
*data = val & 0xffff;
/* deassert Read signal */
- dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, 0x00);
+ dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, 0x00);
return pcie_phy_poll_ack(imx6_pcie, 0);
}
static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data)
{
- struct pcie_port *pp = &imx6_pcie->pp;
+ struct dw_pcie *pci = imx6_pcie->pci;
u32 var;
int ret;
@@ -178,11 +178,11 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data)
return ret;
var = data << PCIE_PHY_CTRL_DATA_LOC;
- dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, var);
+ dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var);
/* capture data */
var |= (0x1 << PCIE_PHY_CTRL_CAP_DAT_LOC);
- dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, var);
+ dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var);
ret = pcie_phy_poll_ack(imx6_pcie, 1);
if (ret)
@@ -190,7 +190,7 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data)
/* deassert cap data */
var = data << PCIE_PHY_CTRL_DATA_LOC;
- dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, var);
+ dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var);
/* wait for ack de-assertion */
ret = pcie_phy_poll_ack(imx6_pcie, 0);
@@ -199,7 +199,7 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data)
/* assert wr signal */
var = 0x1 << PCIE_PHY_CTRL_WR_LOC;
- dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, var);
+ dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var);
/* wait for ack */
ret = pcie_phy_poll_ack(imx6_pcie, 1);
@@ -208,14 +208,14 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data)
/* deassert wr signal */
var = data << PCIE_PHY_CTRL_DATA_LOC;
- dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, var);
+ dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var);
/* wait for ack de-assertion */
ret = pcie_phy_poll_ack(imx6_pcie, 0);
if (ret)
return ret;
- dw_pcie_writel_rc(pp, PCIE_PHY_CTRL, 0x0);
+ dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, 0x0);
return 0;
}
@@ -282,7 +282,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
{
- struct device_d *dev = imx6_pcie->pp.dev;
+ struct device_d *dev = imx6_pcie->pci->dev;
int ret;
u32 gpr1;
@@ -386,18 +386,18 @@ static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)
static int imx6_pcie_wait_for_link(struct imx6_pcie *imx6_pcie)
{
- return dw_pcie_wait_for_link(&imx6_pcie->pp);
+ return dw_pcie_wait_for_link(imx6_pcie->pci);
}
static int imx6_pcie_wait_for_speed_change(struct imx6_pcie *imx6_pcie)
{
- struct pcie_port *pp = &imx6_pcie->pp;
- struct device_d *dev = pp->dev;
+ struct dw_pcie *pci = imx6_pcie->pci;
+ struct device_d *dev = pci->dev;
uint32_t tmp;
uint64_t start = get_time_ns();
while (!is_timeout(start, SECOND)) {
- tmp = dw_pcie_readl_rc(pp, PCIE_LINK_WIDTH_SPEED_CONTROL);
+ tmp = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
/* Test if the speed change finished. */
if (!(tmp & PORT_LOGIC_SPEED_CHANGE))
return 0;
@@ -410,8 +410,8 @@ static int imx6_pcie_wait_for_speed_change(struct imx6_pcie *imx6_pcie)
static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
{
- struct pcie_port *pp = &imx6_pcie->pp;
- struct device_d *dev = pp->dev;
+ struct dw_pcie *pci = imx6_pcie->pci;
+ struct device_d *dev = pci->dev;
uint32_t tmp;
int ret;
u32 gpr12;
@@ -421,10 +421,10 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
* started in Gen2 mode, there is a possibility the devices on the
* bus will not be detected at all. This happens with PCIe switches.
*/
- tmp = dw_pcie_readl_rc(pp, PCIE_RC_LCR);
+ tmp = dw_pcie_readl_dbi(pci, PCIE_RC_LCR);
tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1;
- dw_pcie_writel_rc(pp, PCIE_RC_LCR, tmp);
+ dw_pcie_writel_dbi(pci, PCIE_RC_LCR, tmp);
/* Start LTSSM. */
gpr12 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR12);
@@ -438,10 +438,10 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
if (imx6_pcie->link_gen == 2) {
/* Allow Gen2 mode after the link is up. */
- tmp = dw_pcie_readl_rc(pp, PCIE_RC_LCR);
+ tmp = dw_pcie_readl_dbi(pci, PCIE_RC_LCR);
tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK;
tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2;
- dw_pcie_writel_rc(pp, PCIE_RC_LCR, tmp);
+ dw_pcie_writel_dbi(pci, PCIE_RC_LCR, tmp);
} else {
dev_info(dev, "Link: Gen2 disabled\n");
}
@@ -450,9 +450,9 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
* Start Directed Speed Change so the best possible speed both link
* partners support can be negotiated.
*/
- tmp = dw_pcie_readl_rc(pp, PCIE_LINK_WIDTH_SPEED_CONTROL);
+ tmp = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
tmp |= PORT_LOGIC_SPEED_CHANGE;
- dw_pcie_writel_rc(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, tmp);
+ dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, tmp);
ret = imx6_pcie_wait_for_speed_change(imx6_pcie);
if (ret) {
@@ -467,14 +467,14 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
goto err_reset_phy;
}
- tmp = dw_pcie_readl_rc(pp, PCIE_RC_LCSR);
+ tmp = dw_pcie_readl_dbi(pci, PCIE_RC_LCSR);
dev_info(dev, "Link up, Gen%i\n", (tmp >> 16) & 0xf);
return 0;
err_reset_phy:
dev_dbg(dev, "PHY DEBUG_R0=0x%08x DEBUG_R1=0x%08x\n",
- dw_pcie_readl_rc(pp, PCIE_PHY_DEBUG_R0),
- dw_pcie_readl_rc(pp, PCIE_PHY_DEBUG_R1));
+ dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R0),
+ dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R1));
imx6_pcie_reset_phy(imx6_pcie);
return ret;
@@ -482,7 +482,8 @@ err_reset_phy:
static void imx6_pcie_host_init(struct pcie_port *pp)
{
- struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);
imx6_pcie_assert_core_reset(imx6_pcie);
imx6_pcie_init_phy(imx6_pcie);
@@ -491,21 +492,25 @@ static void imx6_pcie_host_init(struct pcie_port *pp)
imx6_pcie_establish_link(imx6_pcie);
}
-static int imx6_pcie_link_up(struct pcie_port *pp)
+static int imx6_pcie_link_up(struct dw_pcie *pci)
{
- return dw_pcie_readl_rc(pp, PCIE_PHY_DEBUG_R1) &
+ return dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R1) &
PCIE_PHY_DEBUG_R1_XMLH_LINK_UP;
}
-static struct pcie_host_ops imx6_pcie_host_ops = {
- .link_up = imx6_pcie_link_up,
+static const struct dw_pcie_ops dw_pcie_ops = {
+ .link_up = imx6_pcie_link_up,
+};
+
+static struct dw_pcie_host_ops imx6_pcie_host_ops = {
.host_init = imx6_pcie_host_init,
};
static int __init imx6_add_pcie_port(struct imx6_pcie *imx6_pcie,
struct device_d *dev)
{
- struct pcie_port *pp = &imx6_pcie->pp;
+ struct dw_pcie *pci = imx6_pcie->pci;
+ struct pcie_port *pp = &pci->pp;
int ret;
pp->root_bus_nr = -1;
@@ -523,23 +528,25 @@ static int __init imx6_add_pcie_port(struct imx6_pcie *imx6_pcie,
static int __init imx6_pcie_probe(struct device_d *dev)
{
struct resource *iores;
+ struct dw_pcie *pci;
struct imx6_pcie *imx6_pcie;
- struct pcie_port *pp;
struct device_node *np = dev->device_node;
int ret;
imx6_pcie = xzalloc(sizeof(*imx6_pcie));
- pp = &imx6_pcie->pp;
- pp->dev = dev;
+ pci = xzalloc(sizeof(*pci));
+ pci->dev = dev;
+ pci->ops = &dw_pcie_ops;
+ imx6_pcie->pci = pci;
imx6_pcie->variant =
(enum imx6_pcie_variants)of_device_get_match_data(dev);
iores = dev_request_mem_resource(dev, 0);
if (IS_ERR(iores))
return PTR_ERR(iores);
- pp->dbi_base = IOMEM(iores->start);
+ pci->dbi_base = IOMEM(iores->start);
/* Fetch GPIOs */
imx6_pcie->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0);
@@ -601,12 +608,12 @@ static int __init imx6_pcie_probe(struct device_d *dev)
if (ret)
imx6_pcie->link_gen = 1;
+ dev->priv = imx6_pcie;
+
ret = imx6_add_pcie_port(imx6_pcie, dev);
if (ret < 0)
return ret;
- dev->priv = imx6_pcie;
-
return 0;
}
@@ -625,15 +632,15 @@ static void imx6_pcie_remove(struct device_d *dev)
* disabling LTSSM, which is a prerequisite for core
* configuration.
*/
- struct pcie_port *pp = &imx6_pcie->pp;
+ struct dw_pcie *pci = imx6_pcie->pci;
u32 gpr12, val;
- val = dw_pcie_readl_rc(pp, PCIE_PL_PFLR);
+ val = dw_pcie_readl_dbi(pci, PCIE_PL_PFLR);
val &= ~PCIE_PL_PFLR_LINK_STATE_MASK;
val |= PCIE_PL_PFLR_FORCE_LINK;
data_abort_mask();
- dw_pcie_writel_rc(pp, PCIE_PL_PFLR, val);
+ dw_pcie_writel_dbi(pci, PCIE_PL_PFLR, val);
data_abort_unmask();
gpr12 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR12);
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index 7e65b56b9..f44046245 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -70,35 +70,35 @@ int dw_pcie_write(void __iomem *addr, int size, u32 val)
return PCIBIOS_SUCCESSFUL;
}
-u32 dw_pcie_readl_rc(struct pcie_port *pp, u32 reg)
+u32 dw_pcie_readl_dbi(struct dw_pcie *pci, u32 reg)
{
- if (pp->ops->readl_rc)
- return pp->ops->readl_rc(pp, reg);
+ if (pci->ops->readl_dbi)
+ return pci->ops->readl_dbi(pci, reg);
- return readl(pp->dbi_base + reg);
+ return readl(pci->dbi_base + reg);
}
-void dw_pcie_writel_rc(struct pcie_port *pp, u32 reg, u32 val)
+void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val)
{
- if (pp->ops->writel_rc)
- pp->ops->writel_rc(pp, reg, val);
+ if (pci->ops->writel_dbi)
+ pci->ops->writel_dbi(pci, reg, val);
else
- writel(val, pp->dbi_base + reg);
+ writel(val, pci->dbi_base + reg);
}
-static u32 dw_pcie_readl_unroll(struct pcie_port *pp, u32 index, u32 reg)
+static u32 dw_pcie_readl_unroll(struct dw_pcie *pci, u32 index, u32 reg)
{
u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);
- return dw_pcie_readl_rc(pp, offset + reg);
+ return dw_pcie_readl_dbi(pci, offset + reg);
}
-static void dw_pcie_writel_unroll(struct pcie_port *pp, u32 index,
+static void dw_pcie_writel_unroll(struct dw_pcie *pci, u32 index,
u32 reg, u32 val)
{
u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);
- dw_pcie_writel_rc(pp, offset + reg, val);
+ dw_pcie_writel_dbi(pci, offset + reg, val);
}
#include <abort.h>
@@ -106,56 +106,63 @@ static void dw_pcie_writel_unroll(struct pcie_port *pp, u32 index,
static int dw_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
u32 *val)
{
+ struct dw_pcie *pci;
+
if (pp->ops->rd_own_conf)
return pp->ops->rd_own_conf(pp, where, size, val);
- return dw_pcie_read(pp->dbi_base + where, size, val);
+ pci = to_dw_pcie_from_pp(pp);
+ return dw_pcie_read(pci->dbi_base + where, size, val);
}
static int dw_pcie_wr_own_conf(struct pcie_port *pp, int where, int size,
u32 val)
{
+ struct dw_pcie *pci;
+
if (pp->ops->wr_own_conf)
return pp->ops->wr_own_conf(pp, where, size, val);
- return dw_pcie_write(pp->dbi_base + where, size, val);
+ pci = to_dw_pcie_from_pp(pp);
+ return dw_pcie_write(pci->dbi_base + where, size, val);
}
-static void dw_pcie_prog_outbound_atu(struct pcie_port *pp, int index,
- int type, u64 cpu_addr, u64 pci_addr, u32 size)
+static void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,
+ int type, u64 cpu_addr, u64 pci_addr,
+ u32 size)
{
u32 retries, val;
- if (pp->iatu_unroll_enabled) {
- dw_pcie_writel_unroll(pp, index, PCIE_ATU_UNR_LOWER_BASE,
- lower_32_bits(cpu_addr));
- dw_pcie_writel_unroll(pp, index, PCIE_ATU_UNR_UPPER_BASE,
- upper_32_bits(cpu_addr));
- dw_pcie_writel_unroll(pp, index, PCIE_ATU_UNR_LIMIT,
- lower_32_bits(cpu_addr + size - 1));
- dw_pcie_writel_unroll(pp, index, PCIE_ATU_UNR_LOWER_TARGET,
- lower_32_bits(pci_addr));
- dw_pcie_writel_unroll(pp, index, PCIE_ATU_UNR_UPPER_TARGET,
- upper_32_bits(pci_addr));
- dw_pcie_writel_unroll(pp, index, PCIE_ATU_UNR_REGION_CTRL1,
- type);
- dw_pcie_writel_unroll(pp, index, PCIE_ATU_UNR_REGION_CTRL2,
- PCIE_ATU_ENABLE);
+ if (pci->iatu_unroll_enabled) {
+ dw_pcie_writel_unroll(pci, index, PCIE_ATU_UNR_LOWER_BASE,
+ lower_32_bits(cpu_addr));
+ dw_pcie_writel_unroll(pci, index, PCIE_ATU_UNR_UPPER_BASE,
+ upper_32_bits(cpu_addr));
+ dw_pcie_writel_unroll(pci, index, PCIE_ATU_UNR_LIMIT,
+ lower_32_bits(cpu_addr + size - 1));
+ dw_pcie_writel_unroll(pci, index, PCIE_ATU_UNR_LOWER_TARGET,
+ lower_32_bits(pci_addr));
+ dw_pcie_writel_unroll(pci, index, PCIE_ATU_UNR_UPPER_TARGET,
+ upper_32_bits(pci_addr));
+ dw_pcie_writel_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL1,
+ type);
+ dw_pcie_writel_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2,
+ PCIE_ATU_ENABLE);
} else {
- dw_pcie_writel_rc(pp, PCIE_ATU_VIEWPORT,
- PCIE_ATU_REGION_OUTBOUND | index);
- dw_pcie_writel_rc(pp, PCIE_ATU_LOWER_BASE,
- lower_32_bits(cpu_addr));
- dw_pcie_writel_rc(pp, PCIE_ATU_UPPER_BASE,
- upper_32_bits(cpu_addr));
- dw_pcie_writel_rc(pp, PCIE_ATU_LIMIT,
- lower_32_bits(cpu_addr + size - 1));
- dw_pcie_writel_rc(pp, PCIE_ATU_LOWER_TARGET,
- lower_32_bits(pci_addr));
- dw_pcie_writel_rc(pp, PCIE_ATU_UPPER_TARGET,
- upper_32_bits(pci_addr));
- dw_pcie_writel_rc(pp, PCIE_ATU_CR1, type);
- dw_pcie_writel_rc(pp, PCIE_ATU_CR2, PCIE_ATU_ENABLE);
+ dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT,
+ PCIE_ATU_REGION_OUTBOUND | index);
+ dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_BASE,
+ lower_32_bits(cpu_addr));
+ dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_BASE,
+ upper_32_bits(cpu_addr));
+ dw_pcie_writel_dbi(pci, PCIE_ATU_LIMIT,
+ lower_32_bits(cpu_addr + size - 1));
+ dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_TARGET,
+ lower_32_bits(pci_addr));
+ dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_TARGET,
+ upper_32_bits(pci_addr));
+ dw_pcie_writel_dbi(pci, PCIE_ATU_CR1, type);
+ dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, PCIE_ATU_ENABLE);
}
/*
@@ -163,46 +170,46 @@ static void dw_pcie_prog_outbound_atu(struct pcie_port *pp, int index,
* and I/O accesses.
*/
for (retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; retries++) {
- if (pp->iatu_unroll_enabled)
- val = dw_pcie_readl_unroll(pp, index,
+ if (pci->iatu_unroll_enabled)
+ val = dw_pcie_readl_unroll(pci, index,
PCIE_ATU_UNR_REGION_CTRL2);
else
- val = dw_pcie_readl_rc(pp, PCIE_ATU_CR2);
+ val = dw_pcie_readl_dbi(pci, PCIE_ATU_CR2);
if (val == PCIE_ATU_ENABLE)
return;
udelay(LINK_WAIT_IATU_MAX);
}
- dev_err(pp->dev, "iATU is not being enabled\n");
+ dev_err(pci->dev, "iATU is not being enabled\n");
}
-int dw_pcie_wait_for_link(struct pcie_port *pp)
+int dw_pcie_wait_for_link(struct dw_pcie *pci)
{
int retries;
/* Check if the link is up or not */
for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
- if (dw_pcie_link_up(pp)) {
- dev_info(pp->dev, "Link up\n");
+ if (dw_pcie_link_up(pci)) {
+ dev_info(pci->dev, "Link up\n");
return 0;
}
udelay(LINK_WAIT_USLEEP_MAX);
}
- dev_err(pp->dev, "Phy link never came up\n");
+ dev_err(pci->dev, "Phy link never came up\n");
return -ETIMEDOUT;
}
-int dw_pcie_link_up(struct pcie_port *pp)
+int dw_pcie_link_up(struct dw_pcie *pci)
{
u32 val;
- if (pp->ops->link_up)
- return pp->ops->link_up(pp);
+ if (pci->ops->link_up)
+ return pci->ops->link_up(pci);
- val = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1);
+ 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));
}
@@ -221,11 +228,11 @@ static void dw_pcie_set_local_bus_nr(struct pci_controller *host, int busno)
static struct pci_ops dw_pcie_ops;
-static u8 dw_pcie_iatu_unroll_enabled(struct pcie_port *pp)
+static u8 dw_pcie_iatu_unroll_enabled(struct dw_pcie *pci)
{
u32 val;
- val = dw_pcie_readl_rc(pp, PCIE_ATU_VIEWPORT);
+ val = dw_pcie_readl_dbi(pci, PCIE_ATU_VIEWPORT);
if (val == 0xffffffff)
return 1;
@@ -235,7 +242,8 @@ static u8 dw_pcie_iatu_unroll_enabled(struct pcie_port *pp)
int __init dw_pcie_host_init(struct pcie_port *pp)
{
- struct device_d *dev = pp->dev;
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ struct device_d *dev = pci->dev;
struct device_node *np = dev->device_node;
struct of_pci_range range;
struct of_pci_range_parser parser;
@@ -313,8 +321,8 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
}
}
- if (!pp->dbi_base)
- pp->dbi_base = (void __force *)pp->cfg.start;
+ if (!pci->dbi_base)
+ pci->dbi_base = (void __force *)pp->cfg.start;
pp->mem_base = pp->mem.start;
@@ -324,13 +332,13 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
if (!pp->va_cfg1_base)
pp->va_cfg1_base = (void __force *)(u32)pp->cfg1_base;
- ret = of_property_read_u32(np, "num-lanes", &pp->lanes);
+ ret = of_property_read_u32(np, "num-lanes", &pci->lanes);
if (ret)
- pp->lanes = 0;
+ pci->lanes = 0;
- ret = of_property_read_u32(np, "num-viewport", &pp->num_viewport);
+ ret = of_property_read_u32(np, "num-viewport", &pci->num_viewport);
if (ret)
- pp->num_viewport = 2;
+ pci->num_viewport = 2;
if (pp->ops->host_init)
pp->ops->host_init(pp);
@@ -353,6 +361,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
u32 address, busdev, cfg_size;
u64 cpu_addr;
void __iomem *va_cfg_base;
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
if (pp->ops->rd_other_conf)
return pp->ops->rd_other_conf(pp, bus, devfn,
@@ -374,12 +383,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
va_cfg_base = pp->va_cfg1_base;
}
- dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
+ dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1,
type, cpu_addr,
busdev, cfg_size);
ret = dw_pcie_read(va_cfg_base + where, size, val);
- if (pp->num_viewport <= 2)
- dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
+ if (pci->num_viewport <= 2)
+ dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1,
PCIE_ATU_TYPE_IO, pp->io_mod_base,
pp->io_bus_addr, pp->io_size);
@@ -393,6 +402,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
u32 busdev, cfg_size;
u64 cpu_addr;
void __iomem *va_cfg_base;
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
if (pp->ops->wr_other_conf)
return pp->ops->wr_other_conf(pp, bus, devfn,
@@ -413,12 +423,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
va_cfg_base = pp->va_cfg1_base;
}
- dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
+ dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1,
type, cpu_addr,
busdev, cfg_size);
ret = dw_pcie_write(va_cfg_base + where, size, val);
- if (pp->num_viewport <= 2)
- dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
+ if (pci->num_viewport <= 2)
+ dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1,
PCIE_ATU_TYPE_IO, pp->io_mod_base,
pp->io_bus_addr, pp->io_size);
@@ -428,9 +438,11 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
static int dw_pcie_valid_device(struct pcie_port *pp, struct pci_bus *bus,
int dev)
{
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+
/* If there is no link, then there is no device */
if (bus->number != pp->root_bus_nr) {
- if (!dw_pcie_link_up(pp))
+ if (!dw_pcie_link_up(pci))
return 0;
}
@@ -510,11 +522,12 @@ static struct pci_ops dw_pcie_ops = {
void dw_pcie_setup_rc(struct pcie_port *pp)
{
u32 val;
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
/* set the number of lanes */
- val = dw_pcie_readl_rc(pp, PCIE_PORT_LINK_CONTROL);
+ val = dw_pcie_readl_dbi(pci, PCIE_PORT_LINK_CONTROL);
val &= ~PORT_LINK_MODE_MASK;
- switch (pp->lanes) {
+ switch (pci->lanes) {
case 1:
val |= PORT_LINK_MODE_1_LANES;
break;
@@ -525,15 +538,15 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
val |= PORT_LINK_MODE_4_LANES;
break;
default:
- dev_err(pp->dev, "num-lanes %u: invalid value\n", pp->lanes);
+ dev_err(pci->dev, "num-lanes %u: invalid value\n", pci->lanes);
return;
}
- dw_pcie_writel_rc(pp, PCIE_PORT_LINK_CONTROL, val);
+ dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, val);
/* set link width speed control register */
- val = dw_pcie_readl_rc(pp, PCIE_LINK_WIDTH_SPEED_CONTROL);
+ val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
val &= ~PORT_LOGIC_LINK_WIDTH_MASK;
- switch (pp->lanes) {
+ switch (pci->lanes) {
case 1:
val |= PORT_LOGIC_LINK_WIDTH_1_LANES;
break;
@@ -544,24 +557,24 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
val |= PORT_LOGIC_LINK_WIDTH_4_LANES;
break;
}
- dw_pcie_writel_rc(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, val);
+ dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val);
/* setup RC BARs */
- dw_pcie_writel_rc(pp, PCI_BASE_ADDRESS_0, 0x00000004);
- dw_pcie_writel_rc(pp, PCI_BASE_ADDRESS_1, 0x00000000);
+ dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, 0x00000004);
+ dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_1, 0x00000000);
/* setup bus numbers */
- val = dw_pcie_readl_rc(pp, PCI_PRIMARY_BUS);
+ val = dw_pcie_readl_dbi(pci, PCI_PRIMARY_BUS);
val &= 0xff000000;
val |= 0x00010100;
- dw_pcie_writel_rc(pp, PCI_PRIMARY_BUS, val);
+ dw_pcie_writel_dbi(pci, PCI_PRIMARY_BUS, val);
/* setup command register */
- val = dw_pcie_readl_rc(pp, PCI_COMMAND);
+ val = dw_pcie_readl_dbi(pci, PCI_COMMAND);
val &= 0xffff0000;
val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
- dw_pcie_writel_rc(pp, PCI_COMMAND, val);
+ dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
/*
* If the platform provides ->rd_other_conf, it means the platform
@@ -570,15 +583,15 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
*/
if (!pp->ops->rd_other_conf) {
/* get iATU unroll support */
- pp->iatu_unroll_enabled = dw_pcie_iatu_unroll_enabled(pp);
- dev_dbg(pp->dev, "iATU unroll: %s\n",
- pp->iatu_unroll_enabled ? "enabled" : "disabled");
+ pci->iatu_unroll_enabled = dw_pcie_iatu_unroll_enabled(pci);
+ dev_dbg(pci->dev, "iATU unroll: %s\n",
+ pci->iatu_unroll_enabled ? "enabled" : "disabled");
- dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
+ dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX0,
PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
pp->mem_bus_addr, pp->mem_size);
- if (pp->num_viewport > 2)
- dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX2,
+ if (pci->num_viewport > 2)
+ dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX2,
PCIE_ATU_TYPE_IO, pp->io_base,
pp->io_bus_addr, pp->io_size);
}
diff --git a/drivers/pci/pcie-designware.h b/drivers/pci/pcie-designware.h
index fb9d2fdb6..b1b8e0554 100644
--- a/drivers/pci/pcie-designware.h
+++ b/drivers/pci/pcie-designware.h
@@ -92,10 +92,22 @@
#define PCIE_PHY_DEBUG_R1_LINK_UP (0x1 << 4)
#define PCIE_PHY_DEBUG_R1_LINK_IN_TRAINING (0x1 << 29)
+struct pcie_port;
+struct dw_pcie;
+
+struct dw_pcie_host_ops {
+ int (*rd_own_conf)(struct pcie_port *pp, int where, int size, u32 *val);
+ int (*wr_own_conf)(struct pcie_port *pp, int where, int size, u32 val);
+ int (*rd_other_conf)(struct pcie_port *pp, struct pci_bus *bus,
+ unsigned int devfn, int where, int size, u32 *val);
+ int (*wr_other_conf)(struct pcie_port *pp, struct pci_bus *bus,
+ unsigned int devfn, int where, int size, u32 val);
+ void (*host_init)(struct pcie_port *pp);
+ void (*scan_bus)(struct pcie_port *pp);
+};
+
struct pcie_port {
- struct device_d *dev;
u8 root_bus_nr;
- void __iomem *dbi_base;
u64 cfg0_base;
u64 cfg0_mod_base;
void __iomem *va_cfg0_base;
@@ -117,35 +129,36 @@ struct pcie_port {
struct resource mem;
struct resource busn;
int irq;
- u32 lanes;
- u32 num_viewport;
- struct pcie_host_ops *ops;
+ struct dw_pcie_host_ops *ops;
struct pci_controller pci;
- u8 iatu_unroll_enabled;
};
-struct pcie_host_ops {
- u32 (*readl_rc)(struct pcie_port *pp, u32 reg);
- void (*writel_rc)(struct pcie_port *pp, u32 reg, u32 val);
- int (*rd_own_conf)(struct pcie_port *pp, int where, int size, u32 *val);
- int (*wr_own_conf)(struct pcie_port *pp, int where, int size, u32 val);
- int (*rd_other_conf)(struct pcie_port *pp, struct pci_bus *bus,
- unsigned int devfn, int where, int size, u32 *val);
- int (*wr_other_conf)(struct pcie_port *pp, struct pci_bus *bus,
- unsigned int devfn, int where, int size, u32 val);
- int (*link_up)(struct pcie_port *pp);
- void (*host_init)(struct pcie_port *pp);
- void (*scan_bus)(struct pcie_port *pp);
+struct dw_pcie_ops {
+ u32 (*readl_dbi)(struct dw_pcie *pcie, u32 reg);
+ void (*writel_dbi)(struct dw_pcie *pcie, u32 reg, u32 val);
+ int (*link_up)(struct dw_pcie *pcie);
};
-u32 dw_pcie_readl_rc(struct pcie_port *pp, u32 reg);
-void dw_pcie_writel_rc(struct pcie_port *pp, u32 reg, u32 val);
+struct dw_pcie {
+ struct device_d *dev;
+ void __iomem *dbi_base;
+ u32 lanes;
+ u32 num_viewport;
+ u8 iatu_unroll_enabled;
+ struct pcie_port pp;
+ const struct dw_pcie_ops *ops;
+};
+
+#define to_dw_pcie_from_pp(port) container_of((port), struct dw_pcie, pp)
+
int dw_pcie_read(void __iomem *addr, int size, u32 *val);
int dw_pcie_write(void __iomem *addr, int size, u32 val);
-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);
-int dw_pcie_wait_for_link(struct pcie_port *pp);
+u32 dw_pcie_readl_dbi(struct dw_pcie *pci, u32 reg);
+void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val);
+int dw_pcie_link_up(struct dw_pcie *pci);
+int dw_pcie_wait_for_link(struct dw_pcie *pci);
#endif /* _PCIE_DESIGNWARE_H */
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 49/65] PCI: dwc: designware: Parse "num-lanes" property in dw_pcie_setup_rc()
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (47 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 48/65] PCI: dwc: all: Split struct pcie_port into host-only and core structures Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 50/65] PCI: dwc: designware: Fix style errors in pcie-designware.c Andrey Smirnov
` (16 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 5f334db665173facf2213854408bb5fa2445d0b3
The "num-lanes" DT property is parsed in dw_pcie_host_init(). However
num-lanes is applicable to both root complex mode and endpoint mode. As a
first step, move the parsing of this property outside dw_pcie_host_init().
This is in preparation for splitting pcie-designware.c to pcie-designware.c
and pcie-designware-host.c
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 18 +++++++++++-------
drivers/pci/pcie-designware.h | 1 -
2 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index f44046245..59884d514 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -332,10 +332,6 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
if (!pp->va_cfg1_base)
pp->va_cfg1_base = (void __force *)(u32)pp->cfg1_base;
- ret = of_property_read_u32(np, "num-lanes", &pci->lanes);
- if (ret)
- pci->lanes = 0;
-
ret = of_property_read_u32(np, "num-viewport", &pci->num_viewport);
if (ret)
pci->num_viewport = 2;
@@ -521,13 +517,21 @@ static struct pci_ops dw_pcie_ops = {
void dw_pcie_setup_rc(struct pcie_port *pp)
{
+ int ret;
+ u32 lanes;
u32 val;
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ struct device_d *dev = pci->dev;
+ struct device_node *np = dev->device_node;
+
+ ret = of_property_read_u32(np, "num-lanes", &lanes);
+ if (ret)
+ lanes = 0;
/* set the number of lanes */
val = dw_pcie_readl_dbi(pci, PCIE_PORT_LINK_CONTROL);
val &= ~PORT_LINK_MODE_MASK;
- switch (pci->lanes) {
+ switch (lanes) {
case 1:
val |= PORT_LINK_MODE_1_LANES;
break;
@@ -538,7 +542,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
val |= PORT_LINK_MODE_4_LANES;
break;
default:
- dev_err(pci->dev, "num-lanes %u: invalid value\n", pci->lanes);
+ dev_err(pci->dev, "num-lanes %u: invalid value\n", lanes);
return;
}
dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, val);
@@ -546,7 +550,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
/* set link width speed control register */
val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
val &= ~PORT_LOGIC_LINK_WIDTH_MASK;
- switch (pci->lanes) {
+ switch (lanes) {
case 1:
val |= PORT_LOGIC_LINK_WIDTH_1_LANES;
break;
diff --git a/drivers/pci/pcie-designware.h b/drivers/pci/pcie-designware.h
index b1b8e0554..06d8c769c 100644
--- a/drivers/pci/pcie-designware.h
+++ b/drivers/pci/pcie-designware.h
@@ -142,7 +142,6 @@ struct dw_pcie_ops {
struct dw_pcie {
struct device_d *dev;
void __iomem *dbi_base;
- u32 lanes;
u32 num_viewport;
u8 iatu_unroll_enabled;
struct pcie_port pp;
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 50/65] PCI: dwc: designware: Fix style errors in pcie-designware.c
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (48 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 49/65] PCI: dwc: designware: Parse "num-lanes" property in dw_pcie_setup_rc() Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 51/65] PCI: dwc: Split pcie-designware.c into host and core files Andrey Smirnov
` (15 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 314fc854f50317931fb4dfaab431695ab886e8de
No functional change. Fix all checkpatch warnings and check errors in
pcie-designware.c
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-By: Joao Pinto <jpinto@synopsys.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index 59884d514..f5a77ae15 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -39,13 +39,13 @@ int dw_pcie_read(void __iomem *addr, int size, u32 *val)
return PCIBIOS_BAD_REGISTER_NUMBER;
}
- if (size == 4)
+ if (size == 4) {
*val = readl(addr);
- else if (size == 2)
+ } else if (size == 2) {
*val = readw(addr);
- else if (size == 1)
+ } else if (size == 1) {
*val = readb(addr);
- else {
+ } else {
*val = 0;
return PCIBIOS_BAD_REGISTER_NUMBER;
}
@@ -260,8 +260,8 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
cfg_res = dev_get_resource_by_name(dev, IORESOURCE_MEM, "config");
if (cfg_res) {
- pp->cfg0_size = resource_size(cfg_res)/2;
- pp->cfg1_size = resource_size(cfg_res)/2;
+ pp->cfg0_size = resource_size(cfg_res) / 2;
+ pp->cfg1_size = resource_size(cfg_res) / 2;
pp->cfg0_base = cfg_res->start;
pp->cfg1_base = cfg_res->start + pp->cfg0_size;
@@ -308,8 +308,8 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
}
if (restype == 0) {
of_pci_range_to_resource(&range, np, &pp->cfg);
- pp->cfg0_size = resource_size(&pp->cfg)/2;
- pp->cfg1_size = resource_size(&pp->cfg)/2;
+ pp->cfg0_size = resource_size(&pp->cfg) / 2;
+ pp->cfg1_size = resource_size(&pp->cfg) / 2;
pp->cfg0_base = pp->cfg.start;
pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
@@ -351,7 +351,7 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
}
static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
- u32 devfn, int where, int size, u32 *val)
+ u32 devfn, int where, int size, u32 *val)
{
int ret, type;
u32 address, busdev, cfg_size;
@@ -392,7 +392,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
}
static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
- u32 devfn, int where, int size, u32 val)
+ u32 devfn, int where, int size, u32 val)
{
int ret, type;
u32 busdev, cfg_size;
@@ -457,7 +457,7 @@ static int dw_pcie_valid_device(struct pcie_port *pp, struct pci_bus *bus,
}
static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
- int size, u32 *val)
+ int size, u32 *val)
{
struct pcie_port *pp = host_to_pcie(bus->host);
int ret;
@@ -482,7 +482,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
}
static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
- int where, int size, u32 val)
+ int where, int size, u32 val)
{
struct pcie_port *pp = host_to_pcie(bus->host);
int ret;
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 51/65] PCI: dwc: Split pcie-designware.c into host and core files
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (49 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 50/65] PCI: dwc: designware: Fix style errors in pcie-designware.c Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 52/65] PCI: dwc: all: Modify dbi accessors to take dbi_base as argument Andrey Smirnov
` (14 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit feb85d9b1c47ea8dbcae559ff127b433fdb245b7
Split pcie-designware.c into pcie-designware-host.c that contains the host
specific parts of the driver and pcie-designware.c that contains the parts
used by both host driver and endpoint driver.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/Makefile | 2 +-
drivers/pci/pcie-designware-host.c | 412 +++++++++++++++++++++++++++++
drivers/pci/pcie-designware.c | 386 +--------------------------
drivers/pci/pcie-designware.h | 5 +-
4 files changed, 422 insertions(+), 383 deletions(-)
create mode 100644 drivers/pci/pcie-designware-host.c
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index ce5d0e2c8..562304c65 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -9,5 +9,5 @@ CPPFLAGS += $(ccflags-y)
obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o pci-mvebu-phy.o
obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
-obj-$(CONFIG_PCIE_DW) += pcie-designware.o
+obj-$(CONFIG_PCIE_DW) += pcie-designware.o pcie-designware-host.o
obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
diff --git a/drivers/pci/pcie-designware-host.c b/drivers/pci/pcie-designware-host.c
new file mode 100644
index 000000000..30bed9444
--- /dev/null
+++ b/drivers/pci/pcie-designware-host.c
@@ -0,0 +1,412 @@
+/*
+ * Synopsys Designware PCIe host controller driver
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Author: Jingoo Han <jg1.han@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
+#include <common.h>
+#include <clock.h>
+#include <malloc.h>
+#include <io.h>
+#include <init.h>
+#include <asm/mmu.h>
+
+#include <linux/clk.h>
+#include <linux/kernel.h>
+#include <of_address.h>
+#include <of_pci.h>
+#include <linux/pci.h>
+#include <linux/phy/phy.h>
+#include <linux/reset.h>
+#include <linux/sizes.h>
+
+#include "pcie-designware.h"
+
+#include <abort.h>
+
+static struct pci_ops dw_pcie_ops;
+static unsigned long global_io_offset;
+
+static int dw_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
+ u32 *val)
+{
+ struct dw_pcie *pci;
+
+ if (pp->ops->rd_own_conf)
+ return pp->ops->rd_own_conf(pp, where, size, val);
+
+ pci = to_dw_pcie_from_pp(pp);
+ return dw_pcie_read(pci->dbi_base + where, size, val);
+}
+
+static int dw_pcie_wr_own_conf(struct pcie_port *pp, int where, int size,
+ u32 val)
+{
+ struct dw_pcie *pci;
+
+ if (pp->ops->wr_own_conf)
+ return pp->ops->wr_own_conf(pp, where, size, val);
+
+ pci = to_dw_pcie_from_pp(pp);
+ return dw_pcie_write(pci->dbi_base + where, size, val);
+}
+
+static inline struct pcie_port *host_to_pcie(struct pci_controller *host)
+{
+ return container_of(host, struct pcie_port, pci);
+}
+
+static void dw_pcie_set_local_bus_nr(struct pci_controller *host, int busno)
+{
+ struct pcie_port *pp = host_to_pcie(host);
+
+ pp->root_bus_nr = busno;
+}
+
+int __init dw_pcie_host_init(struct pcie_port *pp)
+{
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ struct device_d *dev = pci->dev;
+ struct device_node *np = dev->device_node;
+ struct of_pci_range range;
+ struct of_pci_range_parser parser;
+ struct resource *cfg_res;
+ u32 na, ns;
+ const __be32 *addrp;
+ int index, ret;
+
+ /* Find the address cell size and the number of cells in order to get
+ * the untranslated address.
+ */
+ of_property_read_u32(np, "#address-cells", &na);
+ ns = of_n_size_cells(np);
+
+ cfg_res = dev_get_resource_by_name(dev, IORESOURCE_MEM, "config");
+ if (cfg_res) {
+ pp->cfg0_size = resource_size(cfg_res) / 2;
+ pp->cfg1_size = resource_size(cfg_res) / 2;
+ pp->cfg0_base = cfg_res->start;
+ pp->cfg1_base = cfg_res->start + pp->cfg0_size;
+
+ /* Find the untranslated configuration space address */
+ index = of_property_match_string(np, "reg-names", "config");
+ addrp = of_get_address(np, index, NULL, NULL);
+ pp->cfg0_mod_base = of_read_number(addrp, ns);
+ pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
+ } else {
+ dev_err(dev, "missing *config* reg space\n");
+ }
+
+ if (of_pci_range_parser_init(&parser, np)) {
+ dev_err(dev, "missing ranges property\n");
+ return -EINVAL;
+ }
+
+ /* Get the I/O and memory ranges from DT */
+ for_each_of_pci_range(&parser, &range) {
+ unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
+
+ if (restype == IORESOURCE_IO) {
+ of_pci_range_to_resource(&range, np, &pp->io);
+ pp->io.name = "I/O";
+ pp->io.start = range.pci_addr + global_io_offset;
+ pp->io.end = range.pci_addr + range.size + global_io_offset - 1;
+ pp->io_size = resource_size(&pp->io);
+ pp->io_bus_addr = range.pci_addr;
+ pp->io_base = range.cpu_addr;
+
+ /* Find the untranslated IO space address */
+ pp->io_mod_base = of_read_number(parser.range -
+ parser.np + na, ns);
+ }
+ if (restype == IORESOURCE_MEM) {
+ of_pci_range_to_resource(&range, np, &pp->mem);
+ pp->mem.name = "MEM";
+ pp->mem_size = resource_size(&pp->mem);
+ pp->mem_bus_addr = range.pci_addr;
+
+ /* Find the untranslated MEM space address */
+ pp->mem_mod_base = of_read_number(parser.range -
+ parser.np + na, ns);
+ }
+ if (restype == 0) {
+ of_pci_range_to_resource(&range, np, &pp->cfg);
+ pp->cfg0_size = resource_size(&pp->cfg) / 2;
+ pp->cfg1_size = resource_size(&pp->cfg) / 2;
+ pp->cfg0_base = pp->cfg.start;
+ pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
+
+ /* Find the untranslated configuration space address */
+ pp->cfg0_mod_base = of_read_number(parser.range -
+ parser.np + na, ns);
+ pp->cfg1_mod_base = pp->cfg0_mod_base +
+ pp->cfg0_size;
+ }
+ }
+
+ if (!pci->dbi_base)
+ pci->dbi_base = (void __force *)pp->cfg.start;
+
+ pp->mem_base = pp->mem.start;
+
+ if (!pp->va_cfg0_base)
+ pp->va_cfg0_base = (void __force *)(u32)pp->cfg0_base;
+
+ if (!pp->va_cfg1_base)
+ pp->va_cfg1_base = (void __force *)(u32)pp->cfg1_base;
+
+ ret = of_property_read_u32(np, "num-viewport", &pci->num_viewport);
+ if (ret)
+ pci->num_viewport = 2;
+
+ if (pp->ops->host_init)
+ pp->ops->host_init(pp);
+
+ pp->pci.parent = dev;
+ pp->pci.pci_ops = &dw_pcie_ops;
+ pp->pci.set_busno = dw_pcie_set_local_bus_nr;
+ pp->pci.mem_resource = &pp->mem;
+ pp->pci.io_resource = &pp->io;
+
+ register_pci_controller(&pp->pci);
+
+ return 0;
+}
+
+static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
+ u32 devfn, int where, int size, u32 *val)
+{
+ int ret, type;
+ u32 address, busdev, cfg_size;
+ u64 cpu_addr;
+ void __iomem *va_cfg_base;
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+
+ if (pp->ops->rd_other_conf)
+ return pp->ops->rd_other_conf(pp, bus, devfn,
+ where, size, val);
+
+ busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) |
+ PCIE_ATU_FUNC(PCI_FUNC(devfn));
+ address = where & ~0x3;
+
+ if (bus->primary == pp->root_bus_nr) {
+ type = PCIE_ATU_TYPE_CFG0;
+ cpu_addr = pp->cfg0_mod_base;
+ cfg_size = pp->cfg0_size;
+ va_cfg_base = pp->va_cfg0_base;
+ } else {
+ type = PCIE_ATU_TYPE_CFG1;
+ cpu_addr = pp->cfg1_mod_base;
+ cfg_size = pp->cfg1_size;
+ va_cfg_base = pp->va_cfg1_base;
+ }
+
+ dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1,
+ type, cpu_addr,
+ busdev, cfg_size);
+ ret = dw_pcie_read(va_cfg_base + where, size, val);
+ if (pci->num_viewport <= 2)
+ dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1,
+ PCIE_ATU_TYPE_IO, pp->io_mod_base,
+ pp->io_bus_addr, pp->io_size);
+
+ return ret;
+}
+
+static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
+ u32 devfn, int where, int size, u32 val)
+{
+ int ret, type;
+ u32 busdev, cfg_size;
+ u64 cpu_addr;
+ void __iomem *va_cfg_base;
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+
+ if (pp->ops->wr_other_conf)
+ return pp->ops->wr_other_conf(pp, bus, devfn,
+ where, size, val);
+
+ busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) |
+ PCIE_ATU_FUNC(PCI_FUNC(devfn));
+
+ if (bus->primary == pp->root_bus_nr) {
+ type = PCIE_ATU_TYPE_CFG0;
+ cpu_addr = pp->cfg0_mod_base;
+ cfg_size = pp->cfg0_size;
+ va_cfg_base = pp->va_cfg0_base;
+ } else {
+ type = PCIE_ATU_TYPE_CFG1;
+ cpu_addr = pp->cfg1_mod_base;
+ cfg_size = pp->cfg1_size;
+ va_cfg_base = pp->va_cfg1_base;
+ }
+
+ dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1,
+ type, cpu_addr,
+ busdev, cfg_size);
+ ret = dw_pcie_write(va_cfg_base + where, size, val);
+ if (pci->num_viewport <= 2)
+ dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1,
+ PCIE_ATU_TYPE_IO, pp->io_mod_base,
+ pp->io_bus_addr, pp->io_size);
+
+ return ret;
+}
+
+static int dw_pcie_valid_device(struct pcie_port *pp, struct pci_bus *bus,
+ int dev)
+{
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+
+ /* If there is no link, then there is no device */
+ if (bus->number != pp->root_bus_nr) {
+ if (!dw_pcie_link_up(pci))
+ return 0;
+ }
+
+ /* access only one slot on each root port */
+ if (bus->number == pp->root_bus_nr && dev > 0)
+ return 0;
+
+ /*
+ * do not read more than one device on the bus directly attached
+ * to RC's (Virtual Bridge's) DS side.
+ */
+ if (bus->primary == pp->root_bus_nr && dev > 0)
+ return 0;
+
+ return 1;
+}
+
+static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
+ int size, u32 *val)
+{
+ struct pcie_port *pp = host_to_pcie(bus->host);
+ int ret;
+
+ *val = 0xffffffff;
+
+ if (!dw_pcie_valid_device(pp, bus, PCI_SLOT(devfn)))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ data_abort_mask();
+
+ if (bus->number == pp->root_bus_nr)
+ ret = dw_pcie_rd_own_conf(pp, where, size, val);
+ else
+ ret = dw_pcie_rd_other_conf(pp, bus, devfn,
+ where, size, val);
+
+ if (data_abort_unmask())
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ return ret;
+}
+
+static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
+ int where, int size, u32 val)
+{
+ struct pcie_port *pp = host_to_pcie(bus->host);
+ int ret;
+
+ if (!dw_pcie_valid_device(pp, bus, PCI_SLOT(devfn)))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ data_abort_mask();
+
+ if (bus->number == pp->root_bus_nr)
+ ret = dw_pcie_wr_own_conf(pp, where, size, val);
+ else
+ ret = dw_pcie_wr_other_conf(pp, bus, devfn,
+ where, size, val);
+
+ if (data_abort_unmask())
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ return ret;
+}
+
+static int dw_pcie_res_start(struct pci_bus *bus, resource_size_t res_addr)
+{
+ return res_addr;
+}
+
+static struct pci_ops dw_pcie_ops = {
+ .read = dw_pcie_rd_conf,
+ .write = dw_pcie_wr_conf,
+ .res_start = dw_pcie_res_start,
+};
+
+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_rc(struct pcie_port *pp)
+{
+ u32 val;
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+
+ dw_pcie_setup(pci);
+
+ /* setup RC BARs */
+ dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, 0x00000004);
+ dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_1, 0x00000000);
+
+ /* setup bus numbers */
+ val = dw_pcie_readl_dbi(pci, PCI_PRIMARY_BUS);
+ val &= 0xff000000;
+ val |= 0x00010100;
+ dw_pcie_writel_dbi(pci, PCI_PRIMARY_BUS, val);
+
+ /* setup command register */
+ val = dw_pcie_readl_dbi(pci, PCI_COMMAND);
+ val &= 0xffff0000;
+ val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
+ dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
+
+ /*
+ * If the platform provides ->rd_other_conf, it means the platform
+ * uses its own address translation component rather than ATU, so
+ * we should not program the ATU here.
+ */
+ if (!pp->ops->rd_other_conf) {
+ /* get iATU unroll support */
+ pci->iatu_unroll_enabled = dw_pcie_iatu_unroll_enabled(pci);
+ dev_dbg(pci->dev, "iATU unroll: %s\n",
+ pci->iatu_unroll_enabled ? "enabled" : "disabled");
+
+ dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX0,
+ PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
+ pp->mem_bus_addr, pp->mem_size);
+ if (pci->num_viewport > 2)
+ dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX2,
+ PCIE_ATU_TYPE_IO, pp->io_base,
+ pp->io_bus_addr, pp->io_size);
+ }
+
+ dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
+
+ /* program correct class for RC */
+ dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2, PCI_CLASS_BRIDGE_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);
+}
\ No newline at end of file
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index f5a77ae15..6687fff8b 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -30,8 +30,6 @@
#include "pcie-designware.h"
-static unsigned long global_io_offset;
-
int dw_pcie_read(void __iomem *addr, int size, u32 *val)
{
if ((uintptr_t)addr & (size - 1)) {
@@ -101,35 +99,9 @@ static void dw_pcie_writel_unroll(struct dw_pcie *pci, u32 index,
dw_pcie_writel_dbi(pci, offset + reg, val);
}
-#include <abort.h>
-
-static int dw_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
- u32 *val)
-{
- struct dw_pcie *pci;
-
- if (pp->ops->rd_own_conf)
- return pp->ops->rd_own_conf(pp, where, size, val);
-
- pci = to_dw_pcie_from_pp(pp);
- return dw_pcie_read(pci->dbi_base + where, size, val);
-}
-
-static int dw_pcie_wr_own_conf(struct pcie_port *pp, int where, int size,
- u32 val)
-{
- struct dw_pcie *pci;
-
- if (pp->ops->wr_own_conf)
- return pp->ops->wr_own_conf(pp, where, size, val);
-
- pci = to_dw_pcie_from_pp(pp);
- return dw_pcie_write(pci->dbi_base + where, size, val);
-}
-
-static void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,
- int type, u64 cpu_addr, u64 pci_addr,
- u32 size)
+void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,
+ int type, u64 cpu_addr, u64 pci_addr,
+ u32 size)
{
u32 retries, val;
@@ -214,313 +186,11 @@ int dw_pcie_link_up(struct dw_pcie *pci)
!(val & PCIE_PHY_DEBUG_R1_LINK_IN_TRAINING));
}
-static inline struct pcie_port *host_to_pcie(struct pci_controller *host)
-{
- return container_of(host, struct pcie_port, pci);
-}
-
-static void dw_pcie_set_local_bus_nr(struct pci_controller *host, int busno)
-{
- struct pcie_port *pp = host_to_pcie(host);
-
- pp->root_bus_nr = busno;
-}
-
-static struct pci_ops dw_pcie_ops;
-
-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;
-}
-
-
-int __init dw_pcie_host_init(struct pcie_port *pp)
+void dw_pcie_setup(struct dw_pcie *pci)
{
- struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
- struct device_d *dev = pci->dev;
- struct device_node *np = dev->device_node;
- struct of_pci_range range;
- struct of_pci_range_parser parser;
- struct resource *cfg_res;
- u32 na, ns;
- const __be32 *addrp;
- int index, ret;
-
- /* Find the address cell size and the number of cells in order to get
- * the untranslated address.
- */
- of_property_read_u32(np, "#address-cells", &na);
- ns = of_n_size_cells(np);
-
- cfg_res = dev_get_resource_by_name(dev, IORESOURCE_MEM, "config");
- if (cfg_res) {
- pp->cfg0_size = resource_size(cfg_res) / 2;
- pp->cfg1_size = resource_size(cfg_res) / 2;
- pp->cfg0_base = cfg_res->start;
- pp->cfg1_base = cfg_res->start + pp->cfg0_size;
-
- /* Find the untranslated configuration space address */
- index = of_property_match_string(np, "reg-names", "config");
- addrp = of_get_address(np, index, NULL, NULL);
- pp->cfg0_mod_base = of_read_number(addrp, ns);
- pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
- } else {
- dev_err(dev, "missing *config* reg space\n");
- }
-
- if (of_pci_range_parser_init(&parser, np)) {
- dev_err(dev, "missing ranges property\n");
- return -EINVAL;
- }
-
- /* Get the I/O and memory ranges from DT */
- for_each_of_pci_range(&parser, &range) {
- unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
-
- if (restype == IORESOURCE_IO) {
- of_pci_range_to_resource(&range, np, &pp->io);
- pp->io.name = "I/O";
- pp->io.start = range.pci_addr + global_io_offset;
- pp->io.end = range.pci_addr + range.size + global_io_offset - 1;
- pp->io_size = resource_size(&pp->io);
- pp->io_bus_addr = range.pci_addr;
- pp->io_base = range.cpu_addr;
-
- /* Find the untranslated IO space address */
- pp->io_mod_base = of_read_number(parser.range -
- parser.np + na, ns);
- }
- if (restype == IORESOURCE_MEM) {
- of_pci_range_to_resource(&range, np, &pp->mem);
- pp->mem.name = "MEM";
- pp->mem_size = resource_size(&pp->mem);
- pp->mem_bus_addr = range.pci_addr;
-
- /* Find the untranslated MEM space address */
- pp->mem_mod_base = of_read_number(parser.range -
- parser.np + na, ns);
- }
- if (restype == 0) {
- of_pci_range_to_resource(&range, np, &pp->cfg);
- pp->cfg0_size = resource_size(&pp->cfg) / 2;
- pp->cfg1_size = resource_size(&pp->cfg) / 2;
- pp->cfg0_base = pp->cfg.start;
- pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
-
- /* Find the untranslated configuration space address */
- pp->cfg0_mod_base = of_read_number(parser.range -
- parser.np + na, ns);
- pp->cfg1_mod_base = pp->cfg0_mod_base +
- pp->cfg0_size;
- }
- }
-
- if (!pci->dbi_base)
- pci->dbi_base = (void __force *)pp->cfg.start;
-
- pp->mem_base = pp->mem.start;
-
- if (!pp->va_cfg0_base)
- pp->va_cfg0_base = (void __force *)(u32)pp->cfg0_base;
-
- if (!pp->va_cfg1_base)
- pp->va_cfg1_base = (void __force *)(u32)pp->cfg1_base;
-
- ret = of_property_read_u32(np, "num-viewport", &pci->num_viewport);
- if (ret)
- pci->num_viewport = 2;
-
- if (pp->ops->host_init)
- pp->ops->host_init(pp);
-
- pp->pci.parent = dev;
- pp->pci.pci_ops = &dw_pcie_ops;
- pp->pci.set_busno = dw_pcie_set_local_bus_nr;
- pp->pci.mem_resource = &pp->mem;
- pp->pci.io_resource = &pp->io;
-
- register_pci_controller(&pp->pci);
-
- return 0;
-}
-
-static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
- u32 devfn, int where, int size, u32 *val)
-{
- int ret, type;
- u32 address, busdev, cfg_size;
- u64 cpu_addr;
- void __iomem *va_cfg_base;
- struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
-
- if (pp->ops->rd_other_conf)
- return pp->ops->rd_other_conf(pp, bus, devfn,
- where, size, val);
-
- busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) |
- PCIE_ATU_FUNC(PCI_FUNC(devfn));
- address = where & ~0x3;
-
- if (bus->primary == pp->root_bus_nr) {
- type = PCIE_ATU_TYPE_CFG0;
- cpu_addr = pp->cfg0_mod_base;
- cfg_size = pp->cfg0_size;
- va_cfg_base = pp->va_cfg0_base;
- } else {
- type = PCIE_ATU_TYPE_CFG1;
- cpu_addr = pp->cfg1_mod_base;
- cfg_size = pp->cfg1_size;
- va_cfg_base = pp->va_cfg1_base;
- }
-
- dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1,
- type, cpu_addr,
- busdev, cfg_size);
- ret = dw_pcie_read(va_cfg_base + where, size, val);
- if (pci->num_viewport <= 2)
- dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1,
- PCIE_ATU_TYPE_IO, pp->io_mod_base,
- pp->io_bus_addr, pp->io_size);
-
- return ret;
-}
-
-static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
- u32 devfn, int where, int size, u32 val)
-{
- int ret, type;
- u32 busdev, cfg_size;
- u64 cpu_addr;
- void __iomem *va_cfg_base;
- struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
-
- if (pp->ops->wr_other_conf)
- return pp->ops->wr_other_conf(pp, bus, devfn,
- where, size, val);
-
- busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) |
- PCIE_ATU_FUNC(PCI_FUNC(devfn));
-
- if (bus->primary == pp->root_bus_nr) {
- type = PCIE_ATU_TYPE_CFG0;
- cpu_addr = pp->cfg0_mod_base;
- cfg_size = pp->cfg0_size;
- va_cfg_base = pp->va_cfg0_base;
- } else {
- type = PCIE_ATU_TYPE_CFG1;
- cpu_addr = pp->cfg1_mod_base;
- cfg_size = pp->cfg1_size;
- va_cfg_base = pp->va_cfg1_base;
- }
-
- dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1,
- type, cpu_addr,
- busdev, cfg_size);
- ret = dw_pcie_write(va_cfg_base + where, size, val);
- if (pci->num_viewport <= 2)
- dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1,
- PCIE_ATU_TYPE_IO, pp->io_mod_base,
- pp->io_bus_addr, pp->io_size);
-
- return ret;
-}
-
-static int dw_pcie_valid_device(struct pcie_port *pp, struct pci_bus *bus,
- int dev)
-{
- struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
-
- /* If there is no link, then there is no device */
- if (bus->number != pp->root_bus_nr) {
- if (!dw_pcie_link_up(pci))
- return 0;
- }
-
- /* access only one slot on each root port */
- if (bus->number == pp->root_bus_nr && dev > 0)
- return 0;
-
- /*
- * do not read more than one device on the bus directly attached
- * to RC's (Virtual Bridge's) DS side.
- */
- if (bus->primary == pp->root_bus_nr && dev > 0)
- return 0;
-
- return 1;
-}
-
-static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
- int size, u32 *val)
-{
- struct pcie_port *pp = host_to_pcie(bus->host);
- int ret;
-
- *val = 0xffffffff;
-
- if (!dw_pcie_valid_device(pp, bus, PCI_SLOT(devfn)))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- data_abort_mask();
-
- if (bus->number == pp->root_bus_nr)
- ret = dw_pcie_rd_own_conf(pp, where, size, val);
- else
- ret = dw_pcie_rd_other_conf(pp, bus, devfn,
- where, size, val);
-
- if (data_abort_unmask())
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- return ret;
-}
-
-static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
- int where, int size, u32 val)
-{
- struct pcie_port *pp = host_to_pcie(bus->host);
int ret;
-
- if (!dw_pcie_valid_device(pp, bus, PCI_SLOT(devfn)))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- data_abort_mask();
-
- if (bus->number == pp->root_bus_nr)
- ret = dw_pcie_wr_own_conf(pp, where, size, val);
- else
- ret = dw_pcie_wr_other_conf(pp, bus, devfn,
- where, size, val);
-
- if (data_abort_unmask())
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- return ret;
-}
-
-static int dw_pcie_res_start(struct pci_bus *bus, resource_size_t res_addr)
-{
- return res_addr;
-}
-
-static struct pci_ops dw_pcie_ops = {
- .read = dw_pcie_rd_conf,
- .write = dw_pcie_wr_conf,
- .res_start = dw_pcie_res_start,
-};
-
-void dw_pcie_setup_rc(struct pcie_port *pp)
-{
- int ret;
- u32 lanes;
u32 val;
- struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ u32 lanes;
struct device_d *dev = pci->dev;
struct device_node *np = dev->device_node;
@@ -562,52 +232,6 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
break;
}
dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val);
-
- /* setup RC BARs */
- dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, 0x00000004);
- dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_1, 0x00000000);
-
- /* setup bus numbers */
- val = dw_pcie_readl_dbi(pci, PCI_PRIMARY_BUS);
- val &= 0xff000000;
- val |= 0x00010100;
- dw_pcie_writel_dbi(pci, PCI_PRIMARY_BUS, val);
-
- /* setup command register */
- val = dw_pcie_readl_dbi(pci, PCI_COMMAND);
- val &= 0xffff0000;
- val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
- PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
- dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
-
- /*
- * If the platform provides ->rd_other_conf, it means the platform
- * uses its own address translation component rather than ATU, so
- * we should not program the ATU here.
- */
- if (!pp->ops->rd_other_conf) {
- /* get iATU unroll support */
- pci->iatu_unroll_enabled = dw_pcie_iatu_unroll_enabled(pci);
- dev_dbg(pci->dev, "iATU unroll: %s\n",
- pci->iatu_unroll_enabled ? "enabled" : "disabled");
-
- dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX0,
- PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
- pp->mem_bus_addr, pp->mem_size);
- if (pci->num_viewport > 2)
- dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX2,
- PCIE_ATU_TYPE_IO, pp->io_base,
- pp->io_bus_addr, pp->io_size);
- }
-
- dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
-
- /* program correct class for RC */
- dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2, PCI_CLASS_BRIDGE_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);
}
MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
diff --git a/drivers/pci/pcie-designware.h b/drivers/pci/pcie-designware.h
index 06d8c769c..97c8b0b3c 100644
--- a/drivers/pci/pcie-designware.h
+++ b/drivers/pci/pcie-designware.h
@@ -159,5 +159,8 @@ u32 dw_pcie_readl_dbi(struct dw_pcie *pci, u32 reg);
void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val);
int dw_pcie_link_up(struct dw_pcie *pci);
int dw_pcie_wait_for_link(struct dw_pcie *pci);
-
+void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,
+ int type, u64 cpu_addr, u64 pci_addr,
+ u32 size);
+void dw_pcie_setup(struct dw_pcie *pci);
#endif /* _PCIE_DESIGNWARE_H */
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 52/65] PCI: dwc: all: Modify dbi accessors to take dbi_base as argument
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (50 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 51/65] PCI: dwc: Split pcie-designware.c into host and core files Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 53/65] PCI: dwc: all: Modify dbi accessors to access data of 4/2/1 bytes Andrey Smirnov
` (13 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit b50b2db266d8a8c303e8d88590c6416dfe576c6c
dwc has 2 dbi address space labeled dbics and dbics2. The existing helper
to access dbi address space can access only dbics. However dbics2 has to
be accessed for programming the BAR registers in the case of EP mode. This
is in preparation for adding EP mode support to dwc driver.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Niklas Cassel <niklas.cassel@axis.com>
Cc: Jingoo Han <jingoohan1@gmail.com>
Cc: Joao Pinto <Joao.Pinto@synopsys.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 13 +++++++------
drivers/pci/pcie-designware.h | 19 +++++++++++++++----
2 files changed, 22 insertions(+), 10 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index 6687fff8b..25f9f8df1 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -68,20 +68,21 @@ int dw_pcie_write(void __iomem *addr, int size, u32 val)
return PCIBIOS_SUCCESSFUL;
}
-u32 dw_pcie_readl_dbi(struct dw_pcie *pci, u32 reg)
+u32 __dw_pcie_readl_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg)
{
if (pci->ops->readl_dbi)
- return pci->ops->readl_dbi(pci, reg);
+ return pci->ops->readl_dbi(pci, base, reg);
- return readl(pci->dbi_base + reg);
+ return readl(base + reg);
}
-void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val)
+void __dw_pcie_writel_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg,
+ u32 val)
{
if (pci->ops->writel_dbi)
- pci->ops->writel_dbi(pci, reg, val);
+ pci->ops->writel_dbi(pci, base, reg, val);
else
- writel(val, pci->dbi_base + reg);
+ writel(val, base + reg);
}
static u32 dw_pcie_readl_unroll(struct dw_pcie *pci, u32 index, u32 reg)
diff --git a/drivers/pci/pcie-designware.h b/drivers/pci/pcie-designware.h
index 97c8b0b3c..10deb577a 100644
--- a/drivers/pci/pcie-designware.h
+++ b/drivers/pci/pcie-designware.h
@@ -134,8 +134,9 @@ struct pcie_port {
};
struct dw_pcie_ops {
- u32 (*readl_dbi)(struct dw_pcie *pcie, u32 reg);
- void (*writel_dbi)(struct dw_pcie *pcie, u32 reg, u32 val);
+ u32 (*readl_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg);
+ void (*writel_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg,
+ u32 val);
int (*link_up)(struct dw_pcie *pcie);
};
@@ -155,12 +156,22 @@ int dw_pcie_write(void __iomem *addr, int size, u32 val);
void dw_pcie_setup_rc(struct pcie_port *pp);
int dw_pcie_host_init(struct pcie_port *pp);
-u32 dw_pcie_readl_dbi(struct dw_pcie *pci, u32 reg);
-void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val);
+u32 __dw_pcie_readl_dbi(struct dw_pcie *pci, void __iomem *addr, u32 reg);
+void __dw_pcie_writel_dbi(struct dw_pcie *pci, void __iomem *addr, u32 reg, u32 val);
int dw_pcie_link_up(struct dw_pcie *pci);
int dw_pcie_wait_for_link(struct dw_pcie *pci);
void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,
int type, u64 cpu_addr, u64 pci_addr,
u32 size);
void dw_pcie_setup(struct dw_pcie *pci);
+
+static inline void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val)
+{
+ __dw_pcie_writel_dbi(pci, pci->dbi_base, reg, val);
+}
+
+static inline u32 dw_pcie_readl_dbi(struct dw_pcie *pci, u32 reg)
+{
+ return __dw_pcie_readl_dbi(pci, pci->dbi_base, reg);
+}
#endif /* _PCIE_DESIGNWARE_H */
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 53/65] PCI: dwc: all: Modify dbi accessors to access data of 4/2/1 bytes
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (51 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 52/65] PCI: dwc: all: Modify dbi accessors to take dbi_base as argument Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 54/65] PCI: dwc: designware: Move _unroll configurations to a separate function Andrey Smirnov
` (12 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit a509d7d9af5ebf86ffbefa98e49761d813fb1d40
Previously dbi accessors can be used to access data of size 4 bytes. But
there might be situations (like accessing MSI_MESSAGE_CONTROL in order to
set/get the number of required MSI interrupts in EP mode) where dbi
accessors must be used to access data of size 2. This is in preparation
for adding endpoint mode support to designware driver.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Niklas Cassel <niklas.cassel@axis.com>
Cc: Jingoo Han <jingoohan1@gmail.com>
Cc: Joao Pinto <Joao.Pinto@synopsys.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 30 ++++++++++++++++++++++--------
drivers/pci/pcie-designware.h | 15 +++++++++------
2 files changed, 31 insertions(+), 14 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index 25f9f8df1..e67991fa0 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -68,21 +68,35 @@ int dw_pcie_write(void __iomem *addr, int size, u32 val)
return PCIBIOS_SUCCESSFUL;
}
-u32 __dw_pcie_readl_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg)
+u32 __dw_pcie_readl_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg,
+ size_t size)
{
+ int ret;
+ u32 val;
+
if (pci->ops->readl_dbi)
- return pci->ops->readl_dbi(pci, base, reg);
+ return pci->ops->readl_dbi(pci, base, reg, size);
- return readl(base + reg);
+ ret = dw_pcie_read(base + reg, size, &val);
+ if (ret)
+ dev_err(pci->dev, "read DBI address failed\n");
+
+ return val;
}
void __dw_pcie_writel_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg,
- u32 val)
+ size_t size, u32 val)
{
- if (pci->ops->writel_dbi)
- pci->ops->writel_dbi(pci, base, reg, val);
- else
- writel(val, base + reg);
+ int ret;
+
+ if (pci->ops->writel_dbi) {
+ pci->ops->writel_dbi(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_unroll(struct dw_pcie *pci, u32 index, u32 reg)
diff --git a/drivers/pci/pcie-designware.h b/drivers/pci/pcie-designware.h
index 10deb577a..149ce1da5 100644
--- a/drivers/pci/pcie-designware.h
+++ b/drivers/pci/pcie-designware.h
@@ -134,9 +134,10 @@ struct pcie_port {
};
struct dw_pcie_ops {
- u32 (*readl_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg);
+ u32 (*readl_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg,
+ size_t size);
void (*writel_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg,
- u32 val);
+ size_t size, u32 val);
int (*link_up)(struct dw_pcie *pcie);
};
@@ -156,8 +157,10 @@ int dw_pcie_write(void __iomem *addr, int size, u32 val);
void dw_pcie_setup_rc(struct pcie_port *pp);
int dw_pcie_host_init(struct pcie_port *pp);
-u32 __dw_pcie_readl_dbi(struct dw_pcie *pci, void __iomem *addr, u32 reg);
-void __dw_pcie_writel_dbi(struct dw_pcie *pci, void __iomem *addr, u32 reg, u32 val);
+u32 __dw_pcie_readl_dbi(struct dw_pcie *pci, void __iomem *addr, u32 reg,
+ size_t size);
+void __dw_pcie_writel_dbi(struct dw_pcie *pci, void __iomem *addr, u32 reg,
+ size_t size, u32 val);
int dw_pcie_link_up(struct dw_pcie *pci);
int dw_pcie_wait_for_link(struct dw_pcie *pci);
void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,
@@ -167,11 +170,11 @@ void dw_pcie_setup(struct dw_pcie *pci);
static inline void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val)
{
- __dw_pcie_writel_dbi(pci, pci->dbi_base, reg, val);
+ __dw_pcie_writel_dbi(pci, pci->dbi_base, reg, 0x4, val);
}
static inline u32 dw_pcie_readl_dbi(struct dw_pcie *pci, u32 reg)
{
- return __dw_pcie_readl_dbi(pci, pci->dbi_base, reg);
+ return __dw_pcie_readl_dbi(pci, pci->dbi_base, reg, 0x4);
}
#endif /* _PCIE_DESIGNWARE_H */
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 54/65] PCI: dwc: designware: Move _unroll configurations to a separate function
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (52 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 53/65] PCI: dwc: all: Modify dbi accessors to access data of 4/2/1 bytes Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 55/65] PCI: dwc: designware: Test PCIE_ATU_ENABLE bit specifically Andrey Smirnov
` (11 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit edd45e3968299f9b4635bdfeca1edab842d81eac
No functional change. Rename dw_pcie_writel_unroll/dw_pcie_readl_unroll to
dw_pcie_writel_ob_unroll/dw_pcie_readl_ob_unroll respectively as these
functions are used to perform only outbound configurations. Also move
these _unroll configurations to a separate function.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 98 +++++++++++++++++++++--------------
1 file changed, 59 insertions(+), 39 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index e67991fa0..5c476e815 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -99,21 +99,57 @@ void __dw_pcie_writel_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg,
dev_err(pci->dev, "write DBI address failed\n");
}
-static u32 dw_pcie_readl_unroll(struct dw_pcie *pci, u32 index, u32 reg)
+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);
return dw_pcie_readl_dbi(pci, offset + reg);
}
-static void dw_pcie_writel_unroll(struct dw_pcie *pci, u32 index,
- u32 reg, u32 val)
+static void dw_pcie_writel_ob_unroll(struct dw_pcie *pci, u32 index,
+ u32 reg, u32 val)
{
u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);
dw_pcie_writel_dbi(pci, offset + reg, val);
}
+void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, int index, int type,
+ u64 cpu_addr, u64 pci_addr, u32 size)
+
+{
+ u32 retries, val;
+
+ dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_LOWER_BASE,
+ lower_32_bits(cpu_addr));
+ dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_UPPER_BASE,
+ upper_32_bits(cpu_addr));
+ dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_LIMIT,
+ lower_32_bits(cpu_addr + size - 1));
+ dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_LOWER_TARGET,
+ lower_32_bits(pci_addr));
+ dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_UPPER_TARGET,
+ upper_32_bits(pci_addr));
+ dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL1,
+ type);
+ dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2,
+ PCIE_ATU_ENABLE);
+
+ /*
+ * Make sure ATU enable takes effect before any subsequent config
+ * and I/O accesses.
+ */
+ for (retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; retries++) {
+ val = dw_pcie_readl_ob_unroll(pci, index,
+ PCIE_ATU_UNR_REGION_CTRL2);
+ if (val & PCIE_ATU_ENABLE)
+ return;
+
+ udelay(LINK_WAIT_IATU_MAX);
+ }
+ dev_err(pci->dev, "outbound iATU is not being enabled\n");
+}
+
void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,
int type, u64 cpu_addr, u64 pci_addr,
u32 size)
@@ -121,54 +157,38 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,
u32 retries, val;
if (pci->iatu_unroll_enabled) {
- dw_pcie_writel_unroll(pci, index, PCIE_ATU_UNR_LOWER_BASE,
- lower_32_bits(cpu_addr));
- dw_pcie_writel_unroll(pci, index, PCIE_ATU_UNR_UPPER_BASE,
- upper_32_bits(cpu_addr));
- dw_pcie_writel_unroll(pci, index, PCIE_ATU_UNR_LIMIT,
- lower_32_bits(cpu_addr + size - 1));
- dw_pcie_writel_unroll(pci, index, PCIE_ATU_UNR_LOWER_TARGET,
- lower_32_bits(pci_addr));
- dw_pcie_writel_unroll(pci, index, PCIE_ATU_UNR_UPPER_TARGET,
- upper_32_bits(pci_addr));
- dw_pcie_writel_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL1,
- type);
- dw_pcie_writel_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2,
- PCIE_ATU_ENABLE);
- } else {
- dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT,
- PCIE_ATU_REGION_OUTBOUND | index);
- dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_BASE,
- lower_32_bits(cpu_addr));
- dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_BASE,
- upper_32_bits(cpu_addr));
- dw_pcie_writel_dbi(pci, PCIE_ATU_LIMIT,
- lower_32_bits(cpu_addr + size - 1));
- dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_TARGET,
- lower_32_bits(pci_addr));
- dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_TARGET,
- upper_32_bits(pci_addr));
- dw_pcie_writel_dbi(pci, PCIE_ATU_CR1, type);
- dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, PCIE_ATU_ENABLE);
+ dw_pcie_prog_outbound_atu_unroll(pci, index, type, cpu_addr,
+ pci_addr, size);
+ return;
}
+ dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT,
+ PCIE_ATU_REGION_OUTBOUND | index);
+ dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_BASE,
+ lower_32_bits(cpu_addr));
+ dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_BASE,
+ upper_32_bits(cpu_addr));
+ dw_pcie_writel_dbi(pci, PCIE_ATU_LIMIT,
+ lower_32_bits(cpu_addr + size - 1));
+ dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_TARGET,
+ lower_32_bits(pci_addr));
+ dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_TARGET,
+ upper_32_bits(pci_addr));
+ dw_pcie_writel_dbi(pci, PCIE_ATU_CR1, type);
+ dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, PCIE_ATU_ENABLE);
+
/*
* Make sure ATU enable takes effect before any subsequent config
* and I/O accesses.
*/
for (retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; retries++) {
- if (pci->iatu_unroll_enabled)
- val = dw_pcie_readl_unroll(pci, index,
- PCIE_ATU_UNR_REGION_CTRL2);
- else
- val = dw_pcie_readl_dbi(pci, PCIE_ATU_CR2);
-
+ val = dw_pcie_readl_dbi(pci, PCIE_ATU_CR2);
if (val == PCIE_ATU_ENABLE)
return;
udelay(LINK_WAIT_IATU_MAX);
}
- dev_err(pci->dev, "iATU is not being enabled\n");
+ dev_err(pci->dev, "outbound iATU is not being enabled\n");
}
int dw_pcie_wait_for_link(struct dw_pcie *pci)
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 55/65] PCI: dwc: designware: Test PCIE_ATU_ENABLE bit specifically
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (53 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 54/65] PCI: dwc: designware: Move _unroll configurations to a separate function Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 56/65] PCI: dwc: designware: Make dw_pcie_prog_*_atu_unroll() static Andrey Smirnov
` (10 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit e9be4d78618af2e0d5592d9556cf0bba210cfd1a
The ATU CTRL2 register is 32 bits, and bits other than the enable bit may
be set. To check whether the ATU is enabled or not, we should test the
enable bit specifically.
Signed-off-by: Jisheng Zhang <jszhang@marvell.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Joao Pinto <jpinto@synopsys.com>
Acked-by: Jingoo Han <jingoohan1@gmail.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index 5c476e815..d2d4fe34a 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -183,7 +183,7 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,
*/
for (retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; retries++) {
val = dw_pcie_readl_dbi(pci, PCIE_ATU_CR2);
- if (val == PCIE_ATU_ENABLE)
+ if (val & PCIE_ATU_ENABLE)
return;
udelay(LINK_WAIT_IATU_MAX);
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 56/65] PCI: dwc: designware: Make dw_pcie_prog_*_atu_unroll() static
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (54 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 55/65] PCI: dwc: designware: Test PCIE_ATU_ENABLE bit specifically Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 57/65] PCI: Fix typos and whitespace errors Andrey Smirnov
` (9 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 684a3a91da401195dbe33b7cef9472bca41c61b9
Helper functions dw_pcie_prog_*_atu_unroll() don't need to be in global
scope, so make them static.
Cleans up sparse warnings:
- symbol 'dw_pcie_prog_outbound_atu_unroll' was not declared. Should it be static?
- symbol 'dw_pcie_prog_inbound_atu_unroll' was not declared. Should it be static?
Signed-off-by: Carlos Palminha <palminha@synopsys.com>
[bhelgaas: rewrap to fit in 80 columns]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Joao Pinto <jpinto@synopsys.com>
Acked-by: Jingoo Han <jingoohan1@gmail.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index d2d4fe34a..211acdfed 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -114,9 +114,9 @@ static void dw_pcie_writel_ob_unroll(struct dw_pcie *pci, u32 index,
dw_pcie_writel_dbi(pci, offset + reg, val);
}
-void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, int index, int type,
- u64 cpu_addr, u64 pci_addr, u32 size)
-
+static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, int index,
+ int type, u64 cpu_addr,
+ u64 pci_addr, u32 size)
{
u32 retries, val;
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 57/65] PCI: Fix typos and whitespace errors
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (55 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 56/65] PCI: dwc: designware: Make dw_pcie_prog_*_atu_unroll() static Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 58/65] PCI: Add SPDX GPL-2.0 to replace GPL v2 boilerplate Andrey Smirnov
` (8 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 96291d565550c1fd363e488cc17cb3189d2e4cc2
Fix various typos and whitespace errors:
s/Synopsis/Synopsys/
s/Designware/DesignWare/
s/Keystine/Keystone/
s/gpio/GPIO/
s/pcie/PCIe/
s/phy/PHY/
s/confgiruation/configuration/
No functional change intended.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware-host.c | 2 +-
drivers/pci/pcie-designware.c | 2 +-
drivers/pci/pcie-designware.h | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/pcie-designware-host.c b/drivers/pci/pcie-designware-host.c
index 30bed9444..d4fd58377 100644
--- a/drivers/pci/pcie-designware-host.c
+++ b/drivers/pci/pcie-designware-host.c
@@ -1,5 +1,5 @@
/*
- * Synopsys Designware PCIe host controller driver
+ * Synopsys DesignWare PCIe host controller driver
*
* Copyright (C) 2013 Samsung Electronics Co., Ltd.
* http://www.samsung.com
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index 211acdfed..e608ad47a 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -1,5 +1,5 @@
/*
- * Synopsys Designware PCIe host controller driver
+ * Synopsys DesignWare PCIe host controller driver
*
* Copyright (C) 2013 Samsung Electronics Co., Ltd.
* http://www.samsung.com
diff --git a/drivers/pci/pcie-designware.h b/drivers/pci/pcie-designware.h
index 149ce1da5..98565f201 100644
--- a/drivers/pci/pcie-designware.h
+++ b/drivers/pci/pcie-designware.h
@@ -1,5 +1,5 @@
/*
- * Synopsys Designware PCIe host controller driver
+ * Synopsys DesignWare PCIe host controller driver
*
* Copyright (C) 2013 Samsung Electronics Co., Ltd.
* http://www.samsung.com
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 58/65] PCI: Add SPDX GPL-2.0 to replace GPL v2 boilerplate
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (56 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 57/65] PCI: Fix typos and whitespace errors Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 59/65] PCI: dwc: Replace lower into upper case characters Andrey Smirnov
` (7 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 8cfab3cf63cfe5a53e2e566b3b86b30c187edf3a
Add SPDX GPL-2.0 to all PCI files that specified the GPL version 2 license.
Remove the boilerplate GPL version 2 language, relying on the assertion in
b24413180f56 ("License cleanup: add SPDX GPL-2.0 license identifier to
files with no license") that the SPDX identifier may be used instead of the
full boilerplate text.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pci-imx6.c | 5 +----
drivers/pci/pci-mvebu-phy.c | 5 +----
drivers/pci/pci-mvebu.c | 5 +----
drivers/pci/pci-mvebu.h | 5 +----
drivers/pci/pci-tegra.c | 13 +------------
drivers/pci/pcie-designware-host.c | 5 +----
drivers/pci/pcie-designware.c | 5 +----
drivers/pci/pcie-designware.h | 5 +----
8 files changed, 8 insertions(+), 40 deletions(-)
diff --git a/drivers/pci/pci-imx6.c b/drivers/pci/pci-imx6.c
index 67ef47db9..78aa5215a 100644
--- a/drivers/pci/pci-imx6.c
+++ b/drivers/pci/pci-imx6.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PCIe host controller driver for Freescale i.MX6 SoCs
*
@@ -5,10 +6,6 @@
* http://www.kosagi.com
*
* Author: Sean Cross <xobs@kosagi.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
*/
#include <common.h>
diff --git a/drivers/pci/pci-mvebu-phy.c b/drivers/pci/pci-mvebu-phy.c
index 55a1d39f6..f1bfc99ee 100644
--- a/drivers/pci/pci-mvebu-phy.c
+++ b/drivers/pci/pci-mvebu-phy.c
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* SoC specific PCIe PHY setup for Marvell MVEBU SoCs
*
* Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
*
* based on Marvell BSP code (C) Marvell International Ltd.
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
*/
#include <common.h>
diff --git a/drivers/pci/pci-mvebu.c b/drivers/pci/pci-mvebu.c
index 91e8ca870..1c20f9154 100644
--- a/drivers/pci/pci-mvebu.c
+++ b/drivers/pci/pci-mvebu.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PCIe driver for Marvell MVEBU SoCs
*
* Based on Linux drivers/pci/host/pci-mvebu.c
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
*/
#include <common.h>
diff --git a/drivers/pci/pci-mvebu.h b/drivers/pci/pci-mvebu.h
index 8ced9fefc..2797bc4c8 100644
--- a/drivers/pci/pci-mvebu.h
+++ b/drivers/pci/pci-mvebu.h
@@ -1,11 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* PCIe include for Marvell MVEBU SoCs
*
* Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
*/
#ifndef __MVEBU_PCI_H
diff --git a/drivers/pci/pci-tegra.c b/drivers/pci/pci-tegra.c
index b532c464a..b6ccf8e5b 100644
--- a/drivers/pci/pci-tegra.c
+++ b/drivers/pci/pci-tegra.c
@@ -1,21 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2014 Lucas Stach <l.stach@pengutronix.de>
*
* based on code
* Copyright (c) 2010, CompuLab, Ltd.
* Copyright (c) 2008-2009, NVIDIA Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <common.h>
diff --git a/drivers/pci/pcie-designware-host.c b/drivers/pci/pcie-designware-host.c
index d4fd58377..29967fbc5 100644
--- a/drivers/pci/pcie-designware-host.c
+++ b/drivers/pci/pcie-designware-host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Synopsys DesignWare PCIe host controller driver
*
@@ -5,10 +6,6 @@
* http://www.samsung.com
*
* Author: Jingoo Han <jg1.han@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
*/
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index e608ad47a..6b2458c9f 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Synopsys DesignWare PCIe host controller driver
*
@@ -5,10 +6,6 @@
* http://www.samsung.com
*
* Author: Jingoo Han <jg1.han@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
*/
diff --git a/drivers/pci/pcie-designware.h b/drivers/pci/pcie-designware.h
index 98565f201..b18f1b83e 100644
--- a/drivers/pci/pcie-designware.h
+++ b/drivers/pci/pcie-designware.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Synopsys DesignWare PCIe host controller driver
*
@@ -5,10 +6,6 @@
* http://www.samsung.com
*
* Author: Jingoo Han <jg1.han@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
*/
#ifndef _PCIE_DESIGNWARE_H
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 59/65] PCI: dwc: Replace lower into upper case characters
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (57 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 58/65] PCI: Add SPDX GPL-2.0 to replace GPL v2 boilerplate Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 60/65] PCI: dwc: designware: Handle ->host_init() failures Andrey Smirnov
` (6 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit b4a8a51caf7de47c2fb03dfb1bbbe442661b5732
Replace of all initial lowercase character in comments and debug messages
to uppercase to maintain coherence.
Fix messages coherence within the DesignWare driver.
Fix code style on dw_pcie_irq_domain_free() function.
Signed-off-by: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Jingoo Han <jingoohan1@gmail.com>
Acked-by: Joao Pinto <jpinto@synopsys.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware-host.c | 16 ++++++++--------
drivers/pci/pcie-designware.c | 12 ++++++------
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/pci/pcie-designware-host.c b/drivers/pci/pcie-designware-host.c
index 29967fbc5..5de9cd8ea 100644
--- a/drivers/pci/pcie-designware-host.c
+++ b/drivers/pci/pcie-designware-host.c
@@ -99,11 +99,11 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
pp->cfg0_mod_base = of_read_number(addrp, ns);
pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
} else {
- dev_err(dev, "missing *config* reg space\n");
+ dev_err(dev, "Missing *config* reg space\n");
}
if (of_pci_range_parser_init(&parser, np)) {
- dev_err(dev, "missing ranges property\n");
+ dev_err(dev, "Missing ranges property\n");
return -EINVAL;
}
@@ -270,12 +270,12 @@ static int dw_pcie_valid_device(struct pcie_port *pp, struct pci_bus *bus,
return 0;
}
- /* access only one slot on each root port */
+ /* Access only one slot on each root port */
if (bus->number == pp->root_bus_nr && dev > 0)
return 0;
/*
- * do not read more than one device on the bus directly attached
+ * Do not read more than one device on the bus directly attached
* to RC's (Virtual Bridge's) DS side.
*/
if (bus->primary == pp->root_bus_nr && dev > 0)
@@ -361,17 +361,17 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
dw_pcie_setup(pci);
- /* setup RC BARs */
+ /* Setup RC BARs */
dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, 0x00000004);
dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_1, 0x00000000);
- /* setup bus numbers */
+ /* Setup bus numbers */
val = dw_pcie_readl_dbi(pci, PCI_PRIMARY_BUS);
val &= 0xff000000;
val |= 0x00010100;
dw_pcie_writel_dbi(pci, PCI_PRIMARY_BUS, val);
- /* setup command register */
+ /* Setup command register */
val = dw_pcie_readl_dbi(pci, PCI_COMMAND);
val &= 0xffff0000;
val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
@@ -400,7 +400,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
- /* program correct class for RC */
+ /* Program correct class for RC */
dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2, PCI_CLASS_BRIDGE_PCI);
dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, &val);
diff --git a/drivers/pci/pcie-designware.c b/drivers/pci/pcie-designware.c
index 6b2458c9f..aaea316e9 100644
--- a/drivers/pci/pcie-designware.c
+++ b/drivers/pci/pcie-designware.c
@@ -76,7 +76,7 @@ u32 __dw_pcie_readl_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg,
ret = dw_pcie_read(base + reg, size, &val);
if (ret)
- dev_err(pci->dev, "read DBI address failed\n");
+ dev_err(pci->dev, "Read DBI address failed\n");
return val;
}
@@ -93,7 +93,7 @@ void __dw_pcie_writel_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg,
ret = dw_pcie_write(base + reg, size, val);
if (ret)
- dev_err(pci->dev, "write DBI address failed\n");
+ dev_err(pci->dev, "Write DBI address failed\n");
}
static u32 dw_pcie_readl_ob_unroll(struct dw_pcie *pci, u32 index, u32 reg)
@@ -144,7 +144,7 @@ static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, int index,
udelay(LINK_WAIT_IATU_MAX);
}
- dev_err(pci->dev, "outbound iATU is not being enabled\n");
+ dev_err(pci->dev, "Outbound iATU is not being enabled\n");
}
void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,
@@ -185,7 +185,7 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,
udelay(LINK_WAIT_IATU_MAX);
}
- dev_err(pci->dev, "outbound iATU is not being enabled\n");
+ dev_err(pci->dev, "Outbound iATU is not being enabled\n");
}
int dw_pcie_wait_for_link(struct dw_pcie *pci)
@@ -230,7 +230,7 @@ void dw_pcie_setup(struct dw_pcie *pci)
if (ret)
lanes = 0;
- /* set the number of lanes */
+ /* Set the number of lanes */
val = dw_pcie_readl_dbi(pci, PCIE_PORT_LINK_CONTROL);
val &= ~PORT_LINK_MODE_MASK;
switch (lanes) {
@@ -249,7 +249,7 @@ void dw_pcie_setup(struct dw_pcie *pci)
}
dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, val);
- /* set link width speed control register */
+ /* Set link width speed control register */
val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
val &= ~PORT_LOGIC_LINK_WIDTH_MASK;
switch (lanes) {
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 60/65] PCI: dwc: designware: Handle ->host_init() failures
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (58 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 59/65] PCI: dwc: Replace lower into upper case characters Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 61/65] PCI: dwc: Add accessors for write permission of DBI Andrey Smirnov
` (5 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 4a301766f5263dd94c1b95d1b1bbdf338afb1a37
In several dwc-based drivers, ->host_init() can fail, so make sure to
propagate and handle this to avoid continuing operation of a driver or
hardware in an invalid state.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Joao Pinto <jpinto@synopsys.com>
Acked-by: Jingoo Han <jingoohan1@gmail.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pci-imx6.c | 4 +++-
drivers/pci/pcie-designware-host.c | 7 +++++--
drivers/pci/pcie-designware.h | 2 +-
3 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/pci-imx6.c b/drivers/pci/pci-imx6.c
index 78aa5215a..1807f29c9 100644
--- a/drivers/pci/pci-imx6.c
+++ b/drivers/pci/pci-imx6.c
@@ -477,7 +477,7 @@ err_reset_phy:
return ret;
}
-static void imx6_pcie_host_init(struct pcie_port *pp)
+static int imx6_pcie_host_init(struct pcie_port *pp)
{
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);
@@ -487,6 +487,8 @@ static void imx6_pcie_host_init(struct pcie_port *pp)
imx6_pcie_deassert_core_reset(imx6_pcie);
dw_pcie_setup_rc(pp);
imx6_pcie_establish_link(imx6_pcie);
+
+ return 0;
}
static int imx6_pcie_link_up(struct dw_pcie *pci)
diff --git a/drivers/pci/pcie-designware-host.c b/drivers/pci/pcie-designware-host.c
index 5de9cd8ea..e98560818 100644
--- a/drivers/pci/pcie-designware-host.c
+++ b/drivers/pci/pcie-designware-host.c
@@ -164,8 +164,11 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
if (ret)
pci->num_viewport = 2;
- if (pp->ops->host_init)
- pp->ops->host_init(pp);
+ if (pp->ops->host_init) {
+ ret = pp->ops->host_init(pp);
+ if (ret)
+ return ret;
+ }
pp->pci.parent = dev;
pp->pci.pci_ops = &dw_pcie_ops;
diff --git a/drivers/pci/pcie-designware.h b/drivers/pci/pcie-designware.h
index b18f1b83e..933c2b533 100644
--- a/drivers/pci/pcie-designware.h
+++ b/drivers/pci/pcie-designware.h
@@ -99,7 +99,7 @@ struct dw_pcie_host_ops {
unsigned int devfn, int where, int size, u32 *val);
int (*wr_other_conf)(struct pcie_port *pp, struct pci_bus *bus,
unsigned int devfn, int where, int size, u32 val);
- void (*host_init)(struct pcie_port *pp);
+ int (*host_init)(struct pcie_port *pp);
void (*scan_bus)(struct pcie_port *pp);
};
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 61/65] PCI: dwc: Add accessors for write permission of DBI
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (59 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 60/65] PCI: dwc: designware: Handle ->host_init() failures Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 62/65] PCI: dwc: Enable write permission for Class Code, Interrupt Pin updates Andrey Smirnov
` (4 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit e44abfed6fcb750d24f4438dc9d5a02eebb5fcac
The read-only DBI registers can be written only when the "Write to RO
Registers Using DBI" (DBI_RO_WR_EN) field of MISC_CONTROL_1_OFF is set.
Add accessors to enable and disable write permission, and use them instead
of accessing MISC_CONTROL_1_OFF directly.
Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Joao Pinto <jpinto@synopsys.com>
Acked-by: Roy Zang <tie-fei.zang@freescale.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware.h | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/drivers/pci/pcie-designware.h b/drivers/pci/pcie-designware.h
index 933c2b533..0f1659319 100644
--- a/drivers/pci/pcie-designware.h
+++ b/drivers/pci/pcie-designware.h
@@ -83,6 +83,9 @@
#define PCIE_PHY_DEBUG_R1_LINK_UP (0x1 << 4)
#define PCIE_PHY_DEBUG_R1_LINK_IN_TRAINING (0x1 << 29)
+#define PCIE_MISC_CONTROL_1_OFF 0x8BC
+#define PCIE_DBI_RO_WR_EN (0x1 << 0)
+
/* PCIe Port Logic registers */
#define PLR_OFFSET 0x700
#define PCIE_PHY_DEBUG_R1 (PLR_OFFSET + 0x2c)
@@ -174,4 +177,27 @@ static inline u32 dw_pcie_readl_dbi(struct dw_pcie *pci, u32 reg)
{
return __dw_pcie_readl_dbi(pci, pci->dbi_base, reg, 0x4);
}
+
+static inline void dw_pcie_dbi_ro_wr_en(struct dw_pcie *pci)
+{
+ u32 reg;
+ u32 val;
+
+ reg = PCIE_MISC_CONTROL_1_OFF;
+ val = dw_pcie_readl_dbi(pci, reg);
+ val |= PCIE_DBI_RO_WR_EN;
+ dw_pcie_writel_dbi(pci, reg, val);
+}
+
+static inline void dw_pcie_dbi_ro_wr_dis(struct dw_pcie *pci)
+{
+ u32 reg;
+ u32 val;
+
+ reg = PCIE_MISC_CONTROL_1_OFF;
+ val = dw_pcie_readl_dbi(pci, reg);
+ val &= ~PCIE_DBI_RO_WR_EN;
+ dw_pcie_writel_dbi(pci, reg, val);
+}
+
#endif /* _PCIE_DESIGNWARE_H */
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 62/65] PCI: dwc: Enable write permission for Class Code, Interrupt Pin updates
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (60 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 61/65] PCI: dwc: Add accessors for write permission of DBI Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 63/65] PCI: dwc: Fix enumeration end when reaching root subordinate Andrey Smirnov
` (3 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit d91dfe5054d4f2c424bd70ca34fc3328ee179f20
dw_pcie_setup_rc() contains fixes to update the Class Code and Interrupt
Pin registers, but the fixes don't actually work because these registers
are read-only.
Enable write permission before updating the Class Code and Interrupt
Pin.
Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Joao Pinto <jpinto@synopsys.com>
Acked-by: Roy Zang <tie-fei.zang@freescale.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware-host.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/pcie-designware-host.c b/drivers/pci/pcie-designware-host.c
index e98560818..b42d2ac93 100644
--- a/drivers/pci/pcie-designware-host.c
+++ b/drivers/pci/pcie-designware-host.c
@@ -403,8 +403,12 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
- /* Program correct class for RC */
+ /* 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;
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 63/65] PCI: dwc: Fix enumeration end when reaching root subordinate
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (61 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 62/65] PCI: dwc: Enable write permission for Class Code, Interrupt Pin updates Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 64/65] PCI: dwc: Small computation improvement Andrey Smirnov
` (2 subsequent siblings)
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit c2deae44616dab0112d965a0dc72d053b5727b4b
The subordinate value indicates the highest bus number which can be
reached downstream though a certain device.
Commit a20c7f36bd3d ("PCI: Do not allocate more buses than available in
parent")
ensures that downstream devices cannot assign busnumbers higher than the
upstream device subordinate number, which was indeed illogical.
By default, dw_pcie_setup_rc() inits the Root Complex subordinate to a
value of 0x01.
Due to this combined with above commit, enumeration stops digging deeper
downstream as soon as bus num 0x01 has been assigned, which is always
the case for a bridge device.
This results in all devices behind a bridge bus to remain undetected, as
these would be connected to bus 0x02 or higher.
Fix this by initializing the RC to a subordinate value of 0xff, which is
not altering hardware behaviour in any way, but informs probing
function pci_scan_bridge() later on which reads this value back from
register.
Following nasty errors during boot are also fixed by this:
[ 0.459145] pci_bus 0000:02: busn_res: can not insert [bus 02-ff]
under [bus 01] (conflicts with (null) [bus 01])
...
[ 0.464515] pci_bus 0000:03: [bus 03] partially hidden behind bridge
0000:01 [bus 01]
...
[ 0.464892] pci_bus 0000:04: [bus 04] partially hidden behind bridge
0000:01 [bus 01]
...
[ 0.466488] pci_bus 0000:05: [bus 05] partially hidden behind bridge
0000:01 [bus 01]
[ 0.466506] pci_bus 0000:02: busn_res: [bus 02-ff] end is updated to
05
[ 0.466517] pci_bus 0000:02: busn_res: can not insert [bus 02-05]
under [bus 01] (conflicts with (null) [bus 01])
[ 0.466534] pci_bus 0000:02: [bus 02-05] partially hidden behind
bridge 0000:01 [bus 01]
Fixes: a20c7f36bd3d ("PCI: Do not allocate more buses than available in
parent")
Tested-by: Niklas Cassel <niklas.cassel@axis.com>
Tested-by: Fabio Estevam <fabio.estevam@nxp.com>
Tested-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
Signed-off-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Lucas Stach <l.stach@pengutronix.de>
Cc: <stable@vger.kernel.org> # 4.15
Cc: Binghui Wang <wangbinghui@hisilicon.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: Jianguo Sun <sunjianguo1@huawei.com>
Cc: Jingoo Han <jingoohan1@gmail.com>
Cc: Kishon Vijay Abraham I <kishon@ti.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: Minghuan Lian <minghuan.Lian@freescale.com>
Cc: Mingkai Hu <mingkai.hu@freescale.com>
Cc: Murali Karicheri <m-karicheri2@ti.com>
Cc: Pratyush Anand <pratyush.anand@gmail.com>
Cc: Richard Zhu <hongxing.zhu@nxp.com>
Cc: Roy Zang <tie-fei.zang@freescale.com>
Cc: Shawn Guo <shawn.guo@linaro.org>
Cc: Stanimir Varbanov <svarbanov@mm-sol.com>
Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: Xiaowei Song <songxiaowei@hisilicon.com>
Cc: Zhou Wang <wangzhou1@hisilicon.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware-host.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pci/pcie-designware-host.c b/drivers/pci/pcie-designware-host.c
index b42d2ac93..7af5a6561 100644
--- a/drivers/pci/pcie-designware-host.c
+++ b/drivers/pci/pcie-designware-host.c
@@ -371,7 +371,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
/* Setup bus numbers */
val = dw_pcie_readl_dbi(pci, PCI_PRIMARY_BUS);
val &= 0xff000000;
- val |= 0x00010100;
+ val |= 0x00ff0100;
dw_pcie_writel_dbi(pci, PCI_PRIMARY_BUS, val);
/* Setup command register */
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 64/65] PCI: dwc: Small computation improvement
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (62 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 63/65] PCI: dwc: Fix enumeration end when reaching root subordinate Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2018-12-17 5:19 ` [PATCH v2 65/65] PCI: dwc: Constify dw_pcie_host_ops structures Andrey Smirnov
2019-01-07 22:55 ` [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 6995de2168edc6e58a350e7eb76e02dd191b64f4
Replace a division by 2 operation for a right shift rotation of 1 bit.
Probably any recent and decent compiler does this kind of substitution
in order to improve code performance. Nevertheless it's a coding good
practice whenever there is a division / multiplication by multiple of 2
to replace it by the equivalent operation in this case, the shift
rotation.
Signed-off-by: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Jingoo Han <jingoohan1@gmail.com>
Acked-by: Joao Pinto <jpinto@synopsys.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pcie-designware-host.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/pcie-designware-host.c b/drivers/pci/pcie-designware-host.c
index 7af5a6561..6cc4b93a3 100644
--- a/drivers/pci/pcie-designware-host.c
+++ b/drivers/pci/pcie-designware-host.c
@@ -88,8 +88,8 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
cfg_res = dev_get_resource_by_name(dev, IORESOURCE_MEM, "config");
if (cfg_res) {
- pp->cfg0_size = resource_size(cfg_res) / 2;
- pp->cfg1_size = resource_size(cfg_res) / 2;
+ pp->cfg0_size = resource_size(cfg_res) >> 1;
+ pp->cfg1_size = resource_size(cfg_res) >> 1;
pp->cfg0_base = cfg_res->start;
pp->cfg1_base = cfg_res->start + pp->cfg0_size;
@@ -136,8 +136,8 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
}
if (restype == 0) {
of_pci_range_to_resource(&range, np, &pp->cfg);
- pp->cfg0_size = resource_size(&pp->cfg) / 2;
- pp->cfg1_size = resource_size(&pp->cfg) / 2;
+ pp->cfg0_size = resource_size(&pp->cfg) >> 1;
+ pp->cfg1_size = resource_size(&pp->cfg) >> 1;
pp->cfg0_base = pp->cfg.start;
pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* [PATCH v2 65/65] PCI: dwc: Constify dw_pcie_host_ops structures
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (63 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 64/65] PCI: dwc: Small computation improvement Andrey Smirnov
@ 2018-12-17 5:19 ` Andrey Smirnov
2019-01-07 22:55 ` [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
65 siblings, 0 replies; 68+ messages in thread
From: Andrey Smirnov @ 2018-12-17 5:19 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Port of a Linux commit 4ab2e7c0df6b8bbc6c8ea1617b737d33c2510012
The dw_pcie_host_ops structures are never modified. Constify these
structures such that these can be write-protected.
Signed-off-by: Jisheng Zhang <jszhang@marvell.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Jingoo Han <jingoohan1@gmail.com>
Acked-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pci-imx6.c | 2 +-
drivers/pci/pcie-designware.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/pci-imx6.c b/drivers/pci/pci-imx6.c
index 1807f29c9..38e002a1c 100644
--- a/drivers/pci/pci-imx6.c
+++ b/drivers/pci/pci-imx6.c
@@ -501,7 +501,7 @@ static const struct dw_pcie_ops dw_pcie_ops = {
.link_up = imx6_pcie_link_up,
};
-static struct dw_pcie_host_ops imx6_pcie_host_ops = {
+static const struct dw_pcie_host_ops imx6_pcie_host_ops = {
.host_init = imx6_pcie_host_init,
};
diff --git a/drivers/pci/pcie-designware.h b/drivers/pci/pcie-designware.h
index 0f1659319..058a0acbb 100644
--- a/drivers/pci/pcie-designware.h
+++ b/drivers/pci/pcie-designware.h
@@ -129,7 +129,7 @@ struct pcie_port {
struct resource mem;
struct resource busn;
int irq;
- struct dw_pcie_host_ops *ops;
+ const struct dw_pcie_host_ops *ops;
struct pci_controller pci;
};
--
2.19.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* Re: [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1
2018-12-17 5:18 [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
` (64 preceding siblings ...)
2018-12-17 5:19 ` [PATCH v2 65/65] PCI: dwc: Constify dw_pcie_host_ops structures Andrey Smirnov
@ 2019-01-07 22:55 ` Andrey Smirnov
2019-01-08 15:31 ` Sascha Hauer
65 siblings, 1 reply; 68+ messages in thread
From: Andrey Smirnov @ 2019-01-07 22:55 UTC (permalink / raw)
To: Sascha Hauer; +Cc: Barebox List
On Sun, Dec 16, 2018 at 9:19 PM Andrey Smirnov <andrew.smirnov@gmail.com> wrote:
>
> Everyone:
>
> As a part of working on adding support for PCI on i.MX7D/8MQ, I spent
> some time looking through Linux commit history of pci-imx6.c and
> pcie-designware*.c and porting various patches to minimize the
> differences between the two codebases. This series is the result of
> that effort. All of the patches are either fixes for missed corner
> cases or code simplifications/improvements, so no functonal changes
> are expected.
>
> Tested on ZII RDU2 i.MX6Q board with i210 Ethernet card by booting
> 4.20-rc1 via TFTP (via PCI/i210). Also tested as a part of adding on
> i.MX7D/i.MX8MQ suport on i.MX7D SabreSD and i.MX8MQ RDU3 boards.
>
> Feedback is welcome!
>
> Changes since v1:
>
> - Fixed incorrect check/bug in "PCI: designware: Keep viewport fixed
> for IO transaction if num_viewport > 2"
>
> - Added patches containing code to support iATU unroll in order to
> support i.MX8MQ
>
> Thanks,
> Andrey Smirnov
Sascha:
Just to make sure, this series is in you review queue and it didn't
get lost, correct?
Thanks,
Andrey Smirnov
>
> Andrey Smirnov (65):
> PCI: desginware: Remove bogus prototypes
> PCI: designware: Consolidate outbound iATU programming functions
> PCI: designware: Use iATU0 for cfg and IO, iATU1 for MEM
> PCI: designware: Fix PORT_LOGIC_LINK_WIDTH_MASK
> PCI: designware: Use exact access size in dw_pcie_cfg_read()
> PCI: designware: Simplify dw_pcie_cfg_read/write() interfaces
> PCI: designware: Require config accesses to be naturally aligned
> PCI: designware: Make "num-lanes" an optional DT property
> PCI: designware: Ensure ATU is enabled before IO/conf space accesses
> PCI: designware: Simplify control flow
> PCI: designware: Make config accessor override checking symmetric
> PCI: designware: Explain why we don't program ATU for some platforms
> PCI: imx6: Move link up check into imx6_pcie_wait_for_link()
> PCI: designware: Add generic dw_pcie_wait_for_link()
> PCI: designware: Add default link up check if sub-driver doesn't
> override
> PCI: designware: Move Root Complex setup code to dw_pcie_setup_rc()
> PCI: designware: Remove incorrect RC memory base/limit configuration
> PCI: designware: Return data directly from dw_pcie_readl_rc()
> PCI: designware: Move link wait definitions to .c file
> PCI: designware: Wait for iATU enable
> PCI: designware: Add iATU Unroll feature
> PCI: designware: Check LTSSM training bit before deciding link is up
> PCI: designware: Keep viewport fixed for IO transaction if
> num_viewport > 2
> PCI: designware: Exchange viewport of `MEMORYs' and `CFGs/IOs'
> PCI: designware: Rename dw_pcie_valid_config() to
> dw_pcie_valid_device()
> PCI: designware: Simplify dw_pcie_readl_unroll(),
> dw_pcie_writel_unroll()
> PCI: designware: Simplify pcie_host_ops.readl_rc() and .writel_rc()
> interfaces
> PCI: designware: Swap order of dw_pcie_writel_rc() reg/val arguments
> PCI: designware: Export dw_pcie_readl_rc(), dw_pcie_writel_rc()
> PCI: designware: Uninline register accessors
> PCI: designware: Swap order of dw_pcie_writel_unroll() reg/val
> arguments
> PCI: designware: Check for iATU unroll only on platforms that use ATU
> PCI: dwc: designware: Move register defines to designware header file
> PCI: dwc: all: Rename cfg_read/cfg_write to read/write
> PCI: dwc: designware: Get device pointer at the start of
> dw_pcie_host_init()
> PCI: imx6: Add local struct device pointers
> PCI: imx6: Removed unused struct imx6_pcie.mem_base
> PCI: imx6: Pass struct imx6_pcie to PHY accessors
> PCI: imx6: Pass device-specific struct to internal functions
> PCI: imx6: Use generic DesignWare accessors
> PCI: imx6: Reorder struct imx6_pcie
> PCI: imx6: Port error messages for imx6_pcie_deassert_core_reset()
> PCI: imx6: Remove unused return values
> PCI: imx6: Factor out ref clock enable
> PCI: imx6: Add DT property for link gen, default to Gen1
> PCI: imx6: Remove redundant "Link never came up" message
> PCI: imx6: Remove LTSSM disable workaround
> PCI: dwc: all: Split struct pcie_port into host-only and core
> structures
> PCI: dwc: designware: Parse "num-lanes" property in dw_pcie_setup_rc()
> PCI: dwc: designware: Fix style errors in pcie-designware.c
> PCI: dwc: Split pcie-designware.c into host and core files
> PCI: dwc: all: Modify dbi accessors to take dbi_base as argument
> PCI: dwc: all: Modify dbi accessors to access data of 4/2/1 bytes
> PCI: dwc: designware: Move _unroll configurations to a separate
> function
> PCI: dwc: designware: Test PCIE_ATU_ENABLE bit specifically
> PCI: dwc: designware: Make dw_pcie_prog_*_atu_unroll() static
> PCI: Fix typos and whitespace errors
> PCI: Add SPDX GPL-2.0 to replace GPL v2 boilerplate
> PCI: dwc: Replace lower into upper case characters
> PCI: dwc: designware: Handle ->host_init() failures
> PCI: dwc: Add accessors for write permission of DBI
> PCI: dwc: Enable write permission for Class Code, Interrupt Pin
> updates
> PCI: dwc: Fix enumeration end when reaching root subordinate
> PCI: dwc: Small computation improvement
> PCI: dwc: Constify dw_pcie_host_ops structures
>
> drivers/pci/Makefile | 2 +-
> drivers/pci/pci-imx6.c | 368 +++++++++---------
> drivers/pci/pci-mvebu-phy.c | 5 +-
> drivers/pci/pci-mvebu.c | 5 +-
> drivers/pci/pci-mvebu.h | 5 +-
> drivers/pci/pci-tegra.c | 13 +-
> drivers/pci/pcie-designware-host.c | 416 +++++++++++++++++++++
> drivers/pci/pcie-designware.c | 580 ++++++++---------------------
> drivers/pci/pcie-designware.h | 188 ++++++++--
> 9 files changed, 906 insertions(+), 676 deletions(-)
> create mode 100644 drivers/pci/pcie-designware-host.c
>
> --
> 2.19.1
>
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread
* Re: [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1
2019-01-07 22:55 ` [PATCH v2 00/65] PCI i.MX6/DesignWare sync up with 4.20-rc1 Andrey Smirnov
@ 2019-01-08 15:31 ` Sascha Hauer
0 siblings, 0 replies; 68+ messages in thread
From: Sascha Hauer @ 2019-01-08 15:31 UTC (permalink / raw)
To: Andrey Smirnov; +Cc: Barebox List
On Mon, Jan 07, 2019 at 02:55:56PM -0800, Andrey Smirnov wrote:
> On Sun, Dec 16, 2018 at 9:19 PM Andrey Smirnov <andrew.smirnov@gmail.com> wrote:
> >
> > Everyone:
> >
> > As a part of working on adding support for PCI on i.MX7D/8MQ, I spent
> > some time looking through Linux commit history of pci-imx6.c and
> > pcie-designware*.c and porting various patches to minimize the
> > differences between the two codebases. This series is the result of
> > that effort. All of the patches are either fixes for missed corner
> > cases or code simplifications/improvements, so no functonal changes
> > are expected.
> >
> > Tested on ZII RDU2 i.MX6Q board with i210 Ethernet card by booting
> > 4.20-rc1 via TFTP (via PCI/i210). Also tested as a part of adding on
> > i.MX7D/i.MX8MQ suport on i.MX7D SabreSD and i.MX8MQ RDU3 boards.
> >
> > Feedback is welcome!
> >
> > Changes since v1:
> >
> > - Fixed incorrect check/bug in "PCI: designware: Keep viewport fixed
> > for IO transaction if num_viewport > 2"
> >
> > - Added patches containing code to support iATU unroll in order to
> > support i.MX8MQ
> >
> > Thanks,
> > Andrey Smirnov
>
> Sascha:
>
> Just to make sure, this series is in you review queue and it didn't
> get lost, correct?
Hm, yes of course :)
I applied this series without looking at it. I hope nobody else realizes
he just has to send that many patches to bypass any review :/
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 68+ messages in thread