As per MHI spec sec 14, MHI supports bandwidth scaling to reduce power consumption. MHI bandwidth scaling is advertised in devices that contain the bandwidth scaling capability registers. If enabled, the device aggregates bandwidth requirements and sends them to the host in the form of an event. After the host performs the bandwidth switch, it sends an acknowledgment by ringing a doorbell. if the host supports bandwidth scaling events, then it must set BW_CFG.ENABLED bit, set BW_CFG.DB_CHAN_ID to the channel ID to the doorbell that will be used by the host to communicate the bandwidth scaling status and BW_CFG.ER_INDEX to the index for the event ring to which the device should send bandwidth scaling request in the bandwidth scaling capability register. As part of mmio init check if the bw scale capability is present or not, if present advertise host supports bw scale by setting all the required fields. MHI layer will only forward the bw scaling request to the controller driver, it is responsibility of the controller driver to do actual bw scaling and then pass status to the MHI. MHI will response back to the device based up on the status of the bw scale received. Add a new get_misc_doorbell() to get doorbell for misc capabilities to use the doorbell with mhi events like MHI BW scale etc. Use workqueue & mutex for the bw scale events as the pci_set_target_speed() which will called by the mhi controller driver can sleep. If the driver want to move higher data rate/speed then the current data rate/speed then the controller driver may need to change certain votes so that link may come up in requested data rate/speed like QCOM PCIe controllers need to change their RPMh (Resource Power Manager-hardened) state. And also once link retraining is done controller drivers needs to adjust their votes based on the final data rate/speed. Some controllers also may need to update their bandwidth voting like ICC bw votings etc. So, add pre_link_speed_change() & post_link_speed_change() op to call before & after the link re-train. There is no explicit locking mechanisms as these are called by a single client endpoint driver In case of PCIe switch, if there is a request to change target speed for a downstream port then no need to call these function ops as these are outside the scope of the controller drivers. Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@xxxxxxxxxxxxxxxx> --- Changes in v4: - Remove leftover type case, change the function names to pre/post_link_speed_change(Ilpo Järvinen) - Add check's for capability read and convert le32 to cpu (Jeffrey Hugo) - Add macros for GENMASK & BIT() (Ilpo Järvinen) - Link to v3: https://lore.kernel.org/r/20250519-mhi_bw_up-v3-0-3acd4a17bbb5@xxxxxxxxxxxxxxxx Changes in v3: - Move update speed logic to pwrctrl driver (Mani) - Move pre_bus_bw & post_bus_bw to bridge as these are bridge driver specific ops, it feels to me we need to add these in the host bridge driver similar to recently added one reset_slot. - Remove dwc level wrapper (Mani) - Enable ASPM only if they are enabled already (Mani) - Change the name of mhi_get_capability_offset to mhi_find_capability() (Bjorn) - Fix comments in the code, subjects etc (Mani & Bjorn) - Link to v2: https://lore.kernel.org/r/20250313-mhi_bw_up-v2-0-869ca32170bf@xxxxxxxxxxxxxxxx Changes in v2: - Update the comments. - Split the icc bw patch as sepertate one (Bjorn) - update the aspm disablement comment (Bjorn) - Use FIELD_GET & FIELD_PREP instead of hard macros and couple of nits suggested by (Ilpo Järvinen) - Create a new function to change lnkcntrl2speed to enum pci_bus_speed (Jeff) - Link to v1: https://lore.kernel.org/r/20250217-mhi_bw_up-v1-0-9bad1e42bdb1@xxxxxxxxxxxxxxxx --- Krishna Chaitanya Chundru (9): PCI: Update current bus speed as part of pci_pwrctrl_notify() PCI/bwctrl: Add support to scale bandwidth before & after link re-training bus: mhi: host: Add support for Bandwidth scale PCI/ASPM: Return enabled ASPM states as part of pcie_aspm_enabled() PCI/ASPM: Clear aspm_disable as part of __pci_enable_link_state() PCI: qcom: Extract core logic from qcom_pcie_icc_opp_update() PCI: qcom: Add support for PCIe pre/post_link_speed_change() PCI: Export pci_set_target_speed() PCI: Add function to convert lnkctl2speed to pci_bus_speed Miaoqing Pan (1): wifi: ath11k: Add support for MHI bandwidth scaling Vivek Pernamitta (1): bus: mhi: host: Add support to read MHI capabilities drivers/bus/mhi/common.h | 26 +++++++ drivers/bus/mhi/host/init.c | 97 +++++++++++++++++++++++++- drivers/bus/mhi/host/internal.h | 7 +- drivers/bus/mhi/host/main.c | 98 +++++++++++++++++++++++++- drivers/bus/mhi/host/pm.c | 10 ++- drivers/net/wireless/ath/ath11k/mhi.c | 41 +++++++++++ drivers/pci/controller/dwc/pcie-qcom.c | 124 ++++++++++++++++++++++++++------- drivers/pci/pci.c | 12 ++++ drivers/pci/pcie/aspm.c | 5 +- drivers/pci/pcie/bwctrl.c | 16 +++++ drivers/pci/pwrctrl/core.c | 5 ++ include/linux/mhi.h | 13 ++++ include/linux/pci.h | 23 +++++- 13 files changed, 442 insertions(+), 35 deletions(-) --- base-commit: d178209b7c211256ee736ec7c920acb81ddcea48 change-id: 20250217-mhi_bw_up-f31306a5631b Best regards, -- krishnachaitanya-linux <krichai@xxxxxxxxxxxxxxxx>