diff --git a/.dockerignore b/.dockerignore
index 50df2e6..2636a41 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -1,5 +1,6 @@
-*.pyc
-*.pyo
+**/*.pyc
+**/*.pyo
+**/__pycache__
.*.swp
.*.swo
**/.DS_Store
@@ -10,5 +11,10 @@ output/
output/*
!output/linux-headers/
!output/linux-headers/**
+!output/kernel-modules/
+!output/kernel-modules/**
edk2_tici/
-agnos-kernel-sdm845/
+kernel/linux/
+kernel/spectra/
+.ccache/
+.git
diff --git a/.gitattributes b/.gitattributes
index a683ee9..96be0d5 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,3 +1,13 @@
*.deb filter=lfs diff=lfs merge=lfs -text
*.ko filter=lfs diff=lfs merge=lfs -text
userspace/root/usr/share/fonts/NotoSans??-Regular.woff2 filter=lfs diff=lfs merge=lfs -text
+
+userspace/root/usr/lib/firmware/ath10k/** filter=lfs diff=lfs merge=lfs -text
+userspace/root/usr/lib/firmware/qca/* filter=lfs diff=lfs merge=lfs -text
+userspace/root/usr/lib/firmware/qcom/**/*.mbn filter=lfs diff=lfs merge=lfs -text
+userspace/root/usr/lib/firmware/qcom/*.fw filter=lfs diff=lfs merge=lfs -text
+
+# Preserve patch context and mail trailers; builds check the added source.
+*.patch -whitespace
+# Keep this copied upstream license byte-for-byte.
+userspace/root/usr/share/doc/mainline-firmware/licenses/wireless-regdb-LICENSE whitespace=-blank-at-eof
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 9217ee3..e1c5ca5 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -39,7 +39,7 @@ jobs:
- name: Get kernel submodule ref
id: kernel-submodule
- run: echo "ref=$(git ls-tree HEAD | awk '$4 == "agnos-kernel-sdm845"' | awk '{print $3}')" | tee -a $GITHUB_OUTPUT
+ run: echo "ref=$(git -C kernel/linux rev-parse HEAD)" | tee -a $GITHUB_OUTPUT
- name: Restore ccache
uses: actions/cache@v4
diff --git a/.gitmodules b/.gitmodules
index c8520a8..7aff2cf 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,6 @@
-[submodule "agnos-kernel-sdm845"]
- path = agnos-kernel-sdm845
- url = ../../commaai/agnos-kernel-sdm845.git
+[submodule "kernel/linux"]
+ path = kernel/linux
+ url = https://github.com/torvalds/linux.git
+[submodule "kernel/spectra"]
+ path = kernel/spectra
+ url = https://github.com/commaai/vamos.git
diff --git a/Dockerfile.agnos b/Dockerfile.agnos
index c11f9e4..3e5fdfa 100644
--- a/Dockerfile.agnos
+++ b/Dockerfile.agnos
@@ -17,26 +17,22 @@ RUN apt-get update && apt-get install -yq --no-install-recommends \
COPY ./userspace/build_adbd.sh ./userspace/adbd-linux.patch /tmp/agnos/
RUN /tmp/agnos/build_adbd.sh
-# Qualcomm graphics without Wayland or OpenCL runtime dependencies
-FROM agnos-compiler AS agnos-compiler-graphics
-RUN apt-get update && apt-get install -yq --no-install-recommends patchelf
-COPY ./userspace/graphics/ /tmp/agnos/graphics-src/
-RUN mkdir -p /tmp/agnos/graphics && \
- cp /tmp/agnos/graphics-src/libgbm.so /tmp/agnos/graphics/ && \
- cp /tmp/agnos/graphics-src/libeglSubDriverWayland.so.patched /tmp/agnos/graphics/libeglSubDriverWayland.so && \
- cd /tmp/agnos/graphics && \
- gcc -shared -fPIC -Os -s -Wall -Wextra -Werror -Wl,-z,defs -Wl,-z,relro,-z,now \
- -Wl,-soname,libagnos-wayland-stubs.so -o libagnos-wayland-stubs.so /tmp/agnos/graphics-src/stubs.c && \
- gcc -shared -fPIC -Os -s -Wall -Wextra -Werror -Wl,-z,defs -Wl,-z,relro,-z,now \
- -Wl,-soname,libCB.so -o libCB.so /tmp/agnos/graphics-src/opencl_stubs.c && \
- nm -D --defined-only libagnos-wayland-stubs.so | \
- awk '$3 ~ /^agnos_/ { name = $3; sub(/^agnos_/, "", name); print name, $3 }' > /tmp/agnos/graphics-symbols.map && \
- for lib in libgbm.so libeglSubDriverWayland.so; do \
- patchelf --rename-dynamic-symbols /tmp/agnos/graphics-symbols.map \
- --remove-needed libwayland-client.so.0 --remove-needed libwayland-server.so.0 \
- --remove-needed libwayland-egl.so.1 --remove-needed libffi.so.6 \
- --add-needed libagnos-wayland-stubs.so "$lib" || exit 1; \
- done
+FROM agnos-compiler AS agnos-compiler-msm
+RUN apt-get update && apt-get install -yq --no-install-recommends \
+ ca-certificates git meson ninja-build pkg-config libudev-dev libzstd-dev
+COPY ./userspace/build_msm_daemons.sh /tmp/agnos/
+RUN /tmp/agnos/build_msm_daemons.sh
+
+FROM agnos-compiler AS agnos-compiler-raylib
+RUN apt-get update && apt-get install -yq --no-install-recommends \
+ ca-certificates git python3-dev python3-venv pkg-config libdrm-dev libgbm-dev libegl-dev libgles2-mesa-dev
+COPY ./userspace/build_raylib.sh ./userspace/raylib-python.patch ./userspace/raylib.patch /tmp/agnos/
+RUN /tmp/agnos/build_raylib.sh
+
+FROM agnos-compiler AS agnos-compiler-ffmpeg-headers
+RUN apt-get update && apt-get install -yq --no-install-recommends ca-certificates curl
+COPY ./userspace/build_ffmpeg_headers.sh /tmp/agnos/
+RUN /tmp/agnos/build_ffmpeg_headers.sh
# ################## #
# ###### Base ###### #
@@ -70,7 +66,7 @@ FROM agnos-base AS agnos
COPY --from=agnos-compiler-adbd /tmp/agnos/adbd /usr/comma/adbd
COPY --from=agnos-compiler-adbd /tmp/adbd-build/packages/modules/adb/NOTICE /usr/share/doc/adbd/NOTICE
-COPY --from=agnos-compiler-graphics /tmp/agnos/graphics/ /usr/lib/aarch64-linux-gnu/
+COPY --from=agnos-compiler-msm /tmp/agnos/msm-daemons/ /
# modem.service runs the packaged modem.py (AT + IPv4 PPP).
# NetworkManager still requires libmm-glib0 for Wi-Fi/Ethernet operation.
@@ -100,7 +96,19 @@ RUN source $XDG_DATA_HOME/venv/bin/activate && \
--no-install-package pandacan \
--no-install-package rednose \
--no-install-package teleoprtc \
- --no-install-package tinygrad
+ --no-install-package tinygrad \
+ --no-install-package comma-deps-raylib
+
+# The COMMA platform uses Mesa GBM/DRM instead of the vendor KGSL runtime.
+COPY --from=agnos-compiler-raylib /tmp/agnos/raylib/ /tmp/agnos/raylib/
+RUN uv pip install --python $XDG_DATA_HOME/venv/bin/python --no-deps /tmp/agnos/raylib/*.whl && \
+ mkdir -p /usr/share/doc/comma-deps-raylib && \
+ cp /tmp/agnos/raylib/*LICENSE* /tmp/agnos/raylib/*.patch /tmp/agnos/raylib/SOURCES /usr/share/doc/comma-deps-raylib/ && \
+ rm -r /tmp/agnos/raylib
+
+# The pinned FFmpeg wheel includes libswscale but omits its public headers.
+COPY --from=agnos-compiler-ffmpeg-headers /tmp/agnos/ffmpeg-headers/include/ /usr/local/venv/lib/python3.12/site-packages/ffmpeg/install/include/
+COPY --from=agnos-compiler-ffmpeg-headers /tmp/agnos/ffmpeg-headers/share/doc/ /usr/share/doc/
# Install nice to haves
COPY ./userspace/install_extras.sh /tmp/agnos/
@@ -119,6 +127,7 @@ RUN chown -R $USERNAME: /home/$USERNAME
RUN touch -r /lib/systemd/systemd /etc/fstab
COPY ./output/linux-headers/include/ /usr/include/
+COPY ./output/kernel-modules/lib/modules/ /usr/lib/modules/
COPY ./userspace/irsc_util.c /tmp/agnos/
RUN clang -O2 -Wall -Wextra -Werror -o /usr/bin/irsc_util /tmp/agnos/irsc_util.c && rm /tmp/agnos/irsc_util.c
@@ -136,7 +145,7 @@ RUN /tmp/agnos/services.sh
RUN echo "precedence ::ffff:0:0/96 100" >> /etc/gai.conf
# Block incoming cellular traffic, including modem.py's PPP interface.
-# The SDM845 kernel supports xtables, not Ubuntu's default nftables backend.
+# Keep the firewall backend used by modem.py.
RUN update-alternatives --set iptables /usr/sbin/iptables-legacy && \
update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
@@ -145,16 +154,6 @@ RUN sed -i 's/hosts: files dns myhostname/hosts: files myhostn
# keep this last
RUN ldconfig
-# ldconfig rewrites these SONAME links back to Mesa; raylib COMMA needs Adreno.
-RUN cd /usr/lib/aarch64-linux-gnu && \
- test -f libEGL_adreno.so && \
- test -f libGLESv2_adreno.so && \
- install -m 755 libgbm.so /tmp/libgbm_adreno.so && \
- ln -sf libEGL_adreno.so libEGL.so.1 && \
- ln -sf libGLESv2_adreno.so libGLESv2.so.2 && \
- rm -f libgbm.so.1 && \
- mv /tmp/libgbm_adreno.so libgbm.so.1
-
COPY ./userspace/trim.sh /tmp/agnos/
RUN /tmp/agnos/trim.sh
diff --git a/Dockerfile.builder b/Dockerfile.builder
index e32c9be..9379d67 100644
--- a/Dockerfile.builder
+++ b/Dockerfile.builder
@@ -1,6 +1,6 @@
# check=error=true
-FROM ubuntu:20.04
+FROM ubuntu:24.04
ARG UNAME
ARG UID
@@ -10,11 +10,18 @@ ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
apt-get install -y --no-install-recommends \
- python2 \
+ python3 \
build-essential \
+ gcc-aarch64-linux-gnu \
+ bison \
+ flex \
+ git \
+ kmod \
+ zstd \
+ rsync \
+ libelf-dev \
libssl-dev \
bc \
- python-is-python2 \
openssl \
ccache \
libcap2-bin \
diff --git a/README.md b/README.md
index d6933c9..fe1978b 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,7 @@ Run once to set things up:
git clone https://github.com/commaai/agnos-builder.git
cd agnos-builder
-git submodule update --init agnos-kernel-sdm845
+git submodule update --init kernel/linux kernel/spectra
./tools/extract_tools.sh
```
@@ -51,9 +51,14 @@ git submodule update --init agnos-kernel-sdm845
NS=1 ./build_system.sh
```
+The mainline kernel build targets mici and retains the current Ubuntu userspace.
+Its boot payload uses the stock `UNCOMPRESSED_IMG` format: 16-byte magic, little-endian
+32-bit raw Image length, raw arm64 Image, and a single mici DTB. Boot image addresses
+and the signature format remain unchanged.
+
### Flashing
-Flashing to a comma 3/3X (Be sure to set your device in QDL mode before flashing. Refer to [QDL MODE Section](https://flash.comma.ai/) for more information.):
+Flashing to a comma four (mici): put the device in [QDL mode](https://flash.comma.ai/) before flashing.
```
./flash_kernel.sh
./flash_system.sh
diff --git a/agnos-kernel-sdm845 b/agnos-kernel-sdm845
deleted file mode 160000
index 8b0e4d2..0000000
--- a/agnos-kernel-sdm845
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 8b0e4d289b246a5cc1b0484b25a3f9f8d4772544
diff --git a/build_kernel.sh b/build_kernel.sh
index 59a0699..949fb79 100755
--- a/build_kernel.sh
+++ b/build_kernel.sh
@@ -1,120 +1,130 @@
#!/usr/bin/env bash
-set -e
+set -euo pipefail
-DEFCONFIG=tici_defconfig
+DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+cd "$DIR"
-# Get directories and make sure we're in the correct spot to start the build
-DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
-TOOLS=$DIR/tools
-TMP_DIR=/tmp/agnos-builder-tmp
-OUTPUT_DIR=$DIR/output
-BOOT_IMG=./boot.img
-cd $DIR
+SOURCE_DIR="$DIR/kernel/linux"
+KERNEL_DIR="$DIR/build/linux"
+OUT_DIR="$DIR/build/kernel-out"
+SPECTRA_DIR="$DIR/build/spectra-camera"
+OUTPUT_DIR="$DIR/output"
+TOOLS="$DIR/tools"
-if [[ "$(uname)" == 'Darwin' ]]; then
- BASE_VOLUME_PATH=$(echo $DIR | grep -o "^/Volumes/[^/]*" || echo "/")
- if ! diskutil info -plist $BASE_VOLUME_PATH | grep -q "Case-sensitive APFS"; then
- echo "--------------- macOS support ---------------"
+if [[ "$(uname)" == Darwin ]]; then
+ BASE_VOLUME_PATH=$(echo "$DIR" | grep -o "^/Volumes/[^/]*" || echo "/")
+ if ! diskutil info -plist "$BASE_VOLUME_PATH" | grep -q "Case-sensitive APFS"; then
echo "Ensure you are in a Case-sensitive APFS volume to build the AGNOS kernel."
echo "https://github.com/commaai/agnos-builder?tab=readme-ov-file#macos"
- echo "-------------------------------------------------"
exit 1
fi
fi
-# Setup kernel build container
-echo "Building agnos-meta-builder docker image"
-export DOCKER_BUILDKIT=1
-docker build -f Dockerfile.builder -t agnos-meta-builder $DIR \
- --build-arg UNAME=$(id -nu) \
- --build-arg UID=$(id -u) \
- --build-arg GID=$(id -g)
-echo "Starting agnos-meta-builder container"
-CONTAINER_ID=$(docker run -d -v $DIR:$DIR -w $DIR agnos-meta-builder)
-
-# Cleanup container on exit
-trap "echo \"Cleaning up container:\"; \
-docker container rm -f $CONTAINER_ID" EXIT
-
-# Clone kernel if not done already
-if git submodule status --cached agnos-kernel-sdm845/ | grep "^-"; then
- echo "Cloning agnos-kernel-sdm845"
- git submodule update --init agnos-kernel-sdm845
+if [ ! -f "$SOURCE_DIR/Makefile" ]; then
+ git submodule update --init kernel/linux
+fi
+if [ ! -f "$DIR/kernel/spectra/kernel/spectra-camera/Kbuild" ]; then
+ git submodule update --init kernel/spectra
fi
-$DIR/tools/extract_tools.sh
+# Build the pinned upstream tree plus our patches, keeping the submodule clean.
+# The separate output directory preserves incremental build artifacts.
+SOURCE_ID=$({
+ git -C "$SOURCE_DIR" rev-parse HEAD
+ git -C "$DIR/kernel/spectra" rev-parse HEAD
+ shasum -a 256 kernel/patches/*.patch kernel/dts/*
+} | shasum -a 256 | cut -d ' ' -f 1)
+if [ "$(cat "$KERNEL_DIR/.agnos-source" 2>/dev/null || true)" != "$SOURCE_ID" ]; then
+ rm -rf "$KERNEL_DIR"
+ mkdir -p "$KERNEL_DIR"
+ git -C "$SOURCE_DIR" archive HEAD | tar -xf - -C "$KERNEL_DIR"
+ git -C "$KERNEL_DIR" init -q
+ for patch in "$DIR"/kernel/patches/*.patch; do
+ git -C "$KERNEL_DIR" apply --check --whitespace=error "$patch"
+ git -C "$KERNEL_DIR" apply --whitespace=error "$patch"
+ done
+ cp kernel/dts/* "$KERNEL_DIR/arch/arm64/boot/dts/qcom/"
+ echo "$SOURCE_ID" > "$KERNEL_DIR/.agnos-source"
+fi
+
+SPECTRA_ID=$(git -C "$DIR/kernel/spectra" rev-parse HEAD)
+if [ "$(cat "$SPECTRA_DIR/.agnos-source" 2>/dev/null || true)" != "$SPECTRA_ID" ]; then
+ rm -rf "$SPECTRA_DIR"
+ mkdir -p "$SPECTRA_DIR"
+ git -C "$DIR/kernel/spectra" archive HEAD kernel/spectra-camera | \
+ tar -xf - --strip-components=2 -C "$SPECTRA_DIR"
+ echo "$SPECTRA_ID" > "$SPECTRA_DIR/.agnos-source"
+fi
+
+docker build -f Dockerfile.builder -t agnos-mainline-builder . \
+ --build-arg UNAME="$(id -nu)" --build-arg UID="$(id -u)" --build-arg GID="$(id -g)"
build_kernel() {
- cd agnos-kernel-sdm845
-
- # Build parameters
- ARCH=$(uname -m)
- if [ "$ARCH" != "arm64" ] && [ "$ARCH" != "aarch64" ]; then
- export CROSS_COMPILE=$TOOLS/aarch64-linux-gnu-gcc/bin/aarch64-linux-gnu-
- export CC=$TOOLS/aarch64-linux-gnu-gcc/bin/aarch64-linux-gnu-gcc
- export LD=$TOOLS/aarch64-linux-gnu-gcc/bin/aarch64-linux-gnu-ld.bfd
- fi
-
- # Build arm64 arch
export ARCH=arm64
+ export CROSS_COMPILE=""
+ if [[ "$(uname -m)" != aarch64 && "$(uname -m)" != arm64 ]]; then
+ export CROSS_COMPILE=aarch64-linux-gnu-
+ fi
+ export CCACHE_DIR="$DIR/.ccache"
+ export KBUILD_BUILD_USER=comma
+ export KBUILD_BUILD_HOST=agnos
+ export LOCALVERSION=-agnos
- # Set ccache dir
- export CCACHE_DIR=$DIR/.ccache
+ cd "$KERNEL_DIR"
+ local args=(O="$OUT_DIR" CC="ccache ${CROSS_COMPILE}gcc" HOSTCC="ccache gcc" HOSTCXX="ccache g++")
+ make "${args[@]}" defconfig
+ KCONFIG_CONFIG="$OUT_DIR/.config" scripts/kconfig/merge_config.sh -m -y \
+ "$OUT_DIR/.config" "$DIR/kernel/configs/mici.config"
+ make "${args[@]}" olddefconfig
+ make -j"$(nproc)" "${args[@]}" Image qcom/sdm845-comma-mici.dtb modules
+ make -j"$(nproc)" "${args[@]}" M="$SPECTRA_DIR" modules
- # Force ccache usage for kernel build (both target and host compilers)
- export PATH="/usr/lib/ccache:$PATH"
- export HOSTCC="ccache gcc"
- export HOSTCXX="ccache g++"
+ local tmp="$DIR/build/boot"
+ mkdir -p "$tmp" "$OUTPUT_DIR"
+ python3 - "$OUT_DIR/arch/arm64/boot/Image" \
+ "$OUT_DIR/arch/arm64/boot/dts/qcom/sdm845-comma-mici.dtb" "$tmp/Image-dtb" <<'PY'
+import struct
+import sys
+from pathlib import Path
- # Avoid LINUX_COMPILE_HOST to change on every run thus invalidating cache
- # https://patchwork.kernel.org/project/linux-kbuild/patch/1302015561-21047-8-git-send-email-mmarek@suse.cz/
- export KBUILD_BUILD_HOST="docker"
+image = Path(sys.argv[1]).read_bytes()
+dtb = Path(sys.argv[2]).read_bytes()
+Path(sys.argv[3]).write_bytes(b"UNCOMPRESSED_IMG" + struct.pack(" "$tmp/boot.img.sha256"
+ openssl pkeyutl -sign -in "$tmp/boot.img.sha256" -inkey "$DIR/vble-qti.key" \
+ -out "$tmp/boot.img.sig" -pkeyopt digest:sha256 -pkeyopt rsa_padding_mode:pkcs1
+ dd if=/dev/zero of="$tmp/boot.img.sig.padded" bs=2048 count=1 status=none
+ dd if="$tmp/boot.img.sig" of="$tmp/boot.img.sig.padded" conv=notrunc status=none
+ cat "$tmp/boot.img.nonsecure" "$tmp/boot.img.sig.padded" > "$OUTPUT_DIR/boot.img"
- # Load defconfig and build kernel
- echo "-- First make --"
- make $DEFCONFIG O=out
- echo "-- Second make: $(nproc --all) cores --"
- make -j$(nproc --all) O=out # Image-dtb
-
- # Turn on if you want perf
- # LDFLAGS=-static make -j$(nproc --all) -C tools/perf
-
- # Copy over Image-dtb
- mkdir -p $TMP_DIR
- cd $TMP_DIR
- cp $DIR/agnos-kernel-sdm845/out/arch/arm64/boot/Image-dtb .
-
- # Make boot image
- $TOOLS/mkbootimg \
- --kernel Image-dtb \
- --ramdisk /dev/null \
- --cmdline "console=ttyMSM0,115200n8 isolcpus=6,7 quiet loglevel=3 earlycon=msm_geni_serial,0xA84000 androidboot.hardware=qcom androidboot.console=ttyMSM0 ehci-hcd.park=3 lpm_levels.sleep_disabled=1 service_locator.enable=1 androidboot.selinux=permissive firmware_class.path=/firmware/image net.ifnames=0 dyndbg=\"\"" \
- --pagesize 4096 \
- --base 0x80000000 \
- --kernel_offset 0x8000 \
- --ramdisk_offset 0x8000 \
- --tags_offset 0x100 \
- --output $BOOT_IMG.nonsecure
-
- # le signing
- openssl dgst -sha256 -binary $BOOT_IMG.nonsecure > $BOOT_IMG.sha256
- openssl pkeyutl -sign -in $BOOT_IMG.sha256 -inkey $DIR/vble-qti.key -out $BOOT_IMG.sig -pkeyopt digest:sha256 -pkeyopt rsa_padding_mode:pkcs1
- dd if=/dev/zero of=$BOOT_IMG.sig.padded bs=2048 count=1
- dd if=$BOOT_IMG.sig of=$BOOT_IMG.sig.padded conv=notrunc
- cat $BOOT_IMG.nonsecure $BOOT_IMG.sig.padded > $BOOT_IMG
-
- # Copy to output dir
- mkdir -p $OUTPUT_DIR
- mv $BOOT_IMG $OUTPUT_DIR/
- cd $DIR/agnos-kernel-sdm845
-
- echo "-- Install kernel UAPI headers --"
- rm -rf $OUTPUT_DIR/linux-headers
- make headers_install O=out INSTALL_HDR_PATH=$OUTPUT_DIR/linux-headers
+ rm -rf "$OUTPUT_DIR/linux-headers"
+ make "${args[@]}" headers_install INSTALL_HDR_PATH="$OUTPUT_DIR/linux-headers"
+ cp -a "$SPECTRA_DIR/uapi/." "$OUTPUT_DIR/linux-headers/include/"
+ rm -rf "$OUTPUT_DIR/kernel-modules"
+ make "${args[@]}" modules_install INSTALL_MOD_PATH="$OUTPUT_DIR/kernel-modules" INSTALL_MOD_STRIP=1
+ make "${args[@]}" M="$SPECTRA_DIR" modules_install \
+ INSTALL_MOD_PATH="$OUTPUT_DIR/kernel-modules" INSTALL_MOD_STRIP=1
+ find "$OUTPUT_DIR/kernel-modules" -type l -name build -delete
+ python3 "$DIR/kernel/package_modules.py" "$OUTPUT_DIR/kernel-modules" \
+ --report "$OUTPUT_DIR/modules-mici.json"
}
-# Run build_kernel in container
-docker exec -u $(id -nu) $CONTAINER_ID bash -c "set -e; export DEFCONFIG=$DEFCONFIG DIR=$DIR TOOLS=$TOOLS TMP_DIR=$TMP_DIR OUTPUT_DIR=$OUTPUT_DIR BOOT_IMG=$BOOT_IMG; $(declare -f build_kernel); build_kernel"
+docker run --rm -i -u "$(id -u):$(id -g)" -v "$DIR:$DIR" -w "$DIR" \
+ --entrypoint bash agnos-mainline-builder <
+#include
+#include "sdm845.dtsi"
+#include "pm8998.dtsi"
+#include "pmi8998.dtsi"
+
+/ {
+ aliases {
+ serial0 = &uart9;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ lcd3v3: lcd3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "lcd3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pm8998_gpios 13 GPIO_ACTIVE_HIGH>;
+ regulator-boot-on;
+ };
+
+ vph_pwr: vph-pwr-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vph_pwr";
+ regulator-min-microvolt = <3700000>;
+ regulator-max-microvolt = <3700000>;
+ };
+
+ /*
+ * Apparently RPMh does not provide support for PM8998 S4 because it
+ * is always-on; model it as a fixed regulator.
+ */
+ vreg_s4a_1p8: pm8998-smps4 {
+ compatible = "regulator-fixed";
+ regulator-name = "vreg_s4a_1p8";
+
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-always-on;
+ regulator-boot-on;
+
+ vin-supply = <&vph_pwr>;
+ };
+};
+
+&apps_rsc {
+ pm8998-rpmh-regulators {
+ compatible = "qcom,pm8998-rpmh-regulators";
+ qcom,pmic-id = "a";
+
+ vdd-s1-supply = <&vph_pwr>;
+ vdd-s2-supply = <&vph_pwr>;
+ vdd-s3-supply = <&vph_pwr>;
+ vdd-s4-supply = <&vph_pwr>;
+ vdd-s5-supply = <&vph_pwr>;
+ vdd-s6-supply = <&vph_pwr>;
+ vdd-s7-supply = <&vph_pwr>;
+ vdd-s8-supply = <&vph_pwr>;
+ vdd-s9-supply = <&vph_pwr>;
+ vdd-s10-supply = <&vph_pwr>;
+ vdd-s11-supply = <&vph_pwr>;
+ vdd-s12-supply = <&vph_pwr>;
+ vdd-s13-supply = <&vph_pwr>;
+ vdd-l1-l27-supply = <&vreg_s7a_1p025>;
+ vdd-l2-l8-l17-supply = <&vreg_s3a_1p35>;
+ vdd-l3-l11-supply = <&vreg_s7a_1p025>;
+ vdd-l4-l5-supply = <&vreg_s7a_1p025>;
+ vdd-l6-supply = <&vph_pwr>;
+ vdd-l7-l12-l14-l15-supply = <&vreg_s5a_2p04>;
+ vdd-l9-supply = <&vreg_bob>;
+ vdd-l10-l23-l25-supply = <&vreg_bob>;
+ vdd-l13-l19-l21-supply = <&vreg_bob>;
+ vdd-l16-l28-supply = <&vreg_bob>;
+ vdd-l18-l22-supply = <&vreg_bob>;
+ vdd-l20-l24-supply = <&vreg_bob>;
+ vdd-l26-supply = <&vreg_s3a_1p35>;
+ vin-lvs-1-2-supply = <&vreg_s4a_1p8>;
+
+ vreg_s2a_1p125: smps2 {
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ };
+
+ vreg_s3a_1p35: smps3 {
+ regulator-min-microvolt = <1352000>;
+ regulator-max-microvolt = <1352000>;
+ };
+
+ vreg_s5a_2p04: smps5 {
+ regulator-min-microvolt = <1904000>;
+ regulator-max-microvolt = <2040000>;
+ };
+
+ vreg_s7a_1p025: smps7 {
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1028000>;
+ };
+
+ vdd_qusb_hs0:
+ vdda_hp_pcie_core:
+ vdda_mipi_csi0_0p9:
+ vdda_mipi_csi1_0p9:
+ vdda_mipi_csi2_0p9:
+ vdda_mipi_dsi0_pll:
+ vdda_mipi_dsi1_pll:
+ vdda_qlink_lv:
+ vdda_qlink_lv_ck:
+ vdda_qrefs_0p875:
+ vdda_pcie_core:
+ vdda_pll_cc_ebi01:
+ vdda_pll_cc_ebi23:
+ vdda_sp_sensor:
+ vdda_ufs1_core:
+ vdda_ufs2_core:
+ vdda_usb1_ss_core:
+ vdda_usb2_ss_core:
+ vreg_l1a_0p875: ldo1 {
+ regulator-min-microvolt = <880000>;
+ regulator-max-microvolt = <880000>;
+ regulator-initial-mode = ;
+ };
+
+ vddpx_10:
+ vreg_l2a_1p2: ldo2 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = ;
+ regulator-always-on;
+ };
+
+ vreg_l3a_1p0: ldo3 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-initial-mode = ;
+ };
+
+ vdd_wcss_cx:
+ vdd_wcss_mx:
+ vdda_wcss_pll:
+ vreg_l5a_0p8: ldo5 {
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <800000>;
+ regulator-initial-mode = ;
+ };
+
+ vddpx_13:
+ vreg_l6a_1p8: ldo6 {
+ regulator-min-microvolt = <1856000>;
+ regulator-max-microvolt = <1856000>;
+ regulator-initial-mode = ;
+ };
+
+ vreg_l7a_1p8: ldo7 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = ;
+ };
+
+ vreg_l8a_1p2: ldo8 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1248000>;
+ regulator-initial-mode = ;
+ };
+
+ vreg_l9a_1p8: ldo9 {
+ regulator-min-microvolt = <1704000>;
+ regulator-max-microvolt = <2928000>;
+ regulator-initial-mode = ;
+ };
+
+ vreg_l10a_1p8: ldo10 {
+ regulator-min-microvolt = <1704000>;
+ regulator-max-microvolt = <2928000>;
+ regulator-initial-mode = ;
+ };
+
+ vreg_l11a_1p0: ldo11 {
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1048000>;
+ regulator-initial-mode = ;
+ };
+
+ vdd_qfprom:
+ vdd_qfprom_sp:
+ vdda_apc1_cs_1p8:
+ vdda_gfx_cs_1p8:
+ vdda_qrefs_1p8:
+ vdda_qusb_hs0_1p8:
+ vddpx_11:
+ vreg_l12a_1p8: ldo12 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = ;
+ };
+
+ vddpx_2:
+ vreg_l13a_2p95: ldo13 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = ;
+ };
+
+ vreg_l14a_1p88: ldo14 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = ;
+ };
+
+ vreg_l15a_1p8: ldo15 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-initial-mode = ;
+ };
+
+ vreg_l16a_2p7: ldo16 {
+ regulator-min-microvolt = <2704000>;
+ regulator-max-microvolt = <2704000>;
+ regulator-initial-mode = ;
+ };
+
+ vreg_l17a_1p3: ldo17 {
+ regulator-min-microvolt = <1304000>;
+ regulator-max-microvolt = <1304000>;
+ regulator-initial-mode = ;
+ };
+
+ vreg_l18a_2p7: ldo18 {
+ regulator-min-microvolt = <2704000>;
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = ;
+ };
+
+ vreg_l19a_3p0: ldo19 {
+ regulator-min-microvolt = <2856000>;
+ regulator-max-microvolt = <3104000>;
+ regulator-initial-mode = ;
+ };
+
+ vreg_l20a_2p95: ldo20 {
+ regulator-min-microvolt = <2704000>;
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = ;
+ };
+
+ vreg_l21a_2p95: ldo21 {
+ regulator-min-microvolt = <2704000>;
+ regulator-max-microvolt = <2960000>;
+ regulator-initial-mode = ;
+ };
+
+ vreg_l22a_2p85: ldo22 {
+ regulator-min-microvolt = <2864000>;
+ regulator-max-microvolt = <3312000>;
+ regulator-initial-mode = ;
+ };
+
+ vreg_l23a_3p3: ldo23 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3312000>;
+ regulator-initial-mode = ;
+ };
+
+ vdda_qusb_hs0_3p1:
+ vreg_l24a_3p075: ldo24 {
+ regulator-min-microvolt = <3088000>;
+ regulator-max-microvolt = <3088000>;
+ regulator-initial-mode = ;
+ };
+
+ vreg_l25a_3p3: ldo25 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3312000>;
+ regulator-initial-mode = ;
+ };
+
+ vdda_hp_pcie_1p2:
+ vdda_hv_ebi0:
+ vdda_hv_ebi1:
+ vdda_hv_ebi2:
+ vdda_hv_ebi3:
+ vdda_mipi_csi_1p25:
+ vdda_mipi_dsi0_1p2:
+ vdda_mipi_dsi1_1p2:
+ vdda_pcie_1p2:
+ vdda_ufs1_1p2:
+ vdda_ufs2_1p2:
+ vdda_usb1_ss_1p2:
+ vdda_usb2_ss_1p2:
+ vreg_l26a_1p2: ldo26 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-initial-mode = ;
+ };
+
+ vreg_l28a_3p0: ldo28 {
+ regulator-min-microvolt = <2856000>;
+ regulator-max-microvolt = <3008000>;
+ regulator-initial-mode = ;
+ };
+
+ vreg_lvs1a_1p8: lvs1 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vreg_lvs2a_1p8: lvs2 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+ };
+
+ pmi8998-rpmh-regulators {
+ compatible = "qcom,pmi8998-rpmh-regulators";
+ qcom,pmic-id = "b";
+
+ vdd-bob-supply = <&vph_pwr>;
+
+ vreg_bob: bob {
+ regulator-min-microvolt = <3312000>;
+ regulator-max-microvolt = <3600000>;
+ regulator-initial-mode = ;
+ regulator-allow-bypass;
+ };
+ };
+
+ pm8005-rpmh-regulators {
+ compatible = "qcom,pm8005-rpmh-regulators";
+ qcom,pmic-id = "c";
+
+ vdd-s1-supply = <&vph_pwr>;
+ vdd-s2-supply = <&vph_pwr>;
+ vdd-s3-supply = <&vph_pwr>;
+ vdd-s4-supply = <&vph_pwr>;
+
+ vreg_s3c_0p6: smps3 {
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <600000>;
+ };
+ };
+};
+
+&gcc {
+ protected-clocks = ,
+ ,
+ ,
+ ,
+ ;
+};
+
+&gmu {
+ status = "okay";
+};
+
+&gpi_dma0 {
+ status = "okay";
+};
+
+&gpu {
+ status = "okay";
+
+ zap-shader {
+ memory-region = <&gpu_mem>;
+ firmware-name = "qcom/sdm845/a630_zap.mbn";
+ };
+};
+
+&i2c4 {
+ clock-frequency = <400000>;
+
+ status = "okay";
+};
+
+&i2c5 {
+ clock-frequency = <100000>;
+
+ status = "okay";
+};
+
+&mdss {
+ status = "okay";
+};
+
+&mdss_dsi0 {
+ vdda-supply = <&vdda_mipi_dsi0_1p2>;
+
+ status = "okay";
+};
+
+&mdss_dsi0_phy {
+ vdds-supply = <&vdda_mipi_dsi0_pll>;
+
+ status = "okay";
+};
+
+&mss_pil {
+ firmware-name = "qcom/sdm845/mba.mbn", "qcom/sdm845/modem_nm.mbn";
+
+ status = "okay";
+};
+
+&qupv3_id_0 {
+ status = "okay";
+};
+
+&qupv3_id_1 {
+ status = "okay";
+};
+
+&spi0 {
+ status = "okay";
+
+ panda_spi: spidev@0 {
+ compatible = "commaai,panda";
+ spi-max-frequency = <50000000>;
+ reg = <0>;
+ };
+};
+
+&uart6 {
+ pinctrl-0 = <&qup_uart6_4pin>;
+
+ status = "okay";
+
+ bluetooth {
+ compatible = "qcom,wcn3990-bt";
+ vddio-supply = <&vreg_s4a_1p8>;
+ vddxo-supply = <&vreg_l7a_1p8>;
+ vddrf-supply = <&vreg_l17a_1p3>;
+ vddch0-supply = <&vreg_l25a_3p3>;
+ max-speed = <3200000>;
+ };
+};
+
+&uart9 {
+ status = "okay";
+};
+
+&ufs_mem_hc {
+ reset-gpios = <&tlmm 150 GPIO_ACTIVE_LOW>;
+
+ vcc-supply = <&vreg_l20a_2p95>;
+ vcc-max-microamp = <600000>;
+
+ status = "okay";
+};
+
+&ufs_mem_phy {
+ vdda-phy-supply = <&vdda_ufs1_core>;
+ vdda-pll-supply = <&vdda_ufs1_1p2>;
+ vdda-phy-max-microamp = <62900>;
+ vdda-pll-max-microamp = <18300>;
+
+ status = "okay";
+};
+
+&usb_1 {
+ status = "okay";
+};
+
+&usb_1_dwc3 {
+ dr_mode = "peripheral";
+};
+
+&usb_1_hsphy {
+ vdd-supply = <&vdd_qusb_hs0>;
+ vdda-phy-dpdm-supply = <&vdda_qusb_hs0_3p1>;
+ vdda-pll-supply = <&vdda_qusb_hs0_1p8>;
+
+ status = "okay";
+};
+
+&usb_1_qmpphy {
+ vdda-phy-supply = <&vdda_usb1_ss_1p2>;
+ vdda-pll-supply = <&vdda_usb1_ss_core>;
+
+ status = "okay";
+};
+
+&usb_2 {
+ status = "okay";
+};
+
+&usb_2_dwc3 {
+ dr_mode = "host";
+};
+
+&usb_2_hsphy {
+ vdd-supply = <&vdd_qusb_hs0>;
+ vdda-pll-supply = <&vdda_qusb_hs0_1p8>;
+ vdda-phy-dpdm-supply = <&vdda_qusb_hs0_3p1>;
+
+ status = "okay";
+};
+
+&usb_2_qmpphy {
+ vdda-phy-supply = <&vdda_usb2_ss_1p2>;
+ vdda-pll-supply = <&vdda_usb2_ss_core>;
+
+ status = "okay";
+};
+
+&vreg_lvs1a_1p8 {
+ regulator-always-on;
+};
+
+&wifi {
+ vdd-0.8-cx-mx-supply = <&vreg_l5a_0p8>;
+ vdd-1.3-rfa-supply = <&vreg_l17a_1p3>;
+ vdd-1.8-xo-supply = <&vreg_l7a_1p8>;
+ vdd-3.3-ch0-supply = <&vreg_l25a_3p3>;
+ vdd-3.3-ch1-supply = <&vreg_l23a_3p3>;
+
+ qcom,snoc-host-cap-skip-quirk;
+
+ status = "okay";
+};
diff --git a/kernel/dts/sdm845-comma-mici.dts b/kernel/dts/sdm845-comma-mici.dts
new file mode 100644
index 0000000..4c85f2f
--- /dev/null
+++ b/kernel/dts/sdm845-comma-mici.dts
@@ -0,0 +1,421 @@
+/dts-v1/;
+
+#include "sdm845-comma-common.dtsi"
+#include
+#include
+#include
+
+/ {
+ model = "comma mici";
+ compatible = "comma,mici", "qcom,sdm845";
+ qcom,msm-id = , ,
+ , <348 0x20001>;
+ qcom,board-id = <0x22 0>;
+
+ reserved-memory {
+ ramoops@b0000000 {
+ compatible = "ramoops";
+ reg = <0 0xb0000000 0 0x003ff000>;
+ record-size = <0x40000>;
+ console-size = <0x40000>;
+ ftrace-size = <0x40000>;
+ pmsg-size = <0x200000>;
+ };
+
+ /* ABL's power-drop cookie is at the end of this page. */
+ cookies@b03ff000 {
+ no-map;
+ reg = <0 0xb03ff000 0 0x1000>;
+ };
+ };
+
+ aliases {
+ hsuart0 = &uart3;
+ i2c0 = &i2c10;
+ i2c1 = &i2c4;
+ i2c2 = &i2c5;
+ i2c4 = &i2c0;
+ i2c5 = &i2c1;
+ i2c10 = &i2c2;
+ };
+};
+
+&i2c10 {
+ clock-frequency = <400000>;
+ status = "okay";
+};
+
+&i2c5 {
+ touchscreen@38 {
+ compatible = "focaltech,ft3168";
+ reg = <0x38>;
+
+ interrupts-extended = <&tlmm 125 IRQ_TYPE_EDGE_FALLING>;
+ reset-gpios = <&tlmm 104 GPIO_ACTIVE_LOW>;
+
+ iovcc-supply = <&vreg_s4a_1p8>;
+ vcc-supply = <&lcd3v3>;
+
+ touchscreen-size-x = <240>;
+ touchscreen-size-y = <536>;
+ };
+};
+
+&mdss_dsi0 {
+ panel@0 {
+ compatible = "dwo,do0200fat07";
+
+ reg = <0>;
+
+ vddio-supply = <&vreg_l14a_1p88>;
+ vdd-supply = <&lcd3v3>;
+
+ reset-gpios = <&tlmm 6 GPIO_ACTIVE_LOW>;
+
+ rotation = <90>;
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&mdss_dsi0_out>;
+ };
+ };
+ };
+};
+
+&mdss_dsi0_out {
+ remote-endpoint = <&panel_in>;
+ data-lanes = <0>;
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&wifi {
+ qcom,calibration-variant = "comma-mici";
+};
+
+/ {
+ spkr_codec: audio-codec-0 {
+ compatible = "linux,spdif-dit";
+ #sound-dai-cells = <0>;
+ };
+
+ mic_codec: audio-codec-1 {
+ compatible = "linux,spdif-dir";
+ #sound-dai-cells = <0>;
+ };
+};
+
+&adsp_pas {
+ firmware-name = "adsp.mdt";
+ status = "okay";
+};
+
+&q6afedai {
+ dai@12 {
+ reg = ;
+ qcom,sd-lines = <1>;
+ };
+
+ dai@13 {
+ reg = ;
+ qcom,sd-lines = <0>;
+ };
+};
+
+&q6asmdai {
+ dai@0 {
+ reg = ;
+ direction = ;
+ };
+
+ dai@1 {
+ reg = ;
+ direction = ;
+ };
+};
+
+&sound {
+ compatible = "qcom,sdm845-sndcard";
+ model = "comma-mici";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sec_mi2s_active>;
+
+ mm1-dai-link {
+ link-name = "MultiMedia1";
+ cpu {
+ sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA1>;
+ };
+ };
+
+ mm2-dai-link {
+ link-name = "MultiMedia2";
+ cpu {
+ sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA2>;
+ };
+ };
+
+ speaker-dai-link {
+ link-name = "Secondary MI2S Playback";
+ cpu {
+ sound-dai = <&q6afedai SECONDARY_MI2S_RX>;
+ };
+ platform {
+ sound-dai = <&q6routing>;
+ };
+ codec {
+ sound-dai = <&spkr_codec>;
+ };
+ };
+
+ mic-dai-link {
+ link-name = "Secondary MI2S Capture";
+ cpu {
+ sound-dai = <&q6afedai SECONDARY_MI2S_TX>;
+ };
+ platform {
+ sound-dai = <&q6routing>;
+ };
+ codec {
+ sound-dai = <&mic_codec>;
+ };
+ };
+};
+
+&tlmm {
+ sec_mi2s_active: sec-mi2s-active-state {
+ pins = "gpio80", "gpio81", "gpio82", "gpio83";
+ function = "sec_mi2s";
+ drive-strength = <8>;
+ bias-disable;
+ };
+};
+
+&venus {
+ status = "okay";
+ firmware-name = "venus.mdt";
+};
+
+
+&pm8998_adc {
+ channel@4d {
+ reg = ;
+ label = "intake_therm";
+ qcom,ratiometric;
+ qcom,hw-settle-time = <200>;
+ };
+ channel@4e {
+ reg = ;
+ label = "exhaust_therm";
+ qcom,ratiometric;
+ qcom,hw-settle-time = <200>;
+ };
+ channel@50 {
+ reg = ;
+ label = "bottom_soc_therm";
+ qcom,ratiometric;
+ qcom,hw-settle-time = <200>;
+ };
+ channel@51 {
+ reg = ;
+ label = "gnss_therm";
+ qcom,ratiometric;
+ qcom,hw-settle-time = <200>;
+ };
+};
+
+&pm8998_adc_tm {
+ status = "okay";
+ intake-therm@0 {
+ reg = <0>;
+ io-channels = <&pm8998_adc ADC5_AMUX_THM1_100K_PU>;
+ qcom,ratiometric;
+ qcom,hw-settle-time-us = <200>;
+ };
+ exhaust-therm@1 {
+ reg = <1>;
+ io-channels = <&pm8998_adc ADC5_AMUX_THM2_100K_PU>;
+ qcom,ratiometric;
+ qcom,hw-settle-time-us = <200>;
+ };
+ bottom-soc-therm@2 {
+ reg = <2>;
+ io-channels = <&pm8998_adc ADC5_AMUX_THM4_100K_PU>;
+ qcom,ratiometric;
+ qcom,hw-settle-time-us = <200>;
+ };
+ gnss-therm@3 {
+ reg = <3>;
+ io-channels = <&pm8998_adc ADC5_AMUX_THM5_100K_PU>;
+ qcom,ratiometric;
+ qcom,hw-settle-time-us = <200>;
+ };
+};
+
+/ {
+ thermal-zones {
+ intake {
+ polling-delay-passive = <1000>;
+ polling-delay = <0>;
+ thermal-sensors = <&pm8998_adc_tm 0>;
+ trips {
+ intake-alert {
+ temperature = <125000>;
+ hysteresis = <10000>;
+ type = "passive";
+ };
+ };
+ };
+ exhaust {
+ polling-delay-passive = <1000>;
+ polling-delay = <0>;
+ thermal-sensors = <&pm8998_adc_tm 1>;
+ trips {
+ exhaust-alert {
+ temperature = <125000>;
+ hysteresis = <10000>;
+ type = "passive";
+ };
+ };
+ };
+ bottom_soc {
+ polling-delay-passive = <1000>;
+ polling-delay = <0>;
+ thermal-sensors = <&pm8998_adc_tm 2>;
+ trips {
+ bottom-soc-alert {
+ temperature = <125000>;
+ hysteresis = <10000>;
+ type = "passive";
+ };
+ };
+ };
+ gnss {
+ polling-delay-passive = <1000>;
+ polling-delay = <0>;
+ thermal-sensors = <&pm8998_adc_tm 3>;
+ trips {
+ gnss-alert {
+ temperature = <125000>;
+ hysteresis = <10000>;
+ type = "passive";
+ };
+ };
+ };
+ };
+};
+
+/* These board supplies also feed the camera modules. */
+&vreg_l8a_1p2 {
+ regulator-always-on;
+};
+
+&vreg_l19a_3p0 {
+ regulator-always-on;
+};
+
+
+#include "sdm845-comma-spectra.dtsi"
+
+&cam_sensor_mclk0_active { drive-strength = <2>; };
+&cam_sensor_mclk1_active { drive-strength = <2>; };
+&cam_sensor_mclk2_active { drive-strength = <2>; };
+
+/ {
+ som_power: som-power {
+ compatible = "iio-hwmon";
+ io-channels = <&mici_fg_adc 0>, <&mici_fg_adc 1>;
+ };
+};
+
+&pmi8998_lsid0 {
+ mici_fg_adc: adc@4100 {
+ compatible = "qcom,pmi8998-fg-adc";
+ reg = <0x4100>;
+ #io-channel-cells = <1>;
+ };
+};
+
+&pmi8998_flash {
+ status = "okay";
+
+ led-2 {
+ color = ;
+ function = LED_FUNCTION_TORCH;
+ led-sources = <3>;
+ led-max-microamp = <300000>;
+ };
+};
+
+/* USB-C / chestnut proposal: requires the gen1 TCPM and PMI8998 VBUS patches. */
+#include
+
+&pmi8998_lsid0 {
+ mici_vbus: usb-vbus-regulator@1100 {
+ compatible = "qcom,pmi8998-vbus-reg";
+ reg = <0x1100>;
+ interrupts = <0x2 0x11 0x0 IRQ_TYPE_EDGE_RISING>,
+ <0x2 0x11 0x1 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "otg-fail", "otg-overcurrent";
+ regulator-name = "smb2-vbus";
+ regulator-min-microamp = <1500000>;
+ regulator-max-microamp = <1500000>;
+ };
+};
+
+/* Batteryless mici uses the USBIN controls through the Type-C backend. */
+&pmi8998_charger {
+ status = "disabled";
+};
+
+&pmi8998_typec {
+ status = "okay";
+ vdd-pdphy-supply = <&vreg_l24a_3p075>;
+
+ connector {
+ compatible = "usb-c-connector";
+ power-role = "dual";
+ data-role = "dual";
+ try-power-role = "sink";
+ self-powered;
+ vbus-supply = <&mici_vbus>;
+ source-pdos = ;
+ sink-pdos = ;
+ op-sink-microwatt = <7500000>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ mici_typec_hs: endpoint {
+ remote-endpoint = <&usb_1_dwc3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ mici_typec_ss: endpoint {
+ remote-endpoint = <&usb_1_qmpphy_out>;
+ };
+ };
+ };
+ };
+};
+
+&usb_1_dwc3 {
+ dr_mode = "otg";
+ usb-role-switch;
+};
+
+&usb_1_dwc3_hs {
+ remote-endpoint = <&mici_typec_hs>;
+};
+
+&usb_1_qmpphy_out {
+ remote-endpoint = <&mici_typec_ss>;
+};
diff --git a/kernel/dts/sdm845-comma-spectra.dtsi b/kernel/dts/sdm845-comma-spectra.dtsi
new file mode 100644
index 0000000..e5e501d
--- /dev/null
+++ b/kernel/dts/sdm845-comma-spectra.dtsi
@@ -0,0 +1,1423 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Camera-only nodes from cameras-spectra-mainline-andi, 391dedc767d9.
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/ {
+ titan_top_gdsc: titan-top-gdsc-fixed {
+ compatible = "regulator-fixed";
+ regulator-name = "titan_top_gdsc";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ife_0_gdsc: ife-0-gdsc-fixed {
+ compatible = "regulator-fixed";
+ regulator-name = "ife_0_gdsc";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ife_1_gdsc: ife-1-gdsc-fixed {
+ compatible = "regulator-fixed";
+ regulator-name = "ife_1_gdsc";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ipe_0_gdsc: ipe-0-gdsc-fixed {
+ compatible = "regulator-fixed";
+ regulator-name = "ipe_0_gdsc";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ipe_1_gdsc: ipe-1-gdsc-fixed {
+ compatible = "regulator-fixed";
+ regulator-name = "ipe_1_gdsc";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ bps_gdsc: bps-gdsc-fixed {
+ compatible = "regulator-fixed";
+ regulator-name = "bps_gdsc";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ camera_rear_ldo: camera-rear-ldo {
+ compatible = "regulator-fixed";
+ regulator-name = "camera_rear_ldo";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ gpio = <&pm8998_gpios 12 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ pinctrl-names = "default";
+ pinctrl-0 = <&camera_rear_dvdd_en_default>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+
+
+
+
+
+};
+&camss {
+ status = "disabled";
+};
+
+&cci {
+ status = "disabled";
+};
+
+&pm8998_gpios {
+
+ camera_rear_dvdd_en_default: camera-rear-dvdd-en-state {
+ pins = "gpio12";
+ function = "normal";
+ bias-disable;
+ drive-push-pull;
+ qcom,drive-strength = ;
+ output-high;
+ };
+
+
+};
+
+&tlmm {
+ cci0_active: cci0-active-state {
+ pins = "gpio17", "gpio18";
+ function = "cci_i2c";
+ bias-pull-up;
+ drive-strength = <2>;
+ };
+
+ cci0_suspend: cci0-suspend-state {
+ pins = "gpio17", "gpio18";
+ function = "cci_i2c";
+ bias-pull-down;
+ drive-strength = <2>;
+ };
+
+ cci1_active: cci1-active-state {
+ pins = "gpio19", "gpio20";
+ function = "cci_i2c";
+ bias-pull-up;
+ drive-strength = <2>;
+ };
+
+ cci1_suspend: cci1-suspend-state {
+ pins = "gpio19", "gpio20";
+ function = "cci_i2c";
+ bias-pull-down;
+ drive-strength = <2>;
+ };
+
+ cam_sensor_mclk0_active: cam-sensor-mclk0-active-state {
+ pins = "gpio13";
+ function = "cam_mclk";
+ bias-disable;
+ drive-strength = <8>;
+ };
+
+ cam_sensor_mclk0_suspend: cam-sensor-mclk0-suspend-state {
+ pins = "gpio13";
+ function = "cam_mclk";
+ bias-pull-down;
+ drive-strength = <8>;
+ };
+
+ cam_sensor_mclk1_active: cam-sensor-mclk1-active-state {
+ pins = "gpio14";
+ function = "cam_mclk";
+ bias-disable;
+ drive-strength = <8>;
+ };
+
+ cam_sensor_mclk1_suspend: cam-sensor-mclk1-suspend-state {
+ pins = "gpio14";
+ function = "cam_mclk";
+ bias-pull-down;
+ drive-strength = <8>;
+ };
+
+ cam_sensor_mclk2_active: cam-sensor-mclk2-active-state {
+ pins = "gpio15";
+ function = "cam_mclk";
+ bias-disable;
+ drive-strength = <8>;
+ };
+
+ cam_sensor_mclk2_suspend: cam-sensor-mclk2-suspend-state {
+ pins = "gpio15";
+ function = "cam_mclk";
+ bias-pull-down;
+ drive-strength = <8>;
+ };
+
+ cam_sensor_mclk3_active: cam-sensor-mclk3-active-state {
+ pins = "gpio16";
+ function = "cam_mclk";
+ bias-disable;
+ drive-strength = <2>;
+ };
+
+ cam_sensor_mclk3_suspend: cam-sensor-mclk3-suspend-state {
+ pins = "gpio16";
+ function = "cam_mclk";
+ bias-pull-down;
+ drive-strength = <2>;
+ };
+
+ cam_sensor_rear_active: cam-sensor-rear-active-state {
+ pins = "gpio9";
+ function = "gpio";
+ bias-disable;
+ drive-strength = <2>;
+ };
+
+ cam_sensor_rear_suspend: cam-sensor-rear-suspend-state {
+ pins = "gpio9";
+ function = "gpio";
+ bias-pull-down;
+ drive-strength = <2>;
+ output-low;
+ };
+
+ cam_sensor_front_active: cam-sensor-front-active-state {
+ pins = "gpio28";
+ function = "gpio";
+ bias-disable;
+ drive-strength = <2>;
+ };
+
+ cam_sensor_front_suspend: cam-sensor-front-suspend-state {
+ pins = "gpio28";
+ function = "gpio";
+ bias-pull-down;
+ drive-strength = <2>;
+ output-low;
+ };
+
+ cam_sensor_iris_active: cam-sensor-iris-active-state {
+ pins = "gpio21";
+ function = "gpio";
+ bias-disable;
+ drive-strength = <2>;
+ };
+
+ cam_sensor_iris_suspend: cam-sensor-iris-suspend-state {
+ pins = "gpio21";
+ function = "gpio";
+ bias-pull-down;
+ drive-strength = <2>;
+ output-low;
+ };
+
+ cam_res_mgr_active: cam-res-mgr-active-state {
+ pins = "gpio8";
+ function = "gpio";
+ bias-disable;
+ drive-strength = <2>;
+ };
+
+ cam_res_mgr_suspend: cam-res-mgr-suspend-state {
+ pins = "gpio8";
+ function = "gpio";
+ bias-disable;
+ drive-strength = <2>;
+ output-low;
+ };
+};
+
+&soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ qcom,cam-req-mgr {
+ compatible = "qcom,cam-req-mgr";
+ status = "ok";
+ };
+
+ cam_csiphy0: qcom,csiphy@ac65000 {
+ cell-index = <0>;
+ compatible = "qcom,csiphy-v1.0", "qcom,csiphy";
+ reg = <0 0x0ac65000 0 0x1000>;
+ reg-names = "csiphy";
+ reg-cam-base = <0x65000>;
+ interrupts = ;
+ interrupt-names = "csiphy";
+ gdscr-supply = <&titan_top_gdsc>;
+ regulator-names = "gdscr";
+ csi-vdd-voltage = <1200000>;
+ mipi-csi-vdd-supply = <&vreg_l1a_0p875>;
+ clocks = <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>,
+ <&clock_camcc CAM_CC_SOC_AHB_CLK>,
+ <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+ <&clock_camcc CAM_CC_CPAS_AHB_CLK>,
+ <&clock_camcc CAM_CC_CPHY_RX_CLK_SRC>,
+ <&clock_camcc CAM_CC_CSIPHY0_CLK>,
+ <&clock_camcc CAM_CC_CSI0PHYTIMER_CLK_SRC>,
+ <&clock_camcc CAM_CC_CSI0PHYTIMER_CLK>;
+ clock-names = "camnoc_axi_clk",
+ "soc_ahb_clk",
+ "slow_ahb_src_clk",
+ "cpas_ahb_clk",
+ "cphy_rx_clk_src",
+ "csiphy0_clk",
+ "csi0phytimer_clk_src",
+ "csi0phytimer_clk";
+ src-clock-name = "csi0phytimer_clk_src";
+ clock-cntl-level = "svs", "turbo";
+ clock-rates =
+ <0 0 0 0 320000000 0 269333333 0>,
+ <0 0 0 0 384000000 0 269333333 0>;
+ status = "ok";
+ };
+
+ cam_csiphy1: qcom,csiphy@ac66000 {
+ cell-index = <1>;
+ compatible = "qcom,csiphy-v1.0", "qcom,csiphy";
+ reg = <0 0x0ac66000 0 0x1000>;
+ reg-names = "csiphy";
+ reg-cam-base = <0x66000>;
+ interrupts = ;
+ interrupt-names = "csiphy";
+ gdscr-supply = <&titan_top_gdsc>;
+ regulator-names = "gdscr";
+ csi-vdd-voltage = <1200000>;
+ mipi-csi-vdd-supply = <&vreg_l1a_0p875>;
+ clocks = <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>,
+ <&clock_camcc CAM_CC_SOC_AHB_CLK>,
+ <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+ <&clock_camcc CAM_CC_CPAS_AHB_CLK>,
+ <&clock_camcc CAM_CC_CPHY_RX_CLK_SRC>,
+ <&clock_camcc CAM_CC_CSIPHY1_CLK>,
+ <&clock_camcc CAM_CC_CSI1PHYTIMER_CLK_SRC>,
+ <&clock_camcc CAM_CC_CSI1PHYTIMER_CLK>;
+ clock-names = "camnoc_axi_clk",
+ "soc_ahb_clk",
+ "slow_ahb_src_clk",
+ "cpas_ahb_clk",
+ "cphy_rx_clk_src",
+ "csiphy1_clk",
+ "csi1phytimer_clk_src",
+ "csi1phytimer_clk";
+ src-clock-name = "csi1phytimer_clk_src";
+ clock-cntl-level = "svs", "turbo";
+ clock-rates =
+ <0 0 0 0 320000000 0 269333333 0>,
+ <0 0 0 0 384000000 0 269333333 0>;
+ status = "ok";
+ };
+
+ cam_csiphy2: qcom,csiphy@ac67000 {
+ cell-index = <2>;
+ compatible = "qcom,csiphy-v1.0", "qcom,csiphy";
+ reg = <0 0x0ac67000 0 0x1000>;
+ reg-names = "csiphy";
+ reg-cam-base = <0x67000>;
+ interrupts = ;
+ interrupt-names = "csiphy";
+ gdscr-supply = <&titan_top_gdsc>;
+ regulator-names = "gdscr";
+ csi-vdd-voltage = <1200000>;
+ mipi-csi-vdd-supply = <&vreg_l1a_0p875>;
+ clocks = <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>,
+ <&clock_camcc CAM_CC_SOC_AHB_CLK>,
+ <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+ <&clock_camcc CAM_CC_CPAS_AHB_CLK>,
+ <&clock_camcc CAM_CC_CPHY_RX_CLK_SRC>,
+ <&clock_camcc CAM_CC_CSIPHY2_CLK>,
+ <&clock_camcc CAM_CC_CSI2PHYTIMER_CLK_SRC>,
+ <&clock_camcc CAM_CC_CSI2PHYTIMER_CLK>;
+ clock-names = "camnoc_axi_clk",
+ "soc_ahb_clk",
+ "slow_ahb_src_clk",
+ "cpas_ahb_clk",
+ "cphy_rx_clk_src",
+ "csiphy2_clk",
+ "csi2phytimer_clk_src",
+ "csi2phytimer_clk";
+ src-clock-name = "csi2phytimer_clk_src";
+ clock-cntl-level = "svs", "turbo";
+ clock-rates =
+ <0 0 0 0 320000000 0 269333333 0>,
+ <0 0 0 0 384000000 0 269333333 0>;
+ status = "ok";
+ };
+
+ cam_csiphy3: qcom,csiphy@ac68000 {
+ cell-index = <3>;
+ compatible = "qcom,csiphy-v1.0", "qcom,csiphy";
+ reg = <0 0x0ac68000 0 0x1000>;
+ reg-names = "csiphy";
+ reg-cam-base = <0x68000>;
+ interrupts = ;
+ interrupt-names = "csiphy";
+ gdscr-supply = <&titan_top_gdsc>;
+ regulator-names = "gdscr";
+ csi-vdd-voltage = <1200000>;
+ mipi-csi-vdd-supply = <&vreg_l1a_0p875>;
+ clocks = <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>,
+ <&clock_camcc CAM_CC_SOC_AHB_CLK>,
+ <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+ <&clock_camcc CAM_CC_CPAS_AHB_CLK>,
+ <&clock_camcc CAM_CC_CPHY_RX_CLK_SRC>,
+ <&clock_camcc CAM_CC_CSIPHY3_CLK>,
+ <&clock_camcc CAM_CC_CSI3PHYTIMER_CLK_SRC>,
+ <&clock_camcc CAM_CC_CSI3PHYTIMER_CLK>;
+ clock-names = "camnoc_axi_clk",
+ "soc_ahb_clk",
+ "slow_ahb_src_clk",
+ "cpas_ahb_clk",
+ "cphy_rx_clk_src",
+ "csiphy3_clk",
+ "csi3phytimer_clk_src",
+ "csi3phytimer_clk";
+ src-clock-name = "csi3phytimer_clk_src";
+ clock-cntl-level = "svs", "turbo";
+ clock-rates =
+ <0 0 0 0 320000000 0 269333333 0>,
+ <0 0 0 0 384000000 0 269333333 0>;
+ status = "ok";
+ };
+
+ cam_cci: qcom,cci@ac4a000 {
+ cell-index = <0>;
+ compatible = "qcom,cci";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0 0x0ac4a000 0 0x4000>;
+ reg-names = "cci";
+ reg-cam-base = <0x4a000>;
+ interrupt-names = "cci";
+ interrupts = ;
+ status = "ok";
+ gdscr-supply = <&titan_top_gdsc>;
+ regulator-names = "gdscr";
+ clocks = <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>,
+ <&clock_camcc CAM_CC_SOC_AHB_CLK>,
+ <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+ <&clock_camcc CAM_CC_CPAS_AHB_CLK>,
+ <&clock_camcc CAM_CC_CCI_CLK>,
+ <&clock_camcc CAM_CC_CCI_CLK_SRC>;
+ clock-names = "camnoc_axi_clk",
+ "soc_ahb_clk",
+ "slow_ahb_src_clk",
+ "cpas_ahb_clk",
+ "cci_clk",
+ "cci_clk_src";
+ src-clock-name = "cci_clk_src";
+ clock-cntl-level = "lowsvs";
+ clock-rates = <0 0 0 0 0 37500000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+
+ pinctrl-0 = <&cci0_active &cci1_active
+ &cam_sensor_mclk0_active
+ &cam_sensor_mclk1_active
+ &cam_sensor_mclk2_active
+ &cam_sensor_mclk3_active>;
+ pinctrl-1 = <&cci0_suspend &cci1_suspend
+ &cam_sensor_mclk0_suspend
+ &cam_sensor_mclk1_suspend
+ &cam_sensor_mclk2_suspend
+ &cam_sensor_mclk3_suspend>;
+ gpios = <&tlmm 17 0>,
+ <&tlmm 18 0>,
+ <&tlmm 19 0>,
+ <&tlmm 20 0>;
+ gpio-req-tbl-num = <0 1 2 3>;
+ gpio-req-tbl-flags = <1 1 1 1>;
+ gpio-req-tbl-label = "CCI_I2C_DATA0",
+ "CCI_I2C_CLK0",
+ "CCI_I2C_DATA1",
+ "CCI_I2C_CLK1";
+
+ i2c_freq_100Khz: qcom,i2c_standard_mode {
+ hw-thigh = <201>;
+ hw-tlow = <174>;
+ hw-tsu-sto = <204>;
+ hw-tsu-sta = <231>;
+ hw-thd-dat = <22>;
+ hw-thd-sta = <162>;
+ hw-tbuf = <227>;
+ hw-scl-stretch-en = <0>;
+ hw-trdhld = <6>;
+ hw-tsp = <3>;
+ cci-clk-src = <37500000>;
+ status = "ok";
+ };
+
+ i2c_freq_400Khz: qcom,i2c_fast_mode {
+ hw-thigh = <38>;
+ hw-tlow = <56>;
+ hw-tsu-sto = <40>;
+ hw-tsu-sta = <40>;
+ hw-thd-dat = <22>;
+ hw-thd-sta = <35>;
+ hw-tbuf = <62>;
+ hw-scl-stretch-en = <0>;
+ hw-trdhld = <6>;
+ hw-tsp = <3>;
+ cci-clk-src = <37500000>;
+ status = "ok";
+ };
+
+ i2c_freq_custom: qcom,i2c_custom_mode {
+ hw-thigh = <38>;
+ hw-tlow = <56>;
+ hw-tsu-sto = <40>;
+ hw-tsu-sta = <40>;
+ hw-thd-dat = <22>;
+ hw-thd-sta = <35>;
+ hw-tbuf = <62>;
+ hw-scl-stretch-en = <1>;
+ hw-trdhld = <6>;
+ hw-tsp = <3>;
+ cci-clk-src = <37500000>;
+ status = "ok";
+ };
+
+ i2c_freq_1Mhz: qcom,i2c_fast_plus_mode {
+ hw-thigh = <16>;
+ hw-tlow = <22>;
+ hw-tsu-sto = <17>;
+ hw-tsu-sta = <18>;
+ hw-thd-dat = <16>;
+ hw-thd-sta = <15>;
+ hw-tbuf = <24>;
+ hw-scl-stretch-en = <0>;
+ hw-trdhld = <3>;
+ hw-tsp = <3>;
+ cci-clk-src = <37500000>;
+ status = "ok";
+ };
+ };
+
+ qcom,cam_smmu {
+ compatible = "qcom,msm-cam-smmu";
+ status = "ok";
+
+ msm_cam_smmu_ife {
+ compatible = "qcom,msm-cam-smmu-cb";
+ iommus = <&apps_smmu 0x808 0x0>,
+ <&apps_smmu 0x810 0x8>,
+ <&apps_smmu 0xc08 0x0>,
+ <&apps_smmu 0xc10 0x8>;
+ label = "ife";
+ ife_iova_mem_map: iova-mem-map {
+ iova-mem-region-io {
+ iova-region-name = "io";
+ iova-region-start = <0x7400000>;
+ iova-region-len = <0xd8c00000>;
+ iova-region-id = <0x3>;
+ status = "ok";
+ };
+ };
+ };
+
+ msm_cam_smmu_jpeg {
+ compatible = "qcom,msm-cam-smmu-cb";
+ iommus = <&apps_smmu 0x1060 0x8>,
+ <&apps_smmu 0x1068 0x8>;
+ label = "jpeg";
+ jpeg_iova_mem_map: iova-mem-map {
+ iova-mem-region-io {
+ iova-region-name = "io";
+ iova-region-start = <0x7400000>;
+ iova-region-len = <0xd8c00000>;
+ iova-region-id = <0x3>;
+ status = "ok";
+ };
+ };
+ };
+
+ msm_cam_icp_fw {
+ compatible = "qcom,msm-cam-smmu-fw-dev";
+ label = "icp";
+ memory-region = <&camera_mem>;
+ };
+
+ msm_cam_smmu_icp {
+ compatible = "qcom,msm-cam-smmu-cb";
+ iommus = <&apps_smmu 0x1078 0x2>,
+ <&apps_smmu 0x1020 0x8>,
+ <&apps_smmu 0x1040 0x8>,
+ <&apps_smmu 0x1030 0x0>,
+ <&apps_smmu 0x1050 0x0>;
+ label = "icp";
+ icp_iova_mem_map: iova-mem-map {
+ iova-mem-region-firmware {
+ iova-region-name = "firmware";
+ iova-region-start = <0x0>;
+
+ iova-region-len = <0x400000>;
+ iova-region-id = <0x0>;
+ status = "ok";
+ };
+
+ iova-mem-region-shared {
+ iova-region-name = "shared";
+ iova-region-start = <0x7400000>;
+ iova-region-len = <0x6400000>;
+ iova-region-id = <0x1>;
+ status = "ok";
+ };
+
+ iova-mem-region-secondary-heap {
+ iova-region-name = "secheap";
+ iova-region-start = <0xd800000>;
+ iova-region-len = <0x100000>;
+ iova-region-id = <0x4>;
+ status = "ok";
+ };
+
+ iova-mem-region-io {
+ iova-region-name = "io";
+ iova-region-start = <0xda00000>;
+ iova-region-len = <0xd2500000>;
+ iova-region-id = <0x3>;
+ status = "ok";
+ };
+
+ iova-mem-qdss-region {
+ iova-region-name = "qdss";
+ iova-region-start = <0xd900000>;
+ iova-region-len = <0x100000>;
+ iova-region-id = <0x5>;
+ qdss-phy-addr = <0x16790000>;
+ status = "ok";
+ };
+ };
+ };
+
+ msm_cam_smmu_cpas_cdm {
+ compatible = "qcom,msm-cam-smmu-cb";
+ iommus = <&apps_smmu 0x1000 0x0>;
+ label = "cpas-cdm0";
+ cpas_cdm_iova_mem_map: iova-mem-map {
+ iova-mem-region-io {
+ iova-region-name = "io";
+ iova-region-start = <0x7400000>;
+ iova-region-len = <0xd8c00000>;
+ iova-region-id = <0x3>;
+ status = "ok";
+ };
+ };
+ };
+
+ msm_cam_smmu_secure {
+ compatible = "qcom,msm-cam-smmu-cb";
+ label = "cam-secure";
+ qcom,secure-cb;
+ };
+
+ msm_cam_smmu_fd {
+ compatible = "qcom,msm-cam-smmu-cb";
+ iommus = <&apps_smmu 0x1070 0x0>;
+ label = "fd";
+ fd_iova_mem_map: iova-mem-map {
+ iova-mem-region-io {
+ iova-region-name = "io";
+ iova-region-start = <0x7400000>;
+ iova-region-len = <0xd8c00000>;
+ iova-region-id = <0x3>;
+ status = "ok";
+ };
+ };
+ };
+ };
+
+ qcom,cam-cpas@ac40000 {
+ cell-index = <0>;
+ compatible = "qcom,cam-cpas";
+ label = "cpas";
+ arch-compat = "cpas_top";
+ status = "ok";
+ reg-names = "cam_cpas_top", "cam_camnoc";
+ reg = <0 0x0ac40000 0 0x1000>,
+ <0 0x0ac42000 0 0x5000>;
+ reg-cam-base = <0x40000 0x42000>;
+ interrupt-names = "cpas_camnoc";
+ interrupts = ;
+ qcom,cpas-hw-ver = <0x170100>;
+ camnoc-axi-min-ib-bw = <3000000000>;
+ regulator-names = "camss-vdd";
+ camss-vdd-supply = <&titan_top_gdsc>;
+ power-domains = <&clock_camcc TITAN_TOP_GDSC>;
+ clock-names = "gcc_ahb_clk",
+ "gcc_axi_clk",
+ "soc_ahb_clk",
+ "slow_ahb_clk_src",
+ "cpas_ahb_clk",
+ "camnoc_axi_clk";
+ clocks = <&gcc GCC_CAMERA_AHB_CLK>,
+ <&gcc GCC_CAMERA_AXI_CLK>,
+ <&clock_camcc CAM_CC_SOC_AHB_CLK>,
+ <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+ <&clock_camcc CAM_CC_CPAS_AHB_CLK>,
+ <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>;
+ src-clock-name = "slow_ahb_clk_src";
+ clock-rates = <0 0 0 0 0 0>,
+ <0 0 0 19200000 0 0>,
+ <0 0 0 60000000 0 0>,
+ <0 0 0 66660000 0 0>,
+ <0 0 0 73840000 0 0>,
+ <0 0 0 80000000 0 0>,
+ <0 0 0 80000000 0 0>;
+ clock-cntl-level = "suspend", "minsvs", "lowsvs", "svs",
+ "svs_l1", "nominal", "turbo";
+
+ client-id-based;
+
+ client-names =
+ "csiphy0", "csiphy1", "csiphy2", "csiphy3", "cci0",
+ "csid0", "csid1", "csid2",
+ "ife0", "ife1", "ife2", "ipe0",
+ "ipe1", "cam-cdm-intf0", "cpas-cdm0", "bps0",
+ "icp0", "jpeg-dma0", "jpeg-enc0", "fd0", "lrmecpas";
+ client-axi-port-names =
+ "cam_hf_1", "cam_hf_2", "cam_hf_2", "cam_hf_1", "cam_sf_1",
+ "cam_hf_1", "cam_hf_2", "cam_hf_2",
+ "cam_hf_1", "cam_hf_2", "cam_hf_2", "cam_sf_1",
+ "cam_sf_1", "cam_sf_1", "cam_sf_1", "cam_sf_1",
+ "cam_sf_1", "cam_sf_1", "cam_sf_1", "cam_sf_1",
+ "cam_sf_1";
+ client-bus-camnoc-based;
+ qcom,axi-port-list {
+ qcom,axi-port1 {
+ qcom,axi-port-name = "cam_hf_1";
+ qcom,axi-port-mnoc {
+ qcom,msm-bus,name = "cam_hf_1_mnoc";
+ qcom,msm-bus-vector-dyn-vote;
+ };
+ qcom,axi-port-camnoc {
+ qcom,msm-bus,name = "cam_hf_1_camnoc";
+ qcom,msm-bus-vector-dyn-vote;
+ };
+ };
+ qcom,axi-port2 {
+ qcom,axi-port-name = "cam_hf_2";
+ qcom,axi-port-mnoc {
+ qcom,msm-bus,name = "cam_hf_2_mnoc";
+ qcom,msm-bus-vector-dyn-vote;
+ };
+ qcom,axi-port-camnoc {
+ qcom,msm-bus,name = "cam_hf_2_camnoc";
+ qcom,msm-bus-vector-dyn-vote;
+ };
+ };
+ qcom,axi-port3 {
+ qcom,axi-port-name = "cam_sf_1";
+ qcom,axi-port-mnoc {
+ qcom,msm-bus,name = "cam_sf_1_mnoc";
+ qcom,msm-bus-vector-dyn-vote;
+ };
+ qcom,axi-port-camnoc {
+ qcom,msm-bus,name = "cam_sf_1_camnoc";
+ qcom,msm-bus-vector-dyn-vote;
+ };
+ };
+ };
+ };
+
+ qcom,cam-cdm-intf {
+ compatible = "qcom,cam-cdm-intf";
+ cell-index = <0>;
+ label = "cam-cdm-intf";
+ num-hw-cdm = <1>;
+ cdm-client-names = "vfe",
+ "jpegdma",
+ "jpegenc",
+ "fd",
+ "lrmecdm";
+ status = "ok";
+ };
+
+ qcom,cpas-cdm0@ac48000 {
+ cell-index = <0>;
+ compatible = "qcom,cam170-cpas-cdm0";
+ label = "cpas-cdm";
+ reg = <0 0x0ac48000 0 0x1000>;
+ reg-names = "cpas-cdm";
+ reg-cam-base = <0x48000>;
+ interrupts = ;
+ interrupt-names = "cpas-cdm";
+ regulator-names = "camss";
+ camss-supply = <&titan_top_gdsc>;
+ clock-names = "gcc_camera_ahb",
+ "gcc_camera_axi",
+ "cam_cc_soc_ahb_clk",
+ "cam_cc_cpas_ahb_clk",
+ "cam_cc_camnoc_axi_clk";
+ clocks = <&gcc GCC_CAMERA_AHB_CLK>,
+ <&gcc GCC_CAMERA_AXI_CLK>,
+ <&clock_camcc CAM_CC_SOC_AHB_CLK>,
+ <&clock_camcc CAM_CC_CPAS_AHB_CLK>,
+ <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>;
+ clock-rates = <0 0 0 0 0>;
+ clock-cntl-level = "svs";
+ cdm-client-names = "ife";
+ status = "ok";
+ };
+
+ qcom,cam-isp {
+ compatible = "qcom,cam-isp";
+ arch-compat = "ife";
+ status = "ok";
+ };
+
+ cam_csid0: qcom,csid0@acb3000 {
+ cell-index = <0>;
+ compatible = "qcom,csid170";
+ reg-names = "csid";
+ reg = <0 0x0acb3000 0 0x1000>;
+ reg-cam-base = <0xb3000>;
+ interrupt-names = "csid";
+ interrupts = ;
+ regulator-names = "camss", "ife0";
+ camss-supply = <&titan_top_gdsc>;
+ ife0-supply = <&ife_0_gdsc>;
+
+ power-domains = <&clock_camcc IFE_0_GDSC>;
+ clock-names = "camera_ahb",
+ "camera_axi",
+ "soc_ahb_clk",
+ "cpas_ahb_clk",
+ "slow_ahb_clk_src",
+ "ife_csid_clk",
+ "ife_csid_clk_src",
+ "ife_cphy_rx_clk",
+ "cphy_rx_clk_src",
+ "ife_clk",
+ "ife_clk_src",
+ "camnoc_axi_clk",
+ "ife_axi_clk";
+ clocks = <&gcc GCC_CAMERA_AHB_CLK>,
+ <&gcc GCC_CAMERA_AXI_CLK>,
+ <&clock_camcc CAM_CC_SOC_AHB_CLK>,
+ <&clock_camcc CAM_CC_CPAS_AHB_CLK>,
+ <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+ <&clock_camcc CAM_CC_IFE_0_CSID_CLK>,
+ <&clock_camcc CAM_CC_IFE_0_CSID_CLK_SRC>,
+ <&clock_camcc CAM_CC_IFE_0_CPHY_RX_CLK>,
+ <&clock_camcc CAM_CC_CPHY_RX_CLK_SRC>,
+ <&clock_camcc CAM_CC_IFE_0_CLK>,
+ <&clock_camcc CAM_CC_IFE_0_CLK_SRC>,
+ <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>,
+ <&clock_camcc CAM_CC_IFE_0_AXI_CLK>;
+ clock-rates =
+ <0 0 0 0 0 0 384000000 0 0 0 404000000 0 0>,
+ <0 0 0 0 0 0 538000000 0 0 0 600000000 0 0>;
+ clock-cntl-level = "svs", "turbo";
+ src-clock-name = "ife_csid_clk_src";
+ clock-control-debugfs = "true";
+ status = "ok";
+ };
+
+ cam_vfe0: qcom,vfe0@acaf000 {
+ cell-index = <0>;
+ compatible = "qcom,vfe170";
+ reg-names = "ife";
+ reg = <0 0x0acaf000 0 0x4000>;
+ reg-cam-base = <0xaf000>;
+ interrupt-names = "ife";
+ interrupts = ;
+ regulator-names = "camss", "ife0";
+ camss-supply = <&titan_top_gdsc>;
+ ife0-supply = <&ife_0_gdsc>;
+
+ power-domains = <&clock_camcc IFE_0_GDSC>;
+ clock-names = "camera_ahb",
+ "camera_axi",
+ "soc_ahb_clk",
+ "cpas_ahb_clk",
+ "slow_ahb_clk_src",
+ "ife_clk",
+ "ife_clk_src",
+ "camnoc_axi_clk",
+ "ife_axi_clk";
+ clocks = <&gcc GCC_CAMERA_AHB_CLK>,
+ <&gcc GCC_CAMERA_AXI_CLK>,
+ <&clock_camcc CAM_CC_SOC_AHB_CLK>,
+ <&clock_camcc CAM_CC_CPAS_AHB_CLK>,
+ <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+ <&clock_camcc CAM_CC_IFE_0_CLK>,
+ <&clock_camcc CAM_CC_IFE_0_CLK_SRC>,
+ <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>,
+ <&clock_camcc CAM_CC_IFE_0_AXI_CLK>;
+ clock-rates =
+ <0 0 0 0 0 0 404000000 0 0>,
+ <0 0 0 0 0 0 480000000 0 0>,
+ <0 0 0 0 0 0 600000000 0 0>;
+ clock-cntl-level = "svs", "svs_l1", "turbo";
+ src-clock-name = "ife_clk_src";
+ clock-control-debugfs = "true";
+ clock-names-option = "ife_dsp_clk";
+ clocks-option = <&clock_camcc CAM_CC_IFE_0_DSP_CLK>;
+ clock-rates-option = <600000000>;
+ status = "ok";
+ };
+
+ cam_csid1: qcom,csid1@acba000 {
+ cell-index = <1>;
+ compatible = "qcom,csid170";
+ reg-names = "csid";
+ reg = <0 0x0acba000 0 0x1000>;
+ reg-cam-base = <0xba000>;
+ interrupt-names = "csid";
+ interrupts = ;
+ regulator-names = "camss", "ife1";
+ camss-supply = <&titan_top_gdsc>;
+ ife1-supply = <&ife_1_gdsc>;
+
+ power-domains = <&clock_camcc IFE_1_GDSC>;
+ clock-names = "camera_ahb",
+ "camera_axi",
+ "soc_ahb_clk",
+ "cpas_ahb_clk",
+ "slow_ahb_clk_src",
+ "ife_csid_clk",
+ "ife_csid_clk_src",
+ "ife_cphy_rx_clk",
+ "cphy_rx_clk_src",
+ "ife_clk",
+ "ife_clk_src",
+ "camnoc_axi_clk",
+ "ife_axi_clk";
+ clocks = <&gcc GCC_CAMERA_AHB_CLK>,
+ <&gcc GCC_CAMERA_AXI_CLK>,
+ <&clock_camcc CAM_CC_SOC_AHB_CLK>,
+ <&clock_camcc CAM_CC_CPAS_AHB_CLK>,
+ <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+ <&clock_camcc CAM_CC_IFE_1_CSID_CLK>,
+ <&clock_camcc CAM_CC_IFE_1_CSID_CLK_SRC>,
+ <&clock_camcc CAM_CC_IFE_1_CPHY_RX_CLK>,
+ <&clock_camcc CAM_CC_CPHY_RX_CLK_SRC>,
+ <&clock_camcc CAM_CC_IFE_1_CLK>,
+ <&clock_camcc CAM_CC_IFE_1_CLK_SRC>,
+ <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>,
+ <&clock_camcc CAM_CC_IFE_1_AXI_CLK>;
+ clock-rates =
+ <0 0 0 0 0 0 384000000 0 0 0 404000000 0 0>,
+ <0 0 0 0 0 0 538000000 0 0 0 600000000 0 0>;
+ clock-cntl-level = "svs", "turbo";
+ src-clock-name = "ife_csid_clk_src";
+ clock-control-debugfs = "true";
+ status = "ok";
+ };
+
+ cam_vfe1: qcom,vfe1@acb6000 {
+ cell-index = <1>;
+ compatible = "qcom,vfe170";
+ reg-names = "ife";
+ reg = <0 0x0acb6000 0 0x4000>;
+ reg-cam-base = <0xb6000>;
+ interrupt-names = "ife";
+ interrupts = ;
+ regulator-names = "camss", "ife1";
+ camss-supply = <&titan_top_gdsc>;
+ ife1-supply = <&ife_1_gdsc>;
+
+ power-domains = <&clock_camcc IFE_1_GDSC>;
+ clock-names = "camera_ahb",
+ "camera_axi",
+ "soc_ahb_clk",
+ "cpas_ahb_clk",
+ "slow_ahb_clk_src",
+ "ife_clk",
+ "ife_clk_src",
+ "camnoc_axi_clk",
+ "ife_axi_clk";
+ clocks = <&gcc GCC_CAMERA_AHB_CLK>,
+ <&gcc GCC_CAMERA_AXI_CLK>,
+ <&clock_camcc CAM_CC_SOC_AHB_CLK>,
+ <&clock_camcc CAM_CC_CPAS_AHB_CLK>,
+ <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+ <&clock_camcc CAM_CC_IFE_1_CLK>,
+ <&clock_camcc CAM_CC_IFE_1_CLK_SRC>,
+ <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>,
+ <&clock_camcc CAM_CC_IFE_1_AXI_CLK>;
+ clock-rates =
+ <0 0 0 0 0 0 404000000 0 0>,
+ <0 0 0 0 0 0 480000000 0 0>,
+ <0 0 0 0 0 0 600000000 0 0>;
+ clock-cntl-level = "svs", "svs_l1", "turbo";
+ src-clock-name = "ife_clk_src";
+ clock-control-debugfs = "true";
+ clock-names-option = "ife_dsp_clk";
+ clocks-option = <&clock_camcc CAM_CC_IFE_1_DSP_CLK>;
+ clock-rates-option = <600000000>;
+ status = "ok";
+ };
+
+ cam_csid_lite: qcom,csid-lite@acc8000 {
+ cell-index = <2>;
+ compatible = "qcom,csid-lite170";
+ reg-names = "csid-lite";
+ reg = <0 0x0acc8000 0 0x1000>;
+ reg-cam-base = <0xc8000>;
+ interrupt-names = "csid-lite";
+ interrupts = ;
+ regulator-names = "camss";
+ camss-supply = <&titan_top_gdsc>;
+
+ power-domains = <&clock_camcc TITAN_TOP_GDSC>;
+ clock-names = "camera_ahb",
+ "camera_axi",
+ "soc_ahb_clk",
+ "cpas_ahb_clk",
+ "slow_ahb_clk_src",
+ "ife_csid_clk",
+ "ife_csid_clk_src",
+ "ife_cphy_rx_clk",
+ "cphy_rx_clk_src",
+ "ife_clk",
+ "ife_clk_src",
+ "camnoc_axi_clk";
+ clocks = <&gcc GCC_CAMERA_AHB_CLK>,
+ <&gcc GCC_CAMERA_AXI_CLK>,
+ <&clock_camcc CAM_CC_SOC_AHB_CLK>,
+ <&clock_camcc CAM_CC_CPAS_AHB_CLK>,
+ <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+ <&clock_camcc CAM_CC_IFE_LITE_CSID_CLK>,
+ <&clock_camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+ <&clock_camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+ <&clock_camcc CAM_CC_CPHY_RX_CLK_SRC>,
+ <&clock_camcc CAM_CC_IFE_LITE_CLK>,
+ <&clock_camcc CAM_CC_IFE_LITE_CLK_SRC>,
+ <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>;
+ clock-rates =
+ <0 0 0 0 0 0 384000000 0 0 0 404000000 0>,
+ <0 0 0 0 0 0 538000000 0 0 0 600000000 0>;
+ clock-cntl-level = "svs", "turbo";
+ src-clock-name = "ife_csid_clk_src";
+ clock-control-debugfs = "true";
+ status = "ok";
+ };
+
+ cam_vfe_lite: qcom,vfe-lite@acc4000 {
+ cell-index = <2>;
+ compatible = "qcom,vfe-lite170";
+ reg-names = "ife-lite";
+ reg = <0 0x0acc4000 0 0x4000>;
+ reg-cam-base = <0xc4000>;
+ interrupt-names = "ife-lite";
+ interrupts = ;
+ regulator-names = "camss";
+ camss-supply = <&titan_top_gdsc>;
+
+ power-domains = <&clock_camcc TITAN_TOP_GDSC>;
+ clock-names = "camera_ahb",
+ "camera_axi",
+ "soc_ahb_clk",
+ "cpas_ahb_clk",
+ "slow_ahb_clk_src",
+ "ife_clk",
+ "ife_clk_src",
+ "camnoc_axi_clk";
+ clocks = <&gcc GCC_CAMERA_AHB_CLK>,
+ <&gcc GCC_CAMERA_AXI_CLK>,
+ <&clock_camcc CAM_CC_SOC_AHB_CLK>,
+ <&clock_camcc CAM_CC_CPAS_AHB_CLK>,
+ <&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+ <&clock_camcc CAM_CC_IFE_LITE_CLK>,
+ <&clock_camcc CAM_CC_IFE_LITE_CLK_SRC>,
+ <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>;
+ clock-rates =
+ <0 0 0 0 0 0 404000000 0>,
+ <0 0 0 0 0 0 480000000 0>,
+ <0 0 0 0 0 0 600000000 0>;
+ clock-cntl-level = "svs", "svs_l1", "turbo";
+ src-clock-name = "ife_clk_src";
+ clock-control-debugfs = "true";
+ status = "ok";
+ };
+
+ qcom,cam-icp {
+ compatible = "qcom,cam-icp";
+ compat-hw-name = "qcom,a5",
+ "qcom,ipe0",
+ "qcom,ipe1",
+ "qcom,bps";
+ num-a5 = <1>;
+ num-ipe = <2>;
+ num-bps = <1>;
+ status = "ok";
+ };
+
+ cam_a5: qcom,a5@ac00000 {
+ cell-index = <0>;
+ compatible = "qcom,cam-a5";
+ reg = <0 0x0ac00000 0 0x6000>,
+ <0 0x0ac10000 0 0x8000>,
+ <0 0x0ac18000 0 0x3000>;
+ reg-names = "a5_qgic", "a5_sierra", "a5_csr";
+ reg-cam-base = <0x00000 0x10000 0x18000>;
+ interrupts = ;
+ interrupt-names = "a5";
+ regulator-names = "camss-vdd";
+ camss-vdd-supply = <&titan_top_gdsc>;
+ clock-names = "gcc_cam_ahb_clk",
+ "gcc_cam_axi_clk",
+ "soc_fast_ahb",
+ "soc_ahb_clk",
+ "cpas_ahb_clk",
+ "camnoc_axi_clk",
+ "icp_clk",
+ "icp_clk_src";
+ clocks = <&gcc GCC_CAMERA_AHB_CLK>,
+ <&gcc GCC_CAMERA_AXI_CLK>,
+ <&clock_camcc CAM_CC_FAST_AHB_CLK_SRC>,
+ <&clock_camcc CAM_CC_SOC_AHB_CLK>,
+ <&clock_camcc CAM_CC_CPAS_AHB_CLK>,
+ <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>,
+ <&clock_camcc CAM_CC_ICP_CLK>,
+ <&clock_camcc CAM_CC_ICP_CLK_SRC>;
+ clock-rates =
+ <0 0 200000000 0 0 0 0 400000000>,
+ <0 0 200000000 0 0 0 0 600000000>;
+ clock-cntl-level = "svs", "turbo";
+ fw_name = "CAMERA_ICP.elf";
+ ubwc-cfg = <0x7B 0x1EF>;
+ status = "ok";
+ };
+
+ cam_ipe0: qcom,ipe0 {
+ cell-index = <0>;
+ compatible = "qcom,cam-ipe";
+ reg = <0 0x0ac87000 0 0x3000>;
+ reg-names = "ipe0_top";
+ reg-cam-base = <0x87000>;
+ regulator-names = "ipe0-vdd";
+ ipe0-vdd-supply = <&ipe_0_gdsc>;
+
+ power-domains = <&clock_camcc IPE_0_GDSC>;
+ clock-names = "ipe_0_ahb_clk",
+ "ipe_0_areg_clk",
+ "ipe_0_axi_clk",
+ "ipe_0_clk",
+ "ipe_0_clk_src";
+ src-clock-name = "ipe_0_clk_src";
+ clock-control-debugfs = "true";
+ clocks = <&clock_camcc CAM_CC_IPE_0_AHB_CLK>,
+ <&clock_camcc CAM_CC_IPE_0_AREG_CLK>,
+ <&clock_camcc CAM_CC_IPE_0_AXI_CLK>,
+ <&clock_camcc CAM_CC_IPE_0_CLK>,
+ <&clock_camcc CAM_CC_IPE_0_CLK_SRC>;
+ clock-rates =
+ <0 0 0 0 404000000>,
+ <0 0 0 0 480000000>,
+ <0 0 0 0 538000000>,
+ <0 0 0 0 600000000>;
+ clock-cntl-level = "svs",
+ "svs_l1", "nominal", "turbo";
+ status = "ok";
+ };
+
+ cam_ipe1: qcom,ipe1 {
+ cell-index = <1>;
+ compatible = "qcom,cam-ipe";
+ reg = <0 0x0ac91000 0 0x3000>;
+ reg-names = "ipe1_top";
+ reg-cam-base = <0x91000>;
+ regulator-names = "ipe1-vdd";
+ ipe1-vdd-supply = <&ipe_1_gdsc>;
+
+ power-domains = <&clock_camcc IPE_1_GDSC>;
+ clock-names = "ipe_1_ahb_clk",
+ "ipe_1_areg_clk",
+ "ipe_1_axi_clk",
+ "ipe_1_clk",
+ "ipe_1_clk_src";
+ src-clock-name = "ipe_1_clk_src";
+ clock-control-debugfs = "true";
+ clocks = <&clock_camcc CAM_CC_IPE_1_AHB_CLK>,
+ <&clock_camcc CAM_CC_IPE_1_AREG_CLK>,
+ <&clock_camcc CAM_CC_IPE_1_AXI_CLK>,
+ <&clock_camcc CAM_CC_IPE_1_CLK>,
+ <&clock_camcc CAM_CC_IPE_1_CLK_SRC>;
+ clock-rates =
+ <0 0 0 0 404000000>,
+ <0 0 0 0 480000000>,
+ <0 0 0 0 538000000>,
+ <0 0 0 0 600000000>;
+ clock-cntl-level = "svs",
+ "svs_l1", "nominal", "turbo";
+ status = "ok";
+ };
+
+ cam_bps: qcom,bps {
+ cell-index = <0>;
+ compatible = "qcom,cam-bps";
+ reg = <0 0x0ac6f000 0 0x3000>;
+ reg-names = "bps_top";
+ reg-cam-base = <0x6f000>;
+ regulator-names = "bps-vdd";
+ bps-vdd-supply = <&bps_gdsc>;
+
+ power-domains = <&clock_camcc BPS_GDSC>;
+ clock-names = "bps_ahb_clk",
+ "bps_areg_clk",
+ "bps_axi_clk",
+ "bps_clk",
+ "bps_clk_src";
+ src-clock-name = "bps_clk_src";
+ clock-control-debugfs = "true";
+ clocks = <&clock_camcc CAM_CC_BPS_AHB_CLK>,
+ <&clock_camcc CAM_CC_BPS_AREG_CLK>,
+ <&clock_camcc CAM_CC_BPS_AXI_CLK>,
+ <&clock_camcc CAM_CC_BPS_CLK>,
+ <&clock_camcc CAM_CC_BPS_CLK_SRC>;
+ clock-rates =
+ <0 0 0 0 404000000>,
+ <0 0 0 0 480000000>,
+ <0 0 0 0 600000000>,
+ <0 0 0 0 600000000>;
+ clock-cntl-level = "svs",
+ "svs_l1", "nominal", "turbo";
+ status = "ok";
+ };
+
+ qcom,cam-jpeg {
+ compatible = "qcom,cam-jpeg";
+ compat-hw-name = "qcom,jpegenc",
+ "qcom,jpegdma";
+ num-jpeg-enc = <1>;
+ num-jpeg-dma = <1>;
+ status = "ok";
+ };
+
+ cam_jpeg_enc: qcom,jpegenc@ac4e000 {
+ cell-index = <0>;
+ compatible = "qcom,cam_jpeg_enc";
+ reg-names = "jpege_hw";
+ reg = <0 0x0ac4e000 0 0x4000>;
+ reg-cam-base = <0x4e000>;
+ interrupt-names = "jpeg";
+ interrupts = ;
+ regulator-names = "camss-vdd";
+ camss-vdd-supply = <&titan_top_gdsc>;
+ clock-names = "camera_ahb",
+ "camera_axi",
+ "soc_ahb_clk",
+ "cpas_ahb_clk",
+ "camnoc_axi_clk",
+ "jpegenc_clk_src",
+ "jpegenc_clk";
+ clocks = <&gcc GCC_CAMERA_AHB_CLK>,
+ <&gcc GCC_CAMERA_AXI_CLK>,
+ <&clock_camcc CAM_CC_SOC_AHB_CLK>,
+ <&clock_camcc CAM_CC_CPAS_AHB_CLK>,
+ <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>,
+ <&clock_camcc CAM_CC_JPEG_CLK_SRC>,
+ <&clock_camcc CAM_CC_JPEG_CLK>;
+ clock-rates = <0 0 0 0 0 600000000 0>;
+ src-clock-name = "jpegenc_clk_src";
+ clock-cntl-level = "nominal";
+ status = "ok";
+ };
+
+ cam_jpeg_dma: qcom,jpegdma@ac52000 {
+ cell-index = <0>;
+ compatible = "qcom,cam_jpeg_dma";
+ reg-names = "jpegdma_hw";
+ reg = <0 0x0ac52000 0 0x4000>;
+ reg-cam-base = <0x52000>;
+ interrupt-names = "jpegdma";
+ interrupts = ;
+ regulator-names = "camss-vdd";
+ camss-vdd-supply = <&titan_top_gdsc>;
+ clock-names = "camera_ahb",
+ "camera_axi",
+ "soc_ahb_clk",
+ "cpas_ahb_clk",
+ "camnoc_axi_clk",
+ "jpegdma_clk_src",
+ "jpegdma_clk";
+ clocks = <&gcc GCC_CAMERA_AHB_CLK>,
+ <&gcc GCC_CAMERA_AXI_CLK>,
+ <&clock_camcc CAM_CC_SOC_AHB_CLK>,
+ <&clock_camcc CAM_CC_CPAS_AHB_CLK>,
+ <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>,
+ <&clock_camcc CAM_CC_JPEG_CLK_SRC>,
+ <&clock_camcc CAM_CC_JPEG_CLK>;
+ clock-rates = <0 0 0 0 0 600000000 0>;
+ src-clock-name = "jpegdma_clk_src";
+ clock-cntl-level = "nominal";
+ status = "ok";
+ };
+
+ qcom,cam-fd {
+ compatible = "qcom,cam-fd";
+ compat-hw-name = "qcom,fd";
+ num-fd = <1>;
+ status = "ok";
+ };
+
+ cam_fd: qcom,fd@ac5a000 {
+ cell-index = <0>;
+ compatible = "qcom,fd41";
+ reg-names = "fd_core", "fd_wrapper";
+ reg = <0 0x0ac5a000 0 0x1000>,
+ <0 0x0ac5b000 0 0x400>;
+ reg-cam-base = <0x5a000 0x5b000>;
+ interrupt-names = "fd";
+ interrupts = ;
+ regulator-names = "camss-vdd";
+ camss-vdd-supply = <&titan_top_gdsc>;
+ clock-names = "gcc_ahb_clk",
+ "gcc_axi_clk",
+ "soc_ahb_clk",
+ "cpas_ahb_clk",
+ "camnoc_axi_clk",
+ "fd_core_clk_src",
+ "fd_core_clk",
+ "fd_core_uar_clk";
+ clocks = <&gcc GCC_CAMERA_AHB_CLK>,
+ <&gcc GCC_CAMERA_AXI_CLK>,
+ <&clock_camcc CAM_CC_SOC_AHB_CLK>,
+ <&clock_camcc CAM_CC_CPAS_AHB_CLK>,
+ <&clock_camcc CAM_CC_CAMNOC_AXI_CLK>,
+ <&clock_camcc CAM_CC_FD_CORE_CLK_SRC>,
+ <&clock_camcc CAM_CC_FD_CORE_CLK>,
+ <&clock_camcc CAM_CC_FD_CORE_UAR_CLK>;
+ src-clock-name = "fd_core_clk_src";
+ clock-control-debugfs = "true";
+ clock-cntl-level = "svs", "svs_l1", "turbo";
+ clock-rates =
+ <0 0 0 0 0 400000000 0 0>,
+ <0 0 0 0 0 538000000 0 0>,
+ <0 0 0 0 0 600000000 0 0>;
+ status = "ok";
+ };
+};
+
+&cam_cci {
+ qcom,cam-res-mgr {
+ compatible = "qcom,cam-res-mgr";
+ status = "ok";
+
+ gpios = <&tlmm 8 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "cam_res_mgr_default", "cam_res_mgr_suspend";
+ pinctrl-0 = <&cam_res_mgr_active>;
+ pinctrl-1 = <&cam_res_mgr_suspend>;
+ };
+
+ qcom,cam-sensor@0 {
+ cell-index = <0>;
+ compatible = "qcom,cam-sensor";
+ reg = <0x0>;
+ csiphy-sd-index = <0>;
+ sensor-position-roll = <180>;
+ sensor-position-pitch = <0>;
+ sensor-position-yaw = <0>;
+ cam_vio-supply = <&vreg_lvs1a_1p8>;
+ cam_vana-supply = <&vreg_bob>;
+ cam_vdig-supply = <&camera_rear_ldo>;
+ cam_clk-supply = <&titan_top_gdsc>;
+ regulator-names = "cam_vio", "cam_vana", "cam_vdig", "cam_clk";
+ rgltr-cntrl-support;
+ rgltr-min-voltage = <0 3312000 1050000 0>;
+ rgltr-max-voltage = <0 3600000 1050000 0>;
+ rgltr-load-current = <0 80000 105000 0>;
+ gpio-no-mux = <0>;
+ gpios = <&tlmm 13 0>,
+ <&tlmm 9 0>,
+ <&tlmm 8 0>;
+ gpio-reset = <1>;
+ gpio-vana = <2>;
+ gpio-req-tbl-num = <0 1 2>;
+ gpio-req-tbl-flags = <1 0 0>;
+ gpio-req-tbl-label = "CAMIF_MCLK0", "CAM_RESET0", "CAM_VANA0";
+ sensor-mode = <0>;
+ cci-master = <0>;
+ status = "ok";
+ clocks = <&clock_camcc CAM_CC_MCLK0_CLK>;
+ clock-names = "cam_clk";
+ clock-cntl-level = "turbo";
+ clock-rates = <24000000>;
+ };
+
+ qcom,cam-sensor@1 {
+ cell-index = <1>;
+ compatible = "qcom,cam-sensor";
+ reg = <0x1>;
+ csiphy-sd-index = <1>;
+ sensor-position-roll = <180>;
+ sensor-position-pitch = <0>;
+ sensor-position-yaw = <0>;
+ cam_vio-supply = <&vreg_lvs1a_1p8>;
+ cam_vana-supply = <&vreg_bob>;
+ cam_vdig-supply = <&camera_rear_ldo>;
+ cam_clk-supply = <&titan_top_gdsc>;
+ regulator-names = "cam_vio", "cam_vana", "cam_vdig", "cam_clk";
+ rgltr-cntrl-support;
+ rgltr-min-voltage = <0 3312000 1050000 0>;
+ rgltr-max-voltage = <0 3600000 1050000 0>;
+ rgltr-load-current = <0 80000 105000 0>;
+ gpio-no-mux = <0>;
+ gpios = <&tlmm 14 0>,
+ <&tlmm 7 0>,
+ <&tlmm 8 0>;
+ gpio-reset = <1>;
+ gpio-vana = <2>;
+ gpio-req-tbl-num = <0 1 2>;
+ gpio-req-tbl-flags = <1 0 0>;
+ gpio-req-tbl-label = "CAMIF_MCLK1", "CAM_RESET1", "CAM_VANA1";
+ sensor-mode = <0>;
+ cci-master = <0>;
+ status = "ok";
+ clocks = <&clock_camcc CAM_CC_MCLK1_CLK>;
+ clock-names = "cam_clk";
+ clock-cntl-level = "turbo";
+ clock-rates = <24000000>;
+ };
+
+ qcom,cam-sensor@2 {
+ cell-index = <2>;
+ compatible = "qcom,cam-sensor";
+ reg = <0x02>;
+ csiphy-sd-index = <2>;
+ sensor-position-roll = <180>;
+ sensor-position-pitch = <0>;
+ sensor-position-yaw = <0>;
+ cam_vio-supply = <&vreg_lvs1a_1p8>;
+ cam_vana-supply = <&vreg_bob>;
+ cam_vdig-supply = <&camera_rear_ldo>;
+ cam_clk-supply = <&titan_top_gdsc>;
+ regulator-names = "cam_vio", "cam_vana", "cam_vdig", "cam_clk";
+ rgltr-cntrl-support;
+ rgltr-min-voltage = <0 3312000 1050000 0>;
+ rgltr-max-voltage = <0 3600000 1050000 0>;
+ rgltr-load-current = <0 80000 105000 0>;
+ gpio-no-mux = <0>;
+ gpios = <&tlmm 15 0>,
+ <&tlmm 12 0>,
+ <&tlmm 8 0>;
+ gpio-reset = <1>;
+ gpio-vana = <2>;
+ gpio-req-tbl-num = <0 1 2>;
+ gpio-req-tbl-flags = <1 0 0>;
+ gpio-req-tbl-label = "CAMIF_MCLK2", "CAM_RESET2", "CAM_VANA2";
+ sensor-mode = <0>;
+ cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_camcc CAM_CC_MCLK2_CLK>;
+ clock-names = "cam_clk";
+ clock-cntl-level = "turbo";
+ clock-rates = <24000000>;
+ };
+
+
+};
diff --git a/kernel/linux b/kernel/linux
new file mode 160000
index 0000000..c03c1a1
--- /dev/null
+++ b/kernel/linux
@@ -0,0 +1 @@
+Subproject commit c03c1a14507dfaf8b856c2608f9ac216021fc222
diff --git a/kernel/package_modules.py b/kernel/package_modules.py
new file mode 100644
index 0000000..0be4067
--- /dev/null
+++ b/kernel/package_modules.py
@@ -0,0 +1,120 @@
+#!/usr/bin/env python3
+"""Keep mici modules and optional peripherals after modules_install."""
+import argparse
+import json
+from pathlib import Path
+import subprocess
+
+# Onboard devices, service loads, post-root WLAN/BT, and existing interfaces.
+# A root can be built in or modular; silently dropping either is a build error.
+ROOTS = '''
+qcom_q6v5_pas venus_core venus_enc venus_dec spectra_camera fastrpc rpmsg_ctrl
+icc_bwmon qcom_stats qcom_wdt coresight_funnel coresight_replicator coresight_stm
+coresight_tmc stm_p_basic fuse dm_mod hci_uart btqca cfg80211 mac80211
+ath10k_core ath10k_snoc mhi_net cpufreq_powersave cpufreq_conservative qrtr_tun qrtr_mhi
+wcd934x snd_soc_wcd934x snd_soc_wsa881x
+'''.split()
+
+# Preserve configured optional USB/eGPU, networking, crypto and storage APIs.
+# Family selection also accommodates newly configured peripheral drivers.
+FAMILIES = (
+ 'kernel/drivers/usb/', 'kernel/drivers/net/usb/',
+ 'kernel/drivers/gpu/drm/nouveau/', 'kernel/drivers/gpu/drm/ttm/',
+ 'kernel/sound/usb/', 'kernel/drivers/bluetooth/', 'kernel/net/bluetooth/',
+ 'kernel/drivers/bus/mhi/', 'kernel/drivers/net/wwan/',
+ 'kernel/drivers/net/veth.ko', 'kernel/drivers/net/tun.ko', 'kernel/drivers/net/tap.ko',
+ 'kernel/drivers/net/macvlan.ko', 'kernel/drivers/net/macvtap.ko', 'kernel/drivers/net/ipvlan/',
+ 'kernel/drivers/net/ethernet/qualcomm/rmnet/', 'kernel/drivers/net/ipa/',
+ 'kernel/drivers/gnss/', 'kernel/drivers/md/',
+ 'kernel/net/netfilter/', 'kernel/net/ipv4/', 'kernel/net/ipv6/', 'kernel/net/can/',
+ 'kernel/net/bridge/', 'kernel/net/802/', 'kernel/net/8021q/', 'kernel/net/sched/',
+ 'kernel/crypto/', 'kernel/arch/arm64/crypto/', 'kernel/fs/fuse/',
+)
+
+
+def module_name(path):
+ return Path(path).name.removesuffix('.zst').removesuffix('.xz').removesuffix('.gz').removesuffix('.ko').replace('-', '_')
+
+
+def select_modules(directory, roots=ROOTS, families=FAMILIES):
+ dependencies = {}
+ for line in (directory / 'modules.dep').read_text().splitlines():
+ module, required = line.split(':', 1)
+ dependencies[module] = required.split()
+ if any(path not in dependencies for required in dependencies.values() for path in required):
+ raise ValueError('Installed hard dependency is missing')
+ by_name = {module_name(path): path for path in dependencies}
+ if len(by_name) != len(dependencies):
+ raise ValueError('Duplicate module basename')
+ for path in dependencies:
+ relative = Path(path)
+ if relative.is_absolute() or '..' in relative.parts or not (directory / relative).is_file():
+ raise ValueError(f'Invalid installed module: {path}')
+ builtins = {module_name(path) for path in (directory / 'modules.builtin').read_text().splitlines()}
+ soft = {}
+ for line in (directory / 'modules.softdep').read_text().splitlines():
+ words = line.split()
+ if words and words[0] == 'softdep':
+ soft.setdefault(words[1].replace('-', '_'), set()).update(
+ name.replace('-', '_') for name in words[2:] if name not in ('pre:', 'post:'))
+
+ pending = set(roots) | {module_name(path) for path in dependencies if path.startswith(families)}
+ # USB and HID device drivers also live outside drivers/usb and drivers/hid.
+ for line in (directory / 'modules.alias').read_text().splitlines():
+ words = line.split()
+ if len(words) == 3 and words[0] == 'alias' and words[1].startswith(('usb:', 'hid:')):
+ pending.add(words[2])
+ keep = set()
+ visited = set()
+ while pending:
+ name = min(pending)
+ pending.remove(name)
+ name = name.replace('-', '_')
+ if name in visited:
+ continue
+ visited.add(name)
+ pending.update(soft.get(name, ()))
+ if name in builtins:
+ continue
+ if name not in by_name:
+ raise ValueError(f'Required module is neither installed nor builtin: {name}')
+ path = by_name[name]
+ if path in keep:
+ continue
+ keep.add(path)
+ pending.update(module_name(required) for required in dependencies[path])
+ return keep, set(dependencies) - keep
+
+
+def package(root, report=None):
+ versions = sorted((root / 'lib/modules').iterdir())
+ if len(versions) != 1 or not versions[0].is_dir():
+ raise ValueError('Expected exactly one installed kernel version')
+ directory = versions[0]
+ keep, remove = select_modules(directory)
+ before = sum(path.stat().st_size for path in directory.rglob('*') if path.is_file())
+ order = (directory / 'modules.order').read_text().splitlines()
+ uncompressed = {str(Path(path).with_suffix('')) if path.endswith(('.zst', '.xz', '.gz')) else path for path in keep}
+ # Validate the complete graph before changing any installed files.
+ for path in sorted(remove):
+ (directory / path).unlink()
+ (directory / 'modules.order').write_text(''.join(path + '\n' for path in order if path in uncompressed))
+ for path in sorted(directory.rglob('*'), reverse=True):
+ if path.is_dir() and not any(path.iterdir()):
+ path.rmdir()
+ # Keep full modules.builtin/modinfo; regenerate every modular and builtin index.
+ subprocess.run(['depmod', '-b', str(root), directory.name], check=True)
+ after = sum(path.stat().st_size for path in directory.rglob('*') if path.is_file())
+ result = {'version': directory.name, 'keep': sorted(keep), 'remove': sorted(remove),
+ 'before_bytes': before, 'after_bytes': after}
+ if report:
+ report.write_text(json.dumps(result, indent=2) + '\n')
+ print(f'{directory.name}: kept {len(keep)} modules, removed {len(remove)}, saved {before - after} bytes')
+
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument('root', type=Path, help='modules_install INSTALL_MOD_PATH; modifies only this build output')
+ parser.add_argument('--report', type=Path)
+ args = parser.parse_args()
+ package(args.root.resolve(), args.report)
diff --git a/kernel/patches/0001-clk-qcom-dispcc-sdm845-dont-keep-MDSS-GDSC-on.patch b/kernel/patches/0001-clk-qcom-dispcc-sdm845-dont-keep-MDSS-GDSC-on.patch
new file mode 100644
index 0000000..cf0186a
--- /dev/null
+++ b/kernel/patches/0001-clk-qcom-dispcc-sdm845-dont-keep-MDSS-GDSC-on.patch
@@ -0,0 +1,40 @@
+From c1341a65e2ce2d80d72fea6a1142f48da16bf9fe Mon Sep 17 00:00:00 2001
+From: Robin Reckmann
+Date: Tue, 24 Mar 2026 21:53:49 +0900
+Subject: clk: qcom: dispcc-sdm845: don't keep MDSS GDSC on across late
+ init
+
+On SDM845 systems where the bootloader leaves the display pipeline enabled
+for splash/handoff, keeping the MDSS power domain on across late init can
+leave the display controller in stale bootloader state during early Linux
+display bring-up.
+
+This can cause the first DSI modeset to fail with:
+
+ disp_cc_mdss_pclk0_clk_src: rcg didn't update its configuration
+
+and can also lead to display handoff issues when the panel driver is built
+into the kernel and probes early.
+
+Set GENPD_FLAG_NO_STAY_ON on mdss_gdsc so the MDSS power domain is not kept
+enabled until late_initcall_sync, allowing Linux to bring the display block
+up from a clean state.
+---
+ drivers/clk/qcom/dispcc-sdm845.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/qcom/dispcc-sdm845.c b/drivers/clk/qcom/dispcc-sdm845.c
+index 2f9e9665d..91c5bc42b 100644
+--- a/drivers/clk/qcom/dispcc-sdm845.c
++++ b/drivers/clk/qcom/dispcc-sdm845.c
+@@ -763,6 +763,7 @@ static struct gdsc mdss_gdsc = {
+ .en_rest_wait_val = 0x5,
+ .pd = {
+ .name = "mdss_gdsc",
++ .flags = GENPD_FLAG_NO_STAY_ON,
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+ .flags = HW_CTRL | POLL_CFG_GDSCR,
+--
+2.53.0
+
diff --git a/kernel/patches/0002-drm-panel-add-dwo-do0200fat07-panel-driver.patch b/kernel/patches/0002-drm-panel-add-dwo-do0200fat07-panel-driver.patch
new file mode 100644
index 0000000..0932ade
--- /dev/null
+++ b/kernel/patches/0002-drm-panel-add-dwo-do0200fat07-panel-driver.patch
@@ -0,0 +1,383 @@
+From afef331e1a2be2ef2f4f25ee9dfc711aadb5f2b8 Mon Sep 17 00:00:00 2001
+From: Robin Reckmann
+Date: Thu, 26 Mar 2026 00:24:06 +0900
+Subject: drm/panel: add dwo do0200fat07 panel driver
+
+Add support for the dwo do0200fat07 240x536 panel found on the comma mici.
+---
+ drivers/gpu/drm/panel/Kconfig | 10 +
+ drivers/gpu/drm/panel/Makefile | 1 +
+ drivers/gpu/drm/panel/panel-dwo-do0200fat07.c | 333 ++++++++++++++++++
+ 3 files changed, 344 insertions(+)
+ create mode 100644 drivers/gpu/drm/panel/panel-dwo-do0200fat07.c
+
+diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
+--- a/drivers/gpu/drm/panel/Kconfig
++++ b/drivers/gpu/drm/panel/Kconfig
+@@ -136,6 +136,16 @@
+ help
+ Say Y here if you want to enable support for ChipWealth
+ CH13726A-based display panels.
++
++config DRM_PANEL_DWO_DO0200FAT07
++ tristate "DWO DO0200FAT07 panel"
++ depends on OF
++ depends on DRM_MIPI_DSI
++ depends on BACKLIGHT_CLASS_DEVICE
++ select VIDEOMODE_HELPERS
++ help
++ Say Y here if you want to enable support for the DWo DO0200FAT07
++ panel.
+
+ config DRM_PANEL_EBBG_FT8719
+ tristate "EBBG FT8719 panel driver"
+diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
+--- a/drivers/gpu/drm/panel/Makefile
++++ b/drivers/gpu/drm/panel/Makefile
+@@ -16,6 +16,7 @@
+ obj-$(CONFIG_DRM_PANEL_LVDS) += panel-lvds.o
+ obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o
+ obj-$(CONFIG_DRM_PANEL_EDP) += panel-edp.o
++obj-$(CONFIG_DRM_PANEL_DWO_DO0200FAT07) += panel-dwo-do0200fat07.o
+ obj-$(CONFIG_DRM_PANEL_EBBG_FT8719) += panel-ebbg-ft8719.o
+ obj-$(CONFIG_DRM_PANEL_ELIDA_KD35T133) += panel-elida-kd35t133.o
+ obj-$(CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02) += panel-feixin-k101-im2ba02.o
+diff --git a/drivers/gpu/drm/panel/panel-dwo-do0200fat07.c b/drivers/gpu/drm/panel/panel-dwo-do0200fat07.c
+new file mode 100644
+--- /dev/null
++++ b/drivers/gpu/drm/panel/panel-dwo-do0200fat07.c
+@@ -0,0 +1,334 @@
++// SPDX-License-Identifier: GPL-2.0-only
++// Copyright (c) 2026 Robin Reckmann
++
++#include
++#include
++#include
++#include
++#include
++#include
++
++#include