Some platforms keep the PCIe link up across bootloader and kernel
handoff. In such cases, reinitializing the root complex is unnecessary
if the DWC glue drivers wants to retain the PCIe link.
Introduce a link_retain flag in struct dw_pcie_rp to indicate that
the link should be preserved. When this flag is set by DWC glue drivers,
skip dw_pcie_setup_rc() and only initialize MSI, avoiding redundant
configuration steps.
Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
---
drivers/pci/controller/dwc/pcie-designware-host.c | 11 ++++++++---
drivers/pci/controller/dwc/pcie-designware.h | 1 +
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index 372207c33a857b4c98572bb1e9b61fa0080bc871..d050df3f22e9507749a8f2fedd4c24fca43fb410 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -655,9 +655,14 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
if (ret)
goto err_free_msi;
- ret = dw_pcie_setup_rc(pp);
- if (ret)
- goto err_remove_edma;
+ if (!pp->link_retain) {
+ ret = dw_pcie_setup_rc(pp);
+ if (ret)
+ goto err_remove_edma;
+ } else {
+ dw_pcie_msi_init(pp);
+ }
+
if (!dw_pcie_link_up(pci)) {
ret = dw_pcie_start_link(pci);
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index 31685951a080456b8834aab2bf79a36c78f46639..8acab751b66a06e8322e027ab55dc0ecfdcf634c 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -439,6 +439,7 @@ struct dw_pcie_rp {
struct pci_config_window *cfg;
bool ecam_enabled;
bool native_ecam;
+ bool link_retain;
};
struct dw_pcie_ep_ops {
--
2.34.1
On Fri, Jan 09, 2026 at 12:51:07PM +0530, Krishna Chaitanya Chundru wrote:
> Some platforms keep the PCIe link up across bootloader and kernel
> handoff. In such cases, reinitializing the root complex is unnecessary
> if the DWC glue drivers wants to retain the PCIe link.
>
> Introduce a link_retain flag in struct dw_pcie_rp to indicate that
> the link should be preserved. When this flag is set by DWC glue drivers,
> skip dw_pcie_setup_rc() and only initialize MSI, avoiding redundant
> configuration steps.
It sounds like this adds an assumption that the bootloader
initialization is the same as what dw_pcie_setup_rc() would do. This
assumption also applies to future changes in dw_pcie_setup_rc().
It looks like you mention an issue like this in [PATCH 4/5]; DBI & ATU
base being different than "HLOS" (whatever that is). This sounds like
a maintenance issue keeping bootloader and kernel driver assumptions
synchronized.
Is there something in dw_pcie_setup_rc() that takes a lot of time or
forces a link retrain? You mentioned some clock and GENPD issues in
the cover letter, but I don't see the connection between those and
dw_pcie_setup_rc(). If there is a connection, please include it in
this commit log and include a code comment about why
dw_pcie_setup_rc() is being skipped.
> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
> ---
> drivers/pci/controller/dwc/pcie-designware-host.c | 11 ++++++++---
> drivers/pci/controller/dwc/pcie-designware.h | 1 +
> 2 files changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index 372207c33a857b4c98572bb1e9b61fa0080bc871..d050df3f22e9507749a8f2fedd4c24fca43fb410 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -655,9 +655,14 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
> if (ret)
> goto err_free_msi;
>
> - ret = dw_pcie_setup_rc(pp);
> - if (ret)
> - goto err_remove_edma;
> + if (!pp->link_retain) {
Use positive logic if possible (test "pp->link_retain" instead of
"!pp->link_retain").
I suspect this would be more maintainable if you identified specific
things *inside* dw_pcie_setup_rc() that need to be skipped, and you
added tests there.
> + ret = dw_pcie_setup_rc(pp);
> + if (ret)
> + goto err_remove_edma;
> + } else {
> + dw_pcie_msi_init(pp);
> + }
> +
>
> if (!dw_pcie_link_up(pci)) {
> ret = dw_pcie_start_link(pci);
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index 31685951a080456b8834aab2bf79a36c78f46639..8acab751b66a06e8322e027ab55dc0ecfdcf634c 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -439,6 +439,7 @@ struct dw_pcie_rp {
> struct pci_config_window *cfg;
> bool ecam_enabled;
> bool native_ecam;
> + bool link_retain;
> };
>
> struct dw_pcie_ep_ops {
>
> --
> 2.34.1
>
On 1/9/2026 9:23 PM, Bjorn Helgaas wrote:
> On Fri, Jan 09, 2026 at 12:51:07PM +0530, Krishna Chaitanya Chundru wrote:
>> Some platforms keep the PCIe link up across bootloader and kernel
>> handoff. In such cases, reinitializing the root complex is unnecessary
>> if the DWC glue drivers wants to retain the PCIe link.
>>
>> Introduce a link_retain flag in struct dw_pcie_rp to indicate that
>> the link should be preserved. When this flag is set by DWC glue drivers,
>> skip dw_pcie_setup_rc() and only initialize MSI, avoiding redundant
>> configuration steps.
> It sounds like this adds an assumption that the bootloader
> initialization is the same as what dw_pcie_setup_rc() would do. This
> assumption also applies to future changes in dw_pcie_setup_rc().
Yes the bootloader is expected to do everything what dw_pcie_setup_r()
does.
> It looks like you mention an issue like this in [PATCH 4/5]; DBI & ATU
> base being different than "HLOS" (whatever that is). This sounds like
> a maintenance issue keeping bootloader and kernel driver assumptions
> synchronized.
As the devicetree changes already pointing to different address from the
boatloader,
I was trying use this method. As changing device tree properties now
might not
be good, but no harm in doing so. I can skip this and make device tree
changes.
> Is there something in dw_pcie_setup_rc() that takes a lot of time or
> forces a link retrain?
I don't think it might not take much time as it is few register writes,
Just doesn't
want to do redundant register writes which are costly in general.
> You mentioned some clock and GENPD issues in
> the cover letter, but I don't see the connection between those and
> dw_pcie_setup_rc(). If there is a connection, please include it in
> this commit log and include a code comment about why
> dw_pcie_setup_rc() is being skipped.
The clock and GENPD issues have no direct relation ship with
dw_pcie_setup_r(). we are skipping them as they are redundant. I will
add a comment in next series on this. - Krishna Chaitanya.
>> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
>> ---
>> drivers/pci/controller/dwc/pcie-designware-host.c | 11 ++++++++---
>> drivers/pci/controller/dwc/pcie-designware.h | 1 +
>> 2 files changed, 9 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
>> index 372207c33a857b4c98572bb1e9b61fa0080bc871..d050df3f22e9507749a8f2fedd4c24fca43fb410 100644
>> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
>> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
>> @@ -655,9 +655,14 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
>> if (ret)
>> goto err_free_msi;
>>
>> - ret = dw_pcie_setup_rc(pp);
>> - if (ret)
>> - goto err_remove_edma;
>> + if (!pp->link_retain) {
> Use positive logic if possible (test "pp->link_retain" instead of
> "!pp->link_retain").
>
> I suspect this would be more maintainable if you identified specific
> things *inside* dw_pcie_setup_rc() that need to be skipped, and you
> added tests there.
>
>> + ret = dw_pcie_setup_rc(pp);
>> + if (ret)
>> + goto err_remove_edma;
>> + } else {
>> + dw_pcie_msi_init(pp);
>> + }
>> +
>>
>> if (!dw_pcie_link_up(pci)) {
>> ret = dw_pcie_start_link(pci);
>> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
>> index 31685951a080456b8834aab2bf79a36c78f46639..8acab751b66a06e8322e027ab55dc0ecfdcf634c 100644
>> --- a/drivers/pci/controller/dwc/pcie-designware.h
>> +++ b/drivers/pci/controller/dwc/pcie-designware.h
>> @@ -439,6 +439,7 @@ struct dw_pcie_rp {
>> struct pci_config_window *cfg;
>> bool ecam_enabled;
>> bool native_ecam;
>> + bool link_retain;
>> };
>>
>> struct dw_pcie_ep_ops {
>>
>> --
>> 2.34.1
>>
On 1/9/26 4:53 PM, Bjorn Helgaas wrote: > On Fri, Jan 09, 2026 at 12:51:07PM +0530, Krishna Chaitanya Chundru wrote: >> Some platforms keep the PCIe link up across bootloader and kernel >> handoff. In such cases, reinitializing the root complex is unnecessary >> if the DWC glue drivers wants to retain the PCIe link. >> >> Introduce a link_retain flag in struct dw_pcie_rp to indicate that >> the link should be preserved. When this flag is set by DWC glue drivers, >> skip dw_pcie_setup_rc() and only initialize MSI, avoiding redundant >> configuration steps. > > It sounds like this adds an assumption that the bootloader > initialization is the same as what dw_pcie_setup_rc() would do. This > assumption also applies to future changes in dw_pcie_setup_rc(). > > It looks like you mention an issue like this in [PATCH 4/5]; DBI & ATU > base being different than "HLOS" (whatever that is). This sounds like FYI, "HLOS" is a Qualcomm term for "High-Level OS".. which is a very pedantic way to say "OS" Konrad
© 2016 - 2026 Red Hat, Inc.