From: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
To: Manivannan Sadhasivam <mani@kernel.org>
Cc: "Bjorn Helgaas" <bhelgaas@google.com>,
"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
"Jingoo Han" <jingoohan1@gmail.com>,
"Lorenzo Pieralisi" <lpieralisi@kernel.org>,
"Rob Herring" <robh@kernel.org>,
"Jeff Johnson" <jjohnson@kernel.org>,
"Bartosz Golaszewski" <brgl@bgdev.pl>,
"Krzysztof Wilczyński" <kwilczynski@kernel.org>,
linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arm-msm@vger.kernel.org, mhi@lists.linux.dev,
linux-wireless@vger.kernel.org, ath11k@lists.infradead.org,
qiang.yu@oss.qualcomm.com
Subject: Re: [PATCH v5 1/6] PCI/bwctrl: Set host bridge OPP and optionally disable ASPM around link retraining
Date: Wed, 2 Sep 2026 10:22:51 +0530 [thread overview]
Message-ID: <5c3f1611-275e-4664-b3e2-748da6d210ed@oss.qualcomm.com> (raw)
In-Reply-To: <atba2336nxz566wvbfrvclbx7yyma5elhnojb7ozz4ku6dk3q3@c2wa24laiqyd>
On 9/1/2026 1:12 PM, Manivannan Sadhasivam wrote:
> On Wed, Aug 19, 2026 at 06:55:52PM +0530, Krishna Chaitanya Chundru wrote:
>> PCIe host bridge controllers may need their operating point raised before
> Use either "Host Bridge devices" or "PCIe controllers".
>
>> retraining to a higher link speed so that hardware resources (e.g., RPMh
>> votes on Qualcomm platforms) are available at the requested data rate.
>> After retraining, the operating point must be updated to reflect the
>> actual negotiated speed.
>>
>> Add pcie_set_opp() to look up an OPP on the host bridge parent device
>> using a key of (per-lane frequency in kHz, LNKCTL2 Target Link Speed
>> level). Keying by generation rather than total bandwidth lets OPP tables
>> remain width-independent.
>>
>> In pcie_set_target_speed(), call pcie_set_opp() before retraining only
>> when upscaling (speed_req > cur_bus_speed), since only raising the
>> operating point requires pre-staging hardware. After retraining, call
>> pcie_set_opp() unconditionally with the actual cur_bus_speed to settle
>> the votes. Both calls are skipped for downstream ports of PCIe switches,
>> as those are outside the host controller's scope.
>>
>> Some controllers also require ASPM to be disabled around link retraining.
>> Add a disable_aspm_for_retrain flag to pci_host_bridge; when set,
>> pcie_set_target_speed() saves the child device's ASPM state, disables all
>> ASPM link states before retraining, and restores them afterward.
>>
>> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
>> ---
>> drivers/pci/pcie/bwctrl.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++-
>> include/linux/pci.h | 1 +
>> 2 files changed, 63 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/pci/pcie/bwctrl.c b/drivers/pci/pcie/bwctrl.c
>> index c4c8d260bf96..6fa1522c47db 100644
>> --- a/drivers/pci/pcie/bwctrl.c
>> +++ b/drivers/pci/pcie/bwctrl.c
>> @@ -28,9 +28,11 @@
>> #include <linux/mutex.h>
>> #include <linux/pci.h>
>> #include <linux/pci-bwctrl.h>
>> +#include <linux/pm_opp.h>
>> #include <linux/rwsem.h>
>> #include <linux/slab.h>
>> #include <linux/types.h>
>> +#include <linux/units.h>
>>
>> #include "../pci.h"
>> #include "portdrv.h"
>> @@ -120,6 +122,38 @@ static int pcie_bwctrl_change_speed(struct pci_dev *port, u16 target_speed, bool
>> return pcie_retrain_link(port, use_lt);
>> }
>>
>> +static int pcie_set_opp(struct pci_dev *pdev, struct pci_host_bridge *host,
>> + enum pci_bus_speed speed)
>> +{
>> + struct device *dev = host->dev.parent;
>> + struct dev_pm_opp_key key = {};
>> + int ret, freq_mbps, width;
>> + unsigned long freq_kbps;
>> + struct dev_pm_opp *opp;
>> + u16 lnksta;
>> +
>> + pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnksta);
>> + width = FIELD_GET(PCI_EXP_LNKSTA_NLW, lnksta);
>> +
>> + freq_mbps = pcie_dev_speed_mbps(speed);
>> + if (freq_mbps < 0)
>> + return -EINVAL;
>> +
>> + freq_kbps = freq_mbps * KILO;
>> + key.freq = freq_kbps;
>> + key.level = pci_bus_speed2lnkctl2(speed);
>> + key.bw = 0;
> 'key' is already 0 initialized above.
>
>> + opp = dev_pm_opp_find_key_exact(dev, &key, true);
>> + if (!IS_ERR(opp)) {
>> + ret = dev_pm_opp_set_opp(dev, opp);
>> + if (ret)
>> + dev_err(dev, "Failed to set OPP for freq (%lu): %d\n",
>> + freq_kbps * width, ret);
>> + dev_pm_opp_put(opp);
>> + }
>> + return 0;
>> +}
>> +
>> /**
>> * pcie_set_target_speed - Set downstream Link Speed for PCIe Port
>> * @port: PCIe Port
>> @@ -140,9 +174,12 @@ static int pcie_bwctrl_change_speed(struct pci_dev *port, u16 target_speed, bool
>> int pcie_set_target_speed(struct pci_dev *port, enum pci_bus_speed speed_req,
>> bool use_lt)
>> {
>> + struct pci_host_bridge *host = pci_find_host_bridge(port->bus);
>> + bool is_rootbus = pci_is_root_bus(port->bus);
>> struct pci_bus *bus = port->subordinate;
>> + struct pci_dev *child = NULL;
>> + int aspm_state = 0, ret;
>> u16 target_speed;
>> - int ret;
>>
>> if (WARN_ON_ONCE(!pcie_valid_speed(speed_req)))
>> return -EINVAL;
>> @@ -152,6 +189,24 @@ int pcie_set_target_speed(struct pci_dev *port, enum pci_bus_speed speed_req,
>>
>> target_speed = pcie_bwctrl_select_speed(port, speed_req);
>>
>> + /*
>> + * The host bridge driver may need to be scaled for targeted speed
> "Host Bridge resources may need to be..."
>
>> + * otherwise link might not come up at requested speed.
>> + */
>> + if (is_rootbus && host && bus) {
>> + /* Get function 0 of downstream device */
>> + list_for_each_entry(child, &bus->devices, bus_list)
>> + if (PCI_FUNC(child->devfn) == 0)
>> + break;
>> +
>> + if (child && host->disable_aspm_for_retrain) {
>> + aspm_state = pcie_aspm_enabled(child);
>> + pci_disable_link_state_locked(child, PCIE_LINK_STATE_ALL);
>> + }
> You mentioned that the Host Bridge requires disabling ASPM during retraining,
> but here you are disabling ASPM of the downstream device. So the issue is device
> specific or Host Bridge (RP?) specific?
Issue is RP specific, if aspm driver disables the ASPM only when we pass the
child, if the we pass root port dev, it will just return without modifying the
aspm.
Ack for remaining comments.
- Krishna Chaitanya.
>> + if (speed_req > bus->cur_bus_speed)
>> + pcie_set_opp(port, host, speed_req);
>> + }
>> +
>> scoped_guard(rwsem_read, &pcie_bwctrl_setspeed_rwsem) {
>> struct pcie_bwctrl_data *data = port->link_bwctrl;
>>
>> @@ -176,6 +231,12 @@ int pcie_set_target_speed(struct pci_dev *port, enum pci_bus_speed speed_req,
>> !list_empty(&bus->devices))
>> ret = -EAGAIN;
>>
>> + if (bus && is_rootbus && host) {
> Maintain an order for this check. I think this order makes sense than the above
> one.
>
>
> - Mani
>
next prev parent reply other threads:[~2026-09-02 4:52 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-19 13:25 [PATCH v5 0/6] bus: mhi: host: Add support for mhi bus bw Krishna Chaitanya Chundru
2026-08-19 13:25 ` [PATCH v5 1/6] PCI/bwctrl: Set host bridge OPP and optionally disable ASPM around link retraining Krishna Chaitanya Chundru
2026-09-01 7:42 ` Manivannan Sadhasivam
2026-09-02 4:52 ` Krishna Chaitanya Chundru [this message]
2026-10-07 9:11 ` Val Packett
2026-10-08 5:52 ` Krishna Chaitanya Chundru
2026-08-19 13:25 ` [PATCH v5 2/6] PCI: Export pci_set_target_speed() Krishna Chaitanya Chundru
2026-09-01 7:44 ` Manivannan Sadhasivam
2026-08-19 13:25 ` [PATCH v5 3/6] PCI: Add pci_lnkctl2_bus_speed() to convert lnkctl2speed to pci_bus_speed Krishna Chaitanya Chundru
2026-09-01 7:50 ` Manivannan Sadhasivam
2026-08-19 13:25 ` [PATCH v5 4/6] bus: mhi: host: Add support for Bandwidth scale Krishna Chaitanya Chundru
2026-09-01 8:06 ` Manivannan Sadhasivam
2026-09-02 5:00 ` Krishna Chaitanya Chundru
2026-08-19 13:25 ` [PATCH v5 5/6] wifi: ath11k: Add support for MHI bandwidth scaling Krishna Chaitanya Chundru
2026-09-01 14:45 ` Neil Armstrong
2026-09-02 5:30 ` Krishna Chaitanya Chundru
2026-08-19 13:25 ` [PATCH v5 6/6] PCI: qcom: Enable ASPM disabling during link retraining Krishna Chaitanya Chundru
2026-09-01 8:08 ` Manivannan Sadhasivam
2026-09-02 5:22 ` Krishna Chaitanya Chundru
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5c3f1611-275e-4664-b3e2-748da6d210ed@oss.qualcomm.com \
--to=krishna.chundru@oss.qualcomm.com \
--cc=ath11k@lists.infradead.org \
--cc=bhelgaas@google.com \
--cc=brgl@bgdev.pl \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=jingoohan1@gmail.com \
--cc=jjohnson@kernel.org \
--cc=kwilczynski@kernel.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux-wireless@vger.kernel.org \
--cc=lpieralisi@kernel.org \
--cc=mani@kernel.org \
--cc=mhi@lists.linux.dev \
--cc=qiang.yu@oss.qualcomm.com \
--cc=robh@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®