From f2ee87014e914a598c6fd52f7faf2a3ad0ad96cf Mon Sep 17 00:00:00 2001 From: Shuai Zhang Date: Tue, 24 Mar 2026 14:59:48 +0800 Subject: [PATCH 01/16] WORKAROUND: arm64: dts: qcom: hamoa-iot-evk: support Bluetooth over both USB and UART On Hamoa boards, a single M.2 slot may host either a UART-based or a USB-based Bluetooth device. As a result, the UART controller node is always present in DT, while the USB path is hot-pluggable. When Bluetooth operates over USB, the presence of the UART DT node still causes the hci_qca UART driver to probe. During probe or power sequencing, the driver may deassert BT_EN, cutting power to the shared Bluetooth device and disconnecting the USB interface. Model BT_EN as an always-on fixed regulator so it cannot be toggled by the UART probe. This prevents the UART driver from interfering with Bluetooth operation when the device is connected over USB. Workaround will be reverted once the M.2 solutionis available upstream. Signed-off-by: Shuai Zhang --- arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts | 34 ++++++++++++++++------ 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts index c7ba4b353ddd2..0ab15ea5aa73a 100644 --- a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts +++ b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts @@ -522,6 +522,23 @@ regulator-boot-on; }; + vreg_wcn_bt_en: regulator-wcn-bt-en { + compatible = "regulator-fixed"; + + regulator-name = "VREG_WCN_BT_EN"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + gpio = <&tlmm 116 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&wcn_bt_en>; + pinctrl-names = "default"; + + regulator-always-on; + regulator-boot-on; + }; + vreg_wwan: regulator-wwan { compatible = "regulator-fixed"; @@ -687,10 +704,9 @@ vddrfa1p2-supply = <&vreg_wcn_1p9>; vddrfa1p8-supply = <&vreg_wcn_1p9>; - bt-enable-gpios = <&tlmm 116 GPIO_ACTIVE_HIGH>; wlan-enable-gpios = <&tlmm 117 GPIO_ACTIVE_HIGH>; - pinctrl-0 = <&wcn_bt_en>, <&wcn_wlan_en>; + pinctrl-0 = <&wcn_wlan_en>; pinctrl-names = "default"; regulators { @@ -1519,13 +1535,13 @@ compatible = "qcom,wcn7850-bt"; max-speed = <3200000>; - vddaon-supply = <&vreg_pmu_aon_0p59>; - vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; - vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; - vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; - vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; - vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; - vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; + vddrfacmn-supply = <&vreg_wcn_3p3>; + vddaon-supply = <&vreg_wcn_3p3>; + vddwlcx-supply = <&vreg_wcn_3p3>; + vddwlmx-supply = <&vreg_wcn_3p3>; + vddrfa0p8-supply = <&vreg_wcn_3p3>; + vddrfa1p2-supply = <&vreg_wcn_3p3>; + vddrfa1p8-supply = <&vreg_wcn_3p3>; }; }; From 5a472e184be99f6f0094c85ccb96db51453f4656 Mon Sep 17 00:00:00 2001 From: Shuai Zhang Date: Thu, 19 Mar 2026 11:56:41 +0800 Subject: [PATCH 02/16] WORKAROUND: power: sequencing: qcom-wcn: skip BT devices without bt-enable GPIO If a Bluetooth consumer device does not have a bt-enable GPIO configured in the power sequencer (for example, when BT_EN is tied high via a hardware pull-up and therefore absent from the DT), the power sequencer should not match the device. In this case, the Bluetooth consumer driver will fall back to its legacy power control path and correctly set power_ctrl_enabled to false. Bluetooth device nodes are conventionally named "bluetooth" in the device tree, so use of_node_name_eq() as a generic check instead of enumerating specific compatible strings. Workaround will be reverted once the M.2 solution is available upstream. Signed-off-by: Shuai Zhang --- drivers/power/sequencing/pwrseq-qcom-wcn.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/power/sequencing/pwrseq-qcom-wcn.c b/drivers/power/sequencing/pwrseq-qcom-wcn.c index b55b4317e21b6..dc83d32415a2d 100644 --- a/drivers/power/sequencing/pwrseq-qcom-wcn.c +++ b/drivers/power/sequencing/pwrseq-qcom-wcn.c @@ -432,6 +432,20 @@ static int pwrseq_qcom_wcn_match_regulator(struct pwrseq_device *pwrseq, reg_node->parent->parent != ctx->of_node) return PWRSEQ_NO_MATCH; + /* + * If this is a Bluetooth consumer device but the bt-enable GPIO is not + * configured in the power sequencer (e.g. BT_EN is tied high via a + * hardware pull-up and therefore absent from the DT), don't match. + * The consumer driver will fall back to its legacy power control path + * and correctly set power_ctrl_enabled to false. + * + * BT device nodes are conventionally named "bluetooth" in the DT, + * so use of_node_name_eq() as a generic check rather than enumerating + * specific compatible strings. + */ + if (!ctx->bt_gpio && of_node_name_eq(dev_node, "bluetooth")) + return PWRSEQ_NO_MATCH; + return PWRSEQ_MATCH_OK; } From 149f712c98ecd5e697823ad1896876863b911202 Mon Sep 17 00:00:00 2001 From: Salendarsingh Gaud Date: Fri, 8 May 2026 12:46:38 +0530 Subject: [PATCH 03/16] WORKAROUND: Revert "drm/msm/dpu: enable virtual planes by default" Bootup crash seen on kaanapali-mtp board. [ 8.114249][ C0] [drm:dpu_encoder_frame_done_timeout:2731] [dpu error]enc33 frame done timeout [ 8.116480][ T284] Unable to handle kernel paging request at virtual address ffff800080e5e000 [ 8.116488][ T284] Mem abort info: [ 8.116492][ T284] ESR = 0x0000000096000007 [ 8.116497][ T284] EC = 0x25: DABT (current EL), IL = 32 bits [ 8.116502][ T284] SET = 0, FnV = 0 [ 8.116507][ T284] EA = 0, S1PTW = 0 [ 8.116511][ T284] FSC = 0x07: level 3 translation fault [ 8.116516][ T284] Data abort info: [ 8.116519][ T284] ISV = 0, ISS = 0x00000007, ISS2 = 0x00000000 [ 8.116524][ T284] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 [ 8.116529][ T284] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 [ 8.116535][ T284] swapper pgtable: 4k pages, 48-bit VAs, pgdp=00000009bf36c000 [ 8.116541][ T284] [ffff800080e5e000] pgd=0000000000000000, p4d=1000000880346403, pud=1000000880347403, pmd=1000000881e2d403, pte=0000000000000000 [ 8.116567][ T284] Internal error: Oops: 0000000096000007 [#1] SMP Revert the change for now to unblock. This reverts commit b0907ee59e24d3dad572b4ccc6db018b00ca14c8. Signed-off-by: Salendarsingh Gaud --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index da3556eb6ecc2..dbc43e0dc18e3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -52,7 +52,7 @@ #define DPU_DEBUGFS_DIR "msm_dpu" #define DPU_DEBUGFS_HWMASKNAME "hw_log_mask" -bool dpu_use_virtual_planes = true; +bool dpu_use_virtual_planes; module_param(dpu_use_virtual_planes, bool, 0); static int dpu_kms_hw_init(struct msm_kms *kms); From 3aff69522614ad58d4b470d7758852c62cd28275 Mon Sep 17 00:00:00 2001 From: Wei Deng Date: Thu, 7 May 2026 12:53:20 +0530 Subject: [PATCH 04/16] WORKAROUND: arm64: dts: qcom: purwa-iot-evk: support Bluetooth over both USB and UART On Purwa boards, a single M.2 slot may host either a UART-based or a USB-based Bluetooth device. As a result, the UART controller node is always present in DT, while the USB path is hot-pluggable. When Bluetooth operates over USB, the presence of the UART DT node still causes the hci_qca UART driver to probe. During probe or power sequencing, the driver may deassert BT_EN, cutting power to the shared Bluetooth device and disconnecting the USB interface. Model BT_EN as an always-on fixed regulator so it cannot be toggled by the UART probe. This prevents the UART driver from interfering with Bluetooth operation when the device is connected over USB. Workaround will be reverted once the M.2 solutionis available upstream. Signed-off-by: Wei Deng --- arch/arm64/boot/dts/qcom/purwa-iot-evk.dts | 34 ++++++++++++++++------ 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/purwa-iot-evk.dts b/arch/arm64/boot/dts/qcom/purwa-iot-evk.dts index ad503beec1d3d..c39081b064b10 100644 --- a/arch/arm64/boot/dts/qcom/purwa-iot-evk.dts +++ b/arch/arm64/boot/dts/qcom/purwa-iot-evk.dts @@ -514,6 +514,23 @@ regulator-boot-on; }; + vreg_wcn_bt_en: regulator-wcn-bt-en { + compatible = "regulator-fixed"; + + regulator-name = "VREG_WCN_BT_EN"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + gpio = <&tlmm 116 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&wcn_bt_en>; + pinctrl-names = "default"; + + regulator-always-on; + regulator-boot-on; + }; + vreg_wwan: regulator-wwan { compatible = "regulator-fixed"; @@ -628,10 +645,9 @@ vddrfa1p2-supply = <&vreg_wcn_1p9>; vddrfa1p8-supply = <&vreg_wcn_1p9>; - bt-enable-gpios = <&tlmm 116 GPIO_ACTIVE_HIGH>; wlan-enable-gpios = <&tlmm 117 GPIO_ACTIVE_HIGH>; - pinctrl-0 = <&wcn_bt_en>, <&wcn_wlan_en>; + pinctrl-0 = <&wcn_wlan_en>; pinctrl-names = "default"; regulators { @@ -1504,13 +1520,13 @@ compatible = "qcom,wcn7850-bt"; max-speed = <3200000>; - vddaon-supply = <&vreg_pmu_aon_0p59>; - vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; - vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; - vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; - vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; - vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; - vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; + vddaon-supply = <&vreg_wcn_3p3>; + vddwlcx-supply = <&vreg_wcn_3p3>; + vddwlmx-supply = <&vreg_wcn_3p3>; + vddrfacmn-supply = <&vreg_wcn_3p3>; + vddrfa0p8-supply = <&vreg_wcn_3p3>; + vddrfa1p2-supply = <&vreg_wcn_3p3>; + vddrfa1p8-supply = <&vreg_wcn_3p3>; }; }; From a2e72b2fa858db472f56d8d25347daf0b0a07fad Mon Sep 17 00:00:00 2001 From: Ziyue Zhang Date: Fri, 15 May 2026 00:00:00 +0800 Subject: [PATCH 05/16] WORKAROUND: phy: qcom: qmp-pcie: Add vdda-refgen and vdda-qref supplies for Monaco The PCIe QMP PHYs on Monaco (QCS8300) require stable reference voltage provided by refgen and reference clock provided by qref. The refgen and qref require power supplies. Add a new sa8775p_qmp_phy_vreg_l list with vdda-qref and vdda-refgen supplies, and use it for qcs8300_qmp_gen4x2, sa8775p_qmp_gen4x2 and sa8775p_qmp_gen4x4 PCIe PHY configurations. Workaround will be reverted once the vote qref regulator for PCIe available in upstream. Signed-off-by: Ziyue Zhang --- drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c index d3effad7a074b..77b60bd32cd9e 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c @@ -3488,6 +3488,10 @@ static const char * const sm8550_qmp_phy_vreg_l[] = { "vdda-phy", "vdda-pll", "vdda-qref", }; +static const char * const sa8775p_qmp_phy_vreg_l[] = { + "vdda-phy", "vdda-pll", "vdda-qref", "vdda-refgen", +}; + /* list of resets */ static const char * const ipq8074_pciephy_reset_l[] = { "phy", "common", @@ -3853,8 +3857,8 @@ static const struct qmp_phy_cfg qcs8300_qmp_gen4x2_pciephy_cfg = { .reset_list = sdm845_pciephy_reset_l, .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .vreg_list = sa8775p_qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(sa8775p_qmp_phy_vreg_l), .regs = pciephy_v5_regs_layout, .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, @@ -4563,8 +4567,8 @@ static const struct qmp_phy_cfg sa8775p_qmp_gen4x2_pciephy_cfg = { .reset_list = sdm845_pciephy_reset_l, .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .vreg_list = sa8775p_qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(sa8775p_qmp_phy_vreg_l), .regs = pciephy_v5_regs_layout, .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, @@ -4604,8 +4608,8 @@ static const struct qmp_phy_cfg sa8775p_qmp_gen4x4_pciephy_cfg = { .reset_list = sdm845_pciephy_reset_l, .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .vreg_list = sa8775p_qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(sa8775p_qmp_phy_vreg_l), .regs = pciephy_v5_regs_layout, .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, From 95316f8b5f2d1d85a117e216361eef5dfb07f010 Mon Sep 17 00:00:00 2001 From: Ziyue Zhang Date: Fri, 15 May 2026 00:00:00 +0800 Subject: [PATCH 06/16] WORKAROUND: arm64: dts: qcom: qcs8300-ride: Add vdda-qref and vdda-refgen supplies for PCIe PHYs The PCIe QMP PHYs on QCS8300 require stable reference voltage provided by refgen and reference clock provided by qref. Add vdda-qref-supply and vdda-refgen-supply to pcie0_phy and pcie1_phy nodes on the qcs8300-ride board. Workaround will be reverted once the vote qref regulator for PCIe available in upstream. Signed-off-by: Ziyue Zhang --- arch/arm64/boot/dts/qcom/qcs8300-ride.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts index e9a8553a8d821..25be329a98829 100644 --- a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts +++ b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts @@ -638,6 +638,8 @@ &pcie0_phy { vdda-phy-supply = <&vreg_l6a>; vdda-pll-supply = <&vreg_l5a>; + vdda-qref-supply = <&vreg_l7a>; + vdda-refgen-supply = <&refgen>; status = "okay"; }; @@ -657,6 +659,8 @@ &pcie1_phy { vdda-phy-supply = <&vreg_l6a>; vdda-pll-supply = <&vreg_l5a>; + vdda-qref-supply = <&vreg_l7a>; + vdda-refgen-supply = <&refgen>; status = "okay"; }; From 06f2b9c608345b2c4b8ff3259cd91941aa569150 Mon Sep 17 00:00:00 2001 From: Shuai Zhang Date: Thu, 28 May 2026 20:23:39 +0800 Subject: [PATCH 07/16] WORKAROUND: power: sequencing: qcom-wcn: skip BT devices without bt-enable GPIO Add a bt_gpio_required flag to the per-platform data to indicate that a chip's BT enable path requires a dedicated GPIO. Only skip matching the "bluetooth" device node when this flag is set and bt_gpio is absent. Previously the bt_gpio check was applied unconditionally, which caused chips like WCN3990 that have no separate BT/WLAN enable pins by design to fail matching even when bt-enable GPIO is legitimately absent from the DT. Set bt_gpio_required for WCN6855 and WCN7850 which do require a dedicated BT enable GPIO. Signed-off-by: Shuai Zhang --- drivers/power/sequencing/pwrseq-qcom-wcn.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/power/sequencing/pwrseq-qcom-wcn.c b/drivers/power/sequencing/pwrseq-qcom-wcn.c index dc83d32415a2d..a68e6fb344fd6 100644 --- a/drivers/power/sequencing/pwrseq-qcom-wcn.c +++ b/drivers/power/sequencing/pwrseq-qcom-wcn.c @@ -25,6 +25,7 @@ struct pwrseq_qcom_wcn_pdata { unsigned int gpio_enable_delay_ms; const struct pwrseq_target_data **targets; bool has_vddio; /* separate VDD IO regulator */ + bool bt_gpio_required; /* BT enable path requires a dedicated GPIO */ int (*match)(struct pwrseq_device *pwrseq, struct device *dev); }; @@ -383,6 +384,7 @@ static const struct pwrseq_qcom_wcn_pdata pwrseq_wcn6855_of_data = { .pwup_delay_ms = 50, .gpio_enable_delay_ms = 5, .targets = pwrseq_qcom_wcn6855_targets, + .bt_gpio_required = true, }; static const char *const pwrseq_wcn7850_vregs[] = { @@ -400,6 +402,7 @@ static const struct pwrseq_qcom_wcn_pdata pwrseq_wcn7850_of_data = { .num_vregs = ARRAY_SIZE(pwrseq_wcn7850_vregs), .pwup_delay_ms = 50, .targets = pwrseq_qcom_wcn_targets, + .bt_gpio_required = true, }; static int pwrseq_qcom_wcn_match_regulator(struct pwrseq_device *pwrseq, @@ -439,11 +442,17 @@ static int pwrseq_qcom_wcn_match_regulator(struct pwrseq_device *pwrseq, * The consumer driver will fall back to its legacy power control path * and correctly set power_ctrl_enabled to false. * + * Only apply this check for chips whose BT enable path requires a + * dedicated GPIO (bt_gpio_required). Chips like WCN3990 have no + * separate BT/WLAN enable pins by design and must always be matched + * even when bt_gpio is NULL. + * * BT device nodes are conventionally named "bluetooth" in the DT, * so use of_node_name_eq() as a generic check rather than enumerating * specific compatible strings. */ - if (!ctx->bt_gpio && of_node_name_eq(dev_node, "bluetooth")) + if (ctx->pdata->bt_gpio_required && !ctx->bt_gpio && + of_node_name_eq(dev_node, "bluetooth")) return PWRSEQ_NO_MATCH; return PWRSEQ_MATCH_OK; From d88b882e260600379c83fcac065edd937dd34e1b Mon Sep 17 00:00:00 2001 From: Yepuri Siddu Date: Mon, 8 Jun 2026 12:20:46 +0530 Subject: [PATCH 08/16] FROMLIST: dt-bindings: net: bluetooth: qcom: document QCC2072 Add the new compatible string for the QCC2072 BT SoC to the Qualcomm Bluetooth DT binding schema. Link: https://lore.kernel.org/all/20260529175342.3363935-1-yepuri.siddu@oss.qualcomm.com/ Signed-off-by: Yepuri Siddu --- .../net/bluetooth/qcom,qcc2072-bt.yaml | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/bluetooth/qcom,qcc2072-bt.yaml diff --git a/Documentation/devicetree/bindings/net/bluetooth/qcom,qcc2072-bt.yaml b/Documentation/devicetree/bindings/net/bluetooth/qcom,qcc2072-bt.yaml new file mode 100644 index 0000000000000..8e2f15a75d620 --- /dev/null +++ b/Documentation/devicetree/bindings/net/bluetooth/qcom,qcc2072-bt.yaml @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/bluetooth/qcom,qcc2072-bt.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm QCC2072 Bluetooth + +maintainers: + - Balakrishna Godavarthi + - Rocky Liao + +description: + Qualcomm QCC2072 is a UART-based Bluetooth controller. + +properties: + compatible: + enum: + - qcom,qcc2072-bt + +required: + - compatible + +allOf: + - $ref: bluetooth-controller.yaml# + - $ref: qcom,bluetooth-common.yaml# + - $ref: /schemas/serial/serial-peripheral-props.yaml# + +unevaluatedProperties: false + +examples: + - | + serial { + bluetooth { + compatible = "qcom,qcc2072-bt"; + max-speed = <3200000>; + }; + }; From f086e50898137df252189358977028287fd07434 Mon Sep 17 00:00:00 2001 From: Yepuri Siddu Date: Mon, 8 Jun 2026 12:33:14 +0530 Subject: [PATCH 09/16] FROMLIST: Bluetooth: qca: add QCC2072 support QCC2072 is a BT/WiFi combo SoC that uses different firmware filenames and requires no external voltage regulators, so add it as a new SoC type. The chip supports the wideband speech and valid LE states capabilities. Its firmware is named using the "orn" prefix and follows the standard rom-version-based scheme: - qca/ornbtfw.tlv - qca/ornnv.bin These firmware files are already present in the linux-firmware repository. Link: https://lore.kernel.org/all/20260529175822.3366535-1-yepuri.siddu@oss.qualcomm.com/ Signed-off-by: Yepuri Siddu --- drivers/bluetooth/btqca.c | 9 +++++++++ drivers/bluetooth/btqca.h | 1 + drivers/bluetooth/hci_qca.c | 24 ++++++++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c index 04ebe290bc784..8b2ad10ec2d92 100644 --- a/drivers/bluetooth/btqca.c +++ b/drivers/bluetooth/btqca.c @@ -845,6 +845,10 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, snprintf(config.fwname, sizeof(config.fwname), "qca/hmtbtfw%02x.tlv", rom_ver); break; + case QCA_QCC2072: + snprintf(config.fwname, sizeof(config.fwname), + "qca/ornbtfw%02x.tlv", rom_ver); + break; default: snprintf(config.fwname, sizeof(config.fwname), "qca/rampatch_%08x.bin", soc_ver); @@ -939,6 +943,10 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, qca_get_nvm_name_by_board(config.fwname, sizeof(config.fwname), "hmtnv", soc_type, ver, rom_ver, boardid); break; + case QCA_QCC2072: + snprintf(config.fwname, sizeof(config.fwname), + "qca/ornnv%02x.bin", rom_ver); + break; default: snprintf(config.fwname, sizeof(config.fwname), "qca/nvm_%08x.bin", soc_ver); @@ -1001,6 +1009,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, case QCA_WCN6750: case QCA_WCN6855: case QCA_WCN7850: + case QCA_QCC2072: /* get fw build info */ err = qca_read_fw_build_info(hdev); if (err < 0) diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h index 8f3c1b1c77b3d..a175ac31e7b23 100644 --- a/drivers/bluetooth/btqca.h +++ b/drivers/bluetooth/btqca.h @@ -158,6 +158,7 @@ enum qca_btsoc_type { QCA_WCN6750, QCA_WCN6855, QCA_WCN7850, + QCA_QCC2072, }; #if IS_ENABLED(CONFIG_BT_QCA) diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 2444471956197..3f9e3d966747d 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -1372,6 +1372,7 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate) /* Give the controller time to process the request */ switch (qca_soc_type(hu)) { + case QCA_QCC2072: case QCA_WCN3950: case QCA_WCN3988: case QCA_WCN3990: @@ -1459,6 +1460,7 @@ static unsigned int qca_get_speed(struct hci_uart *hu, static int qca_check_speeds(struct hci_uart *hu) { switch (qca_soc_type(hu)) { + case QCA_QCC2072: case QCA_WCN3950: case QCA_WCN3988: case QCA_WCN3990: @@ -1510,6 +1512,7 @@ static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type) case QCA_WCN6750: case QCA_WCN6855: case QCA_WCN7850: + case QCA_QCC2072: hci_uart_set_flow_control(hu, true); break; @@ -1545,6 +1548,7 @@ static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type) case QCA_WCN6750: case QCA_WCN6855: case QCA_WCN7850: + case QCA_QCC2072: hci_uart_set_flow_control(hu, false); break; @@ -1861,6 +1865,7 @@ static int qca_power_on(struct hci_dev *hdev) case QCA_WCN6750: case QCA_WCN6855: case QCA_WCN7850: + case QCA_QCC2072: ret = qca_regulator_init(hu); break; @@ -1960,6 +1965,10 @@ static int qca_setup(struct hci_uart *hu) soc_name = "wcn7850"; break; + case QCA_QCC2072: + soc_name = "qcc2072"; + break; + default: soc_name = "ROME/QCA6390"; } @@ -1983,6 +1992,7 @@ static int qca_setup(struct hci_uart *hu) case QCA_WCN6750: case QCA_WCN6855: case QCA_WCN7850: + case QCA_QCC2072: if (qcadev && qcadev->bdaddr_property_broken) hci_set_quirk(hdev, HCI_QUIRK_BDADDR_PROPERTY_BROKEN); @@ -2016,6 +2026,7 @@ static int qca_setup(struct hci_uart *hu) case QCA_WCN6750: case QCA_WCN6855: case QCA_WCN7850: + case QCA_QCC2072: break; default: @@ -2169,6 +2180,12 @@ static const struct qca_device_data qca_soc_data_wcn3998 __maybe_unused = { .num_vregs = 4, }; +static const struct qca_device_data qca_soc_data_qcc2072 __maybe_unused = { + .soc_type = QCA_QCC2072, + .num_vregs = 0, + .capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES, +}; + static const struct qca_device_data qca_soc_data_wcn6750 __maybe_unused = { .soc_type = QCA_WCN6750, .vregs = (struct qca_vreg []) { @@ -2271,6 +2288,7 @@ static void qca_power_off(struct hci_uart *hu) case QCA_WCN6750: case QCA_WCN6855: + case QCA_QCC2072: gpiod_set_value_cansleep(qcadev->bt_en, 0); msleep(100); qca_regulator_disable(qcadev); @@ -2417,6 +2435,7 @@ static int qca_serdev_probe(struct serdev_device *serdev) qcadev->btsoc_type = QCA_ROME; switch (qcadev->btsoc_type) { + case QCA_QCC2072: case QCA_QCA6390: case QCA_WCN3950: case QCA_WCN3988: @@ -2445,6 +2464,7 @@ static int qca_serdev_probe(struct serdev_device *serdev) case QCA_WCN6750: case QCA_WCN6855: case QCA_WCN7850: + case QCA_QCC2072: if (!device_property_present(&serdev->dev, "enable-gpios")) { /* * Backward compatibility with old DT sources. If the @@ -2487,6 +2507,7 @@ static int qca_serdev_probe(struct serdev_device *serdev) if (!qcadev->bt_en && (data->soc_type == QCA_WCN6750 || data->soc_type == QCA_WCN6855 || + data->soc_type == QCA_QCC2072 || data->soc_type == QCA_WCN7850)) power_ctrl_enabled = false; @@ -2495,6 +2516,7 @@ static int qca_serdev_probe(struct serdev_device *serdev) if (IS_ERR(qcadev->sw_ctrl) && (data->soc_type == QCA_WCN6750 || data->soc_type == QCA_WCN6855 || + data->soc_type == QCA_QCC2072 || data->soc_type == QCA_WCN7850)) { dev_err(&serdev->dev, "failed to acquire SW_CTRL gpio\n"); return PTR_ERR(qcadev->sw_ctrl); @@ -2573,6 +2595,7 @@ static void qca_serdev_remove(struct serdev_device *serdev) struct qca_power *power = qcadev->bt_power; switch (qcadev->btsoc_type) { + case QCA_QCC2072: case QCA_WCN3988: case QCA_WCN3990: case QCA_WCN3991: @@ -2782,6 +2805,7 @@ static const struct of_device_id qca_bluetooth_of_match[] = { { .compatible = "qcom,wcn6750-bt", .data = &qca_soc_data_wcn6750}, { .compatible = "qcom,wcn6855-bt", .data = &qca_soc_data_wcn6855}, { .compatible = "qcom,wcn7850-bt", .data = &qca_soc_data_wcn7850}, + { .compatible = "qcom,qcc2072-bt", .data = &qca_soc_data_qcc2072}, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, qca_bluetooth_of_match); From 8549859c11ab2a780ade9a93ef5d0f829625cae4 Mon Sep 17 00:00:00 2001 From: Yepuri Siddu Date: Mon, 8 Jun 2026 12:39:25 +0530 Subject: [PATCH 10/16] FROMLIST: arm64: dts: qcom: Add M.2 QCC2072 support on qcs6490-rb3gen2 industrial mezzanine Add DTS support for M.2 QCC2072 on Qualcomm qcs6490-rb3gen2 industrial mezzanine board. Link: https://lore.kernel.org/all/20260529180234.3373056-1-yepuri.siddu@oss.qualcomm.com/ Signed-off-by: Yepuri Siddu --- arch/arm64/boot/dts/qcom/Makefile | 2 + ...3gen2-industrial-mezzanine-m2-cologne.dtso | 110 ++++++++++++++++++ .../qcs6490-rb3gen2-industrial-mezzanine.dtso | 4 + 3 files changed, 116 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-industrial-mezzanine-m2-cologne.dtso diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 6f33c4e2f09c3..28eccecea5dfe 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -179,11 +179,13 @@ dtb-$(CONFIG_ARCH_QCOM) += qcs6490-rb3gen2.dtb qcs6490-rb3gen2-vision-mezzanine-dtbs := qcs6490-rb3gen2.dtb qcs6490-rb3gen2-vision-mezzanine.dtbo qcs6490-rb3gen2-industrial-mezzanine-dtbs := qcs6490-rb3gen2.dtb qcs6490-rb3gen2-industrial-mezzanine.dtbo +qcs6490-rb3gen2-industrial-mezzanine-m2-cologne-dtbs := qcs6490-rb3gen2.dtb qcs6490-rb3gen2-industrial-mezzanine.dtbo qcs6490-rb3gen2-industrial-mezzanine-m2-cologne.dtbo dtb-$(CONFIG_ARCH_QCOM) += qcs6490-rb3gen2-industrial-mezzanine.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs6490-rb3gen2-vision-mezzanine.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs6490-thundercomm-minipc-g1iot.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs6490-thundercomm-rubikpi3.dtb +dtb-$(CONFIG_ARCH_QCOM) += qcs6490-rb3gen2-industrial-mezzanine-m2-cologne.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs8300-ride.dtb qcs8300-ride-el2-dtbs := qcs8300-ride.dtb monaco-el2.dtbo diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-industrial-mezzanine-m2-cologne.dtso b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-industrial-mezzanine-m2-cologne.dtso new file mode 100644 index 0000000000000..905a40f4b938f --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-industrial-mezzanine-m2-cologne.dtso @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2026, Qualcomm Innovation Center, Inc. All rights reserved. +*/ + +/dts-v1/; +/plugin/; +#include + +&tlmm { + qup_uart4_sleep_cts: qup-uart4-sleep-cts-state { + pins = "gpio16"; + function = "gpio"; + /* + * Configure a bias-bus-hold on CTS to lower power + * usage when Bluetooth is turned off. Bus hold will + * maintain a low power state regardless of whether + * the Bluetooth module drives the pin in either + * direction or leaves the pin fully unpowered. + */ + bias-bus-hold; + }; + + qup_uart4_sleep_rts: qup-uart4-sleep-rts-state { + pins = "gpio17"; + function = "gpio"; + /* + * Configure pull-down on RTS. As RTS is active low + * signal, pull it low to indicate the BT SoC that it + * can wakeup the system anytime from suspend state by + * pulling RX low (by sending wakeup bytes). + */ + bias-pull-down; + }; + + qup_uart4_sleep_rx: qup-uart4-sleep-rx-state { + pins = "gpio19"; + function = "gpio"; + /* + * Configure a pull-up on RX. This is needed to avoid + * garbage data when the TX pin of the Bluetooth module + * is floating which may cause spurious wakeups. + */ + bias-pull-up; + }; + + qup_uart4_sleep_tx: qup-uart4-sleep-tx-state { + pins = "gpio18"; + function = "gpio"; + /* + * Configure pull-up on TX when it isn't actively driven + * to prevent BT SoC from receiving garbage during sleep. + */ + bias-pull-up; + }; + + sw_ctrl: sw-ctrl-state { + pins = "gpio86"; + function = "gpio"; + bias-pull-down; + }; +}; + +&qup_uart4_cts { + /* + * Configure a bias-bus-hold on CTS to lower power + * usage when Bluetooth is turned off. Bus hold will + * maintain a low power state regardless of whether + * the Bluetooth module drives the pin in either + * direction or leaves the pin fully unpowered. + */ + bias-bus-hold; +}; + +&qup_uart4_rts { + /* We'll drive RTS, so no pull */ + drive-strength = <2>; + bias-disable; +}; + +&qup_uart4_rx { + /* + * Configure a pull-up on RX. This is needed to avoid + * garbage data when the TX pin of the Bluetooth module is + * in tri-state (module powered off or not driving the + * signal yet). + */ + bias-pull-up; +}; + +&qup_uart4_tx { + /* We'll drive TX, so no pull */ + drive-strength = <2>; + bias-disable; +}; + +&uart4 { + status = "okay"; + /delete-property/ interrupts; + interrupts-extended = <&intc GIC_SPI 605 IRQ_TYPE_LEVEL_HIGH>, + <&tlmm 19 IRQ_TYPE_EDGE_FALLING>; + pinctrl-names = "default", "sleep"; + pinctrl-1 = <&qup_uart4_sleep_cts>, <&qup_uart4_sleep_rts>, + <&qup_uart4_sleep_tx>, <&qup_uart4_sleep_rx>; + + bluetooth: bluetooth { + compatible = "qcom,qcc2072-bt"; + max-speed = <3200000>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-industrial-mezzanine.dtso b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-industrial-mezzanine.dtso index 83908db335afa..c96c7f52ea7a0 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-industrial-mezzanine.dtso +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-industrial-mezzanine.dtso @@ -288,3 +288,7 @@ &wifi { status = "disabled"; }; + +&uart7 { + status = "disabled"; +}; From 816f79aee281312db4e443c6065194f3625267ff Mon Sep 17 00:00:00 2001 From: Yepuri Siddu Date: Mon, 8 Jun 2026 12:41:26 +0530 Subject: [PATCH 11/16] FROMLIST: Bluetooth: qca: combine NVM and calibration data for QCC2072 QCC2072 requires the NVM and calibration data to be delivered to the controller bundled together in an outer TLV of type 4. After loading the NVM file, load the calibration file (qca/ornbcscal.bin) and combine both into a single buffer with the outer TLV header before passing it to qca_tlv_check_data(). The outer TLV header encodes the combined payload length in the high 24 bits and type 4 in the low 8 bits of the type_len field. If the calibration file is unavailable, fall back to downloading the NVM alone. Link: https://lore.kernel.org/all/20260529180431.3373856-1-yepuri.siddu@oss.qualcomm.com/ Signed-off-by: Yepuri Siddu --- drivers/bluetooth/btqca.c | 47 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c index 8b2ad10ec2d92..ae3f6e7d8ea95 100644 --- a/drivers/bluetooth/btqca.c +++ b/drivers/bluetooth/btqca.c @@ -614,6 +614,53 @@ static int qca_download_firmware(struct hci_dev *hdev, memcpy(data, fw->data, size); release_firmware(fw); + /* For QCC2072, combine the NVM (type 2) with the calibration file + * into a single TLV of outer type 4. + */ + if (soc_type == QCA_QCC2072 && config->type == TLV_TYPE_NVM) { + const struct firmware *calib_fw = NULL; + char calib_name[32]; + u8 *combined_data = NULL; + size_t inner_len, combined_size; + struct tlv_type_hdr *outer_hdr; + int err; + + snprintf(calib_name, sizeof(calib_name), + "qca/ornbcscal%02x.bin", rom_ver); + err = request_firmware(&calib_fw, calib_name, &hdev->dev); + if (err) { + bt_dev_err(hdev, "QCA Failed to request file: %s (%d)", + calib_name, err); + goto skip_combination; + } + + bt_dev_info(hdev, "QCA Downloading %s", calib_name); + + inner_len = size + calib_fw->size; + combined_size = sizeof(*outer_hdr) + inner_len; + combined_data = vmalloc(combined_size); + if (!combined_data) { + bt_dev_warn(hdev, + "QCA Failed to allocate memory for file: %s", + calib_name); + release_firmware(calib_fw); + goto skip_combination; + } + + outer_hdr = (struct tlv_type_hdr *)combined_data; + /* high 24 bits = payload length, low 8 bits = type */ + outer_hdr->type_len = cpu_to_le32((inner_len << 8) | 4); + memcpy(combined_data + sizeof(*outer_hdr), data, size); + memcpy(combined_data + sizeof(*outer_hdr) + size, + calib_fw->data, calib_fw->size); + release_firmware(calib_fw); + vfree(data); + data = combined_data; + size = combined_size; +skip_combination: + ; + } + ret = qca_tlv_check_data(hdev, config, data, size, soc_type); if (ret) goto out; From 3a884519b83398c6c9c47dcf06463ad78ec9099c Mon Sep 17 00:00:00 2001 From: Krishna Chaitanya Chundru Date: Mon, 22 Jun 2026 11:34:44 +0530 Subject: [PATCH 12/16] WORKAROUND: arch: arm64: qcom: glymur-crd: Disable PCIe6 instance On compute targets, PCIe is dependent on the UEFI. In UEFI, when a PCIe link-up fails on a given root port, the default behavior is to power down that root port. The power-down sequence disables the PHY, removes all clock votes, and drops the Interconnect Bandwidth (ICB) votes that were applied in UEFI for that PCIe controller. The HLOS PCIe driver when probes the PCIe6 root port, but probe fails because the PHY is already powered down and there is no PHY bring-up sequence in HLOS for any controller. Since PCIe probe fails, the Interconnect driver's sync_state callback never gets invoked. As a result, the max boot votes applied to other peripherals are never released or reduced, keeping the system stuck at max bandwidth votes and causing the sync state errors observed, this also blocks XO shutdown. Fix this temporarly, by disabling pcie6 now as modem is not functional in this release. we will revert this after finding proper fix. Signed-off-by: Krishna Chaitanya Chundru --- arch/arm64/boot/dts/qcom/glymur-crd.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/glymur-crd.dtsi b/arch/arm64/boot/dts/qcom/glymur-crd.dtsi index e784b538f42e1..2a507d1692232 100644 --- a/arch/arm64/boot/dts/qcom/glymur-crd.dtsi +++ b/arch/arm64/boot/dts/qcom/glymur-crd.dtsi @@ -522,14 +522,14 @@ pinctrl-0 = <&pcie6_default>; pinctrl-names = "default"; - status = "okay"; + status = "disabled"; }; &pcie6_phy { vdda-phy-supply = <&vreg_l1c_e1_0p82>; vdda-pll-supply = <&vreg_l4f_e1_1p08>; - status = "okay"; + status = "disabled"; }; &pcie6_port0 { From a2ced8808906bb574def108940af56addd80b53f Mon Sep 17 00:00:00 2001 From: Prakash Gupta Date: Tue, 14 Jul 2026 15:57:00 +0530 Subject: [PATCH 13/16] WORKAROUND: iommu/arm-smmu: Work around Qualcomm SMMU-500 TLBIVAL granule issue Qualcomm SMMU-500 has an issue with TLBIVA/TLBIVAL where only the base-page-size entry at the base IOVA is invalidated, leaving stale TLB entries for the rest of the range. This causes use-after-free: after dma_free_coherent() unmaps a large buffer, the device can still access freed physical memory through stale TLB entries. On FastRPC workloads this manifests as ADSP crashes when the ELF loader writes to a freed PA that has been reallocated. Force the TLB invalidation step granule to the minimum page size for all Qualcomm SMMU-500 domains, ensuring each page in the range is individually invalidated. The minimum page size from pgsize_bitmap is used rather than hardcoded 4K to correctly handle 16K and 64K granule configurations. This increases the number of TLB invalidation operations for large ranges, but correctness takes precedence. Signed-off-by: Prakash Gupta Signed-off-by: Sibi Sankar --- drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 9 +++++++++ drivers/iommu/arm/arm-smmu/arm-smmu.c | 10 ++++++++++ drivers/iommu/arm/arm-smmu/arm-smmu.h | 1 + 3 files changed, 20 insertions(+) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c index e2c914fccd6fc..4a98e58159037 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c @@ -438,6 +438,15 @@ static int qcom_smmu_init_context(struct arm_smmu_domain *smmu_domain, int cbndx = smmu_domain->cfg.cbndx; smmu_domain->cfg.flush_walk_prefer_tlbiasid = true; + /* + * Qualcomm SMMU-500 has an issue with TLBIVA/TLBIVAL where only + * the base-page-size entry at the base IOVA is invalidated. Glymur + * SoCs boot by default at EL2 and is the currently the only SoC + * affected by it. Force the minimum page granule to ensure the full + * range is covered. + */ + if (of_device_is_compatible(smmu->dev->of_node, "qcom,glymur-smmu-500")) + smmu_domain->cfg.force_min_tlbival_granule = true; client_match = qsmmu->data->client_match; diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c index 0bd21d206eb3e..75657c74f2910 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -286,6 +286,16 @@ static void arm_smmu_tlb_inv_range_s1(unsigned long iova, size_t size, struct arm_smmu_cfg *cfg = &smmu_domain->cfg; int idx = cfg->cbndx; + /* + * Override the step granule with the minimum supported page size. + * Placed here (rather than in tlb_add_page alone) to cover both + * TLBIVAL and TLBIVA paths. + */ + if (cfg->force_min_tlbival_granule) { + WARN_ON_ONCE(!smmu_domain->domain.pgsize_bitmap); + granule = 1UL << __ffs(smmu_domain->domain.pgsize_bitmap); + } + if (smmu->features & ARM_SMMU_FEAT_COHERENT_WALK) wmb(); diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h index 26d2e33cd328b..85d1f2d7ec506 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h @@ -359,6 +359,7 @@ struct arm_smmu_cfg { enum arm_smmu_cbar_type cbar; enum arm_smmu_context_fmt fmt; bool flush_walk_prefer_tlbiasid; + bool force_min_tlbival_granule; }; #define ARM_SMMU_INVALID_IRPTNDX 0xff From 0d39a9d612b3fe15cb3972ee7678556548b915f5 Mon Sep 17 00:00:00 2001 From: Ziyue Zhang Date: Fri, 3 Jul 2026 17:42:22 +0800 Subject: [PATCH 14/16] WORKAROUND: phy: qcom: qmp-pcie: Add qref and refgen regulator vote for QCS8300 and SA8775p PHY Add a new sa8775p_qmp_phy_vreg_l that includes vdda-phy, vdda-pll, vdda-qref, vdda-refgen and refgen supplies, and use it for QCS8300 and SA8775p PCIe PHY configurations. This avoids modifying sm8550_qmp_phy_vreg_l and breaking SM8550 and SM8650. Note that due to a hardware issue, QREF actually depends on refgen3 rather than refgen2 as documented; refgen3 is therefore voted manually via the refgen supply as a workaround. Fixes: a05b6d5135ec ("phy: qcom-qmp-pcie: add support for sa8775p") Fixes: ebf198f17b5a ("phy: qcom-qmp-pcie: add dual lane PHY support for QCS8300") Link: http://shc-kerarch-hyd:8080/kernel_archive/20260703094224.990231-3-ziyue.zhang@oss.qualcomm.com/ Signed-off-by: Ziyue Zhang --- drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c index 77b60bd32cd9e..9181ad520dbe2 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c @@ -3492,6 +3492,10 @@ static const char * const sa8775p_qmp_phy_vreg_l[] = { "vdda-phy", "vdda-pll", "vdda-qref", "vdda-refgen", }; +static const char * const sa8775p_qmp_phy_vreg_l[] = { + "vdda-phy", "vdda-pll", "vdda-qref", "vdda-refgen", "refgen", +}; + /* list of resets */ static const char * const ipq8074_pciephy_reset_l[] = { "phy", "common", From ab982c1d44dcd87fc530c34cb99efa6bbe9de1d5 Mon Sep 17 00:00:00 2001 From: Ziyue Zhang Date: Fri, 3 Jul 2026 17:42:23 +0800 Subject: [PATCH 15/16] WORKAROUND: arm64: dts: qcom: qcs8300: Add qref and refgen supply for PCIe PHYs The QMP PCIe PHYs on QCS8300 require dedicated qref and refgen voltage supplies for stable operation. Without these supplies, the system may occasionally crash. Add vdda-qref-supply and vdda-refgen-supply in the board files (QCS8300-RIDE, Monaco-EVK and Monaco-Arduino-Monza), and add refgen-supply in the SoC DTSI (monaco.dtsi) since refgen is an on-chip regulator shared across boards. The refgen supply votes for refgen3 as a workaround for a hardware issue where both QREF and the PCIe PHY are expected to depend on refgen2, but QREF actually depends on refgen3. Fixes: 33967eadb215 ("arm64: dts: qcom: qcs8300-ride: enable pcie0 interface") Fixes: cdb613a84527 ("arm64: dts: qcom: qcs8300-ride: enable pcie1 interface") Fixes: 41e2424651f7 ("arm64: dts: qcom: monaco-evk: Enable PCIe0 and PCIe1.") Fixes: 5238f4e7169f ("arm64: dts: qcom: Add Monaco Monza SoM") Link: http://shc-kerarch-hyd:8080/kernel_archive/20260703094224.990231-4-ziyue.zhang@oss.qualcomm.com/ Signed-off-by: Ziyue Zhang --- arch/arm64/boot/dts/qcom/monaco-arduino-monza.dts | 10 ++++++++++ arch/arm64/boot/dts/qcom/monaco-evk.dts | 4 ++++ arch/arm64/boot/dts/qcom/monaco.dtsi | 4 ++++ arch/arm64/boot/dts/qcom/qcs8300-ride.dts | 8 ++++---- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/monaco-arduino-monza.dts b/arch/arm64/boot/dts/qcom/monaco-arduino-monza.dts index 379b796f261f4..809e45dca1064 100644 --- a/arch/arm64/boot/dts/qcom/monaco-arduino-monza.dts +++ b/arch/arm64/boot/dts/qcom/monaco-arduino-monza.dts @@ -475,3 +475,13 @@ status = "okay"; }; + +&pcie0_phy { + vdda-qref-supply = <&vreg_l4a>; + vdda-refgen-supply = <&vreg_l7a>; +}; + +&pcie1_phy { + vdda-qref-supply = <&vreg_l4a>; + vdda-refgen-supply = <&vreg_l7a>; +}; diff --git a/arch/arm64/boot/dts/qcom/monaco-evk.dts b/arch/arm64/boot/dts/qcom/monaco-evk.dts index 9d17ef7d2caf1..c1f63a4ee2438 100644 --- a/arch/arm64/boot/dts/qcom/monaco-evk.dts +++ b/arch/arm64/boot/dts/qcom/monaco-evk.dts @@ -623,6 +623,8 @@ &pcie0_phy { vdda-phy-supply = <&vreg_l6a>; vdda-pll-supply = <&vreg_l5a>; + vdda-qref-supply = <&vreg_l4a>; + vdda-refgen-supply = <&vreg_l7a>; status = "okay"; }; @@ -637,6 +639,8 @@ &pcie1_phy { vdda-phy-supply = <&vreg_l6a>; vdda-pll-supply = <&vreg_l5a>; + vdda-qref-supply = <&vreg_l4a>; + vdda-refgen-supply = <&vreg_l7a>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi index e4c8466f941bd..cd320a24b0cf7 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi @@ -2452,6 +2452,8 @@ #phy-cells = <0>; + refgen-supply = <&refgen>; + status = "disabled"; }; @@ -2643,6 +2645,8 @@ #phy-cells = <0>; + refgen-supply = <&refgen>; + status = "disabled"; }; diff --git a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts index 25be329a98829..2a05845bffb70 100644 --- a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts +++ b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts @@ -638,8 +638,8 @@ &pcie0_phy { vdda-phy-supply = <&vreg_l6a>; vdda-pll-supply = <&vreg_l5a>; - vdda-qref-supply = <&vreg_l7a>; - vdda-refgen-supply = <&refgen>; + vdda-qref-supply = <&vreg_l4a>; + vdda-refgen-supply = <&vreg_l7a>; status = "okay"; }; @@ -659,8 +659,8 @@ &pcie1_phy { vdda-phy-supply = <&vreg_l6a>; vdda-pll-supply = <&vreg_l5a>; - vdda-qref-supply = <&vreg_l7a>; - vdda-refgen-supply = <&refgen>; + vdda-qref-supply = <&vreg_l4a>; + vdda-refgen-supply = <&vreg_l7a>; status = "okay"; }; From 724d4dc4e80a7c4c3467f310aa462bb7a94cc655 Mon Sep 17 00:00:00 2001 From: Ziyue Zhang Date: Fri, 3 Jul 2026 17:42:24 +0800 Subject: [PATCH 16/16] WORKAROUND: arm64: dts: qcom: sa8775p: Add qref and refgen supply for PCIe PHYs The QMP PCIe PHYs on SA8775p require dedicated qref and refgen voltage supplies for stable operation. Without these supplies, the system may occasionally crash. Add vdda-qref-supply and vdda-refgen-supply in the board files (Lemans-EVK, Lemans-RIDE, QCS9100-RIDE, QCS9100-RIDE-R3, SA8775P-RIDE and SA8775P-RIDE-R3), and add refgen-supply in the SoC DTSI (lemans.dtsi) since refgen is an on-chip regulator shared across boards. The refgen supply votes for refgen3 as a workaround for a hardware errata (see cover letter). Fixes: 94d7d37f6ac3 ("arm64: dts: qcom: lemans-evk: Enable PCIe support") Fixes: 76326da895b8 ("arm64: dts: qcom: lemans: Refactor ride/ride-r3 boards based on daughter cards") Link: http://shc-kerarch-hyd:8080/kernel_archive/20260703094224.990231-5-ziyue.zhang@oss.qualcomm.com/ Signed-off-by: Ziyue Zhang --- arch/arm64/boot/dts/qcom/lemans-evk.dts | 4 ++++ arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi | 4 ++++ arch/arm64/boot/dts/qcom/lemans.dtsi | 4 ++++ arch/arm64/boot/dts/qcom/qcs9100-ride-r3.dts | 8 ++++++++ arch/arm64/boot/dts/qcom/qcs9100-ride.dts | 8 ++++++++ arch/arm64/boot/dts/qcom/sa8775p-ride-r3.dts | 8 ++++++++ arch/arm64/boot/dts/qcom/sa8775p-ride.dts | 8 ++++++++ 7 files changed, 44 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/lemans-evk.dts b/arch/arm64/boot/dts/qcom/lemans-evk.dts index 34dfc8d22b6a5..eddad621f0040 100644 --- a/arch/arm64/boot/dts/qcom/lemans-evk.dts +++ b/arch/arm64/boot/dts/qcom/lemans-evk.dts @@ -721,6 +721,8 @@ &pcie0_phy { vdda-phy-supply = <&vreg_l5a>; vdda-pll-supply = <&vreg_l1c>; + vdda-qref-supply = <&vreg_l4a>; + vdda-refgen-supply = <&vreg_l7a>; status = "okay"; }; @@ -738,6 +740,8 @@ &pcie1_phy { vdda-phy-supply = <&vreg_l5a>; vdda-pll-supply = <&vreg_l1c>; + vdda-qref-supply = <&vreg_l4a>; + vdda-refgen-supply = <&vreg_l7a>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi b/arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi index 40f88498999bd..8dc4a5f461e9e 100644 --- a/arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi @@ -983,6 +983,8 @@ &pcie0_phy { vdda-phy-supply = <&vreg_l5a>; vdda-pll-supply = <&vreg_l1c>; + vdda-qref-supply = <&vreg_l4a>; + vdda-refgen-supply = <&vreg_l7a>; status = "okay"; }; @@ -990,6 +992,8 @@ &pcie1_phy { vdda-phy-supply = <&vreg_l5a>; vdda-pll-supply = <&vreg_l1c>; + vdda-qref-supply = <&vreg_l4a>; + vdda-refgen-supply = <&vreg_l7a>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi index d0fc6ccabeb3d..e1da5226c313f 100644 --- a/arch/arm64/boot/dts/qcom/lemans.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans.dtsi @@ -2864,6 +2864,8 @@ #phy-cells = <0>; + refgen-supply = <&refgen>; + status = "disabled"; }; @@ -3035,6 +3037,8 @@ #phy-cells = <0>; + refgen-supply = <&refgen>; + status = "disabled"; }; diff --git a/arch/arm64/boot/dts/qcom/qcs9100-ride-r3.dts b/arch/arm64/boot/dts/qcom/qcs9100-ride-r3.dts index 7fc2de0d3d5e2..1b6a4f9cb8f7e 100644 --- a/arch/arm64/boot/dts/qcom/qcs9100-ride-r3.dts +++ b/arch/arm64/boot/dts/qcom/qcs9100-ride-r3.dts @@ -14,3 +14,11 @@ model = "Qualcomm Technologies, Inc. Lemans Ride Rev3"; compatible = "qcom,qcs9100-ride-r3", "qcom,qcs9100", "qcom,sa8775p"; }; + +&pcie0_phy { + vdda-refgen-supply = <&vreg_l7a>; +}; + +&pcie1_phy { + vdda-refgen-supply = <&vreg_l7a>; +}; diff --git a/arch/arm64/boot/dts/qcom/qcs9100-ride.dts b/arch/arm64/boot/dts/qcom/qcs9100-ride.dts index b0c5fdde56aea..cc15025fdbc1a 100644 --- a/arch/arm64/boot/dts/qcom/qcs9100-ride.dts +++ b/arch/arm64/boot/dts/qcom/qcs9100-ride.dts @@ -14,3 +14,11 @@ model = "Qualcomm Technologies, Inc. Lemans Ride"; compatible = "qcom,qcs9100-ride", "qcom,qcs9100", "qcom,sa8775p"; }; + +&pcie0_phy { + vdda-refgen-supply = <&vreg_l7a>; +}; + +&pcie1_phy { + vdda-refgen-supply = <&vreg_l7a>; +}; diff --git a/arch/arm64/boot/dts/qcom/sa8775p-ride-r3.dts b/arch/arm64/boot/dts/qcom/sa8775p-ride-r3.dts index b25f0b2c94104..333de16b65829 100644 --- a/arch/arm64/boot/dts/qcom/sa8775p-ride-r3.dts +++ b/arch/arm64/boot/dts/qcom/sa8775p-ride-r3.dts @@ -15,3 +15,11 @@ model = "Qualcomm SA8775P Ride Rev3"; compatible = "qcom,sa8775p-ride-r3", "qcom,sa8775p"; }; + +&pcie0_phy { + vdda-refgen-supply = <&vreg_l7a>; +}; + +&pcie1_phy { + vdda-refgen-supply = <&vreg_l7a>; +}; diff --git a/arch/arm64/boot/dts/qcom/sa8775p-ride.dts b/arch/arm64/boot/dts/qcom/sa8775p-ride.dts index 2d9028cd60be4..b3bd343d34436 100644 --- a/arch/arm64/boot/dts/qcom/sa8775p-ride.dts +++ b/arch/arm64/boot/dts/qcom/sa8775p-ride.dts @@ -15,3 +15,11 @@ model = "Qualcomm SA8775P Ride"; compatible = "qcom,sa8775p-ride", "qcom,sa8775p"; }; + +&pcie0_phy { + vdda-refgen-supply = <&vreg_l7a>; +}; + +&pcie1_phy { + vdda-refgen-supply = <&vreg_l7a>; +};