diff --git a/README.md b/README.md index 7b1b960..9e0dd2a 100644 --- a/README.md +++ b/README.md @@ -33,9 +33,10 @@ login. Root is locked. | Works | Works once you supply firmware | Does not work | |---|---|---| -| UFS storage, USB, keyboard, touchpad, touchscreen | Adreno 630 initialises — see mesa note below | Audio — kernel driver, not firmware | -| Display (unaccelerated), battery, charging | Sensor hub — accelerometer, auto-rotate | Onboard WiFi — loaded by the modem, which does not stay up | -| USB WiFi dongles, USB phone tethering | Hardware video decode (venus, `/dev/video0-3`) | LTE modem — crashes at RF init, cause unknown | +| UFS storage, USB, keyboard, touchpad, touchscreen | Adreno 630 initialises — see mesa note below | Onboard WiFi — loaded by the modem, which does not stay up | +| Display (unaccelerated), battery, charging | Sensor hub — accelerometer, auto-rotate | LTE modem — crashes at RF init; see docs/firmware.md for what has been ruled out | +| USB WiFi dongles, USB phone tethering | Hardware video decode (venus, `/dev/video0-3`) | | +| Bluetooth — the controller has no burned-in address; `c630-bt-addr.service` reads the factory one off the DPP partition at boot | Audio — needs `qcadsp850.mbn` plus one kernel module Fedora does not build; see docs/firmware.md | | Verified on hardware. `docs/firmware.md` has the evidence for each, including the things that look like they should help and do not. @@ -153,9 +154,13 @@ installed packages as missing — see [docs/install.md](docs/install.md). With the per-model firmware supplied, the GPU initialises, the ADSP, CDSP and SLPI all run, sensors appear as IIO devices and venus registers `/dev/video0-3`. -Audio and onboard WiFi remain broken for reasons unrelated to firmware — see -[docs/firmware.md](docs/firmware.md), which records both the evidence and the -several plausible fixes that turn out not to work. +Audio additionally needs one kernel module Fedora does not build +(`CONFIG_SND_SOC_WSA881X`); with it compiled out of tree, the sound card +registers and the speakers play. Onboard WiFi remains broken: the modem that +hosts the WLAN firmware dies at RF init, and firmware versions, userspace +services and kernel 6.12-vs-7.1 have all been eliminated as the cause — see +[docs/firmware.md](docs/firmware.md), which records the evidence and the many +plausible fixes that turn out not to work. The internal drive needs `build/install-to-disk.sh` rather than `dd`: its UFS uses 4096-byte logical sectors, which the 512-byte image geometry cannot be diff --git a/docs/firmware.md b/docs/firmware.md index 77829a1..f7bf28e 100644 --- a/docs/firmware.md +++ b/docs/firmware.md @@ -217,8 +217,10 @@ Whichever route, drop the result into `firmware/local/` and rebuild — see ## What the firmware does not fix -Installing all of it still leaves two things broken, both for reasons that are -not about firmware. Recorded here so nobody repeats the search. +Installing all of it still leaves two things not working out of the box, for +reasons that are not about firmware. Audio turns out to be a missing Fedora +kernel module and is fixable today; onboard WiFi remains genuinely broken. +Recorded here so nobody repeats the search. ### Onboard WiFi: everything is in place except a working modem @@ -261,12 +263,14 @@ said to show around 40. #### The modem fetches wlanmdsp over TFTP This is the step that is easy to miss, and the reason `tqftpserv` exists. -`tqftpserv` serves from `/lib/firmware/`, and the modem asks it for the WLAN -firmware by path: +The modem asks it for the WLAN firmware by path — but where tqftpserv serves +from depends on the version, and the layout below (from aarch64-laptops) does +**not** work with Fedora's current build; see [The tqftpserv paths above are +version-dependent](#the-tqftpserv-paths-above-are-version-dependent). On +current Fedora: ```sh -sudo mkdir -p /lib/firmware/readonly/firmware/image -sudo cp wlanmdsp.mbn /lib/firmware/readonly/firmware/image/ +sudo ln -sf updates/qcom/sdm850/LENOVO/81JL/wlanmdsp.mbn /lib/firmware/wlanmdsp.mbn ``` The modem also wants a writable area, and says so in the `tqftpserv` journal: @@ -276,10 +280,13 @@ The modem also wants a writable area, and says so in the `tqftpserv` journal: [TQFTP] WRQ: /readwrite/server_check.txt ``` +On current Fedora that lives in `/tmp/tqftpserv` (recreate after each boot, or +add a tmpfiles.d entry): + ```sh -sudo mkdir -p /lib/firmware/readwrite/ota_firewall -sudo touch /lib/firmware/readwrite/ota_firewall/ruleset -sudo chmod -R 0777 /lib/firmware/readwrite +sudo mkdir -p /tmp/tqftpserv/ota_firewall +sudo touch /tmp/tqftpserv/ota_firewall/ruleset +sudo chmod -R 0777 /tmp/tqftpserv ``` Watching `journalctl -u tqftpserv` while starting the modem is the best @@ -315,26 +322,67 @@ made to load. #### Firmware has been eliminated as the variable -The test that narrows it: both projects publish the modem trio, and their -copies differ — the modem pair matches on size but not checksum. Both were -installed on this machine, with `rmtfs` and `tqftpserv` running and `wlanmdsp` -in the TFTP path. Both produce the **identical** QLINK failure. +The nine driver versions under `Lenovo/YogaC630/` contain five distinct +modem-firmware builds — `200.0.1.0` through `200.0.4.0` share one 2018-vintage +pair (a different mpss size from all later builds, and the closest match to +this machine's 2018-10 manufacture date), `200.0.10.0`, `200.0.11.0`, +`200.0.14.0`/`200.0.16.0`, and `200.0.19.0` are the others, and +aarch64-laptops' copies differ again by checksum. Every one of them was booted +on this machine, with `rmtfs` and `tqftpserv` running. Every one produces the +**identical** QLINK failure, crashing about 0.4 s after mpss comes up. -That is worth stating carefully. It does not show either set to be wrong, and -it does not make one more trustworthy than the other — the aarch64-laptops -copies come from a setup whose support table ticks WiFi, but on a 2019 kernel, -and neither set has been shown to work here. What it does show is that changing -firmware does not change the outcome. +So neither the firmware nor its vintage is the variable. Nor is the kernel +version, at least not recently: Fedora's 6.12.15 (`kernel-core` from koji, +booted with the same device tree) produces the identical crash. The +aarch64-laptops setup that ticked WiFi ran a 2019 5.x branch, so a very old +regression is not excluded — but their issue #51 records modem crash/recovery +lockups on that setup too, so "WiFi worked" and "the modem crashed" may well +have coexisted, with `wlanmdsp` loading in the window before the first crash. +An earlier note in this project's history has the crash loop at roughly 42 s; +today it is ~3.4 s. If those cadences are both real, what changed — and +whether a long first window is enough for `wlfw` to appear — is an open +question. -So the difference is not the firmware, and not the userspace services. What -remains is the kernel: that setup ran `aarch64-laptops/linux` branch `gpu`, -circa 2019 on 5.x, against 7.1.5 here. Both ath10k patches it applied are long -upstream — the device tree carries `qcom,snoc-host-cap-8bit-quirk` from the -first of them. Six years of `qcom-q6v5-mss` churn sits between the two. +#### What QLINK is, and what the modem reads before dying -That points at a kernel regression rather than anything missing on disk. -Confirming it means bisecting or booting an older kernel, which nothing here -does yet. +QLINK is the SerDes link between the SoC and the SDR845 RF transceiver chip; +`rflm_qlnk.cpp` is the modem firmware's manager for it. "Stuck in start state +0x0" means the transceiver never answered — the signature of a chip that is +absent, unpowered, or misconfigured. This unit is an LTE SKU (SIM slot, +factory-label IMEI, modem worked under Windows), so the chip is present and +functional; under Windows, ACPI and the Qualcomm PEP handle subsystem power, +and under device-tree boot whatever they did for the RF front end has no +equivalent. That is a hypothesis, not a finding — the DSDT keeps its power +management in opaque PEP tables, so it could not be confirmed from the tables +alone. + +`rmtfs -v` shows the modem's storage dialogue in the half-second before the +crash: it opens `modem_fs1`, `modem_fs2`, `modem_fsg` and `modem_fsc` +successfully, requests two partitions Linux's rmtfs has never heard of — +`modem_fsg_oem_1` and `modem_fsg_oem_2`, names that appear inside the mpss +image itself, with no provider found in any WOA-Project cabinet — allocates +its 2 MB buffer, reads a superblock's worth, and dies. On this machine +`modemst1`/`modemst2` carry valid `IMGEFS1`/`IMGEFS2` filesystems, while +**`fsg` and `fsc` are entirely blank**. Byte copies of all four live in +`firmware/local/nv-backup/` (gitignored), taken before any experimentation. + +#### The tqftpserv paths above are version-dependent + +The `/lib/firmware/readonly/firmware/image/` and `/lib/firmware/readwrite/` +layout described earlier matches the old aarch64-laptops tqftpserv. Fedora's +current build is different: `/readwrite/*` is served from `/tmp/tqftpserv` +(tmpfs — anything created there is gone on reboot), and +`/readonly/firmware/image/` resolves through the normal firmware search +path, i.e. `/lib/firmware/`. So `wlanmdsp.mbn` needs to be reachable as +`/lib/firmware/wlanmdsp.mbn` (a symlink to the copy under `updates/` works), +and the writable tree belongs under `/tmp/tqftpserv/`. + +The full Windows-side TFTP tree can be reconstructed, and was: the driver +INFs are TFTP-mapping manifests, and `mcfg_subsys_ext850.inf` maps 159 modem +configuration files — carrier configs and, notably, `mcfg_hw` hardware RF +configs for the SDX20 — into `readonly/firmware/image/modem_pr/mcfg/...`. +Serving all of it changes nothing: the modem crashes before requesting any of +it. Things that sound like they should help and do not: @@ -343,14 +391,24 @@ Things that sound like they should help and do not: - **`rmtfs` alone.** Necessary, not sufficient. Its "failed to update start state" warnings are its optional remoteproc-control helper and are harmless. - **The `_nm` variants.** See above. +- **Any published firmware version.** All five distinct builds fail + identically; see above. +- **The MCFG configuration tree.** Served in full over TFTP; the modem never + gets far enough to ask for it. +- **`clk_ignore_unused pd_ignore_unused`.** Already on the command line + (postmarketOS ships the same for this machine). -Untried, in rough order of promise: the other eight driver versions under -`Lenovo/YogaC630/` (this machine's UEFI is `9UCN33WW(V2.06)` from 2019, and the -newest package may not be the right vintage); `mcfg_subsys_ext850.cab`, which -holds modem configuration data; and building `board-2.bin` from the C630's own -`bdwlan.*` files rather than relying on Fedora's. +Untried, in rough order of promise: reporting upstream — the error string +appears nowhere public, and linux-arm-msm (Bjorn Andersson, Dmitry Baryshkov, +Steev Klimaszewski all have C630 history) is where the RF-power hypothesis +could be confirmed or killed; Lenovo's Digital Download Recovery Service image +for this serial, which would show the exact original driver set and whatever +provides `modem_fsg_oem_*` under Windows; building `board-2.bin` from the +C630's own `bdwlan.*` files (only relevant once the modem stays up); and the +5.x aarch64-laptops kernel itself, to test whether its crash cadence leaves a +usable window. -### Audio is a kernel driver problem +### Audio: Fedora does not build the speaker-amp driver The ADSP runs, the audio services register, and the codec answers: @@ -358,23 +416,77 @@ The ADSP runs, the audio services register, and the codec answers: wcd934x-slim 217:250:1:0: WCD934x chip id major 0x108, minor 0x1 ``` -So SLIMbus, the ADSP and the hardware are all fine. What fails is one sub-device -of the codec: +So SLIMbus, the ADSP and the hardware are all fine. The trail of suspicion +used to end at this SoundWire message: ``` qcom-soundwire wcd934x-soundwire.12.auto: din-ports (2) mismatch with controller (6) platform sound: deferred probe pending: msm-snd-sdm845: SLIM Playback: codec dai not found ``` -The codec's SoundWire block declares two data-in ports where the controller -expects six, so it never probes, so the sound card has no codec DAI and never -appears. That is a mismatch inside the kernel, and needs a kernel or -device-tree change rather than any blob. +The first line is a red herring. Since kernel 6.18 (commit `9e53a66a2f2f`, +"soundwire: qcom: deprecate qcom,din/out-ports") it is a warning: the +device-tree value overrides the register value afterwards and the probe +continues. + +The real blocker is the second line. The device tree's `SLIM Playback` link +names four codec DAIs: the WCD9340, the SoundWire master inside it, and the +two WSA881x speaker amplifiers hanging off that master. Fedora's aarch64 +kernel has never set `CONFIG_SND_SOC_WSA881X` — while the newer siblings +WSA883X and WSA884X, which the ThinkPad X13s needs, are both `=m`. With no +amplifier driver the two SoundWire slaves never bind, the machine driver +cannot find its DAIs, and the card sits in deferred probe forever. + +Building the one missing module proves it. `sound/soc/codecs/wsa881x.c` is a +single self-contained file; compiled against the running kernel +(`kernel-devel`, `gcc`, `make`, then `make -C /lib/modules/$(uname -r)/build +M=$PWD modules` with `obj-m += snd-soc-wsa881x.o` and `snd-soc-wsa881x-objs := +wsa881x.o`), installed under `/lib/modules/$(uname -r)/extra/` and picked up +by `depmod -a`, it autoloads on the SoundWire modalias at boot and the +`Lenovo-YOGA-C630-13Q50` card registers, headphone-jack detection included. +The UCM profile has been in alsa-ucm-conf since 2020; `alsaucm` itself is in +`alsa-ucm-utils`, so on the minimal image: + +```sh +alsaucm -c Lenovo-YOGA-C630-13Q50 set _verb HiFi set _enadev Speaker +speaker-test -D plughw:0,0 -c2 -t sine -f 440 -l 1 +``` + +The `overflow error on RX port` and register-read `-16` messages logged when a +stream stops are noise, seen on working sdm845 devices too. + +**PipeWire needs one more thing.** The ADSP front-end advertises S24_LE +(24-bit samples in 32-bit containers) and then garbles it: playback runs +without any error, consumes data at the right rate, and powers every DAPM +widget — a byte-for-byte identical `/sys/kernel/debug/asoc` widget dump +against a working stream — while producing ~-48 dB of near-silence, +consistent with the samples being bit-shifted inside the container. PipeWire +prefers the widest format a device offers, so every PipeWire client (mpv, +GNOME, `pw-play`) is inaudible while `aplay` and `speaker-test`, which +default to S16_LE, work perfectly. This cost most of a day: the failure is +per-format, invisible in every log, and easy to misattribute to routing, +suspend/resume or per-stream volumes, all of which look guilty and are not. +`overlay/etc/wireplumber/wireplumber.conf.d/51-c630-alsa.conf` pins the +built-in card to S16_LE, which fixes every client. The underlying q6asm +format bug is worth a report to alsa-devel. + +Unrelated to the hardware, two pieces of routing politics are worth knowing +on a machine like this: PipeWire's RAOP discovery will happily make a +neighbour's AirPlay speaker the default sink, and a newly connected +Bluetooth device also takes over the default. If sound "does not work", +check `wpctl status` for where the default actually points before blaming +the drivers. + +The durable fix is one line of Fedora kernel config — flipping +`CONFIG_SND_SOC_WSA881X` to `=m` for aarch64, an easy case given the in-tree +device tree requires it and both newer WSA drivers are already enabled. Until +that lands, the module has to be built out of tree per kernel. One thing worth knowing if you go looking: `slim_qcom_ngd_ctrl` can probe before the ADSP is ready and log `QMI wait timeout`. Reloading the module afterwards -gets the codec detected, which is how the chip ID above was obtained — but it -does not get past the SoundWire mismatch. +gets the codec detected, which is how the chip ID above was obtained. A series +of NGD probe-ordering fixes (Bjorn Andersson, mid-2026, Cc: stable) targets +exactly this class of race and should reach Fedora with the 7.2 rebase. ## Extracting them