DO NOT WIPE THE WINDOWS PARTITION UNTIL YOU’VE PULLED THE FIRMWARE FROM IT.

Progress so far with the Lenovo Yoga C630

Thanks to Bamse we now have both USB-C ports working on the c630.

His branch is https://github.com/andersson/kernel/commits/wip/c630-5.7

What I’ve done so far to get it working:

This version of steps is what I use, you will likely want to skip Linus' tree, and just use bamse as the base, unless you want to deal with merge conflicts.

Option 1:

git clone https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux.git
pushd linux
touch .scmversion
git remote add bamse https://github.com/andersson/kernel

Option2:

git clone https://github.com/andersson/kernel -b wip/c630-5.7 linux
pushd linux
touch .scmversion

Continue:

git remote add robclark https://github.com/freedreno/kernel-msm
git fetch --all --no-tags # I don't care about tags, and rob's tree throws some errors with the for-3.6 and for-3.7 tags
git merge bamse/wip/c630-5.7 # Only if you're using Option 1
git cherry-pick f77b935
git cherry-pick a59a400
git cherry-pick eceafb9
git cherry-pick 7e95fcb
git cherry-pick e5fdba1
git cherry-pick 89a4c04
git cherry-pick 3395035
git cherry-pick fa13722
git cherry-pick 86888de
# On kali systems, I also apply the kali wifi injection patch
wget https://gitlab.com/kalilinux/packages/linux/-/raw/kali/master/debian/patches/features/all/kali-wifi-injection.patch
patch -p1 < kali-wifi-injection.patch
make defconfig
make menuconfig

(all kinds of personal changes that I care about - you can find my config at https://dev.gentoo.org/~steev/files/lenovo-yoga-c630-5.7.0-rc5.config)

For my Kali systems - (and because I’m cross compiling):

make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc) deb-pkg

For my Gentoo systems -

make -j$(nproc) && make modules_install && make dtbs_install && make install


Bootloader/Kernel Command Line:

We need some arguments passed to boot, it doesn’t matter if you hard code them in, or if you pass them via the bootloader.

pd_ignore_unused - Keep all power domains already enabled by bootloader on, even if no driver has claimed them.

clk_ignore_unused - Keep boot clocks on, even if no driver has claimed them.

efi=novamap - SetVirtualAddressMap() is not called after ExitBootServices()

An example grub setup could look something like this:

GRUB_DEFAULT=0
#GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=2
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="efi=novamap pd_ignore_unused clk_ignore_unused"
GRUB_CMDLINE_LINUX=""

Note: if you are using the patches from Rob Clark above, you do not need pd_ignore_unused or clk_ignore_unused - only efi=novamap is required.

So you could do something like this instead

GRUB_DEFAULT=0
#GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=2
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="efi=novamap"
GRUB_CMDLINE_LINUX=""

Firmware:

In terms of firmware, things get a wee bit funky. I’m a bit lazy, so I’ll use a script that Celliwig wrote (https://github.com/celliwig/lenovo-yoga-c630) This is all done on a c630 system, since we have to pull some signed firmware from the Windows partition(s?) - This script does require python2 as of 18 May 2020, so keep that in mind if you’re using something like Ubuntu 20.04 where python3 is the default.

git clone https://github.com/celliwig/lenovo-yoga-c630
pushd lenovo-yoga-c630/yoga_fw_extract
./yoga_fw_extract.sh
popd

We’re also going to need a copy of the linux-firmware git repo (though on Gentoo, the linux-firmware package is new enough)

git clone https://kernel.googlesource.com/pub/scm/linux/kernel/git/firmware/linux-firmware.git

Now lets move some files around…

pushd /lib/firmware/qcom
sudo mkdir -p LENOVO/81JL
# Because I couldn't get things to work properly with symlinks...
sudo cp c630/* LENOVO/81JL/
sudo cp ~/linux-firmware/qcom/sdm845/*.jsn LENOVO/81JL/
# We need the zap firmware for the GPU shader, which celliwig's script doesn't seem to pull.
sudo mount $(blkid -L Windows) /mnt
find /mnt/Windows -iname qcdxkmsuc850.mbn
sudo cp $one_of_the_above_results LENOVO/81JL/
# Bluetooth firmware, if you want it.
sudo cp ~/linux-firmware/qca/* /lib/firmware/qca/
popd

Services

Now… we need some services, because the firmware are actually Hexagon binaries that run on a VM of the modem processor (If I understand it correctly, that is) As of 5.7, qrtr-ns is implemented in the kernel, however, because the other services depen on libqrtr.so from it, we still need to install it. qrtr-ns also detects whether you’re on > 5.7, and if so, it does nothing.

mkdir services
cd services
git clone https://github.com/andersson/qrtr
cd qrtr
make && sudo make install && sudo systemctl enable --now qrtr-ns.service
# To make sure things can find libqrtr.so.1, regenerate the /etc/ld.so.cache
sudo ldconfig
cd ..
sudo apt install libudev-dev #on Debian based systems
git clone https://github.com/andersson/rmtfs
cd rmtfs
make && sudo make install && sudo systemctl enable --now rmtfs.service
cd ..
git clone https://github.com/andersson/pd-mapper
cd pd-mapper
make && sudo make install && sudo systemctl enable --now pd-mapper.service
cd ..
git clone https://github.com/andersson/tqftpserv
make && sudo make install && sudo systemctl enable --now tqftpserv.service
cd ~

This isn’t the full setup, but it gets most of the steps there. I still haven’t fully looked into Grub as I’ve started off on the bionic image (and on my Kali installs, apt-mark hold grub-common grub-efi-arm64 grub-efi-arm64-bin grub2-common) so I’m not quite fully there on an installation just yet.


Update:

To get audio working, you’re going to need the ucm files as well, although there’s a bit of question about the proper place they go. People have had different results, I had to move mine into a specific directory that isn’t in the repo - if that doesn’t work, then you can try the same folder as mine, but typically you can check the dmesg output to see where it’s trying to load the files from - or like me, I just copy to both places…

git clone https://github.com/srinivas-kandagatla/alsa-ucm-conf -b wip/DB845c
cd alsa-ucm-conf/ucm2
# First copy the codecs we need
sudo cp -a codecs/w* /usr/share/alsa/ucm2/codecs/
# Now the actual profiles
sudo cp -a Lenovo-YOGA-C63 /usr/share/alsa/ucm2/
cd /usr/share/alsa/ucm2
sudo cp -a Lenovo-YOGA-C63 Lenovo-YOGA-C630-13Q50
cd Lenovo-YOGA-C630-13Q50
sudo mv LENOVO-81JL-LenovoYOGAC630_13Q50-LNVNB161216.conf LENOVO-81JL-LenovoYOGAC630_13Q50.conf
sudo ln -s LENOVO-81JL-LenovoYOGAC630_13Q50.conf /usr/share/alsa/ucm2/Lenovo-YOGA-C630-13Q50/Lenovo-YOGA-C630-13Q50.conf

Notes

X doesn’t run properly currently, you will get lots of screen flickering, however Wayland based DEs/WMs work fine. I’ve personally tested Sway and Gnome.

Update: Rob Clark was able to track the issue down in mesa.

Update for mesa 19.3.x - https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5192 Update for mesa 20.0.x - https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5190 Update for Mesa 20.1.x - https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5188

Another thing to note, the reason why I’m cherry picking from robclark instead of just merging in his wip/c630-5.7 branch, is because of commit f82139e - you absolutely can use it, however, you also need to use his dtbloader. I didn’t want to but if you want to play around, he’s got prebuilt binaries at https://people.freedesktop.org/~robclark/DtbLoader.efi and https://people.freedesktop.org/~robclark/Shell.efi - and a readme for it can be found at https://github.com/robclark/edk2/blob/dtbloader-chid/Readme.md