* [PATCH v2 0/3] PCI: dwc: Fix missing iATU setup when ECAM is enabled
@ 2025-12-29 10:42 Krishna Chaitanya Chundru
2025-12-29 10:42 ` [PATCH v2 1/3] PCI: dwc: Fix skipped index 0 in outbound ATU setup Krishna Chaitanya Chundru
2025-12-29 10:42 ` [PATCH v2 2/3] PCI: dwc: Correct iATU index increment for MSG TLP region Krishna Chaitanya Chundru
0 siblings, 2 replies; 7+ messages in thread
From: Krishna Chaitanya Chundru @ 2025-12-29 10:42 UTC (permalink / raw)
To: Jingoo Han, Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, Frank Li,
Serge Semin
Cc: linux-pci, linux-kernel, macro, Krishna Chaitanya Chundru, stable
When ECAM is enabled, the driver skipped calling dw_pcie_iatu_setup()
before configuring ECAM iATU entries. This left IO and MEM outbound
windows unprogrammed, resulting in broken IO transactions. Additionally,
dw_pcie_config_ecam_iatu() was only called during host initialization,
so ECAM-related iATU entries were not restored after suspend/resume,
leading to failures in configuration space access.
To resolve these issues, the ECAM iATU configuration is moved into
dw_pcie_setup_rc(). At the same time, dw_pcie_iatu_setup() is invoked
when ECAM is enabled.
Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
---
Changes in v2:
- Fixed the index 0 of the ATU window skipping.
- Keep the ob_atu_index in dw_pcie instead of dw_pcie_rp & couple of nitpicks (Bjorn).
- Link to v1: https://lore.kernel.org/r/20251203-ecam_io_fix-v1-0-5cc3d3769c18@oss.qualcomm.com
---
Krishna Chaitanya Chundru (3):
PCI: dwc: Fix skipped index 0 in outbound ATU setup
PCI: dwc: Correct iATU index increment for MSG TLP region
PCI: dwc: Fix missing iATU setup when ECAM is enabled
drivers/pci/controller/dwc/pcie-designware-host.c | 53 ++++++++++++++---------
drivers/pci/controller/dwc/pcie-designware.c | 3 ++
drivers/pci/controller/dwc/pcie-designware.h | 2 +-
3 files changed, 37 insertions(+), 21 deletions(-)
---
base-commit: 3f9f0252130e7dd60d41be0802bf58f6471c691d
change-id: 20251203-ecam_io_fix-6e060fecd3b8
Best regards,
--
Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 1/3] PCI: dwc: Fix skipped index 0 in outbound ATU setup
2025-12-29 10:42 [PATCH v2 0/3] PCI: dwc: Fix missing iATU setup when ECAM is enabled Krishna Chaitanya Chundru
@ 2025-12-29 10:42 ` Krishna Chaitanya Chundru
2026-01-22 15:02 ` Niklas Cassel
2025-12-29 10:42 ` [PATCH v2 2/3] PCI: dwc: Correct iATU index increment for MSG TLP region Krishna Chaitanya Chundru
1 sibling, 1 reply; 7+ messages in thread
From: Krishna Chaitanya Chundru @ 2025-12-29 10:42 UTC (permalink / raw)
To: Jingoo Han, Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, Frank Li,
Serge Semin
Cc: linux-pci, linux-kernel, macro, Krishna Chaitanya Chundru, stable
In dw_pcie_iatu_setup(), the outbound ATU loop uses a pre-increment
on the index and starts programming from 1, effectively skipping
index 0. This results in the first outbound window never being
configured.
Update the logic to start from index 0 and use post-increment (i++)
when assigning atu.index.
Fixes: ce06bf570390f ("PCI: dwc: Check iATU in/outbound range setup status")
Cc: stable@vger.kernel.org
Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
---
Note:- The fix tag shown above is for applying this patch cleanly,
further below versions we need to manually apply them, If any one
intrested to apply this fix then we can submit another patch based on
that kernel version.
---
drivers/pci/controller/dwc/pcie-designware-host.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index e92513c5bda51bde3a7157033ddbd73afa370d78..32a26458ed8f1696fe2fdcf9df6b795c4c761f1f 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -896,10 +896,10 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
if (resource_type(entry->res) != IORESOURCE_MEM)
continue;
- if (pci->num_ob_windows <= ++i)
+ if (pci->num_ob_windows < i)
break;
- atu.index = i;
+ atu.index = i++;
atu.type = PCIE_ATU_TYPE_MEM;
atu.parent_bus_addr = entry->res->start - pci->parent_bus_offset;
atu.pci_addr = entry->res->start - entry->offset;
@@ -920,7 +920,7 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
}
if (pp->io_size) {
- if (pci->num_ob_windows > ++i) {
+ if (pci->num_ob_windows > i) {
atu.index = i;
atu.type = PCIE_ATU_TYPE_IO;
atu.parent_bus_addr = pp->io_base - pci->parent_bus_offset;
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 2/3] PCI: dwc: Correct iATU index increment for MSG TLP region
2025-12-29 10:42 [PATCH v2 0/3] PCI: dwc: Fix missing iATU setup when ECAM is enabled Krishna Chaitanya Chundru
2025-12-29 10:42 ` [PATCH v2 1/3] PCI: dwc: Fix skipped index 0 in outbound ATU setup Krishna Chaitanya Chundru
@ 2025-12-29 10:42 ` Krishna Chaitanya Chundru
1 sibling, 0 replies; 7+ messages in thread
From: Krishna Chaitanya Chundru @ 2025-12-29 10:42 UTC (permalink / raw)
To: Jingoo Han, Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, Frank Li,
Serge Semin
Cc: linux-pci, linux-kernel, macro, Krishna Chaitanya Chundru, stable
Commit e1a4ec1a9520 ("PCI: dwc: Add generic MSG TLP support for sending
PME_Turn_Off when system suspend") introduced a mechanism to reserve an
iATU window for MSG TLP transactions. However, the code incorrectly
assigned pp->msg_atu_index = i without incrementing i first, causing
the MSG TLP region to reuse the last configured outbound window instead
of the next available one. This can cause issue with IO transfers as
this can over write iATU configured for IO memory.
Fix this by incrementing i before assigning it to msg_atu_index so
that the MSG TLP region uses a dedicated iATU entry.
Added error logs in dw_pcie_pme_turn_off().
Fixes: e1a4ec1a9520 ("PCI: dwc: Add generic MSG TLP support for sending PME_Turn_Off when system suspend")
Tested-by: Maciej W. Rozycki <macro@orcam.me.uk>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Cc: stable@vger.kernel.org
Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
---
drivers/pci/controller/dwc/pcie-designware-host.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index 32a26458ed8f1696fe2fdcf9df6b795c4c761f1f..88b6ace0607e97bf6dd6bf7886baaa13bf267e6e 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -942,7 +942,7 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
dev_warn(pci->dev, "Ranges exceed outbound iATU size (%d)\n",
pci->num_ob_windows);
- pp->msg_atu_index = i;
+ pp->msg_atu_index = ++i;
i = 0;
resource_list_for_each_entry(entry, &pp->bridge->dma_ranges) {
@@ -1113,11 +1113,15 @@ static int dw_pcie_pme_turn_off(struct dw_pcie *pci)
void __iomem *mem;
int ret;
- if (pci->num_ob_windows <= pci->pp.msg_atu_index)
+ if (pci->num_ob_windows <= pci->pp.msg_atu_index) {
+ dev_err(pci->dev, "No available iATU enteries\n");
return -ENOSPC;
+ }
- if (!pci->pp.msg_res)
+ if (!pci->pp.msg_res) {
+ dev_err(pci->dev, "Msg resource is not allocated\n");
return -ENOSPC;
+ }
atu.code = PCIE_MSG_CODE_PME_TURN_OFF;
atu.routing = PCIE_MSG_TYPE_R_BC;
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/3] PCI: dwc: Fix skipped index 0 in outbound ATU setup
2025-12-29 10:42 ` [PATCH v2 1/3] PCI: dwc: Fix skipped index 0 in outbound ATU setup Krishna Chaitanya Chundru
@ 2026-01-22 15:02 ` Niklas Cassel
2026-01-22 18:16 ` Maciej W. Rozycki
0 siblings, 1 reply; 7+ messages in thread
From: Niklas Cassel @ 2026-01-22 15:02 UTC (permalink / raw)
To: Krishna Chaitanya Chundru
Cc: Jingoo Han, Manivannan Sadhasivam, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, Frank Li,
Serge Semin, linux-pci, linux-kernel, macro, stable
On Mon, Dec 29, 2025 at 04:12:41PM +0530, Krishna Chaitanya Chundru wrote:
> In dw_pcie_iatu_setup(), the outbound ATU loop uses a pre-increment
> on the index and starts programming from 1, effectively skipping
> index 0. This results in the first outbound window never being
> configured.
This in not true.
outbound iatu at index 0 is used for CFG IOs, see dw_pcie_other_conf_map_bus()
and:
https://github.com/torvalds/linux/blob/v6.19-rc6/drivers/pci/controller/dwc/pcie-designware-host.c#L888
Also see my series here:
https://lore.kernel.org/linux-pci/20260122145411.453291-4-cassel@kernel.org/T/
That tries to clean up this mess.
Kind regards,
Niklas
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/3] PCI: dwc: Fix skipped index 0 in outbound ATU setup
2026-01-22 15:02 ` Niklas Cassel
@ 2026-01-22 18:16 ` Maciej W. Rozycki
2026-01-22 21:19 ` Niklas Cassel
0 siblings, 1 reply; 7+ messages in thread
From: Maciej W. Rozycki @ 2026-01-22 18:16 UTC (permalink / raw)
To: Niklas Cassel
Cc: Krishna Chaitanya Chundru, Jingoo Han, Manivannan Sadhasivam,
Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring,
Bjorn Helgaas, Frank Li, Serge Semin, linux-pci, linux-kernel,
stable
On Thu, 22 Jan 2026, Niklas Cassel wrote:
> Also see my series here:
> https://lore.kernel.org/linux-pci/20260122145411.453291-4-cassel@kernel.org/T/
>
> That tries to clean up this mess.
Is your patchset referred meant to replace this one or does it apply on
top? Shall I verify yours with my RISC-V HiFive Unmatched system so as to
determine whether it is as good a fix for the port I/O access regression
caused by commit f6fd357f7afb ("PCI: dwc: Prepare the driver for enabling
ECAM mechanism using iATU 'CFG Shift Feature'")? You don't seem to refer
to either my issue previously reported or the offending commit.
Maciej
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/3] PCI: dwc: Fix skipped index 0 in outbound ATU setup
2026-01-22 18:16 ` Maciej W. Rozycki
@ 2026-01-22 21:19 ` Niklas Cassel
2026-01-23 20:35 ` Maciej W. Rozycki
0 siblings, 1 reply; 7+ messages in thread
From: Niklas Cassel @ 2026-01-22 21:19 UTC (permalink / raw)
To: Maciej W. Rozycki
Cc: Krishna Chaitanya Chundru, Jingoo Han, Manivannan Sadhasivam,
Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring,
Bjorn Helgaas, Frank Li, Serge Semin, linux-pci, linux-kernel,
stable
[-- Attachment #1: Type: text/plain, Size: 1909 bytes --]
On Thu, Jan 22, 2026 at 06:16:11PM +0000, Maciej W. Rozycki wrote:
> On Thu, 22 Jan 2026, Niklas Cassel wrote:
>
> > Also see my series here:
> > https://lore.kernel.org/linux-pci/20260122145411.453291-4-cassel@kernel.org/T/
> >
> > That tries to clean up this mess.
>
> Is your patchset referred meant to replace this one or does it apply on
> top?
This series does no longer apply, as it collides with a commit queued on
controller/dwc branch:
https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git/commit/?h=controller/dwc&id=e9a5415adb209f86a05e55b850127ada82e070f1
My patches are based on top of the above commit.
(I saw the big mess we currently have with regards to iatu indexing,
so I decided to clean it up, but making things consistent.)
So first of all, this series needs to be rebased.
If you ask me personally, I would prefer if Krishna could rebase on top
of my cleanups.
Patch 1/3 in this series is simply wrong, so it should be dropped.
Patch 2/3 in this series is similar to patch 1/3 in my series, but seems
to also have some extra prints that seem to be unrelated to fixing the issue
at hand. (Fine to add extra prints in some other function, but don't do it in
the fix patch itself that will be backported to stable releases.)
Patch 3/3 is the only patch that needs to be rebased, and seem to be the
patch that solves your issue.
I don't like the way that patch 3/3 is implemented.
ECAM will use two iATUs, one for PCIE_ATU_TYPE_CFG0 one for
PCIE_ATU_TYPE_CFG1. But this patch completely disregards that
this driver already reserves iATU index 0 for PCIE_ATU_TYPE_CFG0,
but for non-ECAM versions.
Now I understand why they have patch 1/3 in this series.
But it is still wrong. It has to change the indexing based on ECAM
is used or not.
Please try the attached patch on top of my series.
It avoids the need to introduce a new struct member.
Kind regards,
Niklas
[-- Attachment #2: 0001-PCI-dwc-Fix-ECAM.patch --]
[-- Type: text/plain, Size: 4398 bytes --]
From b3d345d7075a4757c10b8fbf85154da66bccfebf Mon Sep 17 00:00:00 2001
From: Niklas Cassel <cassel@kernel.org>
Date: Thu, 22 Jan 2026 22:05:39 +0100
Subject: [PATCH] PCI: dwc: Fix ECAM ...
Signed-off-by: Niklas Cassel <cassel@kernel.org>
---
.../pci/controller/dwc/pcie-designware-host.c | 34 +++++++++++--------
drivers/pci/controller/dwc/pcie-designware.c | 6 ++++
2 files 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 eda94db04b63..ef66a031f0bb 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -441,7 +441,7 @@ static int dw_pcie_config_ecam_iatu(struct dw_pcie_rp *pp)
/*
* Root bus under the host bridge doesn't require any iATU configuration
* as DBI region will be used to access root bus config space.
- * Immediate bus under Root Bus, needs type 0 iATU configuration and
+ * Immediate bus under Root Bus needs type 0 iATU configuration and
* remaining buses need type 1 iATU configuration.
*/
atu.index = 0;
@@ -641,14 +641,6 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
if (ret)
goto err_free_msi;
- if (pp->ecam_enabled) {
- ret = dw_pcie_config_ecam_iatu(pp);
- if (ret) {
- dev_err(dev, "Failed to configure iATU in ECAM mode\n");
- goto err_free_msi;
- }
- }
-
/*
* Allocate the resource for MSG TLP before programming the iATU
* outbound window in dw_pcie_setup_rc(). Since the allocation depends
@@ -892,8 +884,8 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
struct dw_pcie_ob_atu_cfg atu = { 0 };
struct resource_entry *entry;
- int ob_iatu_index_to_use = 0;
- int ib_iatu_index_to_use = 0;
+ int ob_iatu_index_to_use;
+ int ib_iatu_index_to_use;
int i, ret;
if (!pci->num_ob_windows) {
@@ -915,8 +907,20 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
* NOTE: For outbound address translation, outbound iATU at index 0 is
* reserved for CFG IOs (dw_pcie_other_conf_map_bus()), thus start at
* index 1.
+ *
+ * If using ECAM, outbound iATU at index 0 and index 1 is reserved for
+ * CFG IOs.
*/
- ob_iatu_index_to_use++;
+ if (pp->ecam_enabled) {
+ ob_iatu_index_to_use = 2;
+ ret = dw_pcie_config_ecam_iatu(pp);
+ if (ret) {
+ dev_err(pci->dev, "Failed to configure iATU in ECAM mode\n");
+ return ret;
+ }
+ } else {
+ ob_iatu_index_to_use = 1;
+ }
resource_list_for_each_entry(entry, &pp->bridge->windows) {
resource_size_t res_size;
@@ -1002,6 +1006,7 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
}
}
+ ib_iatu_index_to_use = 0;
resource_list_for_each_entry(entry, &pp->bridge->dma_ranges) {
resource_size_t res_start, res_size, window_size;
@@ -1157,9 +1162,10 @@ int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
/*
* If the platform provides its own child bus config accesses, it means
* the platform uses its own address translation component rather than
- * ATU, so we should not program the ATU here.
+ * ATU, so we should not program the ATU here. If ECAM is enabled,
+ * config space access goes through ATU, so set up ATU here.
*/
- if (pp->bridge->child_ops == &dw_child_pcie_ops) {
+ if (pp->bridge->child_ops == &dw_child_pcie_ops || pp->ecam_enabled) {
ret = dw_pcie_iatu_setup(pp);
if (ret)
return ret;
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
index 2fa9f6ee149e..766df22fe46e 100644
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -531,6 +531,9 @@ int dw_pcie_prog_outbound_atu(struct dw_pcie *pci,
u32 retries, val;
u64 limit_addr;
+ if (atu->index > pci->num_ob_windows)
+ return -ENOSPC;
+
limit_addr = parent_bus_addr + atu->size - 1;
if ((limit_addr & ~pci->region_limit) != (parent_bus_addr & ~pci->region_limit) ||
@@ -604,6 +607,9 @@ int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int type,
u64 limit_addr = pci_addr + size - 1;
u32 retries, val;
+ if (index > pci->num_ib_windows)
+ return -ENOSPC;
+
if ((limit_addr & ~pci->region_limit) != (pci_addr & ~pci->region_limit) ||
!IS_ALIGNED(parent_bus_addr, pci->region_align) ||
!IS_ALIGNED(pci_addr, pci->region_align) || !size) {
--
2.52.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/3] PCI: dwc: Fix skipped index 0 in outbound ATU setup
2026-01-22 21:19 ` Niklas Cassel
@ 2026-01-23 20:35 ` Maciej W. Rozycki
0 siblings, 0 replies; 7+ messages in thread
From: Maciej W. Rozycki @ 2026-01-23 20:35 UTC (permalink / raw)
To: Niklas Cassel
Cc: Krishna Chaitanya Chundru, Jingoo Han, Manivannan Sadhasivam,
Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring,
Bjorn Helgaas, Frank Li, Serge Semin, linux-pci, linux-kernel,
stable
On Thu, 22 Jan 2026, Niklas Cassel wrote:
> Please try the attached patch on top of my series.
Thank you for the clarification and the updated patches. I can see you
have posted new versions since. I'll try them sometime next week as I'm
out of time right now.
Maciej
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-01-23 20:35 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-29 10:42 [PATCH v2 0/3] PCI: dwc: Fix missing iATU setup when ECAM is enabled Krishna Chaitanya Chundru
2025-12-29 10:42 ` [PATCH v2 1/3] PCI: dwc: Fix skipped index 0 in outbound ATU setup Krishna Chaitanya Chundru
2026-01-22 15:02 ` Niklas Cassel
2026-01-22 18:16 ` Maciej W. Rozycki
2026-01-22 21:19 ` Niklas Cassel
2026-01-23 20:35 ` Maciej W. Rozycki
2025-12-29 10:42 ` [PATCH v2 2/3] PCI: dwc: Correct iATU index increment for MSG TLP region Krishna Chaitanya Chundru
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox