* [PATCH v3 1/5] PCI: dwc: Skip failed outbound iATU and continue
2025-09-23 11:36 [PATCH v3 0/5] Add support for Andes Qilai SoC PCIe controller Randolph Lin
@ 2025-09-23 11:36 ` Randolph Lin
2025-09-23 14:42 ` Bjorn Helgaas
2025-09-23 11:36 ` [PATCH v3 2/5] dt-bindings: PCI: Add Andes QiLai PCIe support Randolph Lin
` (3 subsequent siblings)
4 siblings, 1 reply; 13+ messages in thread
From: Randolph Lin @ 2025-09-23 11:36 UTC (permalink / raw)
To: linux-kernel
Cc: linux-pci, linux-riscv, devicetree, jingoohan1, mani, lpieralisi,
kwilczynski, robh, bhelgaas, krzk+dt, conor+dt, alex, aou, palmer,
paul.walmsley, ben717, inochiama, thippeswamy.havalige, namcao,
shradha.t, randolph.sklin, tim609, Randolph Lin
Previously, outbound iATU programming included range checks based
on hardware limitations. If a configuration did not meet these
constraints, the loop would stop immediately.
This patch updates the behavior to enhance flexibility. Instead of
stopping at the first issue, it now logs a warning with details of
the affected window and proceeds to program the remaining iATU
entries.
This enables partial configuration to complete in cases where some
iATU windows may not meet requirements, improving overall
compatibility.
Signed-off-by: Randolph Lin <randolph@andestech.com>
---
drivers/pci/controller/dwc/pcie-designware-host.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index 952f8594b501..91ee6b903934 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -756,7 +756,7 @@ 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;
@@ -773,9 +773,10 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
ret = dw_pcie_prog_outbound_atu(pci, &atu);
if (ret) {
- dev_err(pci->dev, "Failed to set MEM range %pr\n",
- entry->res);
- return ret;
+ dev_warn(pci->dev, "Failed to set MEM range %pr\n",
+ entry->res);
+ } else {
+ i++;
}
}
--
2.34.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH v3 1/5] PCI: dwc: Skip failed outbound iATU and continue
2025-09-23 11:36 ` [PATCH v3 1/5] PCI: dwc: Skip failed outbound iATU and continue Randolph Lin
@ 2025-09-23 14:42 ` Bjorn Helgaas
2025-09-24 12:58 ` Randolph Lin
0 siblings, 1 reply; 13+ messages in thread
From: Bjorn Helgaas @ 2025-09-23 14:42 UTC (permalink / raw)
To: Randolph Lin
Cc: linux-kernel, linux-pci, linux-riscv, devicetree, jingoohan1,
mani, lpieralisi, kwilczynski, robh, bhelgaas, krzk+dt, conor+dt,
alex, aou, palmer, paul.walmsley, ben717, inochiama,
thippeswamy.havalige, namcao, shradha.t, randolph.sklin, tim609
On Tue, Sep 23, 2025 at 07:36:43PM +0800, Randolph Lin wrote:
> Previously, outbound iATU programming included range checks based
> on hardware limitations. If a configuration did not meet these
> constraints, the loop would stop immediately.
>
> This patch updates the behavior to enhance flexibility. Instead of
> stopping at the first issue, it now logs a warning with details of
> the affected window and proceeds to program the remaining iATU
> entries.
>
> This enables partial configuration to complete in cases where some
> iATU windows may not meet requirements, improving overall
> compatibility.
It's not really clear why this is needed. I assume it's related to
dropping qilai_pcie_outbound_atu_addr_valid().
I guess dw_pcie_prog_outbound_atu() must return an error for one of
the QiLai ranges? Which one, and what exactly is the problem? I
still suspect something wrong in the devicetree description.
> Signed-off-by: Randolph Lin <randolph@andestech.com>
> ---
> drivers/pci/controller/dwc/pcie-designware-host.c | 9 +++++----
> 1 file changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index 952f8594b501..91ee6b903934 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -756,7 +756,7 @@ 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;
> @@ -773,9 +773,10 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
>
> ret = dw_pcie_prog_outbound_atu(pci, &atu);
> if (ret) {
> - dev_err(pci->dev, "Failed to set MEM range %pr\n",
> - entry->res);
> - return ret;
> + dev_warn(pci->dev, "Failed to set MEM range %pr\n",
> + entry->res);
> + } else {
> + i++;
> }
> }
>
> --
> 2.34.1
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v3 1/5] PCI: dwc: Skip failed outbound iATU and continue
2025-09-23 14:42 ` Bjorn Helgaas
@ 2025-09-24 12:58 ` Randolph Lin
2025-09-26 21:10 ` Bjorn Helgaas
0 siblings, 1 reply; 13+ messages in thread
From: Randolph Lin @ 2025-09-24 12:58 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-kernel, linux-pci, linux-riscv, devicetree, jingoohan1,
mani, lpieralisi, kwilczynski, robh, bhelgaas, krzk+dt, conor+dt,
alex, aou, palmer, paul.walmsley, ben717, inochiama,
thippeswamy.havalige, namcao, shradha.t, randolph.sklin, tim609
Hi Bjorn,
Sorry, I forgot to reply to the email before sending the patch.
I missed the email.
On Tue, Sep 23, 2025 at 09:42:23AM -0500, Bjorn Helgaas wrote:
> [EXTERNAL MAIL]
>
> On Tue, Sep 23, 2025 at 07:36:43PM +0800, Randolph Lin wrote:
> > Previously, outbound iATU programming included range checks based
> > on hardware limitations. If a configuration did not meet these
> > constraints, the loop would stop immediately.
> >
> > This patch updates the behavior to enhance flexibility. Instead of
> > stopping at the first issue, it now logs a warning with details of
> > the affected window and proceeds to program the remaining iATU
> > entries.
> >
> > This enables partial configuration to complete in cases where some
> > iATU windows may not meet requirements, improving overall
> > compatibility.
>
> It's not really clear why this is needed. I assume it's related to
> dropping qilai_pcie_outbound_atu_addr_valid().
>
Yes, I want to drop the previous atu_addr_valid function.
> I guess dw_pcie_prog_outbound_atu() must return an error for one of
> the QiLai ranges? Which one, and what exactly is the problem? I
> still suspect something wrong in the devicetree description.
>
The main issue is not the returned error; just need to avoid terminating
the process when the configuration exceeds the hardware’s expected limits.
There are two methods to fix the issue on the Qilai SoC:
1. Simply skip the entries that do not match the designware hardware iATU limitations.
An error will be returned, but it can be ignored. On the Qilai SoC, the iATU
limitation is the 4GB boundary. Qilai SoC only need to configure iATU support
to translate addresses below the "32-bits" address range. Although 64-bits
addresses do not match the designware hardware iATU limitations, there is no
need to configure 64-bits addresses, since the connection is hard-wired.
2. Set the devicetree only 2 viewport for iATU and force using devicetree value.
This is a workaround in the devicetree, but the fix logic is not easy to document.
Instead, we should enforce the use of the viewport defined in the devicetree and
modify the designware generic code accordingly — using the viewport values
from the devicetree instead of reading them from the designware registers.
Since only two viewports are available for iATU, we should reserve one for
the configuration registers and the other for 32-bit address access.
Therefore, reverse logic still needs to be added to the designware generic code.
Method 2 adds excessive complexity to the designware generic code. Instead,
directly configuring the iATU and reporting an error when the configuration
exceeds the hardware iATU limitations is a simpler and more effective
approach to applying the fix.
Conclusion:
1. The iATU needs to be configured for 32-bits address space.
In compliance with hardware limitations.
2. The iATU needs to be configured for config space.
In compliance with hardware limitations.
3. The iATU needs to be configured for 64-bit address space.
This does not comply with hardware limitations and will print an error.
As long as it does not return an error value that terminates subsequent
operations, it is acceptable.
Simply skipping this entry when configuring the iATU is acceptable.
> > Signed-off-by: Randolph Lin <randolph@andestech.com>
> > ---
> > drivers/pci/controller/dwc/pcie-designware-host.c | 9 +++++----
> > 1 file changed, 5 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> > index 952f8594b501..91ee6b903934 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > @@ -756,7 +756,7 @@ 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;
> > @@ -773,9 +773,10 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
> >
> > ret = dw_pcie_prog_outbound_atu(pci, &atu);
> > if (ret) {
> > - dev_err(pci->dev, "Failed to set MEM range %pr\n",
> > - entry->res);
> > - return ret;
> > + dev_warn(pci->dev, "Failed to set MEM range %pr\n",
> > + entry->res);
> > + } else {
> > + i++;
> > }
> > }
> >
> > --
> > 2.34.1
> >
> >
> > _______________________________________________
> > linux-riscv mailing list
> > linux-riscv@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-riscv
Sincerely,
Randolph
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v3 1/5] PCI: dwc: Skip failed outbound iATU and continue
2025-09-24 12:58 ` Randolph Lin
@ 2025-09-26 21:10 ` Bjorn Helgaas
2025-09-29 14:03 ` Rob Herring
2025-09-29 14:25 ` Manivannan Sadhasivam
0 siblings, 2 replies; 13+ messages in thread
From: Bjorn Helgaas @ 2025-09-26 21:10 UTC (permalink / raw)
To: Randolph Lin
Cc: linux-kernel, linux-pci, linux-riscv, devicetree, jingoohan1,
mani, lpieralisi, kwilczynski, robh, bhelgaas, krzk+dt, conor+dt,
alex, aou, palmer, paul.walmsley, ben717, inochiama,
thippeswamy.havalige, namcao, shradha.t, randolph.sklin, tim609
On Wed, Sep 24, 2025 at 08:58:11PM +0800, Randolph Lin wrote:
> On Tue, Sep 23, 2025 at 09:42:23AM -0500, Bjorn Helgaas wrote:
> > On Tue, Sep 23, 2025 at 07:36:43PM +0800, Randolph Lin wrote:
> > > Previously, outbound iATU programming included range checks
> > > based on hardware limitations. If a configuration did not meet
> > > these constraints, the loop would stop immediately.
> > >
> > > This patch updates the behavior to enhance flexibility. Instead
> > > of stopping at the first issue, it now logs a warning with
> > > details of the affected window and proceeds to program the
> > > remaining iATU entries.
> > >
> > > This enables partial configuration to complete in cases where
> > > some iATU windows may not meet requirements, improving overall
> > > compatibility.
> >
> > It's not really clear why this is needed. I assume it's related
> > to dropping qilai_pcie_outbound_atu_addr_valid().
>
> Yes, I want to drop the previous atu_addr_valid function.
>
> > I guess dw_pcie_prog_outbound_atu() must return an error for one
> > of the QiLai ranges? Which one, and what exactly is the problem?
> > I still suspect something wrong in the devicetree description.
>
> The main issue is not the returned error; just need to avoid
> terminating the process when the configuration exceeds the
> hardware’s expected limits.
>
> There are two methods to fix the issue on the Qilai SoC:
>
> 1. Simply skip the entries that do not match the designware hardware
> iATU limitations. An error will be returned, but it can be ignored.
> On the Qilai SoC, the iATU limitation is the 4GB boundary. Qilai SoC
> only need to configure iATU support to translate addresses below the
> "32-bits" address range. Although 64-bits addresses do not match the
> designware hardware iATU limitations, there is no need to configure
> 64-bits addresses, since the connection is hard-wired.
>
> 2. Set the devicetree only 2 viewport for iATU and force using
> devicetree value. This is a workaround in the devicetree, but the
> fix logic is not easy to document. Instead, we should enforce the
> use of the viewport defined in the devicetree and modify the
> designware generic code accordingly — using the viewport values from
> the devicetree instead of reading them from the designware
> registers. Since only two viewports are available for iATU, we
> should reserve one for the configuration registers and the other for
> 32-bit address access. Therefore, reverse logic still needs to be
> added to the designware generic code.
>
> Method 2 adds excessive complexity to the designware generic code.
> Instead, directly configuring the iATU and reporting an error when
> the configuration exceeds the hardware iATU limitations is a simpler
> and more effective approach to applying the fix.
I don't know the DesignWare iATU design very well, so I don't know if
this issue is something unique to Qilai or if it's something that
could be handled via devicetree.
Will look for input/acks from DesignWare maintainers (Jingoo, Mani).
> Conclusion:
> 1. The iATU needs to be configured for 32-bits address space.
> In compliance with hardware limitations.
> 2. The iATU needs to be configured for config space.
> In compliance with hardware limitations.
> 3. The iATU needs to be configured for 64-bit address space.
> This does not comply with hardware limitations and will print an error.
> As long as it does not return an error value that terminates subsequent
> operations, it is acceptable.
> Simply skipping this entry when configuring the iATU is acceptable.
>
> > > Signed-off-by: Randolph Lin <randolph@andestech.com>
> > > ---
> > > drivers/pci/controller/dwc/pcie-designware-host.c | 9 +++++----
> > > 1 file changed, 5 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > index 952f8594b501..91ee6b903934 100644
> > > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > @@ -756,7 +756,7 @@ 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;
> > > @@ -773,9 +773,10 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
> > >
> > > ret = dw_pcie_prog_outbound_atu(pci, &atu);
> > > if (ret) {
> > > - dev_err(pci->dev, "Failed to set MEM range %pr\n",
> > > - entry->res);
> > > - return ret;
> > > + dev_warn(pci->dev, "Failed to set MEM range %pr\n",
> > > + entry->res);
> > > + } else {
> > > + i++;
> > > }
> > > }
> > >
> > > --
> > > 2.34.1
> > >
> > >
> > > _______________________________________________
> > > linux-riscv mailing list
> > > linux-riscv@lists.infradead.org
> > > http://lists.infradead.org/mailman/listinfo/linux-riscv
>
> Sincerely,
> Randolph
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v3 1/5] PCI: dwc: Skip failed outbound iATU and continue
2025-09-26 21:10 ` Bjorn Helgaas
@ 2025-09-29 14:03 ` Rob Herring
2025-09-30 12:05 ` Randolph Lin
2025-09-29 14:25 ` Manivannan Sadhasivam
1 sibling, 1 reply; 13+ messages in thread
From: Rob Herring @ 2025-09-29 14:03 UTC (permalink / raw)
To: Bjorn Helgaas, Randolph Lin
Cc: linux-kernel, linux-pci, linux-riscv, devicetree, jingoohan1,
mani, lpieralisi, kwilczynski, bhelgaas, krzk+dt, conor+dt, alex,
aou, palmer, paul.walmsley, ben717, inochiama,
thippeswamy.havalige, namcao, shradha.t, randolph.sklin, tim609
On Fri, Sep 26, 2025 at 4:10 PM Bjorn Helgaas <helgaas@kernel.org> wrote:
>
> On Wed, Sep 24, 2025 at 08:58:11PM +0800, Randolph Lin wrote:
> > On Tue, Sep 23, 2025 at 09:42:23AM -0500, Bjorn Helgaas wrote:
> > > On Tue, Sep 23, 2025 at 07:36:43PM +0800, Randolph Lin wrote:
> > > > Previously, outbound iATU programming included range checks
> > > > based on hardware limitations. If a configuration did not meet
> > > > these constraints, the loop would stop immediately.
> > > >
> > > > This patch updates the behavior to enhance flexibility. Instead
> > > > of stopping at the first issue, it now logs a warning with
> > > > details of the affected window and proceeds to program the
> > > > remaining iATU entries.
> > > >
> > > > This enables partial configuration to complete in cases where
> > > > some iATU windows may not meet requirements, improving overall
> > > > compatibility.
> > >
> > > It's not really clear why this is needed. I assume it's related
> > > to dropping qilai_pcie_outbound_atu_addr_valid().
> >
> > Yes, I want to drop the previous atu_addr_valid function.
> >
> > > I guess dw_pcie_prog_outbound_atu() must return an error for one
> > > of the QiLai ranges? Which one, and what exactly is the problem?
> > > I still suspect something wrong in the devicetree description.
> >
> > The main issue is not the returned error; just need to avoid
> > terminating the process when the configuration exceeds the
> > hardware’s expected limits.
> >
> > There are two methods to fix the issue on the Qilai SoC:
> >
> > 1. Simply skip the entries that do not match the designware hardware
> > iATU limitations. An error will be returned, but it can be ignored.
> > On the Qilai SoC, the iATU limitation is the 4GB boundary. Qilai SoC
> > only need to configure iATU support to translate addresses below the
> > "32-bits" address range. Although 64-bits addresses do not match the
> > designware hardware iATU limitations, there is no need to configure
> > 64-bits addresses, since the connection is hard-wired.
> >
> > 2. Set the devicetree only 2 viewport for iATU and force using
> > devicetree value. This is a workaround in the devicetree, but the
> > fix logic is not easy to document. Instead, we should enforce the
> > use of the viewport defined in the devicetree and modify the
> > designware generic code accordingly — using the viewport values from
> > the devicetree instead of reading them from the designware
> > registers. Since only two viewports are available for iATU, we
> > should reserve one for the configuration registers and the other for
> > 32-bit address access. Therefore, reverse logic still needs to be
> > added to the designware generic code.
> >
> > Method 2 adds excessive complexity to the designware generic code.
> > Instead, directly configuring the iATU and reporting an error when
> > the configuration exceeds the hardware iATU limitations is a simpler
> > and more effective approach to applying the fix.
>
> I don't know the DesignWare iATU design very well, so I don't know if
> this issue is something unique to Qilai or if it's something that
> could be handled via devicetree.
I believe it should probably be handled in the DT. The iATU is
programmed based on the bridge window resources which are in turn
based on DT ranges and dma-ranges. If there's a failure, then
ranges/dma-ranges is wrong. Or the driver could adjust the bridge
window resources before programming the iATU.
Please provide what the DT looks like (for ranges/dma-ranges) and
where problem entry is.
Rob
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v3 1/5] PCI: dwc: Skip failed outbound iATU and continue
2025-09-29 14:03 ` Rob Herring
@ 2025-09-30 12:05 ` Randolph Lin
0 siblings, 0 replies; 13+ messages in thread
From: Randolph Lin @ 2025-09-30 12:05 UTC (permalink / raw)
To: Rob Herring
Cc: Bjorn Helgaas, linux-kernel, linux-pci, linux-riscv, devicetree,
jingoohan1, mani, lpieralisi, kwilczynski, bhelgaas, krzk+dt,
conor+dt, alex, aou, palmer, paul.walmsley, ben717, inochiama,
thippeswamy.havalige, namcao, shradha.t, randolph.sklin, tim609
Hi Rob,
On Mon, Sep 29, 2025 at 09:03:59AM -0500, Rob Herring wrote:
> [EXTERNAL MAIL]
>
> On Fri, Sep 26, 2025 at 4:10 PM Bjorn Helgaas <helgaas@kernel.org> wrote:
> >
> > On Wed, Sep 24, 2025 at 08:58:11PM +0800, Randolph Lin wrote:
> > > On Tue, Sep 23, 2025 at 09:42:23AM -0500, Bjorn Helgaas wrote:
> > > > On Tue, Sep 23, 2025 at 07:36:43PM +0800, Randolph Lin wrote:
> > > > > Previously, outbound iATU programming included range checks
> > > > > based on hardware limitations. If a configuration did not meet
> > > > > these constraints, the loop would stop immediately.
> > > > >
> > > > > This patch updates the behavior to enhance flexibility. Instead
> > > > > of stopping at the first issue, it now logs a warning with
> > > > > details of the affected window and proceeds to program the
> > > > > remaining iATU entries.
> > > > >
> > > > > This enables partial configuration to complete in cases where
> > > > > some iATU windows may not meet requirements, improving overall
> > > > > compatibility.
> > > >
> > > > It's not really clear why this is needed. I assume it's related
> > > > to dropping qilai_pcie_outbound_atu_addr_valid().
> > >
> > > Yes, I want to drop the previous atu_addr_valid function.
> > >
> > > > I guess dw_pcie_prog_outbound_atu() must return an error for one
> > > > of the QiLai ranges? Which one, and what exactly is the problem?
> > > > I still suspect something wrong in the devicetree description.
> > >
> > > The main issue is not the returned error; just need to avoid
> > > terminating the process when the configuration exceeds the
> > > hardware’s expected limits.
> > >
> > > There are two methods to fix the issue on the Qilai SoC:
> > >
> > > 1. Simply skip the entries that do not match the designware hardware
> > > iATU limitations. An error will be returned, but it can be ignored.
> > > On the Qilai SoC, the iATU limitation is the 4GB boundary. Qilai SoC
> > > only need to configure iATU support to translate addresses below the
> > > "32-bits" address range. Although 64-bits addresses do not match the
> > > designware hardware iATU limitations, there is no need to configure
> > > 64-bits addresses, since the connection is hard-wired.
> > >
> > > 2. Set the devicetree only 2 viewport for iATU and force using
> > > devicetree value. This is a workaround in the devicetree, but the
> > > fix logic is not easy to document. Instead, we should enforce the
> > > use of the viewport defined in the devicetree and modify the
> > > designware generic code accordingly — using the viewport values from
> > > the devicetree instead of reading them from the designware
> > > registers. Since only two viewports are available for iATU, we
> > > should reserve one for the configuration registers and the other for
> > > 32-bit address access. Therefore, reverse logic still needs to be
> > > added to the designware generic code.
> > >
> > > Method 2 adds excessive complexity to the designware generic code.
> > > Instead, directly configuring the iATU and reporting an error when
> > > the configuration exceeds the hardware iATU limitations is a simpler
> > > and more effective approach to applying the fix.
> >
> > I don't know the DesignWare iATU design very well, so I don't know if
> > this issue is something unique to Qilai or if it's something that
> > could be handled via devicetree.
>
> I believe it should probably be handled in the DT. The iATU is
> programmed based on the bridge window resources which are in turn
> based on DT ranges and dma-ranges. If there's a failure, then
> ranges/dma-ranges is wrong. Or the driver could adjust the bridge
> window resources before programming the iATU.
>
Thank you very much. That’s a great hint for me.
My driver can handle most of the logic within the .init callback of the
dw_pcie_host_ops structure. This includes parsing the Device Tree data
and performing the required pre-initialization steps, such as counting
how many bridge window resources comply with the iATU limitations and
verifying the 32-bit address mappings within those bridge window
resources.
The following additional logic is still required to ensure
pci->num_ob_windows correctly reflects the driver’s pre-initialization
value, with the current approach remaining more generic and purposeful.
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -907,8 +907,10 @@ void dw_pcie_iatu_detect(struct dw_pcie *pci)
max = 0;
}
- pci->num_ob_windows = ob;
- pci->num_ib_windows = ib;
+ if (!pci->num_ob_windows)
+ pci->num_ob_windows = ob;
+ if (!pci->num_ib_windows)
+ pci->num_ib_windows = ib;
pci->region_align = 1 << fls(min);
pci->region_limit = (max << 32) | (SZ_4G - 1);
> Please provide what the DT looks like (for ranges/dma-ranges) and
> where problem entry is.
>
bus@80000000 {
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
dma-ranges = <0x44 0x00000000 0x04 0x00000000 0x04 0x00000000>;
ranges = <0x00 0x80000000 0x00 0x80000000 0x00 0x20000000>,
<0x00 0x04000000 0x00 0x04000000 0x00 0x00001000>,
<0x00 0x00000000 0x20 0x00000000 0x20 0x00000000>;
pci@80000000 {
compatible = "andestech,qilai-pcie";
device_type = "pci";
reg = <0x00 0x80000000 0x00 0x20000000>, /* DBI registers */
<0x00 0x04000000 0x00 0x00001000>, /* APB registers */
<0x00 0x00000000 0x00 0x00010000>; /* Configuration registers */
reg-names = "dbi", "apb", "config";
linux,pci-domain = <0>;
bus-range = <0x0 0xff>;
num-viewport = <4>;
#address-cells = <3>;
#size-cells = <2>;
ranges = <0x02000000 0x00 0x10000000 0x00 0x10000000 0x00 0xf0000000>,
<0x43000000 0x01 0x00000000 0x01 0x00000000 0x1f 0x00000000>;
Just look at the last "ranges" property — the first line is the only one
we want to program into the iATU, as its size is below SZ_4G
(the iATU region limitation for this SoC).
The next line exceeds the iATU region limitation; therefore, we do not
want to program it into the iATU. It is natively wire-connected by
design and does not need to pass through the iATU.
> Rob
Sincerely,
Randolph
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v3 1/5] PCI: dwc: Skip failed outbound iATU and continue
2025-09-26 21:10 ` Bjorn Helgaas
2025-09-29 14:03 ` Rob Herring
@ 2025-09-29 14:25 ` Manivannan Sadhasivam
1 sibling, 0 replies; 13+ messages in thread
From: Manivannan Sadhasivam @ 2025-09-29 14:25 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Randolph Lin, linux-kernel, linux-pci, linux-riscv, devicetree,
jingoohan1, lpieralisi, kwilczynski, robh, bhelgaas, krzk+dt,
conor+dt, alex, aou, palmer, paul.walmsley, ben717, inochiama,
thippeswamy.havalige, namcao, shradha.t, randolph.sklin, tim609
On Fri, Sep 26, 2025 at 04:10:23PM -0500, Bjorn Helgaas wrote:
> On Wed, Sep 24, 2025 at 08:58:11PM +0800, Randolph Lin wrote:
> > On Tue, Sep 23, 2025 at 09:42:23AM -0500, Bjorn Helgaas wrote:
> > > On Tue, Sep 23, 2025 at 07:36:43PM +0800, Randolph Lin wrote:
> > > > Previously, outbound iATU programming included range checks
> > > > based on hardware limitations. If a configuration did not meet
> > > > these constraints, the loop would stop immediately.
> > > >
> > > > This patch updates the behavior to enhance flexibility. Instead
> > > > of stopping at the first issue, it now logs a warning with
> > > > details of the affected window and proceeds to program the
> > > > remaining iATU entries.
> > > >
> > > > This enables partial configuration to complete in cases where
> > > > some iATU windows may not meet requirements, improving overall
> > > > compatibility.
> > >
> > > It's not really clear why this is needed. I assume it's related
> > > to dropping qilai_pcie_outbound_atu_addr_valid().
> >
> > Yes, I want to drop the previous atu_addr_valid function.
> >
> > > I guess dw_pcie_prog_outbound_atu() must return an error for one
> > > of the QiLai ranges? Which one, and what exactly is the problem?
> > > I still suspect something wrong in the devicetree description.
> >
> > The main issue is not the returned error; just need to avoid
> > terminating the process when the configuration exceeds the
> > hardware’s expected limits.
> >
> > There are two methods to fix the issue on the Qilai SoC:
> >
> > 1. Simply skip the entries that do not match the designware hardware
> > iATU limitations. An error will be returned, but it can be ignored.
> > On the Qilai SoC, the iATU limitation is the 4GB boundary. Qilai SoC
> > only need to configure iATU support to translate addresses below the
> > "32-bits" address range. Although 64-bits addresses do not match the
> > designware hardware iATU limitations, there is no need to configure
> > 64-bits addresses, since the connection is hard-wired.
> >
Why does the DT supplies broken 'ranges' in the first place? DT describes the
hardware and if the hardware only supports 32bit OB window, then DT has to
supply the range accordingly. It is not currently clear on what issue you are
trying to solve by skipping the range check for broken resources.
> > 2. Set the devicetree only 2 viewport for iATU and force using
> > devicetree value. This is a workaround in the devicetree, but the
> > fix logic is not easy to document. Instead, we should enforce the
> > use of the viewport defined in the devicetree and modify the
> > designware generic code accordingly — using the viewport values from
> > the devicetree instead of reading them from the designware
> > registers. Since only two viewports are available for iATU, we
> > should reserve one for the configuration registers and the other for
> > 32-bit address access. Therefore, reverse logic still needs to be
> > added to the designware generic code.
> >
'num-viewport' property is deprecated. So should not be used in new DTs.
- Mani
--
மணிவண்ணன் சதாசிவம்
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v3 2/5] dt-bindings: PCI: Add Andes QiLai PCIe support
2025-09-23 11:36 [PATCH v3 0/5] Add support for Andes Qilai SoC PCIe controller Randolph Lin
2025-09-23 11:36 ` [PATCH v3 1/5] PCI: dwc: Skip failed outbound iATU and continue Randolph Lin
@ 2025-09-23 11:36 ` Randolph Lin
2025-09-23 11:36 ` [PATCH v3 3/5] riscv: dts: andes: Add PCIe node into the QiLai SoC Randolph Lin
` (2 subsequent siblings)
4 siblings, 0 replies; 13+ messages in thread
From: Randolph Lin @ 2025-09-23 11:36 UTC (permalink / raw)
To: linux-kernel
Cc: linux-pci, linux-riscv, devicetree, jingoohan1, mani, lpieralisi,
kwilczynski, robh, bhelgaas, krzk+dt, conor+dt, alex, aou, palmer,
paul.walmsley, ben717, inochiama, thippeswamy.havalige, namcao,
shradha.t, randolph.sklin, tim609, Randolph Lin
Add the Andes QiLai PCIe node, which includes 3 Root Complexes.
Only one example is required in the DTS bindings YAML file.
Signed-off-by: Randolph Lin <randolph@andestech.com>
---
.../bindings/pci/andestech,qilai-pcie.yaml | 103 ++++++++++++++++++
1 file changed, 103 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pci/andestech,qilai-pcie.yaml
diff --git a/Documentation/devicetree/bindings/pci/andestech,qilai-pcie.yaml b/Documentation/devicetree/bindings/pci/andestech,qilai-pcie.yaml
new file mode 100644
index 000000000000..8effe6ebd9d7
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/andestech,qilai-pcie.yaml
@@ -0,0 +1,103 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/andestech,qilai-pcie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Andes QiLai PCIe host controller
+
+description: |+
+ Andes QiLai PCIe host controller is based on the Synopsys DesignWare
+ PCI core. It shares common features with the PCIe DesignWare core and
+ inherits common properties defined in
+ Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml.
+
+maintainers:
+ - Randolph Lin <randolph@andestech.com>
+
+allOf:
+ - $ref: /schemas/pci/snps,dw-pcie.yaml#
+
+properties:
+ compatible:
+ const: andestech,qilai-pcie
+
+ reg:
+ items:
+ - description: Data Bus Interface (DBI) registers.
+ - description: APB registers.
+ - description: PCIe configuration space region.
+
+ reg-names:
+ items:
+ - const: dbi
+ - const: apb
+ - const: config
+
+ ranges:
+ maxItems: 2
+
+ interrupts:
+ maxItems: 1
+
+ "#interrupt-cells":
+ const: 1
+
+ interrupt-map: true
+
+required:
+ - reg
+ - reg-names
+ - "#interrupt-cells"
+ - interrupts
+ - interrupt-names
+ - interrupt-map-mask
+ - interrupt-map
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ bus@80000000 {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ dma-ranges = <0x44 0x00000000 0x04 0x00000000 0x04 0x00000000>;
+ ranges = <0x00 0x80000000 0x00 0x80000000 0x00 0x20000000>,
+ <0x00 0x04000000 0x00 0x04000000 0x00 0x00001000>,
+ <0x00 0x00000000 0x20 0x00000000 0x20 0x00000000>;
+
+ pci@80000000 {
+ compatible = "andestech,qilai-pcie";
+ device_type = "pci";
+ reg = <0x0 0x80000000 0x0 0x20000000>,
+ <0x0 0x04000000 0x0 0x00001000>,
+ <0x0 0x00000000 0x0 0x00010000>;
+ reg-names = "dbi", "apb", "config";
+
+ linux,pci-domain = <0>;
+ bus-range = <0x0 0xff>;
+ num-viewport = <4>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges = <0x02000000 0x00 0x10000000 0x00 0x10000000 0x0 0xf0000000>,
+ <0x43000000 0x01 0x00000000 0x01 0x0000000 0x1f 0x00000000>;
+
+ #interrupt-cells = <1>;
+ interrupts = <0xf>;
+ interrupt-names = "msi";
+ interrupt-parent = <&plic0>;
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &plic0 0xf IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 2 &plic0 0xf IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 3 &plic0 0xf IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 4 &plic0 0xf IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+ };
--
2.34.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 3/5] riscv: dts: andes: Add PCIe node into the QiLai SoC
2025-09-23 11:36 [PATCH v3 0/5] Add support for Andes Qilai SoC PCIe controller Randolph Lin
2025-09-23 11:36 ` [PATCH v3 1/5] PCI: dwc: Skip failed outbound iATU and continue Randolph Lin
2025-09-23 11:36 ` [PATCH v3 2/5] dt-bindings: PCI: Add Andes QiLai PCIe support Randolph Lin
@ 2025-09-23 11:36 ` Randolph Lin
2025-09-23 11:36 ` [PATCH v3 4/5] PCI: andes: Add Andes QiLai SoC PCIe host driver support Randolph Lin
2025-09-23 11:36 ` [PATCH v3 5/5] MAINTAINERS: Add maintainers for Andes QiLai PCIe driver Randolph Lin
4 siblings, 0 replies; 13+ messages in thread
From: Randolph Lin @ 2025-09-23 11:36 UTC (permalink / raw)
To: linux-kernel
Cc: linux-pci, linux-riscv, devicetree, jingoohan1, mani, lpieralisi,
kwilczynski, robh, bhelgaas, krzk+dt, conor+dt, alex, aou, palmer,
paul.walmsley, ben717, inochiama, thippeswamy.havalige, namcao,
shradha.t, randolph.sklin, tim609, Randolph Lin
Add the Andes QiLai PCIe node, which includes 3 Root Complexes.
Signed-off-by: Randolph Lin <randolph@andestech.com>
---
arch/riscv/boot/dts/andes/qilai.dtsi | 112 +++++++++++++++++++++++++++
1 file changed, 112 insertions(+)
diff --git a/arch/riscv/boot/dts/andes/qilai.dtsi b/arch/riscv/boot/dts/andes/qilai.dtsi
index de3de32f8c39..69669111d9fb 100644
--- a/arch/riscv/boot/dts/andes/qilai.dtsi
+++ b/arch/riscv/boot/dts/andes/qilai.dtsi
@@ -182,5 +182,117 @@ uart0: serial@30300000 {
reg-io-width = <4>;
no-loopback-test;
};
+
+ bus@80000000 {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ dma-ranges = <0x44 0x00000000 0x04 0x00000000 0x04 0x00000000>;
+ ranges = <0x00 0x80000000 0x00 0x80000000 0x00 0x20000000>,
+ <0x00 0x04000000 0x00 0x04000000 0x00 0x00001000>,
+ <0x00 0x00000000 0x20 0x00000000 0x20 0x00000000>;
+
+ pci@80000000 {
+ compatible = "andestech,qilai-pcie";
+ device_type = "pci";
+ reg = <0x00 0x80000000 0x00 0x20000000>, /* DBI registers */
+ <0x00 0x04000000 0x00 0x00001000>, /* APB registers */
+ <0x00 0x00000000 0x00 0x00010000>; /* Configuration registers */
+ reg-names = "dbi", "apb", "config";
+
+ linux,pci-domain = <0>;
+ bus-range = <0x0 0xff>;
+ num-viewport = <4>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges = <0x02000000 0x00 0x10000000 0x00 0x10000000 0x00 0xf0000000>,
+ <0x43000000 0x01 0x00000000 0x01 0x00000000 0x1f 0x00000000>;
+
+ #interrupt-cells = <1>;
+ interrupts = <0xf 0x4>;
+ interrupt-names = "msi";
+ interrupt-parent = <&plic>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 1 &plic 0xf 0x4>,
+ <0 0 0 2 &plic 0xf 0x4>,
+ <0 0 0 3 &plic 0xf 0x4>,
+ <0 0 0 4 &plic 0xf 0x4>;
+ };
+ };
+
+ bus@a0000000 {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ dma-ranges = <0x44 0x00000000 0x04 0x00000000 0x04 0x00000000>;
+ ranges = <0x00 0xa0000000 0x00 0xa0000000 0x00 0x20000000>,
+ <0x00 0x04001000 0x00 0x04001000 0x00 0x00001000>,
+ <0x00 0x00000000 0x10 0x00000000 0x08 0x00000000>;
+
+ pci@a0000000 {
+ compatible = "andestech,qilai-pcie";
+ device_type = "pci";
+ reg = <0x00 0xa0000000 0x00 0x20000000>, /* DBI registers */
+ <0x00 0x04001000 0x00 0x00001000>, /* APB registers */
+ <0x00 0x00000000 0x00 0x00010000>; /* Configuration registers */
+ reg-names = "dbi", "apb", "config";
+
+ linux,pci-domain = <1>;
+ bus-range = <0x0 0xff>;
+ num-viewport = <4>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges = <0x02000000 0x00 0x10000000 0x00 0x10000000 0x0 0xf0000000>,
+ <0x43000000 0x01 0x00000000 0x01 0x00000000 0x7 0x00000000>;
+
+ #interrupt-cells = <1>;
+ interrupts = <0xe 0x4>;
+ interrupt-names = "msi";
+ interrupt-parent = <&plic>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 1 &plic 0xe 0x4>,
+ <0 0 0 2 &plic 0xe 0x4>,
+ <0 0 0 3 &plic 0xe 0x4>,
+ <0 0 0 4 &plic 0xe 0x4>;
+ };
+ };
+
+ bus@c0000000 {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ dma-ranges = <0x44 0x00000000 0x04 0x00000000 0x04 0x00000000>;
+ ranges = <0x00 0xc0000000 0x00 0xc0000000 0x00 0x20000000>,
+ <0x00 0x04002000 0x00 0x04002000 0x00 0x00001000>,
+ <0x00 0x00000000 0x18 0x00000000 0x08 0x00000000>;
+
+ pci@c0000000 {
+ compatible = "andestech,qilai-pcie";
+ device_type = "pci";
+ reg = <0x00 0xc0000000 0x00 0x20000000>, /* DBI registers */
+ <0x00 0x04002000 0x00 0x00001000>, /* APB registers */
+ <0x00 0x00000000 0x00 0x00010000>; /* Configuration registers */
+ reg-names = "dbi", "apb", "config";
+
+ linux,pci-domain = <2>;
+ bus-range = <0x0 0xff>;
+ num-viewport = <4>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges = <0x02000000 0x00 0x10000000 0x00 0x10000000 0x0 0xf0000000>,
+ <0x43000000 0x01 0x00000000 0x01 0x00000000 0x7 0x00000000>;
+
+ #interrupt-cells = <1>;
+ interrupts = <0xd 0x4>;
+ interrupt-names = "msi";
+ interrupt-parent = <&plic>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 1 &plic 0xd 0x4>,
+ <0 0 0 2 &plic 0xd 0x4>,
+ <0 0 0 3 &plic 0xd 0x4>,
+ <0 0 0 4 &plic 0xd 0x4>;
+ };
+ };
+
};
};
--
2.34.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v3 4/5] PCI: andes: Add Andes QiLai SoC PCIe host driver support
2025-09-23 11:36 [PATCH v3 0/5] Add support for Andes Qilai SoC PCIe controller Randolph Lin
` (2 preceding siblings ...)
2025-09-23 11:36 ` [PATCH v3 3/5] riscv: dts: andes: Add PCIe node into the QiLai SoC Randolph Lin
@ 2025-09-23 11:36 ` Randolph Lin
2025-09-23 15:54 ` Bjorn Helgaas
2025-09-23 11:36 ` [PATCH v3 5/5] MAINTAINERS: Add maintainers for Andes QiLai PCIe driver Randolph Lin
4 siblings, 1 reply; 13+ messages in thread
From: Randolph Lin @ 2025-09-23 11:36 UTC (permalink / raw)
To: linux-kernel
Cc: linux-pci, linux-riscv, devicetree, jingoohan1, mani, lpieralisi,
kwilczynski, robh, bhelgaas, krzk+dt, conor+dt, alex, aou, palmer,
paul.walmsley, ben717, inochiama, thippeswamy.havalige, namcao,
shradha.t, randolph.sklin, tim609, Randolph Lin
Add driver support for DesignWare based PCIe controller in Andes
QiLai SoC. The driver only supports the Root Complex mode.
Signed-off-by: Randolph Lin <randolph@andestech.com>
---
drivers/pci/controller/dwc/Kconfig | 13 ++
drivers/pci/controller/dwc/Makefile | 1 +
drivers/pci/controller/dwc/pcie-andes-qilai.c | 189 ++++++++++++++++++
3 files changed, 203 insertions(+)
create mode 100644 drivers/pci/controller/dwc/pcie-andes-qilai.c
diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
index ff6b6d9e18ec..3cff05920233 100644
--- a/drivers/pci/controller/dwc/Kconfig
+++ b/drivers/pci/controller/dwc/Kconfig
@@ -49,6 +49,19 @@ config PCIE_AMD_MDB
DesignWare IP and therefore the driver re-uses the DesignWare
core functions to implement the driver.
+config PCIE_ANDES_QILAI
+ bool "ANDES QiLai PCIe controller"
+ depends on ARCH_ANDES || COMPILE_TEST
+ depends on PCI_MSI
+ select PCIE_DW_HOST
+ help
+ Say Y here to enable PCIe controller support on Andes QiLai SoCs,
+ which operate in Root Complex mode. The Andes QiLai SoCs PCIe
+ controller is based on DesignWare IP (5.97a version) and therefore
+ the driver re-uses the DesignWare core functions to implement the
+ driver. The Andes QiLai SoC features three Root Complexes, each
+ operating on PCIe 4.0.
+
config PCI_MESON
tristate "Amlogic Meson PCIe controller"
default m if ARCH_MESON
diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
index 6919d27798d1..de9583cbd675 100644
--- a/drivers/pci/controller/dwc/Makefile
+++ b/drivers/pci/controller/dwc/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o
obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
obj-$(CONFIG_PCIE_AMD_MDB) += pcie-amd-mdb.o
+obj-$(CONFIG_PCIE_ANDES_QILAI) += pcie-andes-qilai.o
obj-$(CONFIG_PCIE_BT1) += pcie-bt1.o
obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
diff --git a/drivers/pci/controller/dwc/pcie-andes-qilai.c b/drivers/pci/controller/dwc/pcie-andes-qilai.c
new file mode 100644
index 000000000000..8a44d67410f2
--- /dev/null
+++ b/drivers/pci/controller/dwc/pcie-andes-qilai.c
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for the PCIe Controller in QiLai from Andes
+ *
+ * Copyright (C) 2025 Andes Technology Corporation
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+
+#include "pcie-designware.h"
+
+#define PCIE_INTR_CONTROL1 0x15c
+#define PCIE_MSI_CTRL_INT_EN BIT(28)
+
+#define PCIE_LOGIC_COHERENCY_CONTROL3 0x8e8
+
+/*
+ * Refer to Table A4-5 (Memory type encoding) in the
+ * AMBA AXI and ACE Protocol Specification.
+ *
+ * The selected value corresponds to the Memory type field:
+ * "Write-back, Read and Write-allocate".
+ */
+#define IOCP_ARCACHE 0b1111
+#define IOCP_AWCACHE 0b1111
+
+#define PCIE_CFG_MSTR_ARCACHE_MODE GENMASK(6, 3)
+#define PCIE_CFG_MSTR_AWCACHE_MODE GENMASK(14, 11)
+#define PCIE_CFG_MSTR_ARCACHE_VALUE GENMASK(22, 19)
+#define PCIE_CFG_MSTR_AWCACHE_VALUE GENMASK(30, 27)
+
+#define PCIE_GEN_CONTROL2 0x54
+#define PCIE_CFG_LTSSM_EN BIT(0)
+
+#define PCIE_REGS_PCIE_SII_PM_STATE 0xc0
+#define SMLH_LINK_UP BIT(6)
+#define RDLH_LINK_UP BIT(7)
+#define PCIE_REGS_PCIE_SII_LINK_UP (SMLH_LINK_UP | RDLH_LINK_UP)
+
+struct qilai_pcie {
+ struct dw_pcie pci;
+ struct platform_device *pdev;
+ void __iomem *apb_base;
+};
+
+#define to_qilai_pcie(_pci) container_of(_pci, struct qilai_pcie, pci)
+
+
+static bool qilai_pcie_link_up(struct dw_pcie *pci)
+{
+ struct qilai_pcie *pcie = to_qilai_pcie(pci);
+ u32 val;
+
+ /* Read smlh & rdlh link up by checking debug port */
+ val = readl(pcie->apb_base + PCIE_REGS_PCIE_SII_PM_STATE);
+
+ return (val & PCIE_REGS_PCIE_SII_LINK_UP) == PCIE_REGS_PCIE_SII_LINK_UP;
+}
+
+static int qilai_pcie_start_link(struct dw_pcie *pci)
+{
+ struct qilai_pcie *pcie = to_qilai_pcie(pci);
+ u32 val;
+
+ val = readl(pcie->apb_base + PCIE_GEN_CONTROL2);
+ val |= PCIE_CFG_LTSSM_EN;
+ writel(val, pcie->apb_base + PCIE_GEN_CONTROL2);
+
+ return 0;
+}
+
+static const struct dw_pcie_ops qilai_pcie_ops = {
+ .link_up = qilai_pcie_link_up,
+ .start_link = qilai_pcie_start_link,
+};
+
+/*
+ * Setup the Qilai PCIe IOCP (IO Coherence Port) Read/Write Behaviors to the
+ * Write-Back, Read and Write Allocate mode.
+ * The IOCP HW target is SoC last-level cache (L2 Cache), which serves as the
+ * system cache. The IOCP HW helps maintain cache monitoring, ensuring that
+ * the device can snoop data from/to the cache.
+ */
+static void qilai_pcie_iocp_cache_setup(struct dw_pcie_rp *pp)
+{
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ u32 val;
+
+ dw_pcie_dbi_ro_wr_en(pci);
+
+ dw_pcie_read(pci->dbi_base + PCIE_LOGIC_COHERENCY_CONTROL3,
+ sizeof(val), &val);
+ FIELD_MODIFY(PCIE_CFG_MSTR_ARCACHE_MODE, &val, IOCP_ARCACHE);
+ FIELD_MODIFY(PCIE_CFG_MSTR_AWCACHE_MODE, &val, IOCP_AWCACHE);
+ FIELD_MODIFY(PCIE_CFG_MSTR_ARCACHE_VALUE, &val, IOCP_ARCACHE);
+ FIELD_MODIFY(PCIE_CFG_MSTR_AWCACHE_VALUE, &val, IOCP_AWCACHE);
+ dw_pcie_write(pci->dbi_base + PCIE_LOGIC_COHERENCY_CONTROL3,
+ sizeof(val), val);
+
+ dw_pcie_dbi_ro_wr_dis(pci);
+}
+
+static void qilai_pcie_enable_msi(struct qilai_pcie *pcie)
+{
+ u32 val;
+
+ val = readl(pcie->apb_base + PCIE_INTR_CONTROL1);
+ val |= PCIE_MSI_CTRL_INT_EN;
+ writel(val, pcie->apb_base + PCIE_INTR_CONTROL1);
+}
+
+static int qilai_pcie_host_init(struct dw_pcie_rp *pp)
+{
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ struct qilai_pcie *pcie = to_qilai_pcie(pci);
+
+ qilai_pcie_enable_msi(pcie);
+
+ return 0;
+}
+
+static const struct dw_pcie_host_ops qilai_pcie_host_ops = {
+ .init = qilai_pcie_host_init,
+};
+
+static int qilai_pcie_probe(struct platform_device *pdev)
+{
+ struct qilai_pcie *pcie;
+ struct dw_pcie *pci;
+ struct device *dev;
+ int ret;
+
+ pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
+ if (!pcie)
+ return -ENOMEM;
+
+ pcie->pdev = pdev;
+ platform_set_drvdata(pdev, pcie);
+
+ pci = &pcie->pci;
+ dev = &pcie->pdev->dev;
+ pcie->pci.dev = dev;
+ pcie->pci.ops = &qilai_pcie_ops;
+ pcie->pci.pp.ops = &qilai_pcie_host_ops;
+ pci->use_parent_dt_ranges = true;
+
+ dw_pcie_cap_set(&pcie->pci, REQ_RES);
+
+ pcie->apb_base = devm_platform_ioremap_resource_byname(pdev, "apb");
+ if (IS_ERR(pcie->apb_base))
+ return PTR_ERR(pcie->apb_base);
+
+ ret = dw_pcie_host_init(&pcie->pci.pp);
+ if (ret) {
+ dev_err_probe(dev, ret, "Failed to initialize PCIe host\n");
+ return ret;
+ }
+
+ qilai_pcie_iocp_cache_setup(&pcie->pci.pp);
+
+ return 0;
+}
+
+static const struct of_device_id qilai_pcie_of_match[] = {
+ { .compatible = "andestech,qilai-pcie" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, qilai_pcie_of_match);
+
+static struct platform_driver qilai_pcie_driver = {
+ .probe = qilai_pcie_probe,
+ .driver = {
+ .name = "qilai-pcie",
+ .of_match_table = qilai_pcie_of_match,
+ .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+ },
+};
+
+builtin_platform_driver(qilai_pcie_driver);
+
+MODULE_AUTHOR("Randolph Lin <randolph@andestech.com>");
+MODULE_DESCRIPTION("Andes Qilai PCIe driver");
+MODULE_LICENSE("GPL");
--
2.34.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH v3 4/5] PCI: andes: Add Andes QiLai SoC PCIe host driver support
2025-09-23 11:36 ` [PATCH v3 4/5] PCI: andes: Add Andes QiLai SoC PCIe host driver support Randolph Lin
@ 2025-09-23 15:54 ` Bjorn Helgaas
0 siblings, 0 replies; 13+ messages in thread
From: Bjorn Helgaas @ 2025-09-23 15:54 UTC (permalink / raw)
To: Randolph Lin
Cc: linux-kernel, linux-pci, linux-riscv, devicetree, jingoohan1,
mani, lpieralisi, kwilczynski, robh, bhelgaas, krzk+dt, conor+dt,
alex, aou, palmer, paul.walmsley, ben717, inochiama,
thippeswamy.havalige, namcao, shradha.t, randolph.sklin, tim609
On Tue, Sep 23, 2025 at 07:36:46PM +0800, Randolph Lin wrote:
> Add driver support for DesignWare based PCIe controller in Andes
> QiLai SoC. The driver only supports the Root Complex mode.
> +++ b/drivers/pci/controller/dwc/Kconfig
> @@ -49,6 +49,19 @@ config PCIE_AMD_MDB
> DesignWare IP and therefore the driver re-uses the DesignWare
> core functions to implement the driver.
>
> +config PCIE_ANDES_QILAI
> + bool "ANDES QiLai PCIe controller"
> + depends on ARCH_ANDES || COMPILE_TEST
> + depends on PCI_MSI
> + select PCIE_DW_HOST
> + help
> + Say Y here to enable PCIe controller support on Andes QiLai SoCs,
> + which operate in Root Complex mode. The Andes QiLai SoCs PCIe
> + controller is based on DesignWare IP (5.97a version) and therefore
> + the driver re-uses the DesignWare core functions to implement the
> + driver. The Andes QiLai SoC features three Root Complexes, each
> + operating on PCIe 4.0.
Sort these by vendor name:
AMD MDB Versal2 PCIe controller
Amlogic Meson PCIe controller
ANDES QiLai PCIe controller
Axis ARTPEC-6 PCIe controller (host mode)
> config PCI_MESON
> tristate "Amlogic Meson PCIe controller"
> + * Refer to Table A4-5 (Memory type encoding) in the
> + * AMBA AXI and ACE Protocol Specification.
> + *
> + * The selected value corresponds to the Memory type field:
> + * "Write-back, Read and Write-allocate".
> + */
> +#define IOCP_ARCACHE 0b1111
> +#define IOCP_AWCACHE 0b1111
Deserves a note about why these values are identical.
> +struct qilai_pcie {
> + struct dw_pcie pci;
> + struct platform_device *pdev;
"pdev" appears to be set but never used; drop it if you don't need it.
> +/*
> + * Setup the Qilai PCIe IOCP (IO Coherence Port) Read/Write Behaviors to the
> + * Write-Back, Read and Write Allocate mode.
Add blank line or rewrap into single paragraph.
> + * The IOCP HW target is SoC last-level cache (L2 Cache), which serves as the
> + * system cache. The IOCP HW helps maintain cache monitoring, ensuring that
> + * the device can snoop data from/to the cache.
> + */
> +static void qilai_pcie_iocp_cache_setup(struct dw_pcie_rp *pp)
> +{
> + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> + u32 val;
> +
> + dw_pcie_dbi_ro_wr_en(pci);
> +
> + dw_pcie_read(pci->dbi_base + PCIE_LOGIC_COHERENCY_CONTROL3,
> + sizeof(val), &val);
> + FIELD_MODIFY(PCIE_CFG_MSTR_ARCACHE_MODE, &val, IOCP_ARCACHE);
> + FIELD_MODIFY(PCIE_CFG_MSTR_AWCACHE_MODE, &val, IOCP_AWCACHE);
> + FIELD_MODIFY(PCIE_CFG_MSTR_ARCACHE_VALUE, &val, IOCP_ARCACHE);
> + FIELD_MODIFY(PCIE_CFG_MSTR_AWCACHE_VALUE, &val, IOCP_AWCACHE);
> + dw_pcie_write(pci->dbi_base + PCIE_LOGIC_COHERENCY_CONTROL3,
> + sizeof(val), val);
> +
> + dw_pcie_dbi_ro_wr_dis(pci);
> +}
> +static int qilai_pcie_host_init(struct dw_pcie_rp *pp)
> +{
> + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> + struct qilai_pcie *pcie = to_qilai_pcie(pci);
> +
> + qilai_pcie_enable_msi(pcie);
> +
> + return 0;
> +}
> +
> +static const struct dw_pcie_host_ops qilai_pcie_host_ops = {
> + .init = qilai_pcie_host_init,
> +};
> +
> +static int qilai_pcie_probe(struct platform_device *pdev)
> +{
> + struct qilai_pcie *pcie;
> + struct dw_pcie *pci;
> + struct device *dev;
> + int ret;
> +
> + pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
> + if (!pcie)
> + return -ENOMEM;
> +
> + pcie->pdev = pdev;
> + platform_set_drvdata(pdev, pcie);
> +
> + pci = &pcie->pci;
> + dev = &pcie->pdev->dev;
> + pcie->pci.dev = dev;
> + pcie->pci.ops = &qilai_pcie_ops;
> + pcie->pci.pp.ops = &qilai_pcie_host_ops;
> + pci->use_parent_dt_ranges = true;
> +
> + dw_pcie_cap_set(&pcie->pci, REQ_RES);
> +
> + pcie->apb_base = devm_platform_ioremap_resource_byname(pdev, "apb");
> + if (IS_ERR(pcie->apb_base))
> + return PTR_ERR(pcie->apb_base);
> +
> + ret = dw_pcie_host_init(&pcie->pci.pp);
> + if (ret) {
> + dev_err_probe(dev, ret, "Failed to initialize PCIe host\n");
> + return ret;
> + }
> +
> + qilai_pcie_iocp_cache_setup(&pcie->pci.pp);
I don't think we should be doing anything after dw_pcie_host_init()
because by the time we get here, we've already enumerated downstream
devices and potentially bound drivers to them.
If you need things done in dw_pcie_host_init() before enumeration,
qilai_pcie_host_init() and similar hooks are possibilities.
> + return 0;
> +}
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v3 5/5] MAINTAINERS: Add maintainers for Andes QiLai PCIe driver
2025-09-23 11:36 [PATCH v3 0/5] Add support for Andes Qilai SoC PCIe controller Randolph Lin
` (3 preceding siblings ...)
2025-09-23 11:36 ` [PATCH v3 4/5] PCI: andes: Add Andes QiLai SoC PCIe host driver support Randolph Lin
@ 2025-09-23 11:36 ` Randolph Lin
4 siblings, 0 replies; 13+ messages in thread
From: Randolph Lin @ 2025-09-23 11:36 UTC (permalink / raw)
To: linux-kernel
Cc: linux-pci, linux-riscv, devicetree, jingoohan1, mani, lpieralisi,
kwilczynski, robh, bhelgaas, krzk+dt, conor+dt, alex, aou, palmer,
paul.walmsley, ben717, inochiama, thippeswamy.havalige, namcao,
shradha.t, randolph.sklin, tim609, Randolph Lin
Here add maintainer information for Andes QiLai PCIe driver.
Signed-off-by: Randolph Lin <randolph@andestech.com>
---
MAINTAINERS | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 520fb4e379a3..0fe27108e6b9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19256,6 +19256,13 @@ S: Supported
F: Documentation/devicetree/bindings/pci/altr,pcie-root-port.yaml
F: drivers/pci/controller/pcie-altera.c
+PCI DRIVER FOR ANDES QILAI PCIE
+M: Randolph Lin <randolph@andestech.com>
+L: linux-pci@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/pci/andestech,qilai-pcie.yaml
+F: drivers/pci/controller/dwc/pcie-andes-qilai.c
+
PCI DRIVER FOR APPLIEDMICRO XGENE
M: Toan Le <toan@os.amperecomputing.com>
L: linux-pci@vger.kernel.org
--
2.34.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 13+ messages in thread