From 9736e78227999bb9d48b64db12c24c1489aa7626 Mon Sep 17 00:00:00 2001 From: Gopikishan Thawre Date: Thu, 10 Sep 2026 14:44:31 +0530 Subject: [PATCH 1/7] dt-bindings: arm: qcom: Add LeMans Draco EVK compatible strings Add the compatible string for the Qualcomm LeMans Draco EVK board (SA8775P/QCS9100 SoC). The compatible chain is: qcom,lemans-draco-evk qcom,lemans-draco-evk-som qcom,qcs9100 qcom,sa8775p Signed-off-by: Gopikishan Thawre --- Documentation/devicetree/bindings/arm/qcom.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml index ff8a35df7862d..67530e35b79aa 100644 --- a/Documentation/devicetree/bindings/arm/qcom.yaml +++ b/Documentation/devicetree/bindings/arm/qcom.yaml @@ -467,6 +467,13 @@ properties: - qcom,sa8775p-ride-r3 - const: qcom,sa8775p + - items: + - enum: + - qcom,lemans-draco-evk + - const: qcom,lemans-draco-evk-som + - const: qcom,qcs9100 + - const: qcom,sa8775p + - items: - enum: - qcom,lemans-evk From 885a81b3be393d4eb7fb4202806b3f0f5a88b7c6 Mon Sep 17 00:00:00 2001 From: Gopikishan Thawre Date: Thu, 10 Sep 2026 14:44:36 +0530 Subject: [PATCH 2/7] arm64: dts: qcom: Add lemans-draco-evk.dtb to Makefile Add build entry for the LeMans Draco EVK board DTB. Signed-off-by: Gopikishan Thawre --- arch/arm64/boot/dts/qcom/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 1c86e7e98f55d..3fb366f270396 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -45,6 +45,7 @@ dtb-$(CONFIG_ARCH_QCOM) += ipq9650-rdp488.dtb dtb-$(CONFIG_ARCH_QCOM) += kaanapali-mtp.dtb dtb-$(CONFIG_ARCH_QCOM) += kaanapali-qrd.dtb dtb-$(CONFIG_ARCH_QCOM) += lemans-evk.dtb +dtb-$(CONFIG_ARCH_QCOM) += lemans-draco-evk.dtb lemans-evk-camera-csi1-imx577-dtbs := lemans-evk.dtb lemans-evk-camera-csi1-imx577.dtbo lemans-evk-camera-dtbs := lemans-evk.dtb lemans-evk-camera.dtbo From 8db5519c7b6f64f608e6a2edeea2076395ae0a62 Mon Sep 17 00:00:00 2001 From: Gopikishan Thawre Date: Thu, 10 Sep 2026 14:44:43 +0530 Subject: [PATCH 3/7] arm64: dts: qcom: Add LeMans Draco EVK SOM device tree Add device tree for the LeMans Draco EVK System-on-Module (SOM) based on the SA8775P/QCS9100 SoC. The SOM includes: - Complete RPMH regulator configuration for three pmm8654au PMICs: pmic-id a: smps4/5/9 and ldo4/5/6/7/8/9 pmic-id c: ldo1/2/3/4/5/6/7/8/9 pmic-id e: smps4/7/9 and ldo6/8 - Firmware paths for QUP firmware and remote processors (ADSP, CDSP0) - Debug UART (uart0) - XO board clock at 38.4 MHz, sleep clock at 32.768 kHz Signed-off-by: Gopikishan Thawre --- .../boot/dts/qcom/lemans-draco-evk-som.dtsi | 317 ++++++++++++++++++ 1 file changed, 317 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/lemans-draco-evk-som.dtsi diff --git a/arch/arm64/boot/dts/qcom/lemans-draco-evk-som.dtsi b/arch/arm64/boot/dts/qcom/lemans-draco-evk-som.dtsi new file mode 100644 index 0000000000000..c84a79ef06220 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/lemans-draco-evk-som.dtsi @@ -0,0 +1,317 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +/dts-v1/; + +#include +#include "lemans.dtsi" +#include "lemans-pmics.dtsi" +/ { + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&apps_rsc { + regulators-0 { + compatible = "qcom,pmm8654au-rpmh-regulators"; + qcom,pmic-id = "a"; + + vreg_s4a: smps4 { + regulator-name = "vreg_s4a"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1816000>; + regulator-initial-mode = ; + }; + + vreg_s5a: smps5 { + regulator-name = "vreg_s5a"; + regulator-min-microvolt = <1850000>; + regulator-max-microvolt = <1996000>; + regulator-initial-mode = ; + }; + + vreg_s9a: smps9 { + regulator-name = "vreg_s9a"; + regulator-min-microvolt = <535000>; + regulator-max-microvolt = <1120000>; + regulator-initial-mode = ; + }; + + vreg_l4a: ldo4 { + regulator-name = "vreg_l4a"; + regulator-min-microvolt = <788000>; + regulator-max-microvolt = <1050000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l5a: ldo5 { + regulator-name = "vreg_l5a"; + regulator-min-microvolt = <870000>; + regulator-max-microvolt = <950000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l6a: ldo6 { + regulator-name = "vreg_l6a"; + regulator-min-microvolt = <870000>; + regulator-max-microvolt = <970000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l7a: ldo7 { + regulator-name = "vreg_l7a"; + regulator-min-microvolt = <720000>; + regulator-max-microvolt = <950000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l8a: ldo8 { + regulator-name = "vreg_l8a"; + regulator-min-microvolt = <2504000>; + regulator-max-microvolt = <3300000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l9a: ldo9 { + regulator-name = "vreg_l9a"; + regulator-min-microvolt = <2970000>; + regulator-max-microvolt = <3544000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + }; + + regulators-1 { + compatible = "qcom,pmm8654au-rpmh-regulators"; + qcom,pmic-id = "c"; + + vreg_l1c: ldo1 { + regulator-name = "vreg_l1c"; + regulator-min-microvolt = <1140000>; + regulator-max-microvolt = <1260000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l2c: ldo2 { + regulator-name = "vreg_l2c"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1100000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l3c: ldo3 { + regulator-name = "vreg_l3c"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1300000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l4c: ldo4 { + regulator-name = "vreg_l4c"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l5c: ldo5 { + regulator-name = "vreg_l5c"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1300000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l6c: ldo6 { + regulator-name = "vreg_l6c"; + regulator-min-microvolt = <1620000>; + regulator-max-microvolt = <1980000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l7c: ldo7 { + regulator-name = "vreg_l7c"; + regulator-min-microvolt = <1620000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l8c: ldo8 { + regulator-name = "vreg_l8c"; + regulator-min-microvolt = <2400000>; + regulator-max-microvolt = <3300000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l9c: ldo9 { + regulator-name = "vreg_l9c"; + regulator-min-microvolt = <1650000>; + regulator-max-microvolt = <2700000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + }; + + regulators-2 { + compatible = "qcom,pmm8654au-rpmh-regulators"; + qcom,pmic-id = "e"; + + vreg_s4e: smps4 { + regulator-name = "vreg_s4e"; + regulator-min-microvolt = <970000>; + regulator-max-microvolt = <1520000>; + regulator-initial-mode = ; + }; + + vreg_s7e: smps7 { + regulator-name = "vreg_s7e"; + regulator-min-microvolt = <1010000>; + regulator-max-microvolt = <1170000>; + regulator-initial-mode = ; + }; + + vreg_s9e: smps9 { + regulator-name = "vreg_s9e"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <570000>; + regulator-initial-mode = ; + }; + + vreg_l6e: ldo6 { + regulator-name = "vreg_l6e"; + regulator-min-microvolt = <1280000>; + regulator-max-microvolt = <1450000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l8e: ldo8 { + regulator-name = "vreg_l8e"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1950000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + }; +}; + +&gpu_zap_shader { + firmware-name = "qcom/sa8775p/a663_zap.mbn"; +}; + +&iris { + firmware-name = "qcom/vpu/vpu30_p4_s6_16mb.mbn"; + + status = "okay"; +}; + +&qupv3_id_0 { + firmware-name = "qcom/sa8775p/qupv3fw.elf"; + + status = "okay"; +}; + +&qupv3_id_1 { + firmware-name = "qcom/sa8775p/qupv3fw.elf"; + + status = "okay"; +}; + +&qupv3_id_2 { + firmware-name = "qcom/sa8775p/qupv3fw.elf"; + + status = "okay"; +}; + +&remoteproc_adsp { + firmware-name = "qcom/sa8775p/adsp.mbn"; + + status = "okay"; +}; + +&remoteproc_cdsp0 { + firmware-name = "qcom/sa8775p/cdsp0.mbn"; + + status = "okay"; +}; + +&remoteproc_cdsp1 { + firmware-name = "qcom/sa8775p/cdsp1.mbn"; + + status = "okay"; +}; + +&remoteproc_gpdsp0 { + firmware-name = "qcom/sa8775p/gpdsp0.mbn"; + + status = "okay"; +}; + +&remoteproc_gpdsp1 { + firmware-name = "qcom/sa8775p/gpdsp1.mbn"; + + status = "okay"; +}; + +&sleep_clk { + clock-frequency = <32768>; +}; + +&uart0 { + status = "okay"; +}; + +&xo_board_clk { + clock-frequency = <38400000>; +}; From d5c1ee44f7fd4da741dcbeb06d4e774d3c981558 Mon Sep 17 00:00:00 2001 From: Gopikishan Thawre Date: Fri, 18 Sep 2026 13:53:28 +0530 Subject: [PATCH 4/7] arm64: dts: qcom: lemans-draco-evk: add device tree and board support Add top-level board device tree and extend the SOM DTSI with peripherals for the Qualcomm LeMans Draco EVK carrier board: - Five I2C GPIO expanders on i2c2: four TCA6416-compatible at 0x20-0x23 (U236, U238, U422, U417) for camera/display MUX and power enables, one PCA9534-compatible (U445) at 0x38 for camera MCLK enables - EEPROM (U?,giantec,gt24c256c) at 0x50 with MAC address nvmem layout - uart10 as the geni-debug-uart (console) - ufs_mem_hc and ufs_mem_phy with regulator assignments - USB nodes: usb_0, usb_0_hsphy, usb_0_qmpphy, usb_2 and usb_2_hsphy - pmm8654au_2 GPIO states for USB interrupt and ID lines - Remoteproc SMMU stream IDs for ADSP, CDSP0/1, GPDSP0/1 - Correct mmc1 alias (was mmc0); serial0 -> uart10, serial2 -> uart0 - Remove pcie0, pcie1 and ethernet0 -- not present on this board Signed-off-by: Gopikishan Thawre --- .../boot/dts/qcom/lemans-draco-evk-som.dtsi | 104 ++++++++++-- arch/arm64/boot/dts/qcom/lemans-draco-evk.dts | 157 ++++++++++++++++++ 2 files changed, 246 insertions(+), 15 deletions(-) create mode 100644 arch/arm64/boot/dts/qcom/lemans-draco-evk.dts diff --git a/arch/arm64/boot/dts/qcom/lemans-draco-evk-som.dtsi b/arch/arm64/boot/dts/qcom/lemans-draco-evk-som.dtsi index c84a79ef06220..c70f85781bdc1 100644 --- a/arch/arm64/boot/dts/qcom/lemans-draco-evk-som.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans-draco-evk-som.dtsi @@ -2,14 +2,18 @@ /* * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ -/dts-v1/; +#include +#include #include #include "lemans.dtsi" #include "lemans-pmics.dtsi" + / { aliases { - serial0 = &uart0; + mmc1 = &sdhc; + serial0 = &uart10; + serial2 = &uart0; }; chosen { @@ -256,6 +260,29 @@ status = "okay"; }; +&pmm8654au_0_pon_resin { + linux,code = ; + status = "okay"; +}; + +&pmm8654au_2_gpios { + usb0_intr_state: usb0-intr-state { + pins = "gpio5"; + function = "normal"; + input-enable; + bias-pull-up; + power-source = <0>; + }; + + usb2_id: usb2-id-state { + pins = "gpio11"; + function = "normal"; + input-enable; + bias-pull-up; + power-source = <0>; + }; +}; + &qupv3_id_0 { firmware-name = "qcom/sa8775p/qupv3fw.elf"; @@ -274,41 +301,88 @@ status = "okay"; }; -&remoteproc_adsp { - firmware-name = "qcom/sa8775p/adsp.mbn"; +&sleep_clk { + clock-frequency = <32768>; +}; + +&tlmm { + qup_i2c11_default: qup-i2c11-state { + pins = "gpio48", "gpio49"; + function = "qup1_se4"; + drive-strength = <2>; + bias-pull-up; + }; + + sd_cd: sd-cd-state { + pins = "gpio36"; + function = "gpio"; + bias-pull-up; + }; + + usb_id: usb-id-state { + pins = "gpio50"; + function = "gpio"; + bias-pull-up; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart10 { + compatible = "qcom,geni-debug-uart"; + pinctrl-0 = <&qup_uart10_default>; + pinctrl-names = "default"; status = "okay"; }; -&remoteproc_cdsp0 { - firmware-name = "qcom/sa8775p/cdsp0.mbn"; +&ufs_mem_hc { + reset-gpios = <&tlmm 149 GPIO_ACTIVE_LOW>; + vcc-supply = <&vreg_l8a>; + vcc-max-microamp = <1100000>; + vccq-supply = <&vreg_l4c>; + vccq-max-microamp = <1200000>; status = "okay"; }; -&remoteproc_cdsp1 { - firmware-name = "qcom/sa8775p/cdsp1.mbn"; +&ufs_mem_phy { + vdda-phy-supply = <&vreg_l4a>; + vdda-pll-supply = <&vreg_l1c>; status = "okay"; }; -&remoteproc_gpdsp0 { - firmware-name = "qcom/sa8775p/gpdsp0.mbn"; +&usb_0 { + status = "okay"; +}; + +&usb_0_hsphy { + vdda-pll-supply = <&vreg_l7a>; + vdda18-supply = <&vreg_l6c>; + vdda33-supply = <&vreg_l9a>; status = "okay"; }; -&remoteproc_gpdsp1 { - firmware-name = "qcom/sa8775p/gpdsp1.mbn"; +&usb_0_qmpphy { + vdda-phy-supply = <&vreg_l1c>; + vdda-pll-supply = <&vreg_l7a>; status = "okay"; }; -&sleep_clk { - clock-frequency = <32768>; +&usb_2 { + status = "okay"; }; -&uart0 { +&usb_2_hsphy { + vdda-pll-supply = <&vreg_l7a>; + vdda18-supply = <&vreg_l6c>; + vdda33-supply = <&vreg_l9a>; + status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/lemans-draco-evk.dts b/arch/arm64/boot/dts/qcom/lemans-draco-evk.dts new file mode 100644 index 0000000000000..f7fd5c54524f9 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/lemans-draco-evk.dts @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +/dts-v1/; + +#include "lemans-draco-evk-som.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. Lemans Draco EVK"; + compatible = "qcom,lemans-draco-evk", "qcom,lemans-draco-evk-som", "qcom,qcs9100", + "qcom,sa8775p"; + chassis-type = "embedded"; +}; + +&i2c2 { + status = "okay"; + + /* + * U236: 16-bit GPIO expander (KTS1620EUAA-TR, TCA6416-compatible) + * Address 0x20 (A1=VDD, A2=A0=GND). Camera OCP power enables, + * USB power enables and detection signals. + * INT_N → EXP2_INT → SoC TLMM gpio22. + */ + expander0: gpio@20 { + compatible = "ti,tca6416"; + reg = <0x20>; + #gpio-cells = <2>; + gpio-controller; + }; + + /* + * U238: 16-bit GPIO expander (KTS1620EUAA-TR, TCA6416-compatible) + * Address 0x21 (A1=VDD, A0=VDD, A2=GND). USB2 power, PCIe power + * enables, display/SAL-ETH power enables. + * INT_N → EXP3_INT → SoC TLMM gpio22. + */ + expander1: gpio@21 { + compatible = "ti,tca6416"; + reg = <0x21>; + #gpio-cells = <2>; + gpio-controller; + }; + + /* + * U422: 16-bit GPIO expander (KTS1620EUAA-TR, TCA6416-compatible) + * Address 0x22 (A1=VDD, A2=A0=GND). + * INT_N → SoC TLMM gpio22. + */ + expander2: gpio@22 { + compatible = "ti,tca6416"; + reg = <0x22>; + #gpio-cells = <2>; + gpio-controller; + }; + + /* + * U417: 16-bit GPIO expander (KTS1620EUAA-TR, TCA6416-compatible) + * Address 0x23 (A1=VDD, A0=VDD, A2=GND). + * INT_N → SoC TLMM gpio22. + */ + expander3: gpio@23 { + compatible = "ti,tca6416"; + reg = <0x23>; + #gpio-cells = <2>; + gpio-controller; + }; + + /* + * U445: 8-bit GPIO expander (TCA9534APWR, PCA9534-compatible) + * Address 0x38 (A2=A1=A0=GND, base 0x38). Camera MCLK enables on + * P0–P4; P5–P7 are unconnected test points. + * INT_N → IOEXP_INT → SoC TLMM gpio22. + */ + expander4: gpio@38 { + compatible = "nxp,pca9534"; + reg = <0x38>; + #gpio-cells = <2>; + gpio-controller; + }; + + eeprom@50 { + compatible = "giantec,gt24c256c", "atmel,24c256"; + reg = <0x50>; + pagesize = <64>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + mac_addr0: mac-addr@0 { + reg = <0x0 0x6>; + }; + }; + }; +}; + +&tlmm { + expander_int: expander-int-state { + pins = "gpio22"; + function = "gpio"; + bias-pull-up; + input-enable; + }; +}; + +&i2c18 { + status = "okay"; + + /* + * U76: 8-bit GPIO expander (TCA9534APWR, PCA9534-compatible) + * Address 0x3c. M.2 Key-B & Key-E PCIe control. + * INT_N → EXP1_INT_N → TP150 (no SoC interrupt connection). + */ + expander5: gpio@3c { + compatible = "nxp,pca9534"; + reg = <0x3c>; + #gpio-cells = <2>; + gpio-controller; + }; +}; + +&remoteproc_adsp { + firmware-name = "qcom/sa8775p/adsp.mbn"; + iommus = <&apps_smmu 0x3000 0x0>; + + status = "okay"; +}; + +&remoteproc_cdsp0 { + firmware-name = "qcom/sa8775p/cdsp0.mbn"; + iommus = <&apps_smmu 0x21c0 0x0400>; + + status = "okay"; +}; + +&remoteproc_cdsp1 { + firmware-name = "qcom/sa8775p/cdsp1.mbn"; + iommus = <&apps_smmu 0x29c0 0x0400>; + + status = "okay"; +}; + +&remoteproc_gpdsp0 { + firmware-name = "qcom/sa8775p/gpdsp0.mbn"; + iommus = <&apps_smmu 0x38a0 0x0>; + + status = "okay"; +}; + +&remoteproc_gpdsp1 { + firmware-name = "qcom/sa8775p/gpdsp1.mbn"; + iommus = <&apps_smmu 0x38c0 0x0>; + + status = "okay"; +}; From 7ad18e55bad21bcc59d970d825012a088443da98 Mon Sep 17 00:00:00 2001 From: Sushrut Shree Trivedi Date: Tue, 15 Sep 2026 17:30:21 +0530 Subject: [PATCH 5/7] arm64: dts: qcom: lemans-draco-evk: Enable PCIe Enable PCIe0 and PCIe1 on the Lemans based Draco EVK platform. PCIe0 connects to the NTN3 switch while PCIe1 can be routed either to an x4 slot or M.2 M-key slot based on dip switches configuration. Upstream-Status: Pending Signed-off-by: Sushrut Shree Trivedi --- arch/arm64/boot/dts/qcom/lemans-draco-evk.dts | 183 ++++++++++++++++++ 1 file changed, 183 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/lemans-draco-evk.dts b/arch/arm64/boot/dts/qcom/lemans-draco-evk.dts index f7fd5c54524f9..a9fcd0a88d848 100644 --- a/arch/arm64/boot/dts/qcom/lemans-draco-evk.dts +++ b/arch/arm64/boot/dts/qcom/lemans-draco-evk.dts @@ -11,6 +11,24 @@ compatible = "qcom,lemans-draco-evk", "qcom,lemans-draco-evk-som", "qcom,qcs9100", "qcom,sa8775p"; chassis-type = "embedded"; + + vreg_0p9: regulator-0v9 { + compatible = "regulator-fixed"; + regulator-name = "VREG_0P9"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-always-on; + regulator-boot-on; + }; + + vreg_1p8: regulator-1v8 { + compatible = "regulator-fixed"; + regulator-name = "VREG_1P8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; }; &i2c2 { @@ -103,6 +121,59 @@ bias-pull-up; input-enable; }; + + pcie0_default_state: pcie0-default-state { + clkreq-pins { + pins = "gpio1"; + function = "pcie0_clkreq"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-pins { + pins = "gpio2"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + + wake-pins { + pins = "gpio0"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie1_default_state: pcie1-default-state { + clkreq-pins { + pins = "gpio3"; + function = "pcie1_clkreq"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-pins { + pins = "gpio4"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + + wake-pins { + pins = "gpio5"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + tc9563_resx_n: tc9563-resx-state { + pins = "gpio10"; + function = "gpio"; + bias-disable; + output-high; + }; }; &i2c18 { @@ -121,6 +192,118 @@ }; }; +&pcie0 { + perst-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&pcie0_default_state>; + pinctrl-names = "default"; + + iommu-map = <0x0 &pcie_smmu 0x0 0x0 0x1>, + <0x100 &pcie_smmu 0x1 0x0 0x1>, + <0x208 &pcie_smmu 0x2 0x0 0x1>, + <0x210 &pcie_smmu 0x3 0x0 0x1>, + <0x218 &pcie_smmu 0x4 0x0 0x1>, + <0x300 &pcie_smmu 0x5 0x0 0x1>, + <0x400 &pcie_smmu 0x6 0x0 0x1>, + <0x500 &pcie_smmu 0x7 0x0 0x1>, + <0x501 &pcie_smmu 0x8 0x0 0x1>; + + status = "okay"; +}; + +&pcie0_phy { + vdda-phy-supply = <&vreg_l5a>; + vdda-pll-supply = <&vreg_l1c>; + vdda-qref-supply = <&vreg_l4a>; + vdda-refgen-supply = <&vreg_l7a>; + status = "okay"; +}; + +&pcie1 { + perst-gpios = <&tlmm 4 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 5 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&pcie1_default_state>; + pinctrl-names = "default"; + status = "okay"; +}; + +&pcie1_phy { + vdda-phy-supply = <&vreg_l5a>; + vdda-pll-supply = <&vreg_l1c>; + vdda-qref-supply = <&vreg_l4a>; + vdda-refgen-supply = <&vreg_l7a>; + status = "okay"; +}; + +&pcieport0 { + #address-cells = <3>; + #size-cells = <2>; + + pcie@0,0 { + compatible = "pci1179,0623"; + reg = <0x10000 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges; + bus-range = <0x2 0xff>; + + vddc-supply = <&vreg_0p9>; + vdd18-supply = <&vreg_1p8>; + vdd09-supply = <&vreg_0p9>; + vddio1-supply = <&vreg_1p8>; + vddio2-supply = <&vreg_1p8>; + vddio18-supply = <&vreg_1p8>; + i2c-parent = <&i2c18 0x77>; + resx-gpios = <&tlmm 10 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&tc9563_resx_n>; + pinctrl-names = "default"; + + pcie@1,0 { + reg = <0x20800 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges; + bus-range = <0x3 0xff>; + }; + + pcie@2,0 { + reg = <0x21000 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges; + bus-range = <0x4 0xff>; + }; + + pcie@3,0 { + reg = <0x21800 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges; + bus-range = <0x5 0xff>; + + pcie@0,0 { + reg = <0x50000 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges; + }; + + pcie@0,1 { + reg = <0x50100 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges; + }; + }; + }; +}; + &remoteproc_adsp { firmware-name = "qcom/sa8775p/adsp.mbn"; iommus = <&apps_smmu 0x3000 0x0>; From 16070dcf1f31ad6cb950e94093af98cd2651b425 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Mon, 7 Sep 2026 16:33:49 +0200 Subject: [PATCH 6/7] FROMLIST: PCI: qcom: Honor IOMMU provider's #iommu-cells in qcom_pcie_config_sid_1_9_0() qcom_pcie_config_sid_1_9_0() reads the "iommu-map" property as an array of fixed four-word {rid-base, phandle, sid, rid-len} entries to program the BDF to SID translation table. But that layout only holds for an IOMMU with '#iommu-cells = <1>'. The PCIe SMMUs on these SoCs use '#iommu-cells = <2>' (SID and mask), so per the pci-iommu binding each entry is really five cells long. This used to work only because the DTs were themselves broken. They described iommu-map with four-cell entries that omitted the SID mask, which of_map_id() tolerated via its of_check_bad_map() fallback, and the four-word parsing coincidentally matched that malformed shape. Since commit ccb2fd725d41 ("of: Respect #{iommu,msi}-cells in maps") the OF core parses such maps correctly, so the device trees were converted to proper five-cell entries, e.g. commit c41749e9554d ("arm64: dts: qcom: sm8250: Fix the PCIe iommu-map entries"). With five-cell entries the fixed four-word stride slips by one cell for each entry after the first, so qcom_pcie_config_sid_1_9_0() reads the endpoint mapping's RID from the preceding entry's length cell and its SID from the phandle cell. As the RID is the hash key, the endpoint's real RID is never programmed into the BDF to SID table. Its DMA then hashes to an unprogrammed slot, gets tagged with SID 0 and the SMMU faults like below on QCS8300: arm-smmu 15200000.iommu: Unhandled context fault: fsr=0x402, iova=0xffa00000, cbfrsynra=0x0, cb=1 To fix this, walk the map with a stride of 3 + '#iommu-cells' of the referenced IOMMU and take the SID from the first specifier cell, which is all the BDF to SID table needs. Validate the layout instead of trusting the array size. Also, preserve the legacy behavior of the old DTs by detecting the same pattern that of_check_bad_map() recognizes and falling back to a stride of four. Fixes: 4c9398822106 ("PCI: qcom: Add support for configuring BDF to SID mapping for SM8250") Reported-by: Loic Poulain Signed-off-by: Manivannan Sadhasivam Link: https://lore.kernel.org/r/20260907143349.317495-1-mani@kernel.org Signed-off-by: Ziyue Zhang Signed-off-by: Miaoqing Pan Upstream-Status: Pending --- drivers/pci/controller/dwc/pcie-qcom.c | 90 ++++++++++++++++++-------- 1 file changed, 64 insertions(+), 26 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index b58a607b713f5..42cbeef083caf 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -1143,50 +1143,90 @@ static void qcom_pcie_deinit_2_7_0(struct qcom_pcie *pcie) static int qcom_pcie_config_sid_1_9_0(struct qcom_pcie *pcie) { - /* iommu map structure */ - struct { - u32 bdf; - u32 phandle; - u32 smmu_sid; - u32 smmu_sid_len; - } *map; void __iomem *bdf_to_sid_base = pcie->parf + PARF_BDF_TO_SID_TABLE_N; struct device *dev = pcie->pci->dev; + struct device_node *iommu_np; u8 qcom_pcie_crc8_table[CRC8_TABLE_SIZE]; - int i, nr_map, size = 0; - u32 smmu_sid_base; + const __be32 *map; + u32 iommu_cells, entry_cells, phandle, smmu_sid_base; + int i, nr_cells, nr_map, size = 0; u32 val; - of_get_property(dev->of_node, "iommu-map", &size); - if (!size) + map = of_get_property(dev->of_node, "iommu-map", &size); + if (!map || !size) return 0; + if (size % sizeof(*map)) { + dev_err(dev, "Malformed iommu-map property\n"); + return -EINVAL; + } + nr_cells = size / sizeof(*map); + + /* + * Each iommu-map entry is: rid-base (1 cell), phandle (1 cell), + * IOMMU specifier (#iommu-cells cells), length (1 cell). Read + * #iommu-cells from the IOMMU provider referenced by the first + * entry to compute the per-entry stride. + */ + phandle = be32_to_cpu(map[1]); + iommu_np = of_find_node_by_phandle(phandle); + if (!iommu_np) { + dev_err(dev, "Failed to find IOMMU node in iommu-map\n"); + return -ENODEV; + } + + if (of_property_read_u32(iommu_np, "#iommu-cells", &iommu_cells)) + iommu_cells = 1; + of_node_put(iommu_np); + + entry_cells = 3 + iommu_cells; + + /* + * Retain backward compatibility with DTs that describe iommu-map + * with 4-cell entries against an IOMMU declaring #iommu-cells = 2, + * matching the fallback in drivers/of/base.c::of_check_bad_map(). + */ + if (iommu_cells == 2 && !(nr_cells % 4)) { + bool legacy = true; + + for (i = 0; i < nr_cells; i += 4) { + if (be32_to_cpu(map[i + 1]) != phandle || + be32_to_cpu(map[i + 3]) != 1) { + legacy = false; + break; + } + } + + if (legacy) { + dev_warn_once(dev, "iommu-map has 1-cell entries targeting 2-cell #iommu-cells, treating as 1-cell output\n"); + entry_cells = 4; + } + } + + if (nr_cells % entry_cells) { + dev_err(dev, "Malformed iommu-map property\n"); + return -EINVAL; + } + nr_map = nr_cells / entry_cells; + /* Enable BDF to SID translation by disabling bypass mode (default) */ val = readl(pcie->parf + PARF_BDF_TO_SID_CFG); val &= ~BDF_TO_SID_BYPASS; writel(val, pcie->parf + PARF_BDF_TO_SID_CFG); - map = kzalloc(size, GFP_KERNEL); - if (!map) - return -ENOMEM; - - of_property_read_u32_array(dev->of_node, "iommu-map", (u32 *)map, - size / sizeof(u32)); - - nr_map = size / (sizeof(*map)); - crc8_populate_msb(qcom_pcie_crc8_table, QCOM_PCIE_CRC8_POLYNOMIAL); /* Registers need to be zero out first */ memset_io(bdf_to_sid_base, 0, CRC8_TABLE_SIZE * sizeof(u32)); /* Extract the SMMU SID base from the first entry of iommu-map */ - smmu_sid_base = map[0].smmu_sid; + smmu_sid_base = be32_to_cpu(map[2]); /* Look for an available entry to hold the mapping */ for (i = 0; i < nr_map; i++) { - __be16 bdf_be = cpu_to_be16(map[i].bdf); - u32 val; + u32 bdf = be32_to_cpu(map[i * entry_cells]); + u32 sid = be32_to_cpu(map[i * entry_cells + 2]); + __be16 bdf_be = cpu_to_be16(bdf); u8 hash; hash = crc8(qcom_pcie_crc8_table, (u8 *)&bdf_be, sizeof(bdf_be), 0); @@ -1208,12 +1248,10 @@ static int qcom_pcie_config_sid_1_9_0(struct qcom_pcie *pcie) } /* BDF [31:16] | SID [15:8] | NEXT [7:0] */ - val = map[i].bdf << 16 | (map[i].smmu_sid - smmu_sid_base) << 8 | 0; + val = bdf << 16 | (sid - smmu_sid_base) << 8 | 0; writel(val, bdf_to_sid_base + hash * sizeof(u32)); } - kfree(map); - return 0; } From 16d0ff9af2c2fe4fd499ff7113c5deadca94a83c Mon Sep 17 00:00:00 2001 From: Wei Deng Date: Thu, 17 Sep 2026 15:22:59 +0530 Subject: [PATCH 7/7] arm64: dts: qcom: Enable Lemans Draco connectivity Enable the M.2 E-key connectivity slot on Lemans Draco EVK by describing its always-on 3.3 V supply and PCIe and UART graph connections. Describe W_DISABLE2# so pwrseq-pcie-m2 can control Bluetooth power through UART17. Upstream-Status: Pending Signed-off-by: Wei Deng --- arch/arm64/boot/dts/qcom/lemans-draco-evk.dts | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/lemans-draco-evk.dts b/arch/arm64/boot/dts/qcom/lemans-draco-evk.dts index a9fcd0a88d848..9757c46033c3c 100644 --- a/arch/arm64/boot/dts/qcom/lemans-draco-evk.dts +++ b/arch/arm64/boot/dts/qcom/lemans-draco-evk.dts @@ -12,6 +12,10 @@ "qcom,sa8775p"; chassis-type = "embedded"; + aliases { + serial1 = &uart17; + }; + vreg_0p9: regulator-0v9 { compatible = "regulator-fixed"; regulator-name = "VREG_0P9"; @@ -29,6 +33,48 @@ regulator-always-on; regulator-boot-on; }; + + vreg_keye_3p3: regulator-keye-3p3 { + compatible = "regulator-fixed"; + regulator-name = "vreg_keye_3p3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + wifi-bt-connector { + compatible = "pcie-m2-e-connector"; + vpcie3v3-supply = <&vreg_keye_3p3>; + w-disable2-gpios = <&pmm8654au_1_gpios 8 GPIO_ACTIVE_LOW>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + m2_e_pcie_ep: endpoint@0 { + reg = <0>; + remote-endpoint = <&tc9563_pcie1_ep>; + }; + }; + + port@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + + m2_e_uart_ep: endpoint@0 { + reg = <0>; + remote-endpoint = <&uart17_ep>; + }; + }; + }; + }; + }; &i2c2 { @@ -266,6 +312,10 @@ device_type = "pci"; ranges; bus-range = <0x3 0xff>; + + port { + tc9563_pcie1_ep: endpoint {}; + }; }; pcie@2,0 { @@ -304,6 +354,10 @@ }; }; +&tc9563_pcie1_ep { + remote-endpoint = <&m2_e_pcie_ep>; +}; + &remoteproc_adsp { firmware-name = "qcom/sa8775p/adsp.mbn"; iommus = <&apps_smmu 0x3000 0x0>; @@ -338,3 +392,13 @@ status = "okay"; }; + +&uart17 { + status = "okay"; + + port { + uart17_ep: endpoint { + remote-endpoint = <&m2_e_uart_ep>; + }; + }; +};