* [PATCH v10 01/10] PCI: dwc: Use resource start as iomap() input in dw_pcie_pme_turn_off()
2025-03-10 20:16 [PATCH v10 00/10] PCI: Use device bus range info to cleanup RC Host/EP pci_fixup_addr() Frank Li
@ 2025-03-10 20:16 ` Frank Li
2025-03-10 20:16 ` [PATCH v10 02/10] PCI: dwc: Rename cpu_addr to parent_bus_addr for ATU configuration Frank Li
` (8 subsequent siblings)
9 siblings, 0 replies; 18+ messages in thread
From: Frank Li @ 2025-03-10 20:16 UTC (permalink / raw)
To: Rob Herring, Saravana Kannan, Jingoo Han, Manivannan Sadhasivam,
Lorenzo Pieralisi, Krzysztof Wilczyński, Bjorn Helgaas,
Richard Zhu, Lucas Stach, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: devicetree, linux-kernel, linux-pci, linux-arm-kernel, imx,
Niklas Cassel, Frank Li
The msg_res region translates writes into PCIe Message TLPs. Previously we
mapped this region using atu.cpu_addr, the input address programmed into
the ATU.
"cpu_addr" is a misnomer because when a bus fabric translates addresses
between the CPU and the ATU, the ATU input address is different from the
CPU address. A future patch will rename "cpu_addr" and correct the value
to be the ATU input address instead of the CPU physical address.
Map the msg_res region before writing to it using the msg_res resource
start, a CPU physical address.
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
change from v9 to v10
- use bjorn's suggested commit messaage.
change from v8 to v9
- new patch
---
drivers/pci/controller/dwc/pcie-designware-host.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index ffaded8f2df7b..ae3fd2a5dbf85 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -908,7 +908,7 @@ static int dw_pcie_pme_turn_off(struct dw_pcie *pci)
if (ret)
return ret;
- mem = ioremap(atu.cpu_addr, pci->region_align);
+ mem = ioremap(pci->pp.msg_res->start, pci->region_align);
if (!mem)
return -ENOMEM;
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v10 02/10] PCI: dwc: Rename cpu_addr to parent_bus_addr for ATU configuration
2025-03-10 20:16 [PATCH v10 00/10] PCI: Use device bus range info to cleanup RC Host/EP pci_fixup_addr() Frank Li
2025-03-10 20:16 ` [PATCH v10 01/10] PCI: dwc: Use resource start as iomap() input in dw_pcie_pme_turn_off() Frank Li
@ 2025-03-10 20:16 ` Frank Li
2025-03-10 20:16 ` [PATCH v10 03/10] PCI: dwc: Move cfg0 setup to dw_pcie_cfg0_setup() Frank Li
` (7 subsequent siblings)
9 siblings, 0 replies; 18+ messages in thread
From: Frank Li @ 2025-03-10 20:16 UTC (permalink / raw)
To: Rob Herring, Saravana Kannan, Jingoo Han, Manivannan Sadhasivam,
Lorenzo Pieralisi, Krzysztof Wilczyński, Bjorn Helgaas,
Richard Zhu, Lucas Stach, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: devicetree, linux-kernel, linux-pci, linux-arm-kernel, imx,
Niklas Cassel, Frank Li
Rename `cpu_addr` to `parent_bus_addr` in the DesignWare ATU configuration.
The ATU translates parent bus addresses to PCI addresses, which are often
the same as CPU addresses but can differ in systems where the bus fabric
translates addresses before passing them to the PCIe controller. This
renaming clarifies the purpose and avoids confusion.
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
change from v9 to v10
- rename header file's cpu_addr for dw_pcie_prog_inbound_atu() and
dw_pcie_prog_ep_inbound_atu();
change from v8 to v9
- new patch
---
drivers/pci/controller/dwc/pcie-designware-ep.c | 8 +++---
drivers/pci/controller/dwc/pcie-designware-host.c | 12 ++++----
drivers/pci/controller/dwc/pcie-designware.c | 34 +++++++++++------------
drivers/pci/controller/dwc/pcie-designware.h | 7 +++--
4 files changed, 31 insertions(+), 30 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 8e07d432e74f2..80ac2f9e88eb5 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -128,7 +128,7 @@ static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
}
static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, u8 func_no, int type,
- dma_addr_t cpu_addr, enum pci_barno bar,
+ dma_addr_t parent_bus_addr, enum pci_barno bar,
size_t size)
{
int ret;
@@ -146,7 +146,7 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, u8 func_no, int type,
}
ret = dw_pcie_prog_ep_inbound_atu(pci, func_no, free_win, type,
- cpu_addr, bar, size);
+ parent_bus_addr, bar, size);
if (ret < 0) {
dev_err(pci->dev, "Failed to program IB window\n");
return ret;
@@ -181,7 +181,7 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep,
return ret;
set_bit(free_win, ep->ob_window_map);
- ep->outbound_addr[free_win] = atu->cpu_addr;
+ ep->outbound_addr[free_win] = atu->parent_bus_addr;
return 0;
}
@@ -333,7 +333,7 @@ static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
atu.func_no = func_no;
atu.type = PCIE_ATU_TYPE_MEM;
- atu.cpu_addr = addr;
+ atu.parent_bus_addr = addr;
atu.pci_addr = pci_addr;
atu.size = size;
ret = dw_pcie_ep_outbound_atu(ep, &atu);
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index ae3fd2a5dbf85..1206b26bff3f2 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -616,7 +616,7 @@ static void __iomem *dw_pcie_other_conf_map_bus(struct pci_bus *bus,
type = PCIE_ATU_TYPE_CFG1;
atu.type = type;
- atu.cpu_addr = pp->cfg0_base;
+ atu.parent_bus_addr = pp->cfg0_base;
atu.pci_addr = busdev;
atu.size = pp->cfg0_size;
@@ -641,7 +641,7 @@ static int dw_pcie_rd_other_conf(struct pci_bus *bus, unsigned int devfn,
if (pp->cfg0_io_shared) {
atu.type = PCIE_ATU_TYPE_IO;
- atu.cpu_addr = pp->io_base;
+ atu.parent_bus_addr = pp->io_base;
atu.pci_addr = pp->io_bus_addr;
atu.size = pp->io_size;
@@ -667,7 +667,7 @@ static int dw_pcie_wr_other_conf(struct pci_bus *bus, unsigned int devfn,
if (pp->cfg0_io_shared) {
atu.type = PCIE_ATU_TYPE_IO;
- atu.cpu_addr = pp->io_base;
+ atu.parent_bus_addr = pp->io_base;
atu.pci_addr = pp->io_bus_addr;
atu.size = pp->io_size;
@@ -736,7 +736,7 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
atu.index = i;
atu.type = PCIE_ATU_TYPE_MEM;
- atu.cpu_addr = entry->res->start;
+ atu.parent_bus_addr = entry->res->start;
atu.pci_addr = entry->res->start - entry->offset;
/* Adjust iATU size if MSG TLP region was allocated before */
@@ -758,7 +758,7 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
if (pci->num_ob_windows > ++i) {
atu.index = i;
atu.type = PCIE_ATU_TYPE_IO;
- atu.cpu_addr = pp->io_base;
+ atu.parent_bus_addr = pp->io_base;
atu.pci_addr = pp->io_bus_addr;
atu.size = pp->io_size;
@@ -902,7 +902,7 @@ static int dw_pcie_pme_turn_off(struct dw_pcie *pci)
atu.size = resource_size(pci->pp.msg_res);
atu.index = pci->pp.msg_atu_index;
- atu.cpu_addr = pci->pp.msg_res->start;
+ atu.parent_bus_addr = pci->pp.msg_res->start;
ret = dw_pcie_prog_outbound_atu(pci, &atu);
if (ret)
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
index 145e7f579072c..9d0a5f75effcc 100644
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -470,25 +470,25 @@ static inline u32 dw_pcie_enable_ecrc(u32 val)
int dw_pcie_prog_outbound_atu(struct dw_pcie *pci,
const struct dw_pcie_ob_atu_cfg *atu)
{
- u64 cpu_addr = atu->cpu_addr;
+ u64 parent_bus_addr = atu->parent_bus_addr;
u32 retries, val;
u64 limit_addr;
if (pci->ops && pci->ops->cpu_addr_fixup)
- cpu_addr = pci->ops->cpu_addr_fixup(pci, cpu_addr);
+ parent_bus_addr = pci->ops->cpu_addr_fixup(pci, parent_bus_addr);
- limit_addr = cpu_addr + atu->size - 1;
+ limit_addr = parent_bus_addr + atu->size - 1;
- if ((limit_addr & ~pci->region_limit) != (cpu_addr & ~pci->region_limit) ||
- !IS_ALIGNED(cpu_addr, pci->region_align) ||
+ if ((limit_addr & ~pci->region_limit) != (parent_bus_addr & ~pci->region_limit) ||
+ !IS_ALIGNED(parent_bus_addr, pci->region_align) ||
!IS_ALIGNED(atu->pci_addr, pci->region_align) || !atu->size) {
return -EINVAL;
}
dw_pcie_writel_atu_ob(pci, atu->index, PCIE_ATU_LOWER_BASE,
- lower_32_bits(cpu_addr));
+ lower_32_bits(parent_bus_addr));
dw_pcie_writel_atu_ob(pci, atu->index, PCIE_ATU_UPPER_BASE,
- upper_32_bits(cpu_addr));
+ upper_32_bits(parent_bus_addr));
dw_pcie_writel_atu_ob(pci, atu->index, PCIE_ATU_LIMIT,
lower_32_bits(limit_addr));
@@ -502,7 +502,7 @@ int dw_pcie_prog_outbound_atu(struct dw_pcie *pci,
upper_32_bits(atu->pci_addr));
val = atu->type | atu->routing | PCIE_ATU_FUNC_NUM(atu->func_no);
- if (upper_32_bits(limit_addr) > upper_32_bits(cpu_addr) &&
+ if (upper_32_bits(limit_addr) > upper_32_bits(parent_bus_addr) &&
dw_pcie_ver_is_ge(pci, 460A))
val |= PCIE_ATU_INCREASE_REGION_SIZE;
if (dw_pcie_ver_is(pci, 490A))
@@ -545,13 +545,13 @@ static inline void dw_pcie_writel_atu_ib(struct dw_pcie *pci, u32 index, u32 reg
}
int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int type,
- u64 cpu_addr, u64 pci_addr, u64 size)
+ u64 parent_bus_addr, u64 pci_addr, u64 size)
{
u64 limit_addr = pci_addr + size - 1;
u32 retries, val;
if ((limit_addr & ~pci->region_limit) != (pci_addr & ~pci->region_limit) ||
- !IS_ALIGNED(cpu_addr, pci->region_align) ||
+ !IS_ALIGNED(parent_bus_addr, pci->region_align) ||
!IS_ALIGNED(pci_addr, pci->region_align) || !size) {
return -EINVAL;
}
@@ -568,9 +568,9 @@ int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int type,
upper_32_bits(limit_addr));
dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_LOWER_TARGET,
- lower_32_bits(cpu_addr));
+ lower_32_bits(parent_bus_addr));
dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_UPPER_TARGET,
- upper_32_bits(cpu_addr));
+ upper_32_bits(parent_bus_addr));
val = type;
if (upper_32_bits(limit_addr) > upper_32_bits(pci_addr) &&
@@ -597,18 +597,18 @@ int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int type,
}
int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
- int type, u64 cpu_addr, u8 bar, size_t size)
+ int type, u64 parent_bus_addr, u8 bar, size_t size)
{
u32 retries, val;
- if (!IS_ALIGNED(cpu_addr, pci->region_align) ||
- !IS_ALIGNED(cpu_addr, size))
+ if (!IS_ALIGNED(parent_bus_addr, pci->region_align) ||
+ !IS_ALIGNED(parent_bus_addr, size))
return -EINVAL;
dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_LOWER_TARGET,
- lower_32_bits(cpu_addr));
+ lower_32_bits(parent_bus_addr));
dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_UPPER_TARGET,
- upper_32_bits(cpu_addr));
+ upper_32_bits(parent_bus_addr));
dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_REGION_CTRL1, type |
PCIE_ATU_FUNC_NUM(func_no));
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index 501d9ddfea163..d0d8c622a6e8b 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -343,7 +343,7 @@ struct dw_pcie_ob_atu_cfg {
u8 func_no;
u8 code;
u8 routing;
- u64 cpu_addr;
+ u64 parent_bus_addr;
u64 pci_addr;
u64 size;
};
@@ -491,9 +491,10 @@ int dw_pcie_wait_for_link(struct dw_pcie *pci);
int dw_pcie_prog_outbound_atu(struct dw_pcie *pci,
const struct dw_pcie_ob_atu_cfg *atu);
int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int type,
- u64 cpu_addr, u64 pci_addr, u64 size);
+ u64 parent_bus_addr, u64 pci_addr, u64 size);
int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
- int type, u64 cpu_addr, u8 bar, size_t size);
+ int type, u64 parent_bus_addr,
+ u8 bar, size_t size);
void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index);
void dw_pcie_setup(struct dw_pcie *pci);
void dw_pcie_iatu_detect(struct dw_pcie *pci);
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v10 03/10] PCI: dwc: Move cfg0 setup to dw_pcie_cfg0_setup()
2025-03-10 20:16 [PATCH v10 00/10] PCI: Use device bus range info to cleanup RC Host/EP pci_fixup_addr() Frank Li
2025-03-10 20:16 ` [PATCH v10 01/10] PCI: dwc: Use resource start as iomap() input in dw_pcie_pme_turn_off() Frank Li
2025-03-10 20:16 ` [PATCH v10 02/10] PCI: dwc: Rename cpu_addr to parent_bus_addr for ATU configuration Frank Li
@ 2025-03-10 20:16 ` Frank Li
2025-03-10 20:16 ` [PATCH v10 04/10] PCI: dwc: Add helper dw_pcie_init_parent_bus_offset() Frank Li
` (6 subsequent siblings)
9 siblings, 0 replies; 18+ messages in thread
From: Frank Li @ 2025-03-10 20:16 UTC (permalink / raw)
To: Rob Herring, Saravana Kannan, Jingoo Han, Manivannan Sadhasivam,
Lorenzo Pieralisi, Krzysztof Wilczyński, Bjorn Helgaas,
Richard Zhu, Lucas Stach, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: devicetree, linux-kernel, linux-pci, linux-arm-kernel, imx,
Niklas Cassel, Frank Li
From: Bjorn Helgaas <bhelgaas@google.com>
Move pp->cfg0 setup to dw_pcie_cfg0_setup(). No functional change intended.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
Change from v9 to v10
v9 means https://lore.kernel.org/linux-pci/20250307233744.440476-1-helgaas@kernel.org/T/#maa0134c1826bffcccab6028c7732a13f7adcec4d
- move dw_pcie_cfg0_setup() ahead of dw_pcie_host_request_msg_tlp_res() to
nice git diff and easy to review.
---
drivers/pci/controller/dwc/pcie-designware-host.c | 40 +++++++++++++++--------
1 file changed, 26 insertions(+), 14 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index 1206b26bff3f2..c57831902686e 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -392,6 +392,29 @@ static int dw_pcie_msi_host_init(struct dw_pcie_rp *pp)
return 0;
}
+static int dw_pcie_cfg0_setup(struct dw_pcie_rp *pp)
+{
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ struct device *dev = pci->dev;
+ struct platform_device *pdev = to_platform_device(dev);
+ struct resource *res;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
+ if (!res) {
+ dev_err(dev, "Missing \"config\" reg space\n");
+ return -ENODEV;
+ }
+
+ pp->cfg0_size = resource_size(res);
+ pp->cfg0_base = res->start;
+
+ pp->va_cfg0_base = devm_pci_remap_cfg_resource(dev, res);
+ if (IS_ERR(pp->va_cfg0_base))
+ return PTR_ERR(pp->va_cfg0_base);
+
+ return 0;
+}
+
static void dw_pcie_host_request_msg_tlp_res(struct dw_pcie_rp *pp)
{
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
@@ -423,10 +446,8 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
struct device *dev = pci->dev;
struct device_node *np = dev->of_node;
- struct platform_device *pdev = to_platform_device(dev);
struct resource_entry *win;
struct pci_host_bridge *bridge;
- struct resource *res;
int ret;
raw_spin_lock_init(&pp->lock);
@@ -435,18 +456,9 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
if (ret)
return ret;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
- if (!res) {
- dev_err(dev, "Missing \"config\" reg space\n");
- return -ENODEV;
- }
-
- pp->cfg0_size = resource_size(res);
- pp->cfg0_base = res->start;
-
- pp->va_cfg0_base = devm_pci_remap_cfg_resource(dev, res);
- if (IS_ERR(pp->va_cfg0_base))
- return PTR_ERR(pp->va_cfg0_base);
+ ret = dw_pcie_cfg0_setup(pp);
+ if (ret)
+ return ret;
bridge = devm_pci_alloc_host_bridge(dev, 0);
if (!bridge)
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v10 04/10] PCI: dwc: Add helper dw_pcie_init_parent_bus_offset()
2025-03-10 20:16 [PATCH v10 00/10] PCI: Use device bus range info to cleanup RC Host/EP pci_fixup_addr() Frank Li
` (2 preceding siblings ...)
2025-03-10 20:16 ` [PATCH v10 03/10] PCI: dwc: Move cfg0 setup to dw_pcie_cfg0_setup() Frank Li
@ 2025-03-10 20:16 ` Frank Li
2025-03-12 22:16 ` Bjorn Helgaas
2025-03-10 20:16 ` [PATCH v10 05/10] PCI: dwc: Use devicetree 'ranges' property to get rid of cpu_addr_fixup() callback Frank Li
` (5 subsequent siblings)
9 siblings, 1 reply; 18+ messages in thread
From: Frank Li @ 2025-03-10 20:16 UTC (permalink / raw)
To: Rob Herring, Saravana Kannan, Jingoo Han, Manivannan Sadhasivam,
Lorenzo Pieralisi, Krzysztof Wilczyński, Bjorn Helgaas,
Richard Zhu, Lucas Stach, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: devicetree, linux-kernel, linux-pci, linux-arm-kernel, imx,
Niklas Cassel, Frank Li
From: Bjorn Helgaas <bhelgaas@google.com>
Set pci->parent_bus_offset based on the parent bus address from the
"config" (Root complex mode) and "addr_space" (Endpoint mode).
.cpu_addr_fixup(cpu_phy_addr). (if implemented) should return the parent
bus address corresponding according to cpu_phy_addr.
Sets pp->parent_bus_offset, but doesn't use it, so no functional change
intended yet.
Add use_parent_dt_ranges to detect some fake bus translation at platform,
which have not .cpu_addr_fixup(). Set use_parent_dt_ranges true explicitly
at platform that have .cpu_addr_fixup() and fixed DTB's range. If not one
report "fake bus translation" for sometime, this flags can be removed
safely.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
change from v9 to v10
v9: https://lore.kernel.org/imx/20250128-pci_fixup_addr-v9-4-3c4bb506f665@nxp.com/
- use help funtion dw_pcie_init_parent_bus_offset() because both EP and RC
use simular logic.
- still use use_parent_dt_ranges to detect fake bus translation for
no .cpu_addr_fixup()'s platfrom incase block exist platform.
---
drivers/pci/controller/dwc/pcie-designware.c | 47 ++++++++++++++++++++++++++++
drivers/pci/controller/dwc/pcie-designware.h | 13 ++++++++
2 files changed, 60 insertions(+)
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
index 9d0a5f75effcc..70b4d3369158a 100644
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -16,6 +16,7 @@
#include <linux/gpio/consumer.h>
#include <linux/ioport.h>
#include <linux/of.h>
+#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/sizes.h>
#include <linux/types.h>
@@ -1105,3 +1106,49 @@ void dw_pcie_setup(struct dw_pcie *pci)
dw_pcie_link_set_max_link_width(pci, pci->num_lanes);
}
+
+int dw_pcie_init_parent_bus_offset(struct dw_pcie *pci, const char *reg_name,
+ resource_size_t cpu_phy_addr)
+{
+ struct device *dev = pci->dev;
+ struct device_node *np = dev->of_node;
+ u64 (*fixup)(struct dw_pcie *pcie, u64 cpu_addr);
+ u64 reg_addr, fixup_addr;
+ int index;
+
+ /* Look up reg_name address on parent bus */
+ index = of_property_match_string(np, "reg-names", reg_name);
+
+ if (index < 0) {
+ dev_err(dev, "Missed reg-name: %s, Broken DTB file\n", reg_name);
+ return -EINVAL;
+ }
+
+ of_property_read_reg(np, index, ®_addr, NULL);
+
+ fixup = pci->ops->cpu_addr_fixup;
+ if (fixup) {
+ fixup_addr = fixup(pci, cpu_phy_addr);
+ if (reg_addr == fixup_addr) {
+ dev_info(dev, "%#010llx %s reg[%d] == %#010llx; %ps is redundant\n",
+ cpu_phy_addr, reg_name, index,
+ fixup_addr, fixup);
+ } else {
+ dev_warn_once(dev, "%#010llx %s reg[%d] != %#010llx fixed up addr; DT is broken\n",
+ cpu_phy_addr, reg_name,
+ index, fixup_addr);
+ reg_addr = fixup_addr;
+ }
+ } else if (!pci->use_parent_dt_ranges) {
+ if (reg_addr != cpu_phy_addr) {
+ dev_warn_once(dev, "Your DTB try to use fake translation, Please check parent's ranges property,");
+ return 0;
+ }
+ }
+
+ pci->parent_bus_offset = cpu_phy_addr - reg_addr;
+ dev_info(dev, "%s parent bus offset is %#010llx\n",
+ reg_name, pci->parent_bus_offset);
+
+ return 0;
+}
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index d0d8c622a6e8b..5f941eab57110 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -445,6 +445,7 @@ struct dw_pcie {
void __iomem *atu_base;
resource_size_t atu_phys_addr;
size_t atu_size;
+ resource_size_t parent_bus_offset;
u32 num_ib_windows;
u32 num_ob_windows;
u32 region_align;
@@ -465,6 +466,16 @@ struct dw_pcie {
struct reset_control_bulk_data core_rsts[DW_PCIE_NUM_CORE_RSTS];
struct gpio_desc *pe_rst;
bool suspended;
+ /*
+ * This flag indicates that the vendor driver uses devicetree 'ranges'
+ * property to allow iATU to use the Intermediate Address (IA) for
+ * outbound mapping. Using this flag also avoids the usage of
+ * 'cpu_addr_fixup' callback implementation in the driver.
+ *
+ * If use_parent_dt_ranges is false, warning will print if IA is not
+ * equal to cpu physical address. Indicate dtb use a fake translation.
+ */
+ bool use_parent_dt_ranges;
};
#define to_dw_pcie_from_pp(port) container_of((port), struct dw_pcie, pp)
@@ -500,6 +511,8 @@ void dw_pcie_setup(struct dw_pcie *pci);
void dw_pcie_iatu_detect(struct dw_pcie *pci);
int dw_pcie_edma_detect(struct dw_pcie *pci);
void dw_pcie_edma_remove(struct dw_pcie *pci);
+int dw_pcie_init_parent_bus_offset(struct dw_pcie *pci, const char *reg_name,
+ resource_size_t cpu_phy_addr);
static inline void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val)
{
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v10 04/10] PCI: dwc: Add helper dw_pcie_init_parent_bus_offset()
2025-03-10 20:16 ` [PATCH v10 04/10] PCI: dwc: Add helper dw_pcie_init_parent_bus_offset() Frank Li
@ 2025-03-12 22:16 ` Bjorn Helgaas
0 siblings, 0 replies; 18+ messages in thread
From: Bjorn Helgaas @ 2025-03-12 22:16 UTC (permalink / raw)
To: Frank Li
Cc: Rob Herring, Saravana Kannan, Jingoo Han, Manivannan Sadhasivam,
Lorenzo Pieralisi, Krzysztof Wilczyński, Bjorn Helgaas,
Richard Zhu, Lucas Stach, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, devicetree, linux-kernel,
linux-pci, linux-arm-kernel, imx, Niklas Cassel
On Mon, Mar 10, 2025 at 04:16:42PM -0400, Frank Li wrote:
> From: Bjorn Helgaas <bhelgaas@google.com>
>
> Set pci->parent_bus_offset based on the parent bus address from the
> "config" (Root complex mode) and "addr_space" (Endpoint mode).
>
> .cpu_addr_fixup(cpu_phy_addr). (if implemented) should return the parent
> bus address corresponding according to cpu_phy_addr.
>
> Sets pp->parent_bus_offset, but doesn't use it, so no functional change
> intended yet.
>
> Add use_parent_dt_ranges to detect some fake bus translation at platform,
> which have not .cpu_addr_fixup(). Set use_parent_dt_ranges true explicitly
> at platform that have .cpu_addr_fixup() and fixed DTB's range. If not one
> report "fake bus translation" for sometime, this flags can be removed
> safely.
> +int dw_pcie_init_parent_bus_offset(struct dw_pcie *pci, const char *reg_name,
> + resource_size_t cpu_phy_addr)
> +{
> + struct device *dev = pci->dev;
> + struct device_node *np = dev->of_node;
> + u64 (*fixup)(struct dw_pcie *pcie, u64 cpu_addr);
> + u64 reg_addr, fixup_addr;
> + int index;
> +
> + /* Look up reg_name address on parent bus */
> + index = of_property_match_string(np, "reg-names", reg_name);
> +
> + if (index < 0) {
> + dev_err(dev, "Missed reg-name: %s, Broken DTB file\n", reg_name);
> + return -EINVAL;
> + }
> +
> + of_property_read_reg(np, index, ®_addr, NULL);
> +
> + fixup = pci->ops->cpu_addr_fixup;
> + if (fixup) {
> + fixup_addr = fixup(pci, cpu_phy_addr);
> + if (reg_addr == fixup_addr) {
> + dev_info(dev, "%#010llx %s reg[%d] == %#010llx; %ps is redundant\n",
> + cpu_phy_addr, reg_name, index,
> + fixup_addr, fixup);
> + } else {
> + dev_warn_once(dev, "%#010llx %s reg[%d] != %#010llx fixed up addr; DT is broken\n",
> + cpu_phy_addr, reg_name,
> + index, fixup_addr);
> + reg_addr = fixup_addr;
> + }
> + } else if (!pci->use_parent_dt_ranges) {
> + if (reg_addr != cpu_phy_addr) {
> + dev_warn_once(dev, "Your DTB try to use fake translation, Please check parent's ranges property,");
> + return 0;
IIUC the point of this is to catch a DT that describes a non-zero
offset when the driver did not implement .cpu_addr_fixup() and
therefore assumed "reg_addr == cpu_phy_addr".
I guess that makes sense. But I think we should include both
addresses in the message to help understand the issue.
> + }
> + }
> +
> + pci->parent_bus_offset = cpu_phy_addr - reg_addr;
> + dev_info(dev, "%s parent bus offset is %#010llx\n",
> + reg_name, pci->parent_bus_offset);
> +
> + return 0;
> +}
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -465,6 +466,16 @@ struct dw_pcie {
> struct reset_control_bulk_data core_rsts[DW_PCIE_NUM_CORE_RSTS];
> struct gpio_desc *pe_rst;
> bool suspended;
> + /*
> + * This flag indicates that the vendor driver uses devicetree 'ranges'
> + * property to allow iATU to use the Intermediate Address (IA) for
> + * outbound mapping. Using this flag also avoids the usage of
> + * 'cpu_addr_fixup' callback implementation in the driver.
This part of the comment is now wrong.
> + * If use_parent_dt_ranges is false, warning will print if IA is not
> + * equal to cpu physical address. Indicate dtb use a fake translation.
> + */
> + bool use_parent_dt_ranges;
> };
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v10 05/10] PCI: dwc: Use devicetree 'ranges' property to get rid of cpu_addr_fixup() callback
2025-03-10 20:16 [PATCH v10 00/10] PCI: Use device bus range info to cleanup RC Host/EP pci_fixup_addr() Frank Li
` (3 preceding siblings ...)
2025-03-10 20:16 ` [PATCH v10 04/10] PCI: dwc: Add helper dw_pcie_init_parent_bus_offset() Frank Li
@ 2025-03-10 20:16 ` Frank Li
2025-03-12 21:37 ` Bjorn Helgaas
2025-03-10 20:16 ` [PATCH v10 06/10] PCI: dwc: ep: Add parent_bus_addr for outbound window Frank Li
` (4 subsequent siblings)
9 siblings, 1 reply; 18+ messages in thread
From: Frank Li @ 2025-03-10 20:16 UTC (permalink / raw)
To: Rob Herring, Saravana Kannan, Jingoo Han, Manivannan Sadhasivam,
Lorenzo Pieralisi, Krzysztof Wilczyński, Bjorn Helgaas,
Richard Zhu, Lucas Stach, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: devicetree, linux-kernel, linux-pci, linux-arm-kernel, imx,
Niklas Cassel, Frank Li
parent_bus_offset in resource_entry can indicate address information just
ahead of PCIe controller. Most system's bus fabric use 1:1 map between
input and output address. but some hardware like i.MX8QXP doesn't use 1:1
map. See below diagram:
┌─────────┐ ┌────────────┐
┌─────┐ │ │ IA: 0x8ff8_0000 │ │
│ CPU ├───►│ ┌────►├─────────────────┐ │ PCI │
└─────┘ │ │ │ IA: 0x8ff0_0000 │ │ │
CPU Addr │ │ ┌─►├─────────────┐ │ │ Controller │
0x7ff8_0000─┼───┘ │ │ │ │ │ │
│ │ │ │ │ │ │ PCI Addr
0x7ff0_0000─┼──────┘ │ │ └──► IOSpace ─┼────────────►
│ │ │ │ │ 0
0x7000_0000─┼────────►├─────────┐ │ │ │
└─────────┘ │ └──────► CfgSpace ─┼────────────►
BUS Fabric │ │ │ 0
│ │ │
└──────────► MemSpace ─┼────────────►
IA: 0x8000_0000 │ │ 0x8000_0000
└────────────┘
bus@5f000000 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x80000000 0x0 0x70000000 0x10000000>;
pcie@5f010000 {
compatible = "fsl,imx8q-pcie";
reg = <0x5f010000 0x10000>, <0x8ff00000 0x80000>;
reg-names = "dbi", "config";
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
bus-range = <0x00 0xff>;
ranges = <0x81000000 0 0x00000000 0x8ff80000 0 0x00010000>,
<0x82000000 0 0x80000000 0x80000000 0 0x0ff00000>;
...
};
};
Term Intermediate address (IA) here means the address just before PCIe
controller. After ATU use this IA instead CPU address, cpu_addr_fixup() can
be removed.
Use reg-name "config" to detect parent_bus_addr_offset. Suppose the offset
is the same for all kinds of address translation.
Just set parent_bus_offset, but doesn't use it, so no functional change
intended yet.
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
change from v9 to v10
- call helper dw_pcie_init_parent_bus_offset()
chagne from v8 to v9
- use resoure_entry parent_bus_offset to simple code logic
- add check for use_parent_dt_ranges and cpu_addr_fixup to make sure only
one set.
Change from v7 to v8
- Add dev_warning_once at dw_pcie_iatu_detect() to reminder
cpu_addr_fixup() user to correct their code
- use 'use_parent_dt_ranges' control enable use dt parent bus node ranges.
- rename dw_pcie_get_untranslate_addr to dw_pcie_get_parent_addr().
- of_property_read_reg() already have comments, so needn't add more.
- return actual err code from function
Change from v6 to v7
Add a resource_size_t parent_bus_addr local varible to fix 32bit build
error.
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202410291546.kvgEWJv7-lkp@intel.com/
Chagne from v5 to v6
-add comments for of_property_read_reg().
Change from v4 to v5
- remove confused 0x5f00_0000 range in sample dts.
- reorder address at above diagram.
Change from v3 to v4
- none
Change from v2 to v3
- %s/cpu_untranslate_addr/parent_bus_addr/g
- update diagram.
- improve commit message.
Change from v1 to v2
- update because patch1 change get untranslate address method.
- add using_dtbus_info in case break back compatibility for exited platform.
---
drivers/pci/controller/dwc/pcie-designware-host.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index c57831902686e..eaa6dd4c7edda 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -478,6 +478,15 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
bridge->ops = &dw_pcie_ops;
bridge->child_ops = &dw_child_pcie_ops;
+ /*
+ * visconti_pcie_cpu_addr_fixup() use pp->io_base,
+ * so have to call dw_pcie_init_parent_bus_offset() after init
+ * pp->io_base.
+ */
+ ret = dw_pcie_init_parent_bus_offset(pci, "config", pp->cfg0_base);
+ if (ret)
+ return ret;
+
if (pp->ops->init) {
ret = pp->ops->init(pp);
if (ret)
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v10 05/10] PCI: dwc: Use devicetree 'ranges' property to get rid of cpu_addr_fixup() callback
2025-03-10 20:16 ` [PATCH v10 05/10] PCI: dwc: Use devicetree 'ranges' property to get rid of cpu_addr_fixup() callback Frank Li
@ 2025-03-12 21:37 ` Bjorn Helgaas
2025-03-13 14:17 ` Frank Li
0 siblings, 1 reply; 18+ messages in thread
From: Bjorn Helgaas @ 2025-03-12 21:37 UTC (permalink / raw)
To: Frank Li
Cc: Rob Herring, Saravana Kannan, Jingoo Han, Manivannan Sadhasivam,
Lorenzo Pieralisi, Krzysztof Wilczyński, Bjorn Helgaas,
Richard Zhu, Lucas Stach, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, devicetree, linux-kernel,
linux-pci, linux-arm-kernel, imx, Niklas Cassel
On Mon, Mar 10, 2025 at 04:16:43PM -0400, Frank Li wrote:
> parent_bus_offset in resource_entry can indicate address information just
> ahead of PCIe controller. Most system's bus fabric use 1:1 map between
> input and output address. but some hardware like i.MX8QXP doesn't use 1:1
> map. See below diagram:
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -478,6 +478,15 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
> bridge->ops = &dw_pcie_ops;
> bridge->child_ops = &dw_child_pcie_ops;
>
> + /*
> + * visconti_pcie_cpu_addr_fixup() use pp->io_base,
> + * so have to call dw_pcie_init_parent_bus_offset() after init
> + * pp->io_base.
> + */
> + ret = dw_pcie_init_parent_bus_offset(pci, "config", pp->cfg0_base);
> + if (ret)
> + return ret;
The ordering in dw_pcie_host_init() doesn't look right to me. We have
this:
dw_pcie_host_init
dw_pcie_get_resources
dw_pcie_cfg0_setup
devm_pci_alloc_host_bridge
win = resource_list_first_type(&bridge->windows, IORESOURCE_IO)
pp->io_base = pci_pio_to_address(win->res->start)
bridge->ops = ...
bridge->child_ops = ...
dw_pcie_init_parent_bus_offset
pp->ops->init
devm_pci_alloc_host_bridge() is generic, so it obviously can't depend
on any dwc-specific things. I think the ordering should be more like
this:
dw_pcie_host_init
devm_pci_alloc_host_bridge # generic
dw_pcie_get_resources # dwc RP and EP
dw_pcie_cfg0_setup
win = resource_list_first_type(&bridge->windows, IORESOURCE_IO)
pp->io_base = pci_pio_to_address(win->res->start)
dw_pcie_init_parent_bus_offset
bridge->ops = ...
bridge->child_ops = ...
pp->ops->init
and everything in the second block (dw_pcie_cfg0_setup() through
dw_pcie_init_parent_bus_offset()) is strictly DT-related resource
setup and could all go in a dw_pcie_host_get_resources() or similar.
> if (pp->ops->init) {
> ret = pp->ops->init(pp);
> if (ret)
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v10 05/10] PCI: dwc: Use devicetree 'ranges' property to get rid of cpu_addr_fixup() callback
2025-03-12 21:37 ` Bjorn Helgaas
@ 2025-03-13 14:17 ` Frank Li
0 siblings, 0 replies; 18+ messages in thread
From: Frank Li @ 2025-03-13 14:17 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Rob Herring, Saravana Kannan, Jingoo Han, Manivannan Sadhasivam,
Lorenzo Pieralisi, Krzysztof Wilczyński, Bjorn Helgaas,
Richard Zhu, Lucas Stach, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, devicetree, linux-kernel,
linux-pci, linux-arm-kernel, imx, Niklas Cassel
On Wed, Mar 12, 2025 at 04:37:57PM -0500, Bjorn Helgaas wrote:
> On Mon, Mar 10, 2025 at 04:16:43PM -0400, Frank Li wrote:
> > parent_bus_offset in resource_entry can indicate address information just
> > ahead of PCIe controller. Most system's bus fabric use 1:1 map between
> > input and output address. but some hardware like i.MX8QXP doesn't use 1:1
> > map. See below diagram:
>
> > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > @@ -478,6 +478,15 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
> > bridge->ops = &dw_pcie_ops;
> > bridge->child_ops = &dw_child_pcie_ops;
> >
> > + /*
> > + * visconti_pcie_cpu_addr_fixup() use pp->io_base,
> > + * so have to call dw_pcie_init_parent_bus_offset() after init
> > + * pp->io_base.
> > + */
> > + ret = dw_pcie_init_parent_bus_offset(pci, "config", pp->cfg0_base);
> > + if (ret)
> > + return ret;
>
> The ordering in dw_pcie_host_init() doesn't look right to me. We have
> this:
>
> dw_pcie_host_init
> dw_pcie_get_resources
> dw_pcie_cfg0_setup
> devm_pci_alloc_host_bridge
> win = resource_list_first_type(&bridge->windows, IORESOURCE_IO)
> pp->io_base = pci_pio_to_address(win->res->start)
> bridge->ops = ...
> bridge->child_ops = ...
> dw_pcie_init_parent_bus_offset
> pp->ops->init
>
> devm_pci_alloc_host_bridge() is generic, so it obviously can't depend
> on any dwc-specific things. I think the ordering should be more like
> this:
>
> dw_pcie_host_init
> devm_pci_alloc_host_bridge # generic
> dw_pcie_get_resources # dwc RP and EP
>
> dw_pcie_cfg0_setup
> win = resource_list_first_type(&bridge->windows, IORESOURCE_IO)
> pp->io_base = pci_pio_to_address(win->res->start)
> dw_pcie_init_parent_bus_offset
>
> bridge->ops = ...
> bridge->child_ops = ...
> pp->ops->init
>
> and everything in the second block (dw_pcie_cfg0_setup() through
> dw_pcie_init_parent_bus_offset()) is strictly DT-related resource
> setup and could all go in a dw_pcie_host_get_resources() or similar.
It is not related with these patch series. I can change it if you like.
Frank
>
> > if (pp->ops->init) {
> > ret = pp->ops->init(pp);
> > if (ret)
> >
> > --
> > 2.34.1
> >
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v10 06/10] PCI: dwc: ep: Add parent_bus_addr for outbound window
2025-03-10 20:16 [PATCH v10 00/10] PCI: Use device bus range info to cleanup RC Host/EP pci_fixup_addr() Frank Li
` (4 preceding siblings ...)
2025-03-10 20:16 ` [PATCH v10 05/10] PCI: dwc: Use devicetree 'ranges' property to get rid of cpu_addr_fixup() callback Frank Li
@ 2025-03-10 20:16 ` Frank Li
2025-03-10 20:16 ` [PATCH v10 07/10] PCI: dwc: Use parent_bus_offset Frank Li
` (3 subsequent siblings)
9 siblings, 0 replies; 18+ messages in thread
From: Frank Li @ 2025-03-10 20:16 UTC (permalink / raw)
To: Rob Herring, Saravana Kannan, Jingoo Han, Manivannan Sadhasivam,
Lorenzo Pieralisi, Krzysztof Wilczyński, Bjorn Helgaas,
Richard Zhu, Lucas Stach, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: devicetree, linux-kernel, linux-pci, linux-arm-kernel, imx,
Niklas Cassel, Frank Li
Endpoint
┌───────────────────────────────────────────────┐
│ pcie-ep@5f010000 │
│ ┌────────────────┐│
│ │ Endpoint ││
│ │ PCIe ││
│ │ Controller ││
│ bus@5f000000 │ ││
│ ┌──────────┐ │ ││
│ │ │ Outbound Transfer ││
│┌─────┐ │ Bus ┼─────►│ ATU ──────────┬┬─────►
││ │ │ Fabric │Bus │ ││PCI Addr
││ CPU ├───►│ │Addr │ ││0xA000_0000
││ │CPU │ │0x8000_0000 ││
│└─────┘Addr└──────────┘ │ ││
│ 0x7000_0000 └────────────────┘│
└───────────────────────────────────────────────┘
Use 'ranges' property in DT to configure the iATU outbound window address.
The bus fabric generally passes the same address to the PCIe EP controller,
but some bus fabrics map the address before sending it to the PCIe EP
controller.
Above diagram, CPU write data to outbound windows address 0x7000_0000, Bus
fabric map it to 0x8000_0000. ATU should use bus address 0x8000_0000 as
input address and map to PCI address 0xA000_0000 (dynamic alloc and assign
from pci device driver in host side).
Previously, 'cpu_addr_fixup()' was used to handle address conversion. Now,
the device tree provides this information, preferring a common method.
bus@5f000000 {
compatible = "simple-bus";
ranges = <0x80000000 0x0 0x70000000 0x10000000>;
pcie-ep@5f010000 {
reg = <0x80000000 0x10000000>;
reg-names ="addr_space";
...
};
...
};
'ranges' in bus@5f000000 descript how address map from CPU address to bus
address.
Use `of_property_read_reg()` to obtain the bus address and set it to the
ATU correctly, eliminating the need for vendor-specific cpu_addr_fixup().
Use reg-name "addr_space" to detect parent_bus_addr_offset.
Just set parent_bus_offset, but doesn't use it, so no functional change
intended yet.
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
Change from v9 to v10
- drop mani's review tag because big change.
- call help funciton dw_pcie_init_parent_bus_offset().
Change from v8 to v9
- change bus_addr_base to parent_bus_addr
- fix dw_pcie_find_index() address compare, which cause atu allocate
failure when run many time test.
Change from v7 to v8
- Add Mani's reviewedby tag
- s/convert/map in commit message
- update comments for of_property_read_reg()
- use 'use_parent_dt_ranges'
Change from v6 to v7
- none
Change from v5 to v6
- update diagram
- Add comments for of_property_read_reg()
- Remove unrelated 0x5f00_0000 in commit message
Change from v3 to v4
- change parent_bus_addr to u64 to fix 32bit build error
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202410230328.BTHareG1-lkp@intel.com/
Change from v2 to v3
- Add using_dtbus_info to control if use device tree bus ranges
information.
---
drivers/pci/controller/dwc/pcie-designware-ep.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 80ac2f9e88eb5..d69d76c150d92 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -915,6 +915,14 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
ep->phys_base = res->start;
ep->addr_size = resource_size(res);
+ /*
+ * artpec6_pcie_cpu_addr_fixup() use ep->phys_base. so call
+ * dw_pcie_init_parent_bus_offset after init ep->phys_base.
+ */
+ ret = dw_pcie_init_parent_bus_offset(pci, "addr_space", ep->phys_base);
+ if (ret)
+ return ret;
+
if (ep->ops->pre_init)
ep->ops->pre_init(ep);
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v10 07/10] PCI: dwc: Use parent_bus_offset
2025-03-10 20:16 [PATCH v10 00/10] PCI: Use device bus range info to cleanup RC Host/EP pci_fixup_addr() Frank Li
` (5 preceding siblings ...)
2025-03-10 20:16 ` [PATCH v10 06/10] PCI: dwc: ep: Add parent_bus_addr for outbound window Frank Li
@ 2025-03-10 20:16 ` Frank Li
2025-03-10 20:16 ` [PATCH v10 08/10] PCI: dwc: Print warning message when cpu_addr_fixup() exists Frank Li
` (2 subsequent siblings)
9 siblings, 0 replies; 18+ messages in thread
From: Frank Li @ 2025-03-10 20:16 UTC (permalink / raw)
To: Rob Herring, Saravana Kannan, Jingoo Han, Manivannan Sadhasivam,
Lorenzo Pieralisi, Krzysztof Wilczyński, Bjorn Helgaas,
Richard Zhu, Lucas Stach, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: devicetree, linux-kernel, linux-pci, linux-arm-kernel, imx,
Niklas Cassel, Frank Li
From: Bjorn Helgaas <bhelgaas@google.com>
We know the parent_bus_offset, either computed from a DT reg property (the
offset is the CPU physical addr - the 'config'/'addr_space' address on the
parent bus) or from a .cpu_addr_fixup() (which may have used a host bridge
window offset).
Apply that parent_bus_offset instead of calling .cpu_addr_fixup() again.
This assumes that all intermediate addresses are at the same offset from
the CPU physical addresses.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
change from v9 to v10
v9: https://lore.kernel.org/linux-pci/20250307233744.440476-5-helgaas@kernel.org/#R
- pp -> pci
- add ep side support
---
drivers/pci/controller/dwc/pcie-designware-ep.c | 5 +++--
drivers/pci/controller/dwc/pcie-designware-host.c | 12 ++++++------
drivers/pci/controller/dwc/pcie-designware.c | 3 ---
3 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index d69d76c150d92..62bc71ad20719 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -314,7 +314,8 @@ static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
- ret = dw_pcie_find_index(ep, addr, &atu_index);
+ ret = dw_pcie_find_index(ep, addr - pci->parent_bus_offset,
+ &atu_index);
if (ret < 0)
return;
@@ -333,7 +334,7 @@ static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
atu.func_no = func_no;
atu.type = PCIE_ATU_TYPE_MEM;
- atu.parent_bus_addr = addr;
+ atu.parent_bus_addr = addr - pci->parent_bus_offset;
atu.pci_addr = pci_addr;
atu.size = size;
ret = dw_pcie_ep_outbound_atu(ep, &atu);
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index eaa6dd4c7edda..a7b7e15d7b0db 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -637,7 +637,7 @@ static void __iomem *dw_pcie_other_conf_map_bus(struct pci_bus *bus,
type = PCIE_ATU_TYPE_CFG1;
atu.type = type;
- atu.parent_bus_addr = pp->cfg0_base;
+ atu.parent_bus_addr = pp->cfg0_base - pci->parent_bus_offset;
atu.pci_addr = busdev;
atu.size = pp->cfg0_size;
@@ -662,7 +662,7 @@ static int dw_pcie_rd_other_conf(struct pci_bus *bus, unsigned int devfn,
if (pp->cfg0_io_shared) {
atu.type = PCIE_ATU_TYPE_IO;
- atu.parent_bus_addr = pp->io_base;
+ atu.parent_bus_addr = pp->io_base - pci->parent_bus_offset;
atu.pci_addr = pp->io_bus_addr;
atu.size = pp->io_size;
@@ -688,7 +688,7 @@ static int dw_pcie_wr_other_conf(struct pci_bus *bus, unsigned int devfn,
if (pp->cfg0_io_shared) {
atu.type = PCIE_ATU_TYPE_IO;
- atu.parent_bus_addr = pp->io_base;
+ atu.parent_bus_addr = pp->io_base - pci->parent_bus_offset;
atu.pci_addr = pp->io_bus_addr;
atu.size = pp->io_size;
@@ -757,7 +757,7 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
atu.index = i;
atu.type = PCIE_ATU_TYPE_MEM;
- atu.parent_bus_addr = entry->res->start;
+ atu.parent_bus_addr = entry->res->start - pci->parent_bus_offset;
atu.pci_addr = entry->res->start - entry->offset;
/* Adjust iATU size if MSG TLP region was allocated before */
@@ -779,7 +779,7 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
if (pci->num_ob_windows > ++i) {
atu.index = i;
atu.type = PCIE_ATU_TYPE_IO;
- atu.parent_bus_addr = pp->io_base;
+ atu.parent_bus_addr = pp->io_base - pci->parent_bus_offset;
atu.pci_addr = pp->io_bus_addr;
atu.size = pp->io_size;
@@ -923,7 +923,7 @@ static int dw_pcie_pme_turn_off(struct dw_pcie *pci)
atu.size = resource_size(pci->pp.msg_res);
atu.index = pci->pp.msg_atu_index;
- atu.parent_bus_addr = pci->pp.msg_res->start;
+ atu.parent_bus_addr = pci->pp.msg_res->start - pci->parent_bus_offset;
ret = dw_pcie_prog_outbound_atu(pci, &atu);
if (ret)
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
index 70b4d3369158a..7061a7ec08cb2 100644
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -475,9 +475,6 @@ int dw_pcie_prog_outbound_atu(struct dw_pcie *pci,
u32 retries, val;
u64 limit_addr;
- if (pci->ops && pci->ops->cpu_addr_fixup)
- parent_bus_addr = pci->ops->cpu_addr_fixup(pci, parent_bus_addr);
-
limit_addr = parent_bus_addr + atu->size - 1;
if ((limit_addr & ~pci->region_limit) != (parent_bus_addr & ~pci->region_limit) ||
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v10 08/10] PCI: dwc: Print warning message when cpu_addr_fixup() exists
2025-03-10 20:16 [PATCH v10 00/10] PCI: Use device bus range info to cleanup RC Host/EP pci_fixup_addr() Frank Li
` (6 preceding siblings ...)
2025-03-10 20:16 ` [PATCH v10 07/10] PCI: dwc: Use parent_bus_offset Frank Li
@ 2025-03-10 20:16 ` Frank Li
2025-03-12 22:04 ` Bjorn Helgaas
2025-03-10 20:16 ` [PATCH v10 09/10] PCI: dwc: ep: Ensure proper iteration over outbound map windows Frank Li
2025-03-10 20:16 ` [PATCH v10 10/10] PCI: imx6: Remove cpu_addr_fixup() Frank Li
9 siblings, 1 reply; 18+ messages in thread
From: Frank Li @ 2025-03-10 20:16 UTC (permalink / raw)
To: Rob Herring, Saravana Kannan, Jingoo Han, Manivannan Sadhasivam,
Lorenzo Pieralisi, Krzysztof Wilczyński, Bjorn Helgaas,
Richard Zhu, Lucas Stach, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: devicetree, linux-kernel, linux-pci, linux-arm-kernel, imx,
Niklas Cassel, Frank Li
If the parent 'ranges' property in DT correctly describes the address
translation, the cpu_addr_fixup() callback is not needed. Print a warning
message to inform users to correct their DT files.
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
change from v9 to v10
- new patch
---
drivers/pci/controller/dwc/pcie-designware.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
index 7061a7ec08cb2..3ab85dde22ce4 100644
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -1125,6 +1125,8 @@ int dw_pcie_init_parent_bus_offset(struct dw_pcie *pci, const char *reg_name,
fixup = pci->ops->cpu_addr_fixup;
if (fixup) {
+ dev_warn_once(pci->dev, "cpu_addr_fixup() usage detected. Please fix DT!\n");
+
fixup_addr = fixup(pci, cpu_phy_addr);
if (reg_addr == fixup_addr) {
dev_info(dev, "%#010llx %s reg[%d] == %#010llx; %ps is redundant\n",
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v10 08/10] PCI: dwc: Print warning message when cpu_addr_fixup() exists
2025-03-10 20:16 ` [PATCH v10 08/10] PCI: dwc: Print warning message when cpu_addr_fixup() exists Frank Li
@ 2025-03-12 22:04 ` Bjorn Helgaas
2025-03-13 14:32 ` Frank Li
0 siblings, 1 reply; 18+ messages in thread
From: Bjorn Helgaas @ 2025-03-12 22:04 UTC (permalink / raw)
To: Frank Li
Cc: Rob Herring, Saravana Kannan, Jingoo Han, Manivannan Sadhasivam,
Lorenzo Pieralisi, Krzysztof Wilczyński, Bjorn Helgaas,
Richard Zhu, Lucas Stach, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, devicetree, linux-kernel,
linux-pci, linux-arm-kernel, imx, Niklas Cassel
On Mon, Mar 10, 2025 at 04:16:46PM -0400, Frank Li wrote:
> If the parent 'ranges' property in DT correctly describes the address
> translation, the cpu_addr_fixup() callback is not needed. Print a warning
> message to inform users to correct their DT files.
> +++ b/drivers/pci/controller/dwc/pcie-designware.c
> @@ -1125,6 +1125,8 @@ int dw_pcie_init_parent_bus_offset(struct dw_pcie *pci, const char *reg_name,
>
> fixup = pci->ops->cpu_addr_fixup;
> if (fixup) {
> + dev_warn_once(pci->dev, "cpu_addr_fixup() usage detected. Please fix DT!\n");
I don't think we need this. The mere presence of .cpu_addr_fixup()
doesn't tell us the DT is broken. When we have .cpu_addr_fixup(), the
DT is only broken if DT tells us something different than
.cpu_addr_fixup() tells us. And we already warn about that in the
"reg_addr != fixup_addr" case.
> +
> fixup_addr = fixup(pci, cpu_phy_addr);
> if (reg_addr == fixup_addr) {
> dev_info(dev, "%#010llx %s reg[%d] == %#010llx; %ps is redundant\n",
This message is really just a hint that DT is fine and
.cpu_addr_fixup() is redundant but harmless. If you want a dev_warn()
here to encourage people to remove .cpu_addr_fixup(), I'm fine with
that.
Seems like "dev_warn()" would be enough, probably no need for
"dev_warn_once()" since we should only run this once per controller
anyway, so I don't think we'll get spammed with messages.
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v10 08/10] PCI: dwc: Print warning message when cpu_addr_fixup() exists
2025-03-12 22:04 ` Bjorn Helgaas
@ 2025-03-13 14:32 ` Frank Li
0 siblings, 0 replies; 18+ messages in thread
From: Frank Li @ 2025-03-13 14:32 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Rob Herring, Saravana Kannan, Jingoo Han, Manivannan Sadhasivam,
Lorenzo Pieralisi, Krzysztof Wilczyński, Bjorn Helgaas,
Richard Zhu, Lucas Stach, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, devicetree, linux-kernel,
linux-pci, linux-arm-kernel, imx, Niklas Cassel
On Wed, Mar 12, 2025 at 05:04:24PM -0500, Bjorn Helgaas wrote:
> On Mon, Mar 10, 2025 at 04:16:46PM -0400, Frank Li wrote:
> > If the parent 'ranges' property in DT correctly describes the address
> > translation, the cpu_addr_fixup() callback is not needed. Print a warning
> > message to inform users to correct their DT files.
>
> > +++ b/drivers/pci/controller/dwc/pcie-designware.c
> > @@ -1125,6 +1125,8 @@ int dw_pcie_init_parent_bus_offset(struct dw_pcie *pci, const char *reg_name,
> >
> > fixup = pci->ops->cpu_addr_fixup;
> > if (fixup) {
> > + dev_warn_once(pci->dev, "cpu_addr_fixup() usage detected. Please fix DT!\n");
>
> I don't think we need this. The mere presence of .cpu_addr_fixup()
> doesn't tell us the DT is broken. When we have .cpu_addr_fixup(), the
> DT is only broken if DT tells us something different than
> .cpu_addr_fixup() tells us. And we already warn about that in the
> "reg_addr != fixup_addr" case.
It is encourage people to fix dts first and remove .cpu_addr_fixup().
Most case below "...redundant" is not printed at all at most case, even
there are .cpu_addr_fixup().
>
> > +
> > fixup_addr = fixup(pci, cpu_phy_addr);
> > if (reg_addr == fixup_addr) {
> > dev_info(dev, "%#010llx %s reg[%d] == %#010llx; %ps is redundant\n",
>
> This message is really just a hint that DT is fine and
> .cpu_addr_fixup() is redundant but harmless. If you want a dev_warn()
> here to encourage people to remove .cpu_addr_fixup(), I'm fine with
> that.
It is encourage people remove .cpu_addr_fixup() because dts already fixed.
>
> Seems like "dev_warn()" would be enough, probably no need for
> "dev_warn_once()" since we should only run this once per controller
> anyway, so I don't think we'll get spammed with messages.
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v10 09/10] PCI: dwc: ep: Ensure proper iteration over outbound map windows
2025-03-10 20:16 [PATCH v10 00/10] PCI: Use device bus range info to cleanup RC Host/EP pci_fixup_addr() Frank Li
` (7 preceding siblings ...)
2025-03-10 20:16 ` [PATCH v10 08/10] PCI: dwc: Print warning message when cpu_addr_fixup() exists Frank Li
@ 2025-03-10 20:16 ` Frank Li
2025-03-12 21:47 ` Bjorn Helgaas
2025-03-10 20:16 ` [PATCH v10 10/10] PCI: imx6: Remove cpu_addr_fixup() Frank Li
9 siblings, 1 reply; 18+ messages in thread
From: Frank Li @ 2025-03-10 20:16 UTC (permalink / raw)
To: Rob Herring, Saravana Kannan, Jingoo Han, Manivannan Sadhasivam,
Lorenzo Pieralisi, Krzysztof Wilczyński, Bjorn Helgaas,
Richard Zhu, Lucas Stach, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: devicetree, linux-kernel, linux-pci, linux-arm-kernel, imx,
Niklas Cassel, Frank Li
Most systems' PCIe outbound map windows have non-zero physical addresses,
but the possibility of encountering zero increased with commit
("PCI: dwc: ep: Add bus_addr_base for outbound window").
'ep->outbound_addr[n]', representing 'parent_bus_address', might be 0 on
some hardware, which trims high address bits through bus fabric before
sending to the PCIe controller.
Replace the iteration logic with 'for_each_set_bit()' to ensure only
allocated map windows are iterated when determining the ATU index from a
given address.
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
change from v9 to v10
- remove commit hash value
change from v8 to v9
- new patch
---
drivers/pci/controller/dwc/pcie-designware-ep.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 62bc71ad20719..e333855633a77 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -282,7 +282,7 @@ static int dw_pcie_find_index(struct dw_pcie_ep *ep, phys_addr_t addr,
u32 index;
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
- for (index = 0; index < pci->num_ob_windows; index++) {
+ for_each_set_bit(index, ep->ob_window_map, pci->num_ob_windows) {
if (ep->outbound_addr[index] != addr)
continue;
*atu_index = index;
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v10 09/10] PCI: dwc: ep: Ensure proper iteration over outbound map windows
2025-03-10 20:16 ` [PATCH v10 09/10] PCI: dwc: ep: Ensure proper iteration over outbound map windows Frank Li
@ 2025-03-12 21:47 ` Bjorn Helgaas
2025-03-13 14:27 ` Frank Li
0 siblings, 1 reply; 18+ messages in thread
From: Bjorn Helgaas @ 2025-03-12 21:47 UTC (permalink / raw)
To: Frank Li
Cc: Rob Herring, Saravana Kannan, Jingoo Han, Manivannan Sadhasivam,
Lorenzo Pieralisi, Krzysztof Wilczyński, Bjorn Helgaas,
Richard Zhu, Lucas Stach, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, devicetree, linux-kernel,
linux-pci, linux-arm-kernel, imx, Niklas Cassel
On Mon, Mar 10, 2025 at 04:16:47PM -0400, Frank Li wrote:
> Most systems' PCIe outbound map windows have non-zero physical addresses,
> but the possibility of encountering zero increased with commit
> ("PCI: dwc: ep: Add bus_addr_base for outbound window").
What is this commit? I don't see it in the tree, and I don't see it
in this series.
It look like it might be a fixup for something in this series. In
that case it should go *before* the other commit (or be squashed into
it if it's logically part of it).
I don't think this series touches ep->ob_window_map, so if it's a fix
it looks like it could go anywhere earlier.
> 'ep->outbound_addr[n]', representing 'parent_bus_address', might be 0 on
> some hardware, which trims high address bits through bus fabric before
> sending to the PCIe controller.
>
> Replace the iteration logic with 'for_each_set_bit()' to ensure only
> allocated map windows are iterated when determining the ATU index from a
> given address.
>
> Signed-off-by: Frank Li <Frank.Li@nxp.com>
> ---
> change from v9 to v10
> - remove commit hash value
>
> change from v8 to v9
> - new patch
> ---
> drivers/pci/controller/dwc/pcie-designware-ep.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> index 62bc71ad20719..e333855633a77 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> @@ -282,7 +282,7 @@ static int dw_pcie_find_index(struct dw_pcie_ep *ep, phys_addr_t addr,
> u32 index;
> struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
>
> - for (index = 0; index < pci->num_ob_windows; index++) {
> + for_each_set_bit(index, ep->ob_window_map, pci->num_ob_windows) {
> if (ep->outbound_addr[index] != addr)
> continue;
> *atu_index = index;
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v10 09/10] PCI: dwc: ep: Ensure proper iteration over outbound map windows
2025-03-12 21:47 ` Bjorn Helgaas
@ 2025-03-13 14:27 ` Frank Li
0 siblings, 0 replies; 18+ messages in thread
From: Frank Li @ 2025-03-13 14:27 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Rob Herring, Saravana Kannan, Jingoo Han, Manivannan Sadhasivam,
Lorenzo Pieralisi, Krzysztof Wilczyński, Bjorn Helgaas,
Richard Zhu, Lucas Stach, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, devicetree, linux-kernel,
linux-pci, linux-arm-kernel, imx, Niklas Cassel
On Wed, Mar 12, 2025 at 04:47:00PM -0500, Bjorn Helgaas wrote:
> On Mon, Mar 10, 2025 at 04:16:47PM -0400, Frank Li wrote:
> > Most systems' PCIe outbound map windows have non-zero physical addresses,
> > but the possibility of encountering zero increased with commit
> > ("PCI: dwc: ep: Add bus_addr_base for outbound window").
>
> What is this commit? I don't see it in the tree, and I don't see it
> in this series.
Sorry, it refer to old version of this series. It should be
PCI: dwc: Use parent_bus_offset
>
> It look like it might be a fixup for something in this series. In
> that case it should go *before* the other commit (or be squashed into
> it if it's logically part of it).
Yes it should before PCI: dwc: Use parent_bus_offset to support bisect.
>
> I don't think this series touches ep->ob_window_map, so if it's a fix
> it looks like it could go anywhere earlier.
dw_pcie_ep_outbound_atu() touch ob_window_map.
Frank
>
> > 'ep->outbound_addr[n]', representing 'parent_bus_address', might be 0 on
> > some hardware, which trims high address bits through bus fabric before
> > sending to the PCIe controller.
> >
> > Replace the iteration logic with 'for_each_set_bit()' to ensure only
> > allocated map windows are iterated when determining the ATU index from a
> > given address.
> >
> > Signed-off-by: Frank Li <Frank.Li@nxp.com>
> > ---
> > change from v9 to v10
> > - remove commit hash value
> >
> > change from v8 to v9
> > - new patch
> > ---
> > drivers/pci/controller/dwc/pcie-designware-ep.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > index 62bc71ad20719..e333855633a77 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > @@ -282,7 +282,7 @@ static int dw_pcie_find_index(struct dw_pcie_ep *ep, phys_addr_t addr,
> > u32 index;
> > struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> >
> > - for (index = 0; index < pci->num_ob_windows; index++) {
> > + for_each_set_bit(index, ep->ob_window_map, pci->num_ob_windows) {
> > if (ep->outbound_addr[index] != addr)
> > continue;
> > *atu_index = index;
> >
> > --
> > 2.34.1
> >
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v10 10/10] PCI: imx6: Remove cpu_addr_fixup()
2025-03-10 20:16 [PATCH v10 00/10] PCI: Use device bus range info to cleanup RC Host/EP pci_fixup_addr() Frank Li
` (8 preceding siblings ...)
2025-03-10 20:16 ` [PATCH v10 09/10] PCI: dwc: ep: Ensure proper iteration over outbound map windows Frank Li
@ 2025-03-10 20:16 ` Frank Li
9 siblings, 0 replies; 18+ messages in thread
From: Frank Li @ 2025-03-10 20:16 UTC (permalink / raw)
To: Rob Herring, Saravana Kannan, Jingoo Han, Manivannan Sadhasivam,
Lorenzo Pieralisi, Krzysztof Wilczyński, Bjorn Helgaas,
Richard Zhu, Lucas Stach, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: devicetree, linux-kernel, linux-pci, linux-arm-kernel, imx,
Niklas Cassel, Frank Li
Remove cpu_addr_fixup() because dwc common driver already handle address
translate.
Acked-by: Richard Zhu <hongxing.zhu@nxp.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
change from v9 to v10
- none
Change from v8 to v9
- rebase latest linux-next (close enough to v6.14-rc1)
Change from v7 to v8
- add mani and richard's review/ack tag
- use varible 'use_parent_dt_ranges'
Change from v2 to v7
- none
Change from v1 to v2
- set using_dtbus_info true
---
drivers/pci/controller/dwc/pci-imx6.c | 18 +-----------------
1 file changed, 1 insertion(+), 17 deletions(-)
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 90ace941090f9..d1eb535df73e1 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -1217,22 +1217,6 @@ static void imx_pcie_host_exit(struct dw_pcie_rp *pp)
regulator_disable(imx_pcie->vpcie);
}
-static u64 imx_pcie_cpu_addr_fixup(struct dw_pcie *pcie, u64 cpu_addr)
-{
- struct imx_pcie *imx_pcie = to_imx_pcie(pcie);
- struct dw_pcie_rp *pp = &pcie->pp;
- struct resource_entry *entry;
-
- if (!(imx_pcie->drvdata->flags & IMX_PCIE_FLAG_CPU_ADDR_FIXUP))
- return cpu_addr;
-
- entry = resource_list_first_type(&pp->bridge->windows, IORESOURCE_MEM);
- if (!entry)
- return cpu_addr;
-
- return cpu_addr - entry->offset;
-}
-
/*
* In old DWC implementations, PCIE_ATU_INHIBIT_PAYLOAD in iATU Ctrl2
* register is reserved, so the generic DWC implementation of sending the
@@ -1263,7 +1247,6 @@ static const struct dw_pcie_host_ops imx_pcie_host_dw_pme_ops = {
static const struct dw_pcie_ops dw_pcie_ops = {
.start_link = imx_pcie_start_link,
.stop_link = imx_pcie_stop_link,
- .cpu_addr_fixup = imx_pcie_cpu_addr_fixup,
};
static void imx_pcie_ep_init(struct dw_pcie_ep *ep)
@@ -1645,6 +1628,7 @@ static int imx_pcie_probe(struct platform_device *pdev)
if (ret)
return ret;
+ pci->use_parent_dt_ranges = true;
if (imx_pcie->drvdata->mode == DW_PCIE_EP_TYPE) {
ret = imx_add_pcie_ep(imx_pcie, pdev);
if (ret < 0)
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread