Rebuilding the initramfs on the machine rather than in the build container
pulled qcom_q6v5_pas into it. There it probes while the initramfs is still the
root filesystem, asks for qcadsp850.mbn, gets -2, and never retries — the same
race 10-c630.conf already documents for the Adreno firmware. The ADSP hosts
the whole audio path, so the machine comes up with no sound card and a sound
device deferring on "error getting cpu dai name", which points nowhere near
firmware. The blobs cannot go in the initramfs to fix it: they are ~20 MiB and
are extracted from Windows, so they need not exist at build time. Omitting the
driver instead means it loads once the real root is there. The modem driver
goes with it, since it is not needed early either.
Separately, the WCD9340 decides what is plugged in by measuring impedance, so
an amplifier on the headphone socket reads as an open circuit and the jack
control never leaves 'off'. PipeWire marks the port not available, will not
keep it as the default sink, and GNOME hides it — an output that works when
driven directly becomes unreachable from the desktop. Dropping JackControl
from the Headphones device leaves availability unknown rather than no, and the
port becomes permanently selectable.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011XgGF5wfxLDAybVnNz6eNQ
A dnf upgrade to 7.1.8 installed the kernel rpm cleanly, then ran /boot out
of space. dracut wrote no initramfs, and because kernel-install stops at the
first failing plugin, 95-c630-devicetree never ran either — leaving a boot
entry with neither an initrd nor a devicetree line, which on this machine can
never boot. dnf reported success and nothing retried.
A kernel costs ~336 MiB here: a 210 MiB hostonly=no initramfs, a 98 MiB
dtb-<kver> directory carrying every board's device tree, plus vmlinuz and
System.map. Three of those cannot fit 1 GiB, so /boot goes to 2 GiB and
installonly_limit drops to 2.
Also fixes the quieter half of the same trap. snd-soc-wsa881x lives outside
the kernel package, so the speakers go silent after any kernel update with
nothing in the logs to explain it. c630-wsa881x rebuilds it and
96-c630-wsa881x.install calls it on each kernel-install add — always exiting
0, since a plugin failure is precisely what caused the damage above.
grub.cfg gains the next_entry one-shot block that has been carried by hand all
along, so testing a kernel costs a power cycle rather than a rescue.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011XgGF5wfxLDAybVnNz6eNQ
postmarketOS ships a kernel for this laptop, which makes testing an old kernel
cheap: their apk carries vmlinuz, the C630 dtb and modules, no image writing
needed. 6.9.0-sdm845 crashes exactly like 6.12 and 7.1 — 23 QLINK crashes in
70 seconds, wlfw never appears. Three kernels across two years, one of them
from a distro that lists this machine as supported, all identical.
That, plus aarch64-laptops publishing a device tree with wifi disabled and no
modem node at all, leaves the regression premise with nothing supporting it.
Record the method, the modem-test harness that captures verdicts without
networking, and the /lib symlink trap that makes installing foreign modules
dangerous.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011XgGF5wfxLDAybVnNz6eNQ
The RPMh CXO buffers that clock the transceivers were the best remaining
host-side theory — rf_clk1 and rf_clk3 have no consumer in the C630 tree and
zero enable votes from Linux, and a transceiver with no reference clock fails
exactly the way this one does. Voting all six on changes nothing. Unclaimed
regulators are out too, and the DSDT has no WWAN enable line to assert.
Also worth recording: aarch64-laptops' published device tree, the basis for
believing onboard WiFi once worked here, marks wifi@18800000 disabled and has
no modem node at all. Their WiFi instructions are headed UNSTABLE. The
regression premise may be wrong, and bracketing cannot test it anyway — neither
a hand-built 5.10 nor Fedora's own 6.1.18 reaches userspace on this machine.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011XgGF5wfxLDAybVnNz6eNQ
Fedora runs rmtfs with -r, which starts the modem remoteproc at boot. Since
the modem never gets past RF init, every C630 sits in a fatal crash and
recovery cycle every ~3.4 seconds from boot onwards — and is already a dozen
crashes deep by the time anyone logs in, which quietly confuses any manual
experiment. Drop the -r so the modem stays offline until asked for.
Also record today's eliminations, each of which closes an avenue: both
published _nm firmware builds are rejected by the boot ROM, not just the
newest; the PEP tables in this machine's own ACPI show Windows gives the
modem seven clocks, one 752 mV rail vote, cx/mx and IPA bandwidth, and
nothing whatsoever for RF — so the host does not power the RF front end on
either OS, and the one clock mainline lacks changes nothing when forced on;
and kernel bracketing is stuck, because 5.10 will not boot here at all.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011XgGF5wfxLDAybVnNz6eNQ
Audio: Fedora has never built CONFIG_SND_SOC_WSA881X, the speaker-amp
driver the in-tree DTS requires; with it built out of tree the card
registers and plays. The din-ports message is a harmless warning. Also
record the S24_LE format defect and the sink-stealing traps (AirPlay,
Bluetooth, phantom headphone jack) that masqueraded as broken audio.
WiFi: every published modem firmware build (five distinct across nine
WOA versions) and kernel 6.12 all fail identically at QLINK, the link to
the SDR845 RF transceiver. This unit is an LTE SKU with working modem
history under Windows, fsg/fsc are blank, and the modem asks rmtfs for
unknown fsg_oem partitions. Fedora's tqftpserv also serves different
paths than the old aarch64-laptops one — the earlier instructions here
were wrong for it.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011XgGF5wfxLDAybVnNz6eNQ
The repo named WOA-Project as a source and called its cabinets "the easiest
route", while aarch64-laptops appeared only as a place where files "have
circulated before" — despite it having actual .mbn files checked into its tree
and being where the WiFi trio used in today's testing came from. That ranking
was mine, not something the evidence supports.
Both are now documented with what each actually contains. They overlap and
neither is a superset:
WOA-Project is the only source of the two for qcdxkmsuc850.mbn, qcadsp850.mbn,
qccdsp850.mbn, qcslpi850.mbn, qcvss850.mbn and ipa_fws.elf, and publishes nine
versions whose cabinets differ. aarch64-laptops carries the modem/WLAN trio,
the bdwlan board data, a prebuilt board-2.bin and the script that makes it,
a630_gmu.bin, the machine's ACPI tables and a device tree — none of which
WOA-Project has, and it has none of the six above. Its wifi/firmware-5.bin is
an HTML error page rather than firmware, which is worth knowing before copying
it somewhere.
Also restate the modem result without implying a verdict on either source. Both
sets produce the identical QLINK failure here; that shows changing firmware does
not change the outcome, not that either set is wrong, and not that one is more
trustworthy than the other.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XWRjNJMistCy6ngXH5aJLS
aarch64-laptops' support table ticks WiFi for this machine, so the path exists.
Following their WiFi README got considerably further and then stopped somewhere
useful to have documented.
Two of the four services they list are in the kernel now (pd-mapper, qrtr-ns).
The other two, rmtfs and tqftpserv, are packaged in Fedora and shipped
disabled — tqftpserv was not even installed. Both are now in base.pkgs and
enabled by stage2. Enabling them took qrtr-lookup from 19 registered services
to 25; a working setup is said to show around 40.
The step worth having written down: the modem does not read wlanmdsp.mbn from
/lib/firmware. It asks tqftpserv for it over TFTP, from
/lib/firmware/readonly/firmware/image/. Nothing reports this as an error —
ath10k_snoc binds, registers a QMI client, and waits forever for a service that
never registers. c630-firmware now places the file there, and creates the
writable area the modem asks tqftpserv for.
Where it stops: the modem boots and dies at "RF stuck in QLINK start state",
about every 42 seconds, never reaching the point of requesting wlanmdsp. Three
firmware pairings give three distinct failures, recorded in the doc — the _nm
"no modem" variants, which are the obvious idea and would skip cellular RF
entirely, turn out not to be signed for this device.
The result that narrows it: aarch64-laptops' own wifi directory carries the
qcdsp1v2850.mbn, qcdsp2850.mbn and wlanmdsp.mbn from the setup whose table ticks
WiFi. All three differ from the WOA-Project copies. Installed here with the
services running and wlanmdsp in the TFTP path, they produce the identical QLINK
failure — so it is neither the firmware nor the userspace. What is left is the
kernel: 5.x from 2019 there against 7.1.5 here, with both of their ath10k
patches long since upstream. That points at a regression, and confirming it
means a bisect rather than another file.
Also record what is untried: the other eight driver versions (this machine's
UEFI is from 2019 and the newest package may be the wrong vintage),
mcfg_subsys_ext850.cab, and building board-2.bin from the C630's own bdwlan.*
files.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XWRjNJMistCy6ngXH5aJLS
The repository name says 'Reference-Drivers'; that is its name, not a
characterisation of what is inside it, and using it as a descriptor implied
the thing I had already removed from the rest of the file.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XWRjNJMistCy6ngXH5aJLS
Two problems, one of them mine twice over.
The motd is gone entirely. It had been wrong in a way that mattered — telling
anyone who logged in that onboard WiFi worked when it does not — and a login
banner is a bad place to keep claims that need revising every time we learn
something.
The worse issue is what it and the docs said about why the modem fails. I
inferred from the WOA-Project repository being named "Qualcomm-Reference-
Drivers" that its modem image was a generic reference build unsuited to this
machine's radio, and wrote that up as the explanation. That was a guess resting
on a repository name, and the naming is about redistribution rather than the
contents. Removed from both README and docs/firmware.md.
What is actually established stays: the modem boots, loads mpss, and dies at
"RF stuck in QLINK start state", roughly every 42 seconds. The cause is not
known. The machine has a SIM slot and its modem worked under Windows, so the
radio hardware is present — and the same cabinets supply the GPU, DSP and venus
firmware, all of which work, so whatever is wrong is specific to the modem.
The docs now say that and stop there.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XWRjNJMistCy6ngXH5aJLS
The motd was the worst of it — it told anyone logging in that "WiFi and
Bluetooth work with the firmware Fedora ships", which is precisely backwards for
the onboard adapter, and pointed at a Windows partition this machine no longer
has.
What the blobs did fix, verified: the GPU initialises, ADSP/CDSP/SLPI all run,
sensors appear as IIO devices, venus registers /dev/video0-3.
What they did not, and why, so nobody repeats the search:
Onboard WiFi is loaded by the modem — wlan*mdsp* is the WLAN Modem DSP — so
ath10k_snoc binds and then waits silently on a QMI service that never arrives.
The modem boots and dies at "RF stuck in QLINK start state", the RF front-end,
which is board-specific wiring in a way the SoC-level blobs are not. These are
Qualcomm *reference* drivers; good enough for the GPU and DSPs, evidently not
for this machine's radio. Three plausible fixes that do not work are recorded
too: rmtfs (correct to enable, does not help), the _nm firmware variants
(rejected at PBL), and unplugging the USB dongle (different bus entirely — it
was never competing).
Audio gets further than expected. The codec answers over SLIMbus with its chip
id, so hardware and ADSP are fine; what fails is the codec's SoundWire block
declaring two data-in ports where the controller expects six. That is a kernel
mismatch and needs a kernel change.
Also record the mesa caveat properly: the GPU works, but freedreno's EGL path
segfaults gnome-shell into a login loop, and LIBGL_ALWAYS_SOFTWARE does nothing
because mutter uses EGL. MESA_LOADER_DRIVER_OVERRIDE=kms_swrast is what works.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XWRjNJMistCy6ngXH5aJLS
The blobs turned out to be a public download rather than something to recover
from a lost backup. WOA-Project/Qualcomm-Reference-Drivers collects the
Windows-on-ARM driver cabinets by SoC, and three of them cover this machine
completely: qcdx850.cab has the zap shader and venus, qcipa850.cab has
ipa_fws.elf, and qcsubsys850.cab has the four DSP images plus WLANMDSP.MBN —
the WiFi firmware, which is not in the device tree's firmware-name list at all
and so was never on our list of things to look for.
Correct three claims elsewhere in the file that this disproves. `file` reports
these as ELF QUALCOMM DSP6 images, not as `data` — worth stating precisely,
since it is the quickest way to tell a real blob from a download that returned
an HTML error page. The sizes span 14KB to 60MB rather than "a few hundred KB
to a few MB". And the heading claiming they must come off the Windows partition
is no longer true of the easiest route.
Also narrow what c630-firmware puts in the initramfs. It globbed every .mbn in
the firmware directory, which would have pulled in the 60MB qcdsp2850.mbn and
inflated the initramfs roughly twentyfold. Only the GPU needs to be there —
msm_dpu probes at six seconds, while the initramfs is still root; the ADSP,
CDSP, SLPI, venus and modem all probe around forty seconds in and load from the
real root perfectly happily.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XWRjNJMistCy6ngXH5aJLS
The Windows backups never turned up, which looked terminal. It is not, because
these blobs are signed per model rather than per machine — a copy from any
other Yoga C630 works.
The evidence is in linux-firmware itself, which already ships the exact
analogous set for the ThinkPad X13s under qcom/sc8280xp/LENOVO/21BX: the zap
shader, ADSP, CDSP, SLPI and venus firmware, one copy serving every unit of
that model. So redistribution is a licensing question rather than a technical
one, and qcom/sdm850/LENOVO/81JL/ has simply never been contributed. It will
not arrive in a linux-firmware update.
Record two routes: Lenovo's Digital Download Recovery Service, which builds a
Windows recovery image against a machine's serial for its owner and carries the
whole DriverStore; and other C630 owners, where these have circulated before.
Reconcile two earlier claims that this contradicts — that nobody can
redistribute them, and that a backup or surviving Windows partition were the
only routes. Both were wrong in the same way: they described this machine's
situation as though it were a property of the files.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XWRjNJMistCy6ngXH5aJLS
Tested on the machine. With the generic Adreno firmware reachable from the
initramfs and the model-signed blob absent, the GPU gets two files in and stops:
loaded qcom/a630_sqe.fw from new location
loaded qcom/a630_gmu.bin from new location
*ERROR* Unable to load qcom/sdm850/LENOVO/81JL/qcdxkmsuc850.mbn
*ERROR* gpu hw init failed: -2
That settles a question the docs had been hedging: the zap shader is a hard
requirement, not an optimisation, and the generic pieces are necessary but not
sufficient. Getting past sqe and gmu only to die at zap is about as clean a
demonstration as the hardware will give.
Two things fall out of the same trace and are worth writing down, because
nothing upstream documents them for this machine. The driver never falls back
to the installed sdm845/a630_zap.mbn — the device tree pins the model-specific
path — and a fallback would not help anyway, since the shader is signed against
this device's own secure-boot chain. And the display survives the failure
entirely: msm_dpu still binds the panel, so a dead GPU costs acceleration
rather than a picture, and a desktop runs on llvmpipe.
Also record why these files have to travel in the initramfs at all: msm_dpu
probes around six seconds in, while the initramfs is still root, and never
retries.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XWRjNJMistCy6ngXH5aJLS
I had this wrong. The claim that accelerated graphics works on the firmware
Fedora ships does not survive contact with the device tree.
Fedora does package an sdm845/a630_zap.mbn, which is what led me astray, but
that is the generic Snapdragon 845 zap shader. The C630's node in
sdm850-lenovo-yoga-c630.dts names qcom/sdm850/LENOVO/81JL/qcdxkmsuc850.mbn
specifically — model-signed, present only in the machine's Windows partition.
Until it is supplied the display is unaccelerated.
Also add qcslpi850.mbn and qcvss850.mbn, which were missing entirely, and
attribute the sensor hub to slpi_pas rather than cdsp_pas. The list is now
every firmware-name property in the mainline device tree rather than a
recollection of forum posts, so it should be complete: eight files, not five.
WiFi and Bluetooth are unaffected — ath10k WCN3990 including wlanmdsp.mbn is
genuinely redistributable and genuinely shipped.
Add a section on locating the blobs on an old backup, for the case where
Windows is long gone from the machine.
Only comments changed in config/packages/base.pkgs, so the package set hashes
identically and the staged base stays valid.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XWRjNJMistCy6ngXH5aJLS
Assembles a ready-to-write disk image via Gitea Actions. Mainline has carried
sdm850-lenovo-yoga-c630.dts since 5.5 and Fedora ships it in kernel-core, so
unlike aarch64-laptops/build there is no kernel or GRUB to compile — what is
left is producing an image that boots on firmware which hands Linux no device
tree.
The build runs in an aarch64 container under qemu-user and builds filesystems
from directory trees with mke2fs -d and mcopy rather than mounting loop
devices, so it works on runners that will not hand out /dev/loop-control.
A kernel-install hook writes the devicetree line into each BLS entry; without
it the first `dnf update kernel` would produce an unbootable system.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XWRjNJMistCy6ngXH5aJLS