Mainline Linux 7.1.0-rc1 (sdm845) and postmarketOS edge port for the Xiaomi Mi 8 (xiaomi-dipper), running from the internal 128 GB UFS 2.1 storage (userdata) with full 8-core Kryo 385 CPU scaling, Samsung EA8074 AMOLED DRM/KMS display, Adreno 630 (freedreno) GPU acceleration, ST FTS5 capacitive touch, TI TAS2557 + WCD9340 audio (speaker, earpiece, and dual microphones), Bluetooth (WCN3990), and automated 60–80% USB charge-hysteresis supervision.
Companion Technical Deep-Dive: Read Bringing Up Mainline Linux 7.1 on the Xiaomi Mi 8 (
dipper) Without UART for the full debugging story—including how an orphaned bootloader continuous-splash MDSS scan-out caused a 16-second interconnectsync_state()hang when entering cluster power collapse.
This physical unit has a board-level dead RF transceiver (rflm_qlnk.cpp:1082: RF stuck in QLINK start state even on stock Android). Because Snapdragon 845 runs its Wi-Fi firmware inside the modem Q6 DSP (mss), cellular and Wi-Fi are intentionally left disabled in the active Device Tree and the phone runs as a fast, low-power 6 GB RAM / 128 GB UFS Linux node over USB CDC NCM.
Hardware & Software Specifications
| Component | Specification | Details |
|---|---|---|
| Model | Xiaomi Mi 8 (dipper) |
6 GB LPDDR4X RAM (5.5 GiB usable in Linux) + 128 GB UFS 2.1 |
| SoC | Qualcomm Snapdragon 845 (SDM845) |
4× Kryo 385 Gold (Cortex-A75) @ 2.65 GHz + 4× Silver (Cortex-A55) @ 1.77 GHz |
| GPU | Qualcomm Adreno 630 (FD630) |
msm_dpu + freedreno (/dev/dri/card0, /dev/dri/renderD128) |
| Display | Samsung EA8074 6.21" AMOLED |
1080×2248 @ 60 Hz MIPI DSI command-mode panel (panel-samsung-ea8074), 1023-step hardware backlight |
| Touchscreen | STMicroelectronics FingerTip S (FTS5) |
st,stmfts5 on i2c14 @ 0x49, 10-finger multitouch (1079×2247) |
| Audio | TI TAS2557 + Qualcomm WCD9340 (pahu) |
Q6AFE SLIMbus + sound-sdm845 (Xiaomi-Mi8-Tas2557), speaker, earpiece, and dual mics |
| PMICs | PM8998 + PMI8998 + PM8005 | qcom_smbx charger, qcom_fg fuel gauge, pm8941_pwrkey, pm8941-wled |
| Kernel | 7.1.0-rc1-sdm845 |
linux-postmarketos-qcom-sdm845 (sdm845-xiaomi-dipper.dtb) |
| OS / Init | postmarketOS edge (v25.12) |
Alpine Linux aarch64, OpenRC, charge-limit & powerkey-display services |
Subsystem Support Matrix
| Subsystem | Kernel Driver / Module | Status | Notes |
|---|---|---|---|
| CPU & Idle States | qcom-cpufreq-hw, PSCI cpuidle |
Working | All 8 cores online (schedutil), C1 (wfi), C2 (rail-power-collapse), and cluster-sleep-0 enabled |
| UFS 2.1 Storage | ufshcd-qcom (1d84000.ufshc) |
Working | 6 SCSI LUNs (sda–sdf), rootfs on sda21 (userdata, 110 GB ext4) |
| USB Networking | dwc3-qcom (a600000.usb), CDC NCM |
Working | usb0 (172.16.42.1/24 / dedicated 172.16.44.1/24), SSH over USB |
| AMOLED Display | msm_dpu + panel-samsung-ea8074 |
Working | Native 1080×2248p60 DRM/KMS (DSI-1), hardware DPMS power-off (fb0/blank) |
| AMOLED Backlight | samsung-ea8074 (DCS 0x51/0x53) |
Working | Smooth 0–1023 brightness control via /sys/class/backlight/ae94000.dsi.0/ |
| 3D GPU Acceleration | msm / freedreno (a630_sqe.fw, a630_gmu.bin) |
Working | Adreno 630 GMU + zap shader (a630_zap.mbn), Mesa Freedreno |
| Touchscreen | stmfts (st,stmfts5 @ 0x49) |
Working | Full 10-point multitouch (/dev/input/event3, chip ID 0x54 0x36 rev 0x02) |
| Audio Playback | snd-soc-sdm845 + tas2557 + wcd934x |
Working | Bottom mono speaker (TAS2557 DSP tas2557_uCDSP.bin over I2C + Pri MI2S) & top earpiece (WCD9340 EAR) |
| Audio Capture | wcd934x + Q6ASM MultiMedia2 |
Working | Bottom main mic (ADC1/AMIC1) & top secondary mic (ADC3/AMIC3), UCM profiles installed |
| Bluetooth | hci_uart (qcom,wcn3990-bt) |
Working | Loads crbtfw21.tlv / crnv21.bin, scans nearby BLE/BR/EDR devices |
| Battery & Charger | qcom_smbx + qcom_fg + charge-limit |
Working | Live SOC/V/I telemetry + OpenRC daemon maintaining 60–80% SOC via USBIN_SUSPEND |
| Buttons & Vibration | pm8941_pwrkey, gpio-keys, qcom-spmi-haptics |
Working | Power key toggles display blanking (powerkey-display); Vol Up + Power reboots cleanly |
| System Suspend | s2idle |
Working | Clean entry/exit on power button or RTC wakeup (~40 mA battery draw while suspended) |
| Modem / Wi-Fi | qcom-q6v5-mss + ath10k_snoc |
Disabled (HW) | Board has a dead RF transceiver IC (rflm_qlnk.cpp:1082); disabled in DT |
Three Non-Obvious Mainline Bring-Up Findings
All kernel debugging on this device was performed without UART serial, using early pstore/ramoops memory carves, an initramfs /dev/kmsg logger that survives switch_root by staging its own busybox onto the UFS cache partition (sda17), and binary-search device tree bisection.
1. TrustZone SPI GPIO Reservation (gpio-reserved-ranges)
&tlmm {
gpio-reserved-ranges = <0 4>, <81 4>;
};
GPIOs 0..3 and 81..84 are routed to TrustZone-protected SPI controllers (fingerprint sensor and embedded Secure Element). Without gpio-reserved-ranges, pinctrl-msm probes every pin during GPIO chip registration, triggering an immediate TrustZone access violation that resets the SoC before USB or UFS ever initializes.
2. Why cluster-sleep-0 Hung the SoC 16 Seconds Into Boot (Orphaned Bootloader MDSS Scan-Out)
During initial bring-up with a minimal headless Device Tree (&mdss disabled), enabling the deep cluster idle state (cluster_sleep_0, PSCI parameter 0x4100c244) caused a deterministic hard hang ~16 seconds into every boot—even with clk_ignore_unused and pd_ignore_unused on the kernel command line.
Tracing every driver probe and sync_state callback revealed the exact trigger chain:
- At ~16 seconds into boot, userland (
mdev/udev) finishes loading all modular platform drivers. - Once the final consumer probes,
qnoc-sdm845(1500000.interconnect,17900000.interconnect) invokes itssync_state()callback and releases the boot-time interconnect bandwidth votes. - However, the Xiaomi bootloader (
XBL/ABL) leaves the MDSS display controller actively scanning out the Mi boot splash image from DDR memory (cont_splashat0x9d400000). - When
&mdsswas disabled in Linux, no DRM driver ever took ownership of MDSS or shut down that DMA scan-out path. The momentqnoc-sdm845dropped its boot bandwidth floors and the CPU cluster enteredcluster-sleep-0(activating the RPMh sleep set), MDSS attempted an unvoted DDR fetch and locked the SoC bus hard.
The Fix: Enabling &mdss, &mdss_mdp, &mdss_dsi0, and the generated Samsung EA8074 DRM panel driver (panel-samsung-ea8074.c) hands MDSS ownership to Linux (msm_dpu). msm_dpu properly votes for mdp0-mem interconnect bandwidth when the screen is active and cleanly shuts down the DSI/DPU pipes when the screen blanks—making cluster-sleep-0 (C1, C2, and s2idle) 100% stable with zero interconnect workarounds.
3. ST FTS5 Touch Regulator (vdd_l28) & WCD9340 Audio Capture MCLK
- Touchscreen (
vdd_l28): Describingvdd_l28(3.0 V touchavdd) as a fixed3.3 Vrail withregulator-boot-onandREGULATOR_MODE_HPMcrashed RPMh before USB enumeration. Describingvdd_l28with its true hardware range (2.856–3.312 V) and no boot-time override allowed the upstreamstmftsdriver (patched with.compatible = "st,stmfts5") to enable the rail cleanly at module probe time. - Microphones (
WCD9340MCLK DAPM): Recording from the microphones initially returned all-zero PCM samples whenever speaker playback was not running simultaneously. Root cause: insound/soc/qcom/sdm845.c, the WCD9340MCLKsupply widget is only wired toRX_BIAS(playback). Adding"ADC1", "MCLK","ADC2", "MCLK", and"ADC3", "MCLK"toaudio-routinginsdm845-xiaomi-dipper.dts—alongsideAMIC1 <- MIC BIAS4andAMIC3 <- MIC BIAS1—enabled standalone microphone capture.
Always-On USB Power & Thermal Profile
The phone is designed to stay plugged into a host over USB 24/7 without swelling the lithium-ion cell:
charge-limitOpenRC service: Polls/sys/class/power_supply/qcom-battery/capacityevery 60 seconds and toggles/sys/class/power_supply/qcom-smbchg-usb/input_suspend:- At
>= 80%SOC: writes1(USBIN_SUSPEND), cutting charger current completely (status = Discharging). - At
<= 60%SOC: writes0, resuming charging up to 80%.
- At
- Measured Power Draw:
- Screen ON (idle):
~200 mA(~0.85 W) - Screen OFF (
fb0/blank = 1):~120 mA(~0.50 W) - System Suspend (
s2idle):~40 mA(~0.17 W)
- Screen ON (idle):
Build & Flash Workflow
# 1. Compile the device tree (sdm845-xiaomi-dipper.dtb) and package boot.img
dtc -I dts -O dtb -o sdm845-xiaomi-dipper.dtb dts/sdm845-xiaomi-dipper.dts
cat vmlinuz-7.1.0-rc1-sdm845 sdm845-xiaomi-dipper.dtb > Image.gz-dtb
mkbootimg \
--kernel Image.gz-dtb \
--ramdisk initramfs \
--base 0x0 --kernel_offset 0x8000 --ramdisk_offset 0x1000000 --tags_offset 0x100 --pagesize 4096 \
--cmdline "console=tty0 root=/dev/sda21 rw rootwait clk_ignore_unused pd_ignore_unused" \
-o boot-dipper.img
# 2. Flash to boot_a over fastboot
fastboot flash boot_a boot-dipper.img
fastboot reboot
Device Tags: