From 0aa10e891e6a9ff3221babd11bcf67ad57fbe2bd Mon Sep 17 00:00:00 2001 From: Wojciech Slenska Date: Thu, 9 Oct 2025 11:07:17 +0200 Subject: [PATCH 01/30] UPSTREAM: arm64: dts: qcom: qcm2290: Fix uart3 QUP interconnect The config_noc interconnect should use SLAVE_QUP_0. Signed-off-by: Wojciech Slenska Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251009090718.32503-1-wojciech.slenska@gmail.com Signed-off-by: Bjorn Andersson (cherry picked from commit cdf9756037d74dee865570e808e4bded7402c662) Signed-off-by: Ricardo Salveti --- arch/arm64/boot/dts/qcom/qcm2290.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/qcm2290.dtsi b/arch/arm64/boot/dts/qcom/qcm2290.dtsi index d947418302674..a4239fc6b71cb 100644 --- a/arch/arm64/boot/dts/qcom/qcm2290.dtsi +++ b/arch/arm64/boot/dts/qcom/qcm2290.dtsi @@ -1302,7 +1302,7 @@ interconnects = <&qup_virt MASTER_QUP_CORE_0 RPM_ALWAYS_TAG &qup_virt SLAVE_QUP_CORE_0 RPM_ALWAYS_TAG>, <&bimc MASTER_APPSS_PROC RPM_ALWAYS_TAG - &config_noc MASTER_APPSS_PROC RPM_ALWAYS_TAG>; + &config_noc SLAVE_QUP_0 RPM_ALWAYS_TAG>; interconnect-names = "qup-core", "qup-config"; status = "disabled"; From bd7b5f41a96e651ccea446dd2e35b4336a0014a7 Mon Sep 17 00:00:00 2001 From: Wojciech Slenska Date: Thu, 9 Oct 2025 11:08:58 +0200 Subject: [PATCH 02/30] UPSTREAM: arm64: dts: qcom: qcm2290: Add uart1 and uart5 nodes Add nodes to support uart1 and uart5. Signed-off-by: Wojciech Slenska Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251009090858.32911-1-wojciech.slenska@gmail.com Signed-off-by: Bjorn Andersson (cherry picked from commit 89e4902ac7262f368dfb03afd76d71e6bbb4424d) Signed-off-by: Ricardo Salveti --- arch/arm64/boot/dts/qcom/qcm2290.dtsi | 48 +++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcm2290.dtsi b/arch/arm64/boot/dts/qcom/qcm2290.dtsi index a4239fc6b71cb..d5af1e5ac05d5 100644 --- a/arch/arm64/boot/dts/qcom/qcm2290.dtsi +++ b/arch/arm64/boot/dts/qcom/qcm2290.dtsi @@ -552,6 +552,13 @@ bias-disable; }; + qup_uart1_default: qup-uart1-default-state { + pins = "gpio4", "gpio5", "gpio69", "gpio70"; + function = "qup1"; + drive-strength = <2>; + bias-disable; + }; + qup_uart3_default: qup-uart3-default-state { pins = "gpio8", "gpio9", "gpio10", "gpio11"; function = "qup3"; @@ -566,6 +573,13 @@ bias-disable; }; + qup_uart5_default: qup-uart5-default-state { + pins = "gpio14", "gpio15", "gpio16", "gpio17"; + function = "qup5"; + drive-strength = <2>; + bias-disable; + }; + cci0_default: cci0-default-state { pins = "gpio22", "gpio23"; function = "cci_i2c"; @@ -1197,6 +1211,23 @@ status = "disabled"; }; + uart1: serial@4a84000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x04a84000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP0_S1_CLK>; + clock-names = "se"; + pinctrl-0 = <&qup_uart1_default>; + pinctrl-names = "default"; + interconnects = <&qup_virt MASTER_QUP_CORE_0 RPM_ALWAYS_TAG + &qup_virt SLAVE_QUP_CORE_0 RPM_ALWAYS_TAG>, + <&bimc MASTER_APPSS_PROC RPM_ALWAYS_TAG + &config_noc SLAVE_QUP_0 RPM_ALWAYS_TAG>; + interconnect-names = "qup-core", + "qup-config"; + status = "disabled"; + }; + i2c2: i2c@4a88000 { compatible = "qcom,geni-i2c"; reg = <0x0 0x04a88000 0x0 0x4000>; @@ -1418,6 +1449,23 @@ #size-cells = <0>; status = "disabled"; }; + + uart5: serial@4a94000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x04a94000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP0_S5_CLK>; + clock-names = "se"; + pinctrl-0 = <&qup_uart5_default>; + pinctrl-names = "default"; + interconnects = <&qup_virt MASTER_QUP_CORE_0 RPM_ALWAYS_TAG + &qup_virt SLAVE_QUP_CORE_0 RPM_ALWAYS_TAG>, + <&bimc MASTER_APPSS_PROC RPM_ALWAYS_TAG + &config_noc SLAVE_QUP_0 RPM_ALWAYS_TAG>; + interconnect-names = "qup-core", + "qup-config"; + status = "disabled"; + }; }; usb: usb@4ef8800 { From 6f45867d6f1c10abfb9a9a25a4c9f8b36017df50 Mon Sep 17 00:00:00 2001 From: Riccardo Mereu Date: Thu, 20 Nov 2025 16:58:24 +0100 Subject: [PATCH 03/30] BACKPORT: arm64: dts: qcom: agatti: add uart2 node uart2 is used in Arduino UnoQ as an interface between microprocessor and microcontroller. Signed-off-by: Riccardo Mereu Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251120155825.121483-6-r.mereu.kernel@arduino.cc Signed-off-by: Bjorn Andersson (cherry picked from commit 925ac1f6ec75a773e0ec8b91673b647f6d456ccb) [rsalveti: applied to qcm2290.dtsi, as the rename to agatti.dtsi is not part of this branch] Signed-off-by: Ricardo Salveti --- arch/arm64/boot/dts/qcom/qcm2290.dtsi | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcm2290.dtsi b/arch/arm64/boot/dts/qcom/qcm2290.dtsi index d5af1e5ac05d5..5406286db8509 100644 --- a/arch/arm64/boot/dts/qcom/qcm2290.dtsi +++ b/arch/arm64/boot/dts/qcom/qcm2290.dtsi @@ -559,6 +559,13 @@ bias-disable; }; + qup_uart2_default: qup-uart2-default-state { + pins = "gpio6", "gpio7", "gpio71", "gpio80"; + function = "qup2"; + drive-strength = <2>; + bias-disable; + }; + qup_uart3_default: qup-uart3-default-state { pins = "gpio8", "gpio9", "gpio10", "gpio11"; function = "qup3"; @@ -1275,6 +1282,23 @@ status = "disabled"; }; + uart2: serial@4a88000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x04a88000 0x0 0x4000>; + interrupts = ; + clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>; + clock-names = "se"; + pinctrl-0 = <&qup_uart2_default>; + pinctrl-names = "default"; + interconnects = <&qup_virt MASTER_QUP_CORE_0 RPM_ALWAYS_TAG + &qup_virt SLAVE_QUP_CORE_0 RPM_ALWAYS_TAG>, + <&bimc MASTER_APPSS_PROC RPM_ALWAYS_TAG + &config_noc MASTER_APPSS_PROC RPM_ALWAYS_TAG>; + interconnect-names = "qup-core", + "qup-config"; + status = "disabled"; + }; + i2c3: i2c@4a8c000 { compatible = "qcom,geni-i2c"; reg = <0x0 0x04a8c000 0x0 0x4000>; From f1af01a15d5d994601aeb1084f7f2aa32b987ad7 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 28 Oct 2025 23:00:06 +0200 Subject: [PATCH 04/30] BACKPORT: arm64: dts: qcom: add gpu_zap_shader label Patching existing DT nodes based on full path is error prone and generally not recommended. Follow the pattern introduced in the last platforms, add gpu_zap_shader label to the ZAP node and use it in the board files. Only the qcm2290 part of the upstream commit is backported here, as the label is required by the Arduino UNO Q board DT. The remaining platforms are left untouched to avoid churn on boards that do not need it. Signed-off-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Reviewed-by: David Heidelberg Link: https://lore.kernel.org/r/20251028-dt-zap-shader-v1-7-7eccb823b986@oss.qualcomm.com Signed-off-by: Bjorn Andersson (cherry picked from commit 2377626fd216ebdf17294ac0cabc27614fff07d1) Signed-off-by: Ricardo Salveti --- arch/arm64/boot/dts/qcom/qcm2290.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/qcm2290.dtsi b/arch/arm64/boot/dts/qcom/qcm2290.dtsi index 5406286db8509..46bf9912ef916 100644 --- a/arch/arm64/boot/dts/qcom/qcm2290.dtsi +++ b/arch/arm64/boot/dts/qcom/qcm2290.dtsi @@ -1612,7 +1612,7 @@ status = "disabled"; - zap-shader { + gpu_zap_shader: zap-shader { memory-region = <&pil_gpu_mem>; }; From f3230c634fca44b098f6cfaa52cf478f2712d509 Mon Sep 17 00:00:00 2001 From: Alexey Klimov Date: Wed, 22 Oct 2025 07:06:41 +0100 Subject: [PATCH 05/30] UPSTREAM: arm64: dts: qcom: qcm2290: add APR and its services Add APR (asynchronous packet router) node and its associated services required to enable audio on QRB2210 RB1 board. Cc: Srinivas Kandagatla Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Signed-off-by: Alexey Klimov Link: https://lore.kernel.org/r/20251022-rb1_hdmi_audio-v3-1-0d38f777a547@linaro.org Signed-off-by: Bjorn Andersson (cherry picked from commit f8d21b5e4caa7a8e06cf6c08d85f6e992562a667) Signed-off-by: Ricardo Salveti --- arch/arm64/boot/dts/qcom/qcm2290.dtsi | 72 +++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcm2290.dtsi b/arch/arm64/boot/dts/qcom/qcm2290.dtsi index 46bf9912ef916..7f2588b609eb6 100644 --- a/arch/arm64/boot/dts/qcom/qcm2290.dtsi +++ b/arch/arm64/boot/dts/qcom/qcm2290.dtsi @@ -17,6 +17,8 @@ #include #include #include +#include +#include / { interrupt-parent = <&intc>; @@ -2157,6 +2159,76 @@ label = "lpass"; qcom,remote-pid = <2>; mboxes = <&apcs_glb 8>; + + apr { + compatible = "qcom,apr-v2"; + qcom,glink-channels = "apr_audio_svc"; + qcom,domain = ; + #address-cells = <1>; + #size-cells = <0>; + + service@3 { + reg = ; + compatible = "qcom,q6core"; + qcom,protection-domain = "avs/audio", + "msm/adsp/audio_pd"; + }; + + q6afe: service@4 { + compatible = "qcom,q6afe"; + reg = ; + qcom,protection-domain = "avs/audio", + "msm/adsp/audio_pd"; + q6afedai: dais { + compatible = "qcom,q6afe-dais"; + #address-cells = <1>; + #size-cells = <0>; + #sound-dai-cells = <1>; + }; + + q6afecc: clock-controller { + compatible = "qcom,q6afe-clocks"; + #clock-cells = <2>; + }; + }; + + q6asm: service@7 { + compatible = "qcom,q6asm"; + reg = ; + qcom,protection-domain = "avs/audio", + "msm/adsp/audio_pd"; + q6asmdai: dais { + compatible = "qcom,q6asm-dais"; + #address-cells = <1>; + #size-cells = <0>; + #sound-dai-cells = <1>; + iommus = <&apps_smmu 0x1c1 0x0>; + + dai@0 { + reg = ; + }; + + dai@1 { + reg = ; + }; + + dai@2 { + reg = ; + }; + }; + }; + + q6adm: service@8 { + compatible = "qcom,q6adm"; + reg = ; + qcom,protection-domain = "avs/audio", + "msm/adsp/audio_pd"; + q6routing: routing { + compatible = "qcom,q6adm-routing"; + #sound-dai-cells = <0>; + }; + }; + }; }; }; From 3a6acb88ab1651174009242d03cecac9d2a4bfae Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 13 Jan 2026 18:41:59 +0200 Subject: [PATCH 06/30] BACKPORT: arm64: dts: qcom: agatti: enable FastRPC on the ADSP On Agatti platform the ADSP provides FastRPC support. Add corresponding device node, in order to be able to utilize the DSP offload from the Linux side. Signed-off-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20260113-agatti-fastrpc-v2-1-b66870213f89@oss.qualcomm.com Signed-off-by: Bjorn Andersson (cherry picked from commit 851d5ae6003b6517fb641675c33d4b529765fe14) [rsalveti: applied to qcm2290.dtsi, as the rename to agatti.dtsi is not part of this branch] Signed-off-by: Ricardo Salveti --- arch/arm64/boot/dts/qcom/qcm2290.dtsi | 41 +++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcm2290.dtsi b/arch/arm64/boot/dts/qcom/qcm2290.dtsi index 7f2588b609eb6..e52dbd2fdaf70 100644 --- a/arch/arm64/boot/dts/qcom/qcm2290.dtsi +++ b/arch/arm64/boot/dts/qcom/qcm2290.dtsi @@ -2229,6 +2229,47 @@ }; }; }; + + fastrpc { + compatible = "qcom,fastrpc"; + qcom,glink-channels = "fastrpcglink-apps-dsp"; + label = "adsp"; + + qcom,non-secure-domain; + + #address-cells = <1>; + #size-cells = <0>; + + compute-cb@3 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <3>; + iommus = <&apps_smmu 0x1c3 0x0>; + }; + + compute-cb@4 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <4>; + iommus = <&apps_smmu 0x1c4 0x0>; + }; + + compute-cb@5 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <5>; + iommus = <&apps_smmu 0x1c5 0x0>; + }; + + compute-cb@6 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <6>; + iommus = <&apps_smmu 0x1c6 0x0>; + }; + + compute-cb@7 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <7>; + iommus = <&apps_smmu 0x1c7 0x0>; + }; + }; }; }; From fd2979343977dfbb4be9df3ccf9f366d5d0ddc62 Mon Sep 17 00:00:00 2001 From: Alexey Klimov Date: Tue, 7 Oct 2025 03:03:29 +0100 Subject: [PATCH 07/30] UPSTREAM: dt-bindings: pinctrl: qcom,sm6115-lpass-lpi: add QCM2290 compatible Add a compatible for the LPASS LPI pin controller on QCM2290. It seems to be compatible with sm6115 LPASS pinctrl. Cc: Konrad Dybcio Cc: Srinivas Kandagatla Acked-by: Rob Herring (Arm) Signed-off-by: Alexey Klimov Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20251007-rb1_hdmi_audio-v2-1-821b6a705e4c@linaro.org (cherry picked from commit f919466878611065afb0b79feb28969af766ef3f) Signed-off-by: Ricardo Salveti --- .../bindings/pinctrl/qcom,sm6115-lpass-lpi-pinctrl.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-lpass-lpi-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-lpass-lpi-pinctrl.yaml index f4cf2ce86fcd4..ec1cd684753ad 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-lpass-lpi-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-lpass-lpi-pinctrl.yaml @@ -16,7 +16,13 @@ description: properties: compatible: - const: qcom,sm6115-lpass-lpi-pinctrl + oneOf: + - enum: + - qcom,sm6115-lpass-lpi-pinctrl + - items: + - enum: + - qcom,qcm2290-lpass-lpi-pinctrl + - const: qcom,sm6115-lpass-lpi-pinctrl reg: items: From 4a50fb54438d772372723c586268d09ae254cd8e Mon Sep 17 00:00:00 2001 From: Alexey Klimov Date: Wed, 22 Oct 2025 07:06:42 +0100 Subject: [PATCH 08/30] UPSTREAM: arm64: dts: qcom: qcm2290: add LPASS LPI pin controller Add the Low Power Audio SubSystem Low Power Island (LPASS LPI) pin controller device node required for audio subsystem on Qualcomm QRB2210 RB1. QRB2210 is based on qcm2290 which is based on sm6115. While at this, also add description of lpi_i2s2 pins (active state) required for audio playback via HDMI/I2S. Cc: Srinivas Kandagatla Signed-off-by: Alexey Klimov Link: https://lore.kernel.org/r/20251022-rb1_hdmi_audio-v3-2-0d38f777a547@linaro.org Signed-off-by: Bjorn Andersson (cherry picked from commit 1fc30731562bb45e53e09d40fc69bc4364310b6e) Signed-off-by: Ricardo Salveti --- arch/arm64/boot/dts/qcom/qcm2290.dtsi | 38 +++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcm2290.dtsi b/arch/arm64/boot/dts/qcom/qcm2290.dtsi index e52dbd2fdaf70..3e08fde59cf1b 100644 --- a/arch/arm64/boot/dts/qcom/qcm2290.dtsi +++ b/arch/arm64/boot/dts/qcom/qcm2290.dtsi @@ -19,6 +19,7 @@ #include #include #include +#include / { interrupt-parent = <&intc>; @@ -694,6 +695,43 @@ }; }; + lpass_tlmm: pinctrl@a7c0000 { + compatible = "qcom,qcm2290-lpass-lpi-pinctrl", + "qcom,sm6115-lpass-lpi-pinctrl"; + reg = <0x0 0x0a7c0000 0x0 0x20000>, + <0x0 0x0a950000 0x0 0x10000>; + + clocks = <&q6afecc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>; + clock-names = "audio"; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&lpass_tlmm 0 0 19>; + + lpi_i2s2_active: lpi-i2s2-active-state { + sck-pins { + pins = "gpio10"; + function = "i2s2_clk"; + bias-disable; + drive-strength = <8>; + }; + + ws-pins { + pins = "gpio11"; + function = "i2s2_ws"; + bias-disable; + drive-strength = <8>; + }; + + data-pins { + pins = "gpio12"; + function = "i2s2_data"; + bias-disable; + drive-strength = <8>; + }; + }; + }; + gcc: clock-controller@1400000 { compatible = "qcom,gcc-qcm2290"; reg = <0x0 0x01400000 0x0 0x1f0000>; From e49dd169b2dac4138261c3206cc29d54dd9ac89b Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Thu, 7 May 2026 09:42:16 +0300 Subject: [PATCH 09/30] BACKPORT: arm64: dts: qcom: agatti: add higher OPP levels Add additional OPP entries for the Agatti platform to support higher operating frequencies as specified in the hardware documentation. Reviewed-by: Dmitry Baryshkov Signed-off-by: Dikshita Agarwal Link: https://lore.kernel.org/r/20260507-iris-ar50lt-v1-16-d22cccedc3e2@oss.qualcomm.com Signed-off-by: Bjorn Andersson (cherry picked from commit f8874bc5792134b7bdda9706e2a48e6285da3664) [rsalveti: applied to qcm2290.dtsi, as the rename to agatti.dtsi is not part of this branch] Signed-off-by: Ricardo Salveti --- arch/arm64/boot/dts/qcom/qcm2290.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qcm2290.dtsi b/arch/arm64/boot/dts/qcom/qcm2290.dtsi index 3e08fde59cf1b..280bc8a64ef02 100644 --- a/arch/arm64/boot/dts/qcom/qcm2290.dtsi +++ b/arch/arm64/boot/dts/qcom/qcm2290.dtsi @@ -2433,6 +2433,16 @@ opp-hz = /bits/ 64 <240000000>; required-opps = <&rpmpd_opp_svs>; }; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + required-opps = <&rpmpd_opp_svs_plus>; + }; + + opp-384000000 { + opp-hz = /bits/ 64 <384000000>; + required-opps = <&rpmpd_opp_nom>; + }; }; }; From 1bc3f6bb53d4c245f05af2fee3751123dfac4267 Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Sat, 18 Jul 2026 18:26:08 +0530 Subject: [PATCH 10/30] BACKPORT: dt-bindings: clock: qcom,qcm2290-dispcc: Add missing power-domains property Add the missing power-domains property to associate DISPCC with RPMPD_CX. This is to ensure the genpd performance state votes on the GDSC to get propagated to the CX rail and to avoid the rail under-voltage conditions. This change breaks ABI, as the power-domains property is marked as required. Fixes: 85cedb4e0c9d ("dt-bindings: clock: Add qualcomm QCM2290 DISPCC bindings") Reviewed-by: Krzysztof Kozlowski Signed-off-by: Imran Shaik Link: https://lore.kernel.org/r/20260718-shikra-dispcc-gpucc-v6-1-62703e05ef0f@oss.qualcomm.com Signed-off-by: Bjorn Andersson (cherry picked from commit 70ef527b483f6373c4b954e81bbb73f3bdc3184a) [rsalveti: keep the DSI1/sleep clocks already present in this branch, and require power-domains only when the compatible is not qcom,shikra-dispcc. Upstream marks it required for every compatible, but this branch also matches qcom,shikra-dispcc against this schema and the Shikra DTs do not describe the CX domain yet, so making it unconditional regresses dtbs_check on shikra-cq{m,s}-evk{,-imx577-camera}] Signed-off-by: Ricardo Salveti --- .../bindings/clock/qcom,qcm2290-dispcc.yaml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,qcm2290-dispcc.yaml b/Documentation/devicetree/bindings/clock/qcom,qcm2290-dispcc.yaml index 5cee033f2115d..2cf58843e54a4 100644 --- a/Documentation/devicetree/bindings/clock/qcom,qcm2290-dispcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,qcm2290-dispcc.yaml @@ -49,6 +49,10 @@ properties: - const: dsi1_phy_pll_out_dsiclk - const: sleep_clk + power-domains: + items: + - description: CX domain + required: - compatible - clocks @@ -57,6 +61,17 @@ required: allOf: - $ref: qcom,gcc.yaml# + # The Shikra variant carried by this branch does not describe the CX domain + # yet, so only demand it on plain qcm2290. + - if: + not: + properties: + compatible: + contains: + const: qcom,shikra-dispcc + then: + required: + - power-domains unevaluatedProperties: false @@ -65,6 +80,7 @@ examples: #include #include #include + #include clock-controller@5f00000 { compatible = "qcom,qcm2290-dispcc"; reg = <0x5f00000 0x20000>; @@ -86,6 +102,7 @@ examples: "dsi1_phy_pll_out_byteclk", "dsi1_phy_pll_out_dsiclk", "sleep_clk"; + power-domains = <&rpmpd RPMPD_VDDCX>; #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; From 6fbe6d7752c1d928597ca05ad00cd01299c719b9 Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Sat, 18 Jul 2026 18:26:19 +0530 Subject: [PATCH 11/30] BACKPORT: arm64: dts: qcom: agatti: Add missing CX power domain to DISPCC Add the missing power-domains property to associate DISPCC with CX rail. This is to ensure the genpd performance state votes on the GDSC to get propagated to the CX rail and to avoid the rail under-voltage conditions. Fixes: a2b32096709d ("arm64: dts: qcom: qcm2290: Add display nodes") Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Signed-off-by: Imran Shaik Link: https://lore.kernel.org/r/20260718-shikra-dispcc-gpucc-v6-12-62703e05ef0f@oss.qualcomm.com Signed-off-by: Bjorn Andersson (cherry picked from commit 26d7b23caa4b1d8208e28c5981a85cf83e658e7c) [rsalveti: applied to qcm2290.dtsi, keeping the DSI1/sleep clocks already present in this branch] Signed-off-by: Ricardo Salveti --- arch/arm64/boot/dts/qcom/qcm2290.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/qcom/qcm2290.dtsi b/arch/arm64/boot/dts/qcom/qcm2290.dtsi index 280bc8a64ef02..7eaba1edd1f22 100644 --- a/arch/arm64/boot/dts/qcom/qcm2290.dtsi +++ b/arch/arm64/boot/dts/qcom/qcm2290.dtsi @@ -2122,6 +2122,7 @@ "dsi1_phy_pll_out_byteclk", "dsi1_phy_pll_out_dsiclk", "sleep_clk"; + power-domains = <&rpmpd QCM2290_VDDCX>; #power-domain-cells = <1>; #clock-cells = <1>; #reset-cells = <1>; From 3c9236ca537d4d41ce1dd5515290827791fa0258 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Mon, 29 Dec 2025 21:47:39 +0100 Subject: [PATCH 12/30] UPSTREAM: dt-bindings: display/msm/gpu: Straighten out reg-names on A619L/610/702 These GPUs have physically have the same regions as the base case ("main" + "cx_mem" + "cx_dbgc"). Remove the specific override. Signed-off-by: Konrad Dybcio Acked-by: Rob Herring (Arm) Patchwork: https://patchwork.freedesktop.org/patch/696547/ Message-ID: <20251229-topic-6115_2290_gpu_dbgc-v1-1-4a24d196389c@oss.qualcomm.com> Signed-off-by: Rob Clark Link: https://lore.kernel.org/r/20251229-topic-6115_2290_gpu_dbgc-v1-1-4a24d196389c@oss.qualcomm.com (cherry picked from commit ae26b4d513347aa247772a26f374b66d30af550e) Signed-off-by: Ricardo Salveti --- Documentation/devicetree/bindings/display/msm/gpu.yaml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Documentation/devicetree/bindings/display/msm/gpu.yaml b/Documentation/devicetree/bindings/display/msm/gpu.yaml index 2186af7a9d75a..d0f5cff3286ef 100644 --- a/Documentation/devicetree/bindings/display/msm/gpu.yaml +++ b/Documentation/devicetree/bindings/display/msm/gpu.yaml @@ -380,12 +380,6 @@ allOf: - const: xo description: GPUCC clocksource clock - reg-names: - minItems: 1 - items: - - const: kgsl_3d0_reg_memory - - const: cx_dbgc - required: - clocks - clock-names From 4c8e0f7b2c49494d3cd67c893b34f40885050433 Mon Sep 17 00:00:00 2001 From: Riccardo Mereu Date: Thu, 20 Nov 2025 16:58:20 +0100 Subject: [PATCH 13/30] UPSTREAM: dt-bindings: vendor-prefixes: Add Arduino name Add entry for Arduino SRL (https://arduino.cc) Signed-off-by: Riccardo Mereu Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20251120155825.121483-2-r.mereu.kernel@arduino.cc Signed-off-by: Bjorn Andersson (cherry picked from commit d16ffac771715a8c94611b6f8088a3e800bcf5bf) Signed-off-by: Ricardo Salveti --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 7fa32190761b6..5c46fe72204b0 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -154,6 +154,8 @@ patternProperties: description: Arctic Sand "^arcx,.*": description: arcx Inc. / Archronix Inc. + "^arduino,.*": + description: Arduino SRL "^argon40,.*": description: Argon 40 Technologies Limited "^ariaboard,.*": From 163a7df436b058d65621b3424b3d65e91b9a9ae0 Mon Sep 17 00:00:00 2001 From: Riccardo Mereu Date: Thu, 20 Nov 2025 16:58:23 +0100 Subject: [PATCH 14/30] UPSTREAM: dt-bindings: arm: qcom: Add arduino imola, UnoQ codename MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document Arduino imola, UnoQ codename. Arduino UnoQ combines Qualcomm Dragonwing™ QRB2210 microprocessor with STMicroelectronics STM32U585 microcontroller. Signed-off-by: Riccardo Mereu Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20251120155825.121483-5-r.mereu.kernel@arduino.cc Signed-off-by: Bjorn Andersson (cherry picked from commit 311d173da672397a58498841299ec613ff9eb96b) Signed-off-by: Ricardo Salveti --- Documentation/devicetree/bindings/arm/qcom.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml index f0359455dc205..580c79f301bf8 100644 --- a/Documentation/devicetree/bindings/arm/qcom.yaml +++ b/Documentation/devicetree/bindings/arm/qcom.yaml @@ -341,6 +341,7 @@ properties: - description: Qualcomm Technologies, Inc. Robotics RB1 items: - enum: + - arduino,imola - qcom,qrb2210-rb1 - const: qcom,qrb2210 - const: qcom,qcm2290 From 3d5300e98f114c83ff7973c87387f7c2be632194 Mon Sep 17 00:00:00 2001 From: Riccardo Mereu Date: Thu, 20 Nov 2025 16:58:21 +0100 Subject: [PATCH 15/30] UPSTREAM: dt-bindings: trivial-devices: add arduino spi mcu interface Add unoq mcu interface. It describes an iterface between Qualcomm QRB2210 microprocessor and STMicroelectronics STM32U585 microcontroller on Arduino UnoQ single-board computer. This is a trivial device since it's usage is handled in user space by the arduino-router service. Signed-off-by: Riccardo Mereu Reviewed-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20251120155825.121483-3-r.mereu.kernel@arduino.cc Signed-off-by: Mark Brown (cherry picked from commit a7bde7c10902a0f6f903d3bbe67461f2b402a9ca) Signed-off-by: Ricardo Salveti --- Documentation/devicetree/bindings/trivial-devices.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml index 58ff948d93c96..9bff5f0201082 100644 --- a/Documentation/devicetree/bindings/trivial-devices.yaml +++ b/Documentation/devicetree/bindings/trivial-devices.yaml @@ -53,6 +53,8 @@ properties: - adi,lt7182s # AMS iAQ-Core VOC Sensor - ams,iaq-core + # Arduino microcontroller interface over SPI on UnoQ board + - arduino,unoq-mcu # Temperature monitoring of Astera Labs PT5161L PCIe retimer - asteralabs,pt5161l # i2c h/w elliptic curve crypto module From 794b3869cada3a8575e65dc5f4d2dfc076d898ed Mon Sep 17 00:00:00 2001 From: Riccardo Mereu Date: Thu, 20 Nov 2025 16:58:22 +0100 Subject: [PATCH 16/30] UPSTREAM: spi: spidev: add compatible for arduino spi mcu interface Add compatible entry in spidev describing in Arduino UnoQ single-board computer the interface between Qualcomm QRB2210 microprocessor and STMicroelectronics STM32U585 microcontroller. It is handled in user space by the arduino-router service. Signed-off-by: Riccardo Mereu Reviewed-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20251120155825.121483-4-r.mereu.kernel@arduino.cc Signed-off-by: Mark Brown (cherry picked from commit 43a3adb6dd39d98bf84e04569e7604be5e5c0d79) Signed-off-by: Ricardo Salveti --- drivers/spi/spidev.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 4d53c394101a4..f28528ed1c24e 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -686,6 +686,7 @@ static const struct class spidev_class = { */ static const struct spi_device_id spidev_spi_ids[] = { { .name = /* abb */ "spi-sensor" }, + { .name = /* arduino */ "unoq-mcu" }, { .name = /* cisco */ "spi-petra" }, { .name = /* dh */ "dhcom-board" }, { .name = /* elgin */ "jg10309-01" }, @@ -719,6 +720,7 @@ static int spidev_of_check(struct device *dev) static const struct of_device_id spidev_dt_ids[] = { { .compatible = "abb,spi-sensor", .data = &spidev_of_check }, + { .compatible = "arduino,unoq-mcu", .data = &spidev_of_check }, { .compatible = "cisco,spi-petra", .data = &spidev_of_check }, { .compatible = "dh,dhcom-board", .data = &spidev_of_check }, { .compatible = "elgin,jg10309-01", .data = &spidev_of_check }, From 2006dea1a7efd95639b1b581df08926ad0bbe2c7 Mon Sep 17 00:00:00 2001 From: Riccardo Mereu Date: Thu, 20 Nov 2025 16:58:25 +0100 Subject: [PATCH 17/30] BACKPORT: arm64: dts: qcom: qrb2210: add dts for Arduino unoq MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Arduino UnoQ is a single-board computer combining Qualcomm Dragonwing™ QRB2210 microprocessor with STMicroelectronics STM32U585 microcontroller. Support to a simply boot to shell environment includes: - UART, I2C, SPI - onboard LEDS - eMMC - WLAN and BT Signed-off-by: Riccardo Mereu Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20251120155825.121483-7-r.mereu.kernel@arduino.cc Signed-off-by: Bjorn Andersson (cherry picked from commit 3f745bc0f11f66465e3fa19eb0c808c5b39cb0e5) [rsalveti: include qcm2290.dtsi, as the rename to agatti.dtsi is not part of this branch] Signed-off-by: Ricardo Salveti --- arch/arm64/boot/dts/qcom/Makefile | 1 + .../boot/dts/qcom/qrb2210-arduino-imola.dts | 459 ++++++++++++++++++ 2 files changed, 460 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 9056576bdf7bc..c7de091a5864d 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -220,6 +220,7 @@ dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride-r3.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride-el2.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride-r3-el2.dtb dtb-$(CONFIG_ARCH_QCOM) += qdu1000-idp.dtb +dtb-$(CONFIG_ARCH_QCOM) += qrb2210-arduino-imola.dtb dtb-$(CONFIG_ARCH_QCOM) += qrb2210-rb1.dtb dtb-$(CONFIG_ARCH_QCOM) += qrb4210-rb2.dtb dtb-$(CONFIG_ARCH_QCOM) += qrb5165-rb5.dtb diff --git a/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts b/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts new file mode 100644 index 0000000000000..ae6dd13eb89e7 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts @@ -0,0 +1,459 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (c) 2025, Arduino SRL + */ + +/dts-v1/; + +#include +#include "qcm2290.dtsi" +#include "pm4125.dtsi" + +/delete-node/ &cont_splash_memory; + +/ { + model = "Arduino UnoQ"; + compatible = "arduino,imola", "qcom,qrb2210", "qcom,qcm2290"; + chassis-type = "embedded"; + + aliases { + serial0 = &uart4; + serial1 = &uart2; + serial2 = &uart3; + sdhc1 = &sdhc_1; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + gpio-keys { + compatible = "gpio-keys"; + label = "gpio-keys"; + pinctrl-0 = <&key_volp_n>, <&key_vold_n>; + pinctrl-names = "default"; + + key-volume-up { + label = "Volume Up"; + linux,code = ; + gpios = <&tlmm 96 GPIO_ACTIVE_LOW>; + debounce-interval = <15>; + linux,can-disable; + wakeup-source; + }; + + key-volume-down { + label = "Volume Down"; + linux,code = ; + gpios = <&tlmm 36 GPIO_ACTIVE_LOW>; + debounce-interval = <15>; + linux,can-disable; + wakeup-source; + }; + }; + + leds: leds { + compatible = "gpio-leds"; + + led-bt { + label = "unoq:bt-blue2"; + function = LED_FUNCTION_BLUETOOTH; + color = ; + gpios = <&tlmm 47 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "bluetooth-power"; + default-state = "off"; + }; + + led-panic { + label = "unoq:panic-red2"; + function = LED_FUNCTION_INDICATOR; + color = ; + gpios = <&tlmm 39 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "none"; + default-state = "off"; + panic-indicator; + }; + + led-wlan { + label = "unoq:wlan-green2"; + function = LED_FUNCTION_WLAN; + color = ; + gpios = <&tlmm 40 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "phy0tx"; + default-state = "off"; + }; + + ledb: led-user-blue { + label = "unoq:user-blue1"; + gpios = <&tlmm 60 GPIO_ACTIVE_HIGH>; + color = ; + }; + + ledg: led-user-green { + label = "unoq:user-green1"; + gpios = <&tlmm 42 GPIO_ACTIVE_HIGH>; + color = ; + }; + + ledr: led-user-red { + label = "unoq:user-red1"; + gpios = <&tlmm 41 GPIO_ACTIVE_HIGH>; + color = ; + }; + }; + + multi-led { + compatible = "leds-group-multicolor"; + color = ; + function = LED_FUNCTION_INDICATOR; + leds = <&ledr>, <&ledg>, <&ledb>; + }; + + /* PM4125 charger out, supplied by VBAT */ + vph_pwr: regulator-vph-pwr { + compatible = "regulator-fixed"; + regulator-name = "vph_pwr"; + regulator-min-microvolt = <3700000>; + regulator-max-microvolt = <3700000>; + regulator-always-on; + regulator-boot-on; + }; +}; + +&gpi_dma0 { + status = "okay"; +}; + +&gpu { + status = "okay"; +}; + +&gpu_zap_shader { + firmware-name = "qcom/qcm2290/a702_zap.mbn"; +}; + +&i2c0 { + clock-frequency = <100000>; + + status = "okay"; +}; + +&i2c1 { + clock-frequency = <100000>; + + status = "okay"; +}; + +&pm4125_vbus { + regulator-min-microamp = <500000>; + regulator-max-microamp = <500000>; + + status = "okay"; +}; + +&qupv3_id_0 { + status = "okay"; +}; + +&remoteproc_adsp { + firmware-name = "qcom/qcm2290/adsp.mbn"; + + status = "okay"; +}; + +&remoteproc_mpss { + firmware-name = "qcom/qcm2290/modem.mbn"; + + status = "okay"; +}; + +&rpm_requests { + regulators { + compatible = "qcom,rpm-pm2250-regulators"; + vdd_s3-supply = <&vph_pwr>; + vdd_s4-supply = <&vph_pwr>; + vdd_l1_l2_l3_l5_l6_l7_l8_l9_l10_l11_l12-supply = <&pm4125_s3>; + vdd_l4_l17_l18_l19_l20_l21_l22-supply = <&vph_pwr>; + vdd_l13_l14_l15_l16-supply = <&pm4125_s4>; + + pm4125_s3: s3 { + /* 0.4V-1.6625V -> 1.3V (Power tree requirements) */ + regulator-min-microvolt = <1352000>; + regulator-max-microvolt = <1352000>; + regulator-boot-on; + }; + + pm4125_s4: s4 { + /* 1.2V-2.35V -> 2.05V (Power tree requirements) */ + regulator-min-microvolt = <2072000>; + regulator-max-microvolt = <2072000>; + regulator-boot-on; + }; + + pm4125_l2: l2 { + /* LPDDR4X VDD2 */ + regulator-min-microvolt = <1136000>; + regulator-max-microvolt = <1136000>; + regulator-always-on; + regulator-boot-on; + }; + + pm4125_l3: l3 { + /* LPDDR4X VDDQ */ + regulator-min-microvolt = <616000>; + regulator-max-microvolt = <616000>; + regulator-always-on; + regulator-boot-on; + }; + + pm4125_l4: l4 { + /* max = 3.05V -> max = 2.7 to disable 3V signaling (SDHCI2) */ + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2700000>; + regulator-allow-set-load; + }; + + pm4125_l5: l5 { + /* CSI/DSI */ + regulator-min-microvolt = <1232000>; + regulator-max-microvolt = <1232000>; + regulator-allow-set-load; + regulator-boot-on; + }; + + pm4125_l6: l6 { + /* DRAM PLL */ + regulator-min-microvolt = <928000>; + regulator-max-microvolt = <928000>; + regulator-always-on; + regulator-boot-on; + }; + + pm4125_l7: l7 { + /* Wi-Fi CX */ + regulator-min-microvolt = <664000>; + regulator-max-microvolt = <664000>; + }; + + pm4125_l10: l10 { + /* Wi-Fi RFA */ + regulator-min-microvolt = <1304000>; + regulator-max-microvolt = <1304000>; + }; + + pm4125_l11: l11 { + /* ANX7625 DVDD1P0V/AVDD1P0V */ + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-boot-on; + regulator-always-on; + }; + + pm4125_l12: l12 { + /* USB PHYs */ + regulator-min-microvolt = <928000>; + regulator-max-microvolt = <928000>; + regulator-allow-set-load; + regulator-boot-on; + }; + + pm4125_l13: l13 { + /* USB/QFPROM/PLLs */ + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-allow-set-load; + regulator-boot-on; + }; + + pm4125_l14: l14 { + /* SDHCI1 EMMC VCCQ */ + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-allow-set-load; + /* Broken hardware, never turn it off! */ + regulator-always-on; + }; + + pm4125_l15: l15 { + /* VDDIO */ + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-allow-set-load; + regulator-always-on; + regulator-boot-on; + }; + + pm4125_l20: l20 { + /* SDHCI1 EMMC */ + regulator-min-microvolt = <2400000>; + regulator-max-microvolt = <3600000>; + regulator-allow-set-load; + }; + + pm4125_l21: l21 { + /* USB HS */ + regulator-min-microvolt = <2960000>; + regulator-max-microvolt = <3300000>; + regulator-allow-set-load; + regulator-boot-on; + }; + + pm4125_l22: l22 { + /* Wi-Fi VDD */ + regulator-min-microvolt = <3312000>; + regulator-max-microvolt = <3312000>; + }; + }; +}; + +&sdhc_1 { + vmmc-supply = <&pm4125_l20>; + vqmmc-supply = <&pm4125_l14>; + pinctrl-0 = <&sdc1_state_on>; + pinctrl-1 = <&sdc1_state_off>; + pinctrl-names = "default", "sleep"; + mmc-hs400-1_8v; + mmc-hs200-1_8v; + non-removable; + supports-cqe; + no-sdio; + no-sd; + + status = "okay"; +}; + +&spi5 { + status = "okay"; + + spidev@0 { + reg = <0>; + compatible = "arduino,unoq-mcu"; + pinctrl-0 = <&spidev_cs>; + pinctrl-names = "default"; + }; +}; + +&tlmm { + spidev_cs: spidev-cs-state { + pins = "gpio17"; + function = "gpio"; + drive-strength = <16>; + }; + + jmisc_gpio18: jmisc-gpio18-state { + pins = "gpio18"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + jmisc_gpio28: jmisc-gpio28-state { + pins = "gpio28"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + key_vold_n: key-vold-n-state { + pins = "gpio36"; + function = "gpio"; + bias-pull-up; + output-disable; + }; + + key_volp_n: key-volp-n-state { + pins = "gpio96"; + function = "gpio"; + bias-pull-up; + output-disable; + }; + + jmisc_gpio98: jmisc-gpio98-state { + pins = "gpio98"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + jmisc_gpio99: jmisc-gpio99-state { + pins = "gpio99"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + jmisc_gpio100: jmisc-gpio100-state { + pins = "gpio100"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + jmisc_gpio101: jmisc-gpio101-state { + pins = "gpio101"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; +}; + +&uart2 { + status = "okay"; +}; + +/* UART connected to Bluetooth */ +&uart3 { + status = "okay"; + + bluetooth { + compatible = "qcom,wcn3988-bt"; + + vddio-supply = <&pm4125_l15>; + vddxo-supply = <&pm4125_l13>; + vddrf-supply = <&pm4125_l10>; + vddch0-supply = <&pm4125_l22>; + enable-gpios = <&tlmm 87 GPIO_ACTIVE_HIGH>; + max-speed = <3000000>; + }; +}; + +/* UART exposed in JCTL */ +&uart4 { + compatible = "qcom,geni-debug-uart"; + + status = "okay"; +}; + +&usb { + status = "okay"; +}; + +&usb_hsphy { + vdd-supply = <&pm4125_l12>; + vdda-pll-supply = <&pm4125_l13>; + vdda-phy-dpdm-supply = <&pm4125_l21>; + + status = "okay"; +}; + +&usb_qmpphy { + vdda-phy-supply = <&pm4125_l12>; + vdda-pll-supply = <&pm4125_l13>; + + status = "okay"; +}; + +&wifi { + vdd-0.8-cx-mx-supply = <&pm4125_l7>; + vdd-1.8-xo-supply = <&pm4125_l13>; + vdd-1.3-rfa-supply = <&pm4125_l10>; + vdd-3.3-ch0-supply = <&pm4125_l22>; + qcom,ath10k-calibration-variant = "ArduinoImola"; + firmware-name = "qcm2290"; + + status = "okay"; +}; + +&xo_board { + clock-frequency = <38400000>; +}; From 9b8bef5c06897ed24deb99492c665ca45460f2d3 Mon Sep 17 00:00:00 2001 From: Riccardo Mereu Date: Fri, 13 Feb 2026 11:10:02 +0100 Subject: [PATCH 18/30] UPSTREAM: arm64: dts: qcom: arduino-imola: fix faulty spidev node CS pin added on pinctrl0 property is causing spidev to return -ENODEV since that GPIO is already part of spi5 pinmuxing. Fixes: 3f745bc0f11f ("arm64: dts: qcom: qrb2210: add dts for Arduino unoq") Signed-off-by: Riccardo Mereu Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20260213101002.105238-1-r.mereu.kernel@arduino.cc Signed-off-by: Bjorn Andersson (cherry picked from commit 1a040df09fab28b31399fce14a76455b536a2b08) Signed-off-by: Ricardo Salveti --- arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts b/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts index ae6dd13eb89e7..2e9f26ed2f39f 100644 --- a/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts +++ b/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts @@ -325,21 +325,13 @@ &spi5 { status = "okay"; - spidev@0 { - reg = <0>; + mcu@0 { compatible = "arduino,unoq-mcu"; - pinctrl-0 = <&spidev_cs>; - pinctrl-names = "default"; + reg = <0>; }; }; &tlmm { - spidev_cs: spidev-cs-state { - pins = "gpio17"; - function = "gpio"; - drive-strength = <16>; - }; - jmisc_gpio18: jmisc-gpio18-state { pins = "gpio18"; function = "gpio"; From 0c4422c2f30220fef783672f032a61e193814f64 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 21 Jan 2026 12:15:45 +0200 Subject: [PATCH 19/30] UPSTREAM: dt-bindings: drm/bridge: anx7625: describe Type-C connector ANX7625 can be used to mux converted video stream with the USB signals on a Type-C connector. Describe the optional connector subnode, make it exclusive with the AUX bus and port@1 as it is impossible to have both eDP panel and USB-C connector. Reviewed-by: Rob Herring (Arm) Link: https://patch.msgid.link/20260121-anx7625-typec-v2-1-d14f31256a17@oss.qualcomm.com Signed-off-by: Dmitry Baryshkov (cherry picked from commit 1d7532444a32b53ff7344dc52019bab5a4b5ed66) Signed-off-by: Ricardo Salveti --- .../display/bridge/analogix,anx7625.yaml | 98 ++++++++++++++++++- 1 file changed, 97 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml index a1ed1004651b9..6ad466952c02d 100644 --- a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml +++ b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml @@ -85,6 +85,11 @@ properties: aux-bus: $ref: /schemas/display/dp-aux-bus.yaml# + connector: + type: object + $ref: /schemas/connector/usb-connector.yaml# + unevaluatedProperties: false + ports: $ref: /schemas/graph.yaml#/properties/ports @@ -117,7 +122,6 @@ properties: required: - port@0 - - port@1 required: - compatible @@ -127,6 +131,28 @@ required: - vdd33-supply - ports +allOf: + - if: + required: + - aux-bus + - connector + then: + false + + - if: + required: + - connector + then: + properties: + ports: + properties: + port@1: false + else: + properties: + ports: + required: + - port@1 + additionalProperties: false examples: @@ -185,3 +211,73 @@ examples: }; }; }; + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + encoder@58 { + compatible = "analogix,anx7625"; + reg = <0x58>; + enable-gpios = <&pio 45 GPIO_ACTIVE_HIGH>; + reset-gpios = <&pio 73 GPIO_ACTIVE_HIGH>; + vdd10-supply = <&pp1000_mipibrdg>; + vdd18-supply = <&pp1800_mipibrdg>; + vdd33-supply = <&pp3300_mipibrdg>; + analogix,audio-enable; + analogix,lane0-swing = /bits/ 8 <0x14 0x54 0x64 0x74>; + analogix,lane1-swing = /bits/ 8 <0x14 0x54 0x64 0x74>; + + connector { + compatible = "usb-c-connector"; + power-role = "dual"; + data-role = "dual"; + vbus-supply = <&vbus_reg>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + endpoint { + remote-endpoint = <&usb_hs>; + }; + }; + + port@1 { + reg = <1>; + + endpoint { + remote-endpoint = <&usb_ss>; + }; + }; + + port@2 { + reg = <2>; + + endpoint { + remote-endpoint = <&usb_sbu>; + }; + }; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + endpoint { + remote-endpoint = <&mipi_dsi>; + bus-type = <7>; + data-lanes = <0 1 2 3>; + }; + }; + }; + }; + }; From d297a866957994a4490726c562600a8dc3c0fb9a Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 21 Jan 2026 12:15:46 +0200 Subject: [PATCH 20/30] UPSTREAM: drm: bridge: anx7625: implement minimal Type-C support ANX7625 can be used as a USB-C controller, handling USB and DP data streams. Provide minimal Type-C support necessary for ANX7625 to register the Type-C port device and properly respond to data / power role events from the Type-C partner. While ANX7625 provides TCPCI interface, using it would circumvent the on-chip running firmware. Analogix recommended using the higher-level interface instead of TCPCI. Reviewed-by: Xin Ji Reviewed-by: Heikki Krogerus Link: https://patch.msgid.link/20260121-anx7625-typec-v2-2-d14f31256a17@oss.qualcomm.com Signed-off-by: Dmitry Baryshkov (cherry picked from commit f81455b2d3327a5685623e7db4050dbbe5513bc3) Signed-off-by: Ricardo Salveti --- drivers/gpu/drm/bridge/analogix/Kconfig | 1 + drivers/gpu/drm/bridge/analogix/anx7625.c | 155 ++++++++++++++++++++-- drivers/gpu/drm/bridge/analogix/anx7625.h | 22 ++- 3 files changed, 168 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/Kconfig b/drivers/gpu/drm/bridge/analogix/Kconfig index 4846b2e9be7c2..f3448b0631fea 100644 --- a/drivers/gpu/drm/bridge/analogix/Kconfig +++ b/drivers/gpu/drm/bridge/analogix/Kconfig @@ -34,6 +34,7 @@ config DRM_ANALOGIX_ANX7625 tristate "Analogix Anx7625 MIPI to DP interface support" depends on DRM depends on OF + depends on TYPEC || !TYPEC select DRM_DISPLAY_DP_HELPER select DRM_DISPLAY_HDCP_HELPER select DRM_DISPLAY_HELPER diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 836b29fdc8479..423dff131e907 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -3,6 +3,7 @@ * Copyright(c) 2020, Analogix Semiconductor. All rights reserved. * */ +#include #include #include #include @@ -15,6 +16,9 @@ #include #include #include +#include +#include +#include #include #include @@ -1325,7 +1329,7 @@ static int anx7625_read_hpd_gpio_config_status(struct anx7625_data *ctx) static void anx7625_disable_pd_protocol(struct anx7625_data *ctx) { struct device *dev = ctx->dev; - int ret, val; + int ret; /* Reset main ocm */ ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client, 0x88, 0x40); @@ -1339,6 +1343,11 @@ static void anx7625_disable_pd_protocol(struct anx7625_data *ctx) DRM_DEV_DEBUG_DRIVER(dev, "disable PD feature fail.\n"); else DRM_DEV_DEBUG_DRIVER(dev, "disable PD feature succeeded.\n"); +} + +static void anx7625_configure_hpd(struct anx7625_data *ctx) +{ + int val; /* * Make sure the HPD GPIO already be configured after OCM release before @@ -1369,7 +1378,9 @@ static int anx7625_ocm_loading_check(struct anx7625_data *ctx) if ((ret & FLASH_LOAD_STA_CHK) != FLASH_LOAD_STA_CHK) return -ENODEV; - anx7625_disable_pd_protocol(ctx); + if (!ctx->typec_port) + anx7625_disable_pd_protocol(ctx); + anx7625_configure_hpd(ctx); DRM_DEV_DEBUG_DRIVER(dev, "Firmware ver %02x%02x,", anx7625_reg_read(ctx, @@ -1472,6 +1483,107 @@ static void anx7625_start_dp_work(struct anx7625_data *ctx) DRM_DEV_DEBUG_DRIVER(dev, "Secure OCM version=%02x\n", ret); } +#if IS_REACHABLE(CONFIG_TYPEC) +static void anx7625_typec_set_orientation(struct anx7625_data *ctx) +{ + u32 val = anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS); + + if (val & (CC1_RP | CC1_RD)) + typec_set_orientation(ctx->typec_port, TYPEC_ORIENTATION_NORMAL); + else if (val & (CC2_RP | CC2_RD)) + typec_set_orientation(ctx->typec_port, TYPEC_ORIENTATION_REVERSE); + else + typec_set_orientation(ctx->typec_port, TYPEC_ORIENTATION_NONE); +} + +static void anx7625_typec_set_status(struct anx7625_data *ctx, + unsigned int intr_status, + unsigned int intr_vector) +{ + if (intr_vector & CC_STATUS) + anx7625_typec_set_orientation(ctx); + if (intr_vector & DATA_ROLE_STATUS) { + enum typec_data_role data_role = (intr_status & DATA_ROLE_STATUS) ? + TYPEC_HOST : TYPEC_DEVICE; + usb_role_switch_set_role(ctx->role_sw, + (intr_status & DATA_ROLE_STATUS) ? + USB_ROLE_HOST : USB_ROLE_DEVICE); + typec_set_data_role(ctx->typec_port, data_role); + ctx->typec_data_role = data_role; + } + if (intr_vector & VBUS_STATUS) + typec_set_pwr_role(ctx->typec_port, + (intr_status & VBUS_STATUS) ? + TYPEC_SOURCE : TYPEC_SINK); + if (intr_vector & VCONN_STATUS) + typec_set_vconn_role(ctx->typec_port, + (intr_status & VCONN_STATUS) ? + TYPEC_SOURCE : TYPEC_SINK); +} + +static int anx7625_typec_register(struct anx7625_data *ctx) +{ + struct typec_capability typec_cap = { }; + struct fwnode_handle *fwnode __free(fwnode_handle) = + device_get_named_child_node(ctx->dev, "connector"); + u32 val; + int ret; + + if (!fwnode) + return 0; + + ret = typec_get_fw_cap(&typec_cap, fwnode); + if (ret < 0) + return ret; + + typec_cap.revision = 0x0120; + typec_cap.pd_revision = 0x0300; + typec_cap.usb_capability = USB_CAPABILITY_USB2 | USB_CAPABILITY_USB3; + typec_cap.orientation_aware = true; + + typec_cap.driver_data = ctx; + + ctx->typec_port = typec_register_port(ctx->dev, &typec_cap); + if (IS_ERR(ctx->typec_port)) + return PTR_ERR(ctx->typec_port); + + ctx->role_sw = fwnode_usb_role_switch_get(fwnode); + if (IS_ERR(ctx->role_sw)) { + typec_unregister_port(ctx->typec_port); + return PTR_ERR(ctx->role_sw); + } + + val = anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS); + + anx7625_typec_set_status(ctx, val, + CC_STATUS | DATA_ROLE_STATUS | + VBUS_STATUS | VCONN_STATUS); + + return 0; +} + +static void anx7625_typec_unregister(struct anx7625_data *ctx) +{ + usb_role_switch_put(ctx->role_sw); + typec_unregister_port(ctx->typec_port); +} +#else +static void anx7625_typec_set_status(struct anx7625_data *ctx, + unsigned int intr_status, + unsigned int intr_vector) +{ +} + +static int anx7625_typec_register(struct anx7625_data *ctx) +{ + return 0; +} + +static void anx7625_typec_unregister(struct anx7625_data *ctx) +{ +} +#endif + static int anx7625_read_hpd_status_p0(struct anx7625_data *ctx) { return anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS); @@ -1566,7 +1678,7 @@ static void dp_hpd_change_handler(struct anx7625_data *ctx, bool on) } } -static int anx7625_hpd_change_detect(struct anx7625_data *ctx) +static int anx7625_intr_status(struct anx7625_data *ctx) { int intr_vector, status; struct device *dev = ctx->dev; @@ -1593,9 +1705,6 @@ static int anx7625_hpd_change_detect(struct anx7625_data *ctx) return status; } - if (!(intr_vector & HPD_STATUS_CHANGE)) - return -ENOENT; - status = anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS); if (status < 0) { @@ -1604,6 +1713,12 @@ static int anx7625_hpd_change_detect(struct anx7625_data *ctx) } DRM_DEV_DEBUG_DRIVER(dev, "0x7e:0x45=%x\n", status); + + anx7625_typec_set_status(ctx, status, intr_vector); + + if (!(intr_vector & HPD_STATUS)) + return -ENOENT; + dp_hpd_change_handler(ctx, status & HPD_STATUS); return 0; @@ -1622,7 +1737,7 @@ static void anx7625_work_func(struct work_struct *work) return; } - event = anx7625_hpd_change_detect(ctx); + event = anx7625_intr_status(ctx); mutex_unlock(&ctx->lock); @@ -2741,11 +2856,29 @@ static int anx7625_i2c_probe(struct i2c_client *client) } if (!platform->pdata.low_power_mode) { - anx7625_disable_pd_protocol(platform); + struct fwnode_handle *fwnode; + + fwnode = device_get_named_child_node(dev, "connector"); + if (fwnode) + fwnode_handle_put(fwnode); + else + anx7625_disable_pd_protocol(platform); + + anx7625_configure_hpd(platform); + pm_runtime_get_sync(dev); _anx7625_hpd_polling(platform, 5000 * 100); } + if (platform->pdata.intp_irq) + anx7625_reg_write(platform, platform->i2c.rx_p0_client, + INTERFACE_CHANGE_INT_MASK, 0); + + /* After getting runtime handle */ + ret = anx7625_typec_register(platform); + if (ret) + goto pm_suspend; + /* Add work function */ if (platform->pdata.intp_irq) { enable_irq(platform->pdata.intp_irq); @@ -2759,6 +2892,10 @@ static int anx7625_i2c_probe(struct i2c_client *client) return 0; +pm_suspend: + if (!platform->pdata.low_power_mode) + pm_runtime_put_sync_suspend(&client->dev); + free_wq: if (platform->workqueue) destroy_workqueue(platform->workqueue); @@ -2774,6 +2911,8 @@ static void anx7625_i2c_remove(struct i2c_client *client) { struct anx7625_data *platform = i2c_get_clientdata(client); + anx7625_typec_unregister(platform); + drm_bridge_remove(&platform->bridge); if (platform->pdata.intp_irq) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.h b/drivers/gpu/drm/bridge/analogix/anx7625.h index eb5580f1ab2f8..a18561c213af9 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.h +++ b/drivers/gpu/drm/bridge/analogix/anx7625.h @@ -51,9 +51,21 @@ #define INTR_RECEIVED_MSG BIT(5) #define SYSTEM_STSTUS 0x45 +#define INTERFACE_CHANGE_INT_MASK 0x43 #define INTERFACE_CHANGE_INT 0x44 -#define HPD_STATUS_CHANGE 0x80 -#define HPD_STATUS 0x80 +#define VCONN_STATUS BIT(2) +#define VBUS_STATUS BIT(3) +#define CC_STATUS BIT(4) +#define DATA_ROLE_STATUS BIT(5) +#define HPD_STATUS BIT(7) + +#define NEW_CC_STATUS 0x46 +#define CC1_RD BIT(0) +#define CC1_RA BIT(1) +#define CC1_RP (BIT(2) | BIT(3)) +#define CC2_RD BIT(4) +#define CC2_RA BIT(5) +#define CC2_RP (BIT(6) | BIT(7)) /******** END of I2C Address 0x58 ********/ @@ -447,9 +459,15 @@ struct anx7625_i2c_client { struct i2c_client *tcpc_client; }; +struct typec_port; +struct usb_role_switch; + struct anx7625_data { struct anx7625_platform_data pdata; struct platform_device *audio_pdev; + struct typec_port *typec_port; + struct usb_role_switch *role_sw; + int typec_data_role; int hpd_status; int hpd_high_cnt; int dp_en; From f5e18277159f3b919f1cc2964e26440d1055ae55 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 21 Jan 2026 12:15:47 +0200 Subject: [PATCH 21/30] UPSTREAM: drm: bridge: anx7625: implement message sending Swapping the data role requires sending the message to the other USB-C side. Implement sending these messages through the OCM. The code is largely based on the anx7411.c USB-C driver. Reviewed-by: Xin Ji Link: https://patch.msgid.link/20260121-anx7625-typec-v2-3-d14f31256a17@oss.qualcomm.com Signed-off-by: Dmitry Baryshkov (cherry picked from commit 8ad0f7d2e6fdfc4462a5b168ec64d73b7e952ab9) Signed-off-by: Ricardo Salveti --- drivers/gpu/drm/bridge/analogix/anx7625.c | 68 +++++++++++++++++++++++ drivers/gpu/drm/bridge/analogix/anx7625.h | 12 ++++ 2 files changed, 80 insertions(+) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 423dff131e907..9410283b84a57 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1484,6 +1484,73 @@ static void anx7625_start_dp_work(struct anx7625_data *ctx) } #if IS_REACHABLE(CONFIG_TYPEC) +static u8 anx7625_checksum(u8 *buf, u8 len) +{ + u8 ret = 0; + u8 i; + + for (i = 0; i < len; i++) + ret += buf[i]; + + return ret; +} + +static int anx7625_read_msg_ctrl_status(struct anx7625_data *ctx) +{ + return anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, CMD_SEND_BUF); +} + +static int anx7625_wait_msg_empty(struct anx7625_data *ctx) +{ + int val; + + return readx_poll_timeout(anx7625_read_msg_ctrl_status, ctx, + val, (val < 0) || (val == 0), + 2000, 2000 * 150); +} + +static int anx7625_send_msg(struct anx7625_data *ctx, u8 type, u8 *buf, u8 size) +{ + struct fw_msg *msg = &ctx->send_msg; + u8 crc; + int ret; + + size = min_t(u8, size, (u8)MAX_BUF_LEN); + memcpy(msg->buf, buf, size); + msg->msg_type = type; + + /* msg len equals buffer length + msg_type */ + msg->msg_len = size + 1; + + crc = anx7625_checksum((u8 *)msg, size + HEADER_LEN); + msg->buf[size] = 0 - crc; + + ret = anx7625_wait_msg_empty(ctx); + if (ret) + return ret; + + ret = anx7625_reg_block_write(ctx, ctx->i2c.rx_p0_client, + CMD_SEND_BUF + 1, size + HEADER_LEN, + &msg->msg_type); + ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p0_client, CMD_SEND_BUF, + msg->msg_len); + return ret; +} + +static int anx7625_typec_dr_set(struct typec_port *port, enum typec_data_role role) +{ + struct anx7625_data *ctx = typec_get_drvdata(port); + + if (role == ctx->typec_data_role) + return 0; + + return anx7625_send_msg(ctx, 0x11, NULL, 0); +} + +static const struct typec_operations anx7625_typec_ops = { + .dr_set = anx7625_typec_dr_set, +}; + static void anx7625_typec_set_orientation(struct anx7625_data *ctx) { u32 val = anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS); @@ -1542,6 +1609,7 @@ static int anx7625_typec_register(struct anx7625_data *ctx) typec_cap.orientation_aware = true; typec_cap.driver_data = ctx; + typec_cap.ops = &anx7625_typec_ops; ctx->typec_port = typec_register_port(ctx->dev, &typec_cap); if (IS_ERR(ctx->typec_port)) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.h b/drivers/gpu/drm/bridge/analogix/anx7625.h index a18561c213af9..957d234ec07c8 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.h +++ b/drivers/gpu/drm/bridge/analogix/anx7625.h @@ -67,6 +67,9 @@ #define CC2_RA BIT(5) #define CC2_RP (BIT(6) | BIT(7)) +#define CMD_SEND_BUF 0xC0 +#define CMD_RECV_BUF 0xE0 + /******** END of I2C Address 0x58 ********/ /***************************************************************/ @@ -462,6 +465,14 @@ struct anx7625_i2c_client { struct typec_port; struct usb_role_switch; +#define MAX_BUF_LEN 30 +struct fw_msg { + u8 msg_len; + u8 msg_type; + u8 buf[MAX_BUF_LEN]; +} __packed; +#define HEADER_LEN 2 + struct anx7625_data { struct anx7625_platform_data pdata; struct platform_device *audio_pdev; @@ -497,6 +508,7 @@ struct anx7625_data { struct drm_connector *connector; struct mipi_dsi_device *dsi; struct drm_dp_aux aux; + struct fw_msg send_msg; }; #endif /* __ANX7625_H__ */ From 1764203ac47895a9c50ef96fff80a6fcf0d7d6aa Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 4 Mar 2026 09:35:52 +0100 Subject: [PATCH 22/30] UPSTREAM: drm: bridge: anx7625: enforce CONFIG_USB_ROLE_SWITCH dependency When CONFIG_TYPEC is enabled, but USB_ROLE_SWITCH=m, the anx7625 driver fails to link as built-in: aarch64-linux-ld: drivers/gpu/drm/bridge/analogix/anx7625.o: in function `anx7625_i2c_remove': anx7625.c:(.text+0x6ec): undefined reference to `usb_role_switch_put' aarch64-linux-ld: drivers/gpu/drm/bridge/analogix/anx7625.o: in function `anx7625_typec_set_status': anx7625.c:(.text+0x3080): undefined reference to `usb_role_switch_set_role' aarch64-linux-ld: drivers/gpu/drm/bridge/analogix/anx7625.o: in function `anx7625_i2c_probe': anx7625.c:(.text+0x5368): undefined reference to `fwnode_usb_role_switch_get' The problem is that both dependencies are optional in the sense of allowing the anx7625 driver to call the exported interfaces to be used from a loadable module, but cannot work for built-in drivers. It would be possible to handle all nine combinations of the CONFIG_TYPEC and CONFIG_USB_ROLE_SWITCH tristate options, but that does add a lot of complexity that seems unnecessary when in reality any user of this driver would have both enabled anyway. Turn both dependencies into hard 'depends on' here to only allow configurations where it's possible to actually use them, and remove the misguided IS_REACHABLE() check that did nothing here. Fixes: f81455b2d332 ("drm: bridge: anx7625: implement minimal Type-C support") Signed-off-by: Arnd Bergmann Reviewed-by: Neil Armstrong Link: https://patch.msgid.link/20260304083604.724519-1-arnd@kernel.org Signed-off-by: Dmitry Baryshkov (cherry picked from commit 10e9ff46fe07bdfa8c11434d4b943f89d8ba74f6) Signed-off-by: Ricardo Salveti --- drivers/gpu/drm/bridge/analogix/Kconfig | 3 ++- drivers/gpu/drm/bridge/analogix/anx7625.c | 17 ----------------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/Kconfig b/drivers/gpu/drm/bridge/analogix/Kconfig index f3448b0631fea..03dc7ffe824a9 100644 --- a/drivers/gpu/drm/bridge/analogix/Kconfig +++ b/drivers/gpu/drm/bridge/analogix/Kconfig @@ -34,7 +34,8 @@ config DRM_ANALOGIX_ANX7625 tristate "Analogix Anx7625 MIPI to DP interface support" depends on DRM depends on OF - depends on TYPEC || !TYPEC + depends on TYPEC + depends on USB_ROLE_SWITCH select DRM_DISPLAY_DP_HELPER select DRM_DISPLAY_HDCP_HELPER select DRM_DISPLAY_HELPER diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 9410283b84a57..0b842805e0e4b 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1483,7 +1483,6 @@ static void anx7625_start_dp_work(struct anx7625_data *ctx) DRM_DEV_DEBUG_DRIVER(dev, "Secure OCM version=%02x\n", ret); } -#if IS_REACHABLE(CONFIG_TYPEC) static u8 anx7625_checksum(u8 *buf, u8 len) { u8 ret = 0; @@ -1635,22 +1634,6 @@ static void anx7625_typec_unregister(struct anx7625_data *ctx) usb_role_switch_put(ctx->role_sw); typec_unregister_port(ctx->typec_port); } -#else -static void anx7625_typec_set_status(struct anx7625_data *ctx, - unsigned int intr_status, - unsigned int intr_vector) -{ -} - -static int anx7625_typec_register(struct anx7625_data *ctx) -{ - return 0; -} - -static void anx7625_typec_unregister(struct anx7625_data *ctx) -{ -} -#endif static int anx7625_read_hpd_status_p0(struct anx7625_data *ctx) { From fa2f4d458d4ecb3e1a1d85827251e5e11d00b48f Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Sun, 15 Feb 2026 03:30:02 +0200 Subject: [PATCH 23/30] UPSTREAM: drm: bridge: anx7625: don't crash if Type-C port is not used The typec_set_*() functions do not tolerate being passed the NULL typec_port instance. However, if CONFIG_TYPEC is enabled, but anx7625 DT node doesn't have the usb-c connector fwnode, then typec_port remains NULL, crashing the kernel. Prevent calling typec_set_foo() functions by checking that ctx->typec_port is not NULL in anx7625_typec_set_status(). Call trace: typec_set_orientation+0x18/0x68 (P) anx7625_typec_set_status+0x108/0x13c anx7625_work_func+0x124/0x438 process_one_work+0x214/0x648 worker_thread+0x1b4/0x358 kthread+0x14c/0x214 ret_from_fork+0x10/0x20 Code: 910003fd a90153f3 aa0003f3 2a0103f4 (f9431400) Fixes: f81455b2d332 ("drm: bridge: anx7625: implement minimal Type-C support") Reported-by: Salendarsingh Gaud Signed-off-by: Loic Poulain [db: dropped chunk anx7625_typec_unregister(), wrote commit message] Cc: Amit Kucheria Reviewed-by: Neil Armstrong Link: https://patch.msgid.link/20260215-anx-fix-no-typec-v1-1-75172a5ca88b@oss.qualcomm.com Signed-off-by: Dmitry Baryshkov (cherry picked from commit 8e3d8b33859bb8229d1f0b88752cbecb4932790a) Signed-off-by: Ricardo Salveti --- drivers/gpu/drm/bridge/analogix/anx7625.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 0b842805e0e4b..1e4c1c013581e 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1566,6 +1566,9 @@ static void anx7625_typec_set_status(struct anx7625_data *ctx, unsigned int intr_status, unsigned int intr_vector) { + if (!ctx->typec_port) + return; + if (intr_vector & CC_STATUS) anx7625_typec_set_orientation(ctx); if (intr_vector & DATA_ROLE_STATUS) { From 086538743104f834d95dad2ebeb3ad4c3d957dd8 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 11 Feb 2026 11:17:27 +0200 Subject: [PATCH 24/30] UPSTREAM: drm: bridge: anx7625: correctly detect if PD can be disabled During initial checks the ANX7625 bridge can be powered on before setting up the Type-C port. At this point, when anx7625_ocm_loading_check() checks if it can disable PD or not, it will notice that typec_port is not set and disable PD, breaking orientation and HPD handling. Unify the check between anx7625_ocm_loading_check() anx7625_i2c_probe() and anx7625_typec_register() and check for the presence of the "connector" node. Fixes: 8ad0f7d2e6fd ("drm: bridge: anx7625: implement message sending") Reviewed-by: Neil Armstrong Reviewed-by: Xin Ji Tested-by: Loic Poulain Link: https://patch.msgid.link/20260211-anx7625-fix-pd-v1-1-1dd31451b06f@oss.qualcomm.com Signed-off-by: Dmitry Baryshkov (cherry picked from commit 91d045058c68ab0ae133cd0bd8ed25a32c3dee97) Signed-off-by: Ricardo Salveti --- drivers/gpu/drm/bridge/analogix/anx7625.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 1e4c1c013581e..513c11cdbc74a 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1363,6 +1363,18 @@ static void anx7625_configure_hpd(struct anx7625_data *ctx) anx7625_hpd_timer_config(ctx); } +static bool anx7625_need_pd(struct anx7625_data *ctx) +{ + struct fwnode_handle *fwnode; + + fwnode = device_get_named_child_node(ctx->dev, "connector"); + if (!fwnode) + return false; + + fwnode_handle_put(fwnode); + return true; +} + static int anx7625_ocm_loading_check(struct anx7625_data *ctx) { int ret; @@ -1378,7 +1390,7 @@ static int anx7625_ocm_loading_check(struct anx7625_data *ctx) if ((ret & FLASH_LOAD_STA_CHK) != FLASH_LOAD_STA_CHK) return -ENODEV; - if (!ctx->typec_port) + if (!anx7625_need_pd(ctx)) anx7625_disable_pd_protocol(ctx); anx7625_configure_hpd(ctx); @@ -2910,12 +2922,7 @@ static int anx7625_i2c_probe(struct i2c_client *client) } if (!platform->pdata.low_power_mode) { - struct fwnode_handle *fwnode; - - fwnode = device_get_named_child_node(dev, "connector"); - if (fwnode) - fwnode_handle_put(fwnode); - else + if (!anx7625_need_pd(platform)) anx7625_disable_pd_protocol(platform); anx7625_configure_hpd(platform); From 5362bfc7675ce12b10b1f906a98db44bb70bd863 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 13 Feb 2026 19:25:25 +0200 Subject: [PATCH 25/30] UPSTREAM: arm64: dts: qcom: qrb2210-arduino-imola: describe DSI / DP bridge Aruino Uno-Q uses Analogix ANX7625 DSI-to-DP bridge to convert DSI signals to the connected USB-C DisplayPort dongles. Decribe the chip, USB-C connector and routing of USB and display signals. Co-developed-by: Martino Facchin Signed-off-by: Martino Facchin Tested-by: Loic Poulain Signed-off-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20260213-uno-q-anx7625-v2-1-c23359616528@oss.qualcomm.com Signed-off-by: Bjorn Andersson (cherry picked from commit d5574bb935e38c208bb7a20acaa4233b935f1ef9) Signed-off-by: Ricardo Salveti --- .../boot/dts/qcom/qrb2210-arduino-imola.dts | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts b/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts index 2e9f26ed2f39f..713300bc3d556 100644 --- a/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts +++ b/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include #include "qcm2290.dtsi" #include "pm4125.dtsi" @@ -109,6 +110,15 @@ leds = <&ledr>, <&ledg>, <&ledb>; }; + vreg_anx_30: regulator-anx-30 { + compatible = "regulator-fixed"; + regulator-name = "anx30"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + }; + /* PM4125 charger out, supplied by VBAT */ vph_pwr: regulator-vph-pwr { compatible = "regulator-fixed"; @@ -142,6 +152,86 @@ clock-frequency = <100000>; status = "okay"; + + anx7625: encoder@58 { + compatible = "analogix,anx7625"; + reg = <0x58>; + interrupts-extended = <&tlmm 81 IRQ_TYPE_EDGE_FALLING>; + vdd10-supply = <&pm4125_l11>; + vdd18-supply = <&pm4125_l15>; + vdd33-supply = <&vreg_anx_30>; + analogix,audio-enable; + analogix,lane0-swing = /bits/ 8 <0x14 0x54 0x64 0x74>; + analogix,lane1-swing = /bits/ 8 <0x14 0x54 0x64 0x74>; + + pinctrl-0 = <&anx7625_int_pin>, <&anx7625_cable_det_pin>; + + connector { + compatible = "usb-c-connector"; + power-role = "sink"; + data-role = "dual"; + try-power-role = "sink"; + + pd-revision = /bits/ 8 <0x03 0x00 0x00 0x00>; + op-sink-microwatt = <15000000>; + sink-pdos = ; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + anx_hs_in: endpoint { + remote-endpoint = <&usb_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + anx_ss_in: endpoint { + remote-endpoint = <&usb_qmpphy_out>; + }; + }; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + anx_dsi0_in: endpoint { + remote-endpoint = <&mdss_dsi0_out>; + data-lanes = <0 1 2 3>; + }; + }; + }; + }; +}; + +&mdss { + status = "okay"; +}; + +&mdss_dsi0 { + vdda-supply = <&pm4125_l5>; + + status = "okay"; +}; + +&mdss_dsi0_out { + remote-endpoint = <&anx_dsi0_in>; + data-lanes = <0 1 2 3>; +}; + +&mdss_dsi0_phy { + status = "okay"; }; &pm4125_vbus { @@ -353,6 +443,22 @@ output-disable; }; + anx7625_cable_det_pin: anx7625-cable-det-pins-state { + pins = "gpio46"; + function = "gpio"; + drive-strength = <16>; + output-disable; + bias-pull-up; + }; + + anx7625_int_pin: anx7625-int-pins-state { + pins = "gpio81"; + function = "gpio"; + drive-strength = <16>; + output-disable; + bias-pull-up; + }; + key_volp_n: key-volp-n-state { pins = "gpio96"; function = "gpio"; @@ -420,6 +526,10 @@ status = "okay"; }; +&usb_dwc3_hs { + remote-endpoint = <&anx_hs_in>; +}; + &usb_hsphy { vdd-supply = <&pm4125_l12>; vdda-pll-supply = <&pm4125_l13>; @@ -435,6 +545,10 @@ status = "okay"; }; +&usb_qmpphy_out { + remote-endpoint = <&anx_ss_in>; +}; + &wifi { vdd-0.8-cx-mx-supply = <&pm4125_l7>; vdd-1.8-xo-supply = <&pm4125_l13>; From c3fe7ce15f1eecbdf1fb9b3b873a638e7719b9ce Mon Sep 17 00:00:00 2001 From: Rakesh Kota Date: Mon, 6 Jul 2026 18:01:08 +0530 Subject: [PATCH 26/30] FROMGIT: arm64: dts: qcom: Fix pm4125 vbus regulator compatible and constraints Remove pm8150b fallback compatible from pm4125_vbus and fix regulator constraints in qrb2210 DTS files to use microvolt instead of microamp. Signed-off-by: Rakesh Kota Reviewed-by: Bryan O'Donoghue Reviewed-by: Krzysztof Kozlowski Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20260706-add_pm4125-vbus-reg-v3-4-999d78a87b81@oss.qualcomm.com Signed-off-by: Bjorn Andersson (cherry picked from commit cab6d9627ef4bb72c5d6ec3f216028e4271b9abe) Signed-off-by: Ricardo Salveti --- arch/arm64/boot/dts/qcom/pm4125.dtsi | 2 +- arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts | 4 ++-- arch/arm64/boot/dts/qcom/qrb2210-rb1.dts | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/pm4125.dtsi b/arch/arm64/boot/dts/qcom/pm4125.dtsi index ad410b8c4f6be..ca900948c0b3e 100644 --- a/arch/arm64/boot/dts/qcom/pm4125.dtsi +++ b/arch/arm64/boot/dts/qcom/pm4125.dtsi @@ -37,7 +37,7 @@ }; pm4125_vbus: usb-vbus-regulator@1100 { - compatible = "qcom,pm4125-vbus-reg", "qcom,pm8150b-vbus-reg"; + compatible = "qcom,pm4125-vbus-reg"; reg = <0x1100>; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts b/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts index 713300bc3d556..9f21fd1f677cf 100644 --- a/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts +++ b/arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts @@ -235,8 +235,8 @@ }; &pm4125_vbus { - regulator-min-microamp = <500000>; - regulator-max-microamp = <500000>; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts index 3eedfb2cf4799..8c5f9c79b86a7 100644 --- a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts +++ b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts @@ -318,8 +318,8 @@ }; &pm4125_vbus { - regulator-min-microamp = <500000>; - regulator-max-microamp = <500000>; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; status = "okay"; }; From f29047ed9ef6e55146a279947379f104f54b12ee Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 22 Jul 2026 15:46:08 +0300 Subject: [PATCH 27/30] FROMGIT: clk: qcom: gcc-qcm2290: don't park QUP RCGs upon registration The gcc_qupv3_wrap0_s[0-5]_clk_src RCGs feed the QUP serial engines (UART/I2C/SPI). Since shared RCGs are parked to XO at registration time, binding the gcc-qcm2290 driver reprograms these clocks away from the rate configured by the bootloader. For the UART used as the boot console this drops early console output until the serial driver later reconfigures the clock. Switch the QUP wrap0 clock sources over to clk_rcg2_shared_no_init_park_ops so their frequency is left unchanged at registration time, keeping the bootloader-configured console working across the gcc driver probe. Fixes: 01a0a6cc8cfd ("clk: qcom: Park shared RCGs upon registration") Signed-off-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20260722-agatti-no-park-v1-1-31ae3a4774e5@oss.qualcomm.com Signed-off-by: Bjorn Andersson (cherry picked from commit 9c4cee964e0ccc155e4ab8fa6cec88fffc262c63) Signed-off-by: Ricardo Salveti --- drivers/clk/qcom/gcc-qcm2290.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/clk/qcom/gcc-qcm2290.c b/drivers/clk/qcom/gcc-qcm2290.c index 1c832f1053be9..abef4ad0a8567 100644 --- a/drivers/clk/qcom/gcc-qcm2290.c +++ b/drivers/clk/qcom/gcc-qcm2290.c @@ -1082,7 +1082,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = { .name = "gcc_qupv3_wrap0_s0_clk_src", .parent_data = gcc_parents_1, .num_parents = ARRAY_SIZE(gcc_parents_1), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_no_init_park_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = { @@ -1098,7 +1098,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = { .name = "gcc_qupv3_wrap0_s1_clk_src", .parent_data = gcc_parents_1, .num_parents = ARRAY_SIZE(gcc_parents_1), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_no_init_park_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = { @@ -1114,7 +1114,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = { .name = "gcc_qupv3_wrap0_s2_clk_src", .parent_data = gcc_parents_1, .num_parents = ARRAY_SIZE(gcc_parents_1), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_no_init_park_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = { @@ -1130,7 +1130,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = { .name = "gcc_qupv3_wrap0_s3_clk_src", .parent_data = gcc_parents_1, .num_parents = ARRAY_SIZE(gcc_parents_1), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_no_init_park_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = { @@ -1146,7 +1146,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = { .name = "gcc_qupv3_wrap0_s4_clk_src", .parent_data = gcc_parents_1, .num_parents = ARRAY_SIZE(gcc_parents_1), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_no_init_park_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = { @@ -1162,7 +1162,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = { .name = "gcc_qupv3_wrap0_s5_clk_src", .parent_data = gcc_parents_1, .num_parents = ARRAY_SIZE(gcc_parents_1), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_no_init_park_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = { From 80c257f6c534f2f9bb1358dddb55202d524b3118 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Sebastian=20G=C3=B6tte?= Date: Wed, 29 Jul 2026 19:41:05 +0200 Subject: [PATCH 28/30] UPSTREAM: serial: qcom-geni: fix TX DMA buffer flush MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When transmit flushing a qcom-geni UART during an ongoing TX DMA, the UART gets stuck infinitely repeating corrupted TX DMA frames. The DMA-mode uart_ops does not provide a flush_buffer callback, so an in-flight transfer can complete after serial core has reset the transmit kfifo, underflowing its length and resubmitting page-sized transfers indefinitely. Add one that stops the transfer and clears tx_remaining and tx_queued. The stop path was also broken: it unmapped the buffer while the serial engine could still read it, and never reset the TX DMA state machine. Cancel the main sequencer command first, then reset the state machine and wait for it before unmapping. Drop the early return so a pending mapping is also cleaned up when the main command is inactive. The bug can be triggered from userspace with a large write immediately followed by TCOFLUSH. A following tcdrain will hang forever. The bug was reproduced and this fix was validated on Arduino Uno Q (QRB2210) using /dev/ttyHS1. Assisted-by: Claude:claude-5-opus Codex:gpt-5 Signed-off-by: Jan Sebastian Götte Fixes: 2aaa43c70778 ("tty: serial: qcom-geni-serial: add support for serial engine DMA") Cc: stable Reviewed-by: Praveen Talari Link: https://patch.msgid.link/20260729174105.21838-2-git@jaseg.de Signed-off-by: Greg Kroah-Hartman (cherry picked from commit e3c04834ae1ab5e9cfbe8ac54ec734aa4774249d) Signed-off-by: Ricardo Salveti --- drivers/tty/serial/qcom_geni_serial.c | 43 ++++++++++++++------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index a34817a4428c9..1d561a00cbbd9 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -149,6 +149,7 @@ static const struct uart_ops qcom_geni_uart_pops; static struct uart_driver qcom_geni_console_driver; static struct uart_driver qcom_geni_uart_driver; +static void qcom_geni_serial_stop_tx_dma(struct uart_port *uport); static void __qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport); static void qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport); static int qcom_geni_serial_port_setup(struct uart_port *uport); @@ -627,35 +628,34 @@ static unsigned int qcom_geni_serial_tx_empty(struct uart_port *uport) return !readl(uport->membase + SE_GENI_TX_FIFO_STATUS); } +static void qcom_geni_serial_flush_buffer_dma(struct uart_port *uport) +{ + struct qcom_geni_serial_port *port = to_dev_port(uport); + + qcom_geni_serial_stop_tx_dma(uport); + port->tx_remaining = 0; + port->tx_queued = 0; +} + static void qcom_geni_serial_stop_tx_dma(struct uart_port *uport) { struct qcom_geni_serial_port *port = to_dev_port(uport); - bool done; - if (!qcom_geni_serial_main_active(uport)) - return; + if (qcom_geni_serial_main_active(uport)) + __qcom_geni_serial_cancel_tx_cmd(uport); if (port->tx_dma_addr) { + writel(1, uport->membase + SE_DMA_TX_FSM_RST); + if (!qcom_geni_serial_poll_bit(uport, SE_DMA_TX_IRQ_STAT, + TX_RESET_DONE, true)) + dev_err_ratelimited(uport->dev, "TX DMA reset failed"); + writel(TX_RESET_DONE | TX_DMA_DONE, + uport->membase + SE_DMA_TX_IRQ_CLR); + geni_se_tx_dma_unprep(&port->se, port->tx_dma_addr, port->tx_remaining); port->tx_dma_addr = 0; - port->tx_remaining = 0; } - - geni_se_cancel_m_cmd(&port->se); - - done = qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS, - M_CMD_CANCEL_EN, true); - if (!done) { - geni_se_abort_m_cmd(&port->se); - done = qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS, - M_CMD_ABORT_EN, true); - if (!done) - dev_err_ratelimited(uport->dev, "M_CMD_ABORT_EN not set"); - writel(M_CMD_ABORT_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); - } - - writel(M_CMD_CANCEL_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); } static void qcom_geni_serial_start_tx_dma(struct uart_port *uport) @@ -1171,7 +1171,7 @@ static void qcom_geni_serial_shutdown(struct uart_port *uport) uart_port_unlock_irq(uport); } -static void qcom_geni_serial_flush_buffer(struct uart_port *uport) +static void qcom_geni_serial_flush_buffer_fifo(struct uart_port *uport) { qcom_geni_serial_cancel_tx_cmd(uport); } @@ -1695,7 +1695,7 @@ static const struct uart_ops qcom_geni_console_pops = { .request_port = qcom_geni_serial_request_port, .config_port = qcom_geni_serial_config_port, .shutdown = qcom_geni_serial_shutdown, - .flush_buffer = qcom_geni_serial_flush_buffer, + .flush_buffer = qcom_geni_serial_flush_buffer_fifo, .type = qcom_geni_serial_get_type, .set_mctrl = qcom_geni_serial_set_mctrl, .get_mctrl = qcom_geni_serial_get_mctrl, @@ -1718,6 +1718,7 @@ static const struct uart_ops qcom_geni_uart_pops = { .request_port = qcom_geni_serial_request_port, .config_port = qcom_geni_serial_config_port, .shutdown = qcom_geni_serial_shutdown, + .flush_buffer = qcom_geni_serial_flush_buffer_dma, .type = qcom_geni_serial_get_type, .set_mctrl = qcom_geni_serial_set_mctrl, .get_mctrl = qcom_geni_serial_get_mctrl, From b0fc26ab9610bf87bef9a803d3646abfbd5e51a8 Mon Sep 17 00:00:00 2001 From: Guangshuo Li Date: Wed, 8 Jul 2026 21:17:26 +0800 Subject: [PATCH 29/30] FROMGIT: serial: qcom-geni: do not advance stale DMA completions The qcom GENI serial DMA TX completion path advances the transmit fifo by the number of bytes recorded in port->tx_remaining. If uart_flush_buffer() runs after the hardware has completed a DMA transfer but before the DMA completion interrupt has been handled, the serial core resets the transmit fifo while port->tx_remaining still describes the old DMA transfer. A previous fix avoided advancing an empty fifo by checking that the fifo length is at least tx_remaining. That still does not distinguish the old DMA payload from new bytes written after the flush. If userspace writes new data before the stale DMA completion interrupt is handled, the fifo can again contain at least tx_remaining bytes and the stale completion can advance and discard those new bytes. Mark an in-flight DMA transfer stale when the transmit fifo is flushed. The later completion still unprepares the original DMA mapping using the saved length, but it no longer advances the transmit fifo. Fixes: 2aaa43c70778 ("tty: serial: qcom-geni-serial: add support for serial engine DMA") Signed-off-by: Guangshuo Li Link: https://patch.msgid.link/20260708131726.768692-1-lgs201920130244@gmail.com Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 7ea38c49e7178960926657863299face6dc0e1b0) Signed-off-by: Ricardo Salveti --- drivers/tty/serial/qcom_geni_serial.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index 1d561a00cbbd9..953b737357103 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -136,6 +136,7 @@ struct qcom_geni_serial_port { unsigned int tx_remaining; unsigned int tx_queued; + bool tx_dma_stale; int wakeup_irq; bool rx_tx_swap; bool cts_rts_swap; @@ -688,6 +689,7 @@ static void qcom_geni_serial_start_tx_dma(struct uart_port *uport) } port->tx_remaining = xmit_size; + port->tx_dma_stale = false; } static void qcom_geni_serial_start_tx_fifo(struct uart_port *uport) @@ -1020,6 +1022,7 @@ static void qcom_geni_serial_handle_tx_dma(struct uart_port *uport) struct qcom_geni_serial_port *port = to_dev_port(uport); struct tty_port *tport = &uport->state->port; unsigned int fifo_len = kfifo_len(&tport->xmit_fifo); + bool tx_dma_stale = port->tx_dma_stale; /* * Only advance the kfifo if it still contains the bytes that were @@ -1030,12 +1033,13 @@ static void qcom_geni_serial_handle_tx_dma(struct uart_port *uport) * kfifo->in, making kfifo_len() wrap to UART_XMIT_SIZE - tx_remaining * and triggering a spurious large DMA transfer of stale data. */ - if (fifo_len >= port->tx_remaining) + if (!tx_dma_stale && fifo_len >= port->tx_remaining) uart_xmit_advance(uport, port->tx_remaining); geni_se_tx_dma_unprep(&port->se, port->tx_dma_addr, port->tx_remaining); port->tx_dma_addr = 0; port->tx_remaining = 0; + port->tx_dma_stale = false; if (!kfifo_is_empty(&tport->xmit_fifo)) qcom_geni_serial_start_tx_dma(uport); @@ -1173,6 +1177,10 @@ static void qcom_geni_serial_shutdown(struct uart_port *uport) static void qcom_geni_serial_flush_buffer_fifo(struct uart_port *uport) { + struct qcom_geni_serial_port *port = to_dev_port(uport); + + if (port->tx_dma_addr) + port->tx_dma_stale = true; qcom_geni_serial_cancel_tx_cmd(uport); } From 6e188e5097bcd1ecef97849271706eec8ededf14 Mon Sep 17 00:00:00 2001 From: Ricardo Salveti Date: Thu, 20 Aug 2026 03:04:39 +0000 Subject: [PATCH 30/30] QCLINUX: arm64: defconfig: Enable multicolor LED group support The Arduino UNO Q exposes its three user LEDs (red, green, blue) both individually and as a single RGB LED through the leds-group-multicolor driver. Enable it as a module so the multi-led node in qrb2210-arduino-imola.dts probes. Signed-off-by: Ricardo Salveti --- arch/arm64/configs/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index f2d30d8ee4703..0108c46cd4964 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1277,6 +1277,7 @@ CONFIG_LEDS_GPIO=y CONFIG_LEDS_PWM=y CONFIG_LEDS_SYSCON=y CONFIG_LEDS_QCOM_FLASH=m +CONFIG_LEDS_GROUP_MULTICOLOR=m CONFIG_LEDS_QCOM_LPG=m CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_DISK=y