My project is converting two virtual kms driver bochs and cirrus to atomic mode-setting. And after about three months' coding and learning with Daniel Vetter and other community guys, I have accomplished task.
And for the stretch goals, I choose to apply the driver etnaviv on my board, but have got some problems, I need to dig the driver more specifically and try more hard to apply it on my board.
During these days working with Daniel, I have leaned a lot about atomic mode-setting, what I have done is actually refactor the two drivers to meet the new feature DRIVER_ATOMIC. I think I am still short of the DRM core and hardware stuffs, I should learn more about these things in the future.
I really have a lot a difficulties during the project, like after changed the module, the kernel doesn't call the new module, after talking with Daniel, the update-initramfs is what I need. Kernel debugging is far more difficult than other software debug(my humble opnion), and after this project, I have get the skill, though not expert.
In the future, I think I should aim at one specific hardware, like Intel or AMD, and try to help with some test, and learn more things by reading the patches and IRC talk, then maybe try to find some bugs and fix them.
This blog series helps archiving the milestones on my Google Summer of Code 2015 project.
Saturday, August 22, 2015
Sunday, June 28, 2015
GSoC: Some notes of hacking on drm drivers
In the very first, I converted the DRM_BOCHS within just one patch, it's doing too many things, makes me lost my way in kernel land. Daniel suggusted me to split up the patch into smaller steps, this really helps a lot.
Then when test each small step, I find I got stuck in the function register_framebuffer(), locked up while holding console_lock. So Daniel explained a bit the background:
For all kernel log output to the console there is one big lock to protect it all, that's the console_lock. We also need this lock to register a new console and register a legacy fbdev, we have that in drm to be able to use the fb console.
Problem is now that the first thing fbcon does is setup a mode while we still hold console_lock, which means it's going to call all the bochs modeset functions, if it crash in there or anything else happens, not a single line will go to dmesg since console_lock is locked.
The messages that the between the console_lock() and console_unlock() will not display to the console imediatelly, but shows after the lock was released.
At the end of register_framebuffer the console_lock get released, and everything that was logged with DRM_DEBUG or printk appears in one go in the logs, which means if now bug is there it looks like the printing works. But if it crash nothing past the console_lock() call will ever show up anywhere.
Solution:
We need to get rid of fbcon for debugging.
This means the screen will be dark until X comes up, and there won't be a kernel console any more.
So needs prep:
1. make sure X comes up automatically
2. make sure we can log into the vm using ssh (since no other console will work)
3. change the kernel config and set FRMEBUFFER_CONSOLE=n (make munuconfig)
There is even easier way to do this:
Turn off fbdev support in bochs, set bochs.enable_fbdev = false will work.
I tested it with a working distro kernel, set enable_fbdev = false will not print drm log messages like before, and X can finally start up.
Now, as we are clear of the background and solution, we should be able to log into the machine with ssh and look at dmesg to figure out what's wrong.
The native linux and the qemu VM are not in the same Network segment, it's ok to ssh from vm to native linux, but not work the other way around, so I have to configure the qemu network.
Qemu networking:
There are two parts to networking within QEMU:
Below is what I did configuring the network.
We need two tools to configure the network.
Then when test each small step, I find I got stuck in the function register_framebuffer(), locked up while holding console_lock. So Daniel explained a bit the background:
For all kernel log output to the console there is one big lock to protect it all, that's the console_lock. We also need this lock to register a new console and register a legacy fbdev, we have that in drm to be able to use the fb console.
Problem is now that the first thing fbcon does is setup a mode while we still hold console_lock, which means it's going to call all the bochs modeset functions, if it crash in there or anything else happens, not a single line will go to dmesg since console_lock is locked.
The messages that the between the console_lock() and console_unlock() will not display to the console imediatelly, but shows after the lock was released.
At the end of register_framebuffer the console_lock get released, and everything that was logged with DRM_DEBUG or printk appears in one go in the logs, which means if now bug is there it looks like the printing works. But if it crash nothing past the console_lock() call will ever show up anywhere.
Solution:
We need to get rid of fbcon for debugging.
This means the screen will be dark until X comes up, and there won't be a kernel console any more.
So needs prep:
1. make sure X comes up automatically
2. make sure we can log into the vm using ssh (since no other console will work)
3. change the kernel config and set FRMEBUFFER_CONSOLE=n (make munuconfig)
There is even easier way to do this:
Turn off fbdev support in bochs, set bochs.enable_fbdev = false will work.
I tested it with a working distro kernel, set enable_fbdev = false will not print drm log messages like before, and X can finally start up.
Now, as we are clear of the background and solution, we should be able to log into the machine with ssh and look at dmesg to figure out what's wrong.
The native linux and the qemu VM are not in the same Network segment, it's ok to ssh from vm to native linux, but not work the other way around, so I have to configure the qemu network.
Qemu networking:
There are two parts to networking within QEMU:
- the virtual network device that is provided to the guest(e.g. a PCI network card).
- the network backend that interacts with the emulated NIC (e.g. puts packets onto the host's network).
There are a range of options for each part. By default QEMU will create a SLiRP user network backend and an appropriate virtual network device for the guest (eg an E1000 PCI card for most x86 PC guests).
Note: if you are using the (default) SLiRP user networking, the ping(ICMP) will not work, though TCP and UDP will.
In most cases, if you don't have any specific networking requirements other than be able to access to a web page from your guest, user networking(slirp) is a good choice. However, if you are looking to run any kind of network service or have your guest participate in a network in any meaningful way, tap is usually the best choice.
Tap
The tap networking backend makes use of a tap networking device in the host. It offers very good performance and can be configured to create virtually any type of network topology. Unfortunately, it requires configuraion of that network topology in the host which tends to be different depending on the operating system you are using. Generally speaking, it also requres that you have root privileges.
-netdev tap, id=mynet0
Below is what I did configuring the network.
We need two tools to configure the network.
- #apt-get install bridge-utils
- #apt-get install uml-utilities
Then configure the bridge:
- #ifconfig eth0 down
- #brctl addbr br0
- #brctl addif br0 eth0
- #brctl stp br0 off
- #brctl setfd br0 1
- #brctl sethello br0 1
- #ifconfig br0 0.0.0.0 promisc up
- #ifconfig eth0 0.0.0.0 promisc up
- #dhclient br0
Then configure TAP device:
- #tunctl -t tap0 -u root
- #brctl addif br0 tap0
- #ifconfig tap0 0.0.0.0 promisc up
Now add some option when I start the qemu:
qemu-system-x86_64 -m 1024 -smp 2 -hda ./linux-bochs.img -no-acpi -vga std -k en -us -serial stdio -net nic -net tap,ifname=tap0,script=no,downscript=no
It works, now I can use ping and ssh to comunicate from host to guest.
Note:
Must make sure that eth0 has the IP of 0.0.0.0, if the ip of eth0 is same as br0, it will not work.
modetest, a basic kms test program
./modetest -h
./modetest -M bochs-drm
./modetest -p
./modetest -s 21@19:1024x768
Note:
Must make sure that eth0 has the IP of 0.0.0.0, if the ip of eth0 is same as br0, it will not work.
modetest, a basic kms test program
./modetest -h
./modetest -M bochs-drm
./modetest -p
./modetest -s 21@19:1024x768
Wednesday, June 10, 2015
GSoc: Configure a serial console for the Qemu Virtual Machine
As I am stuck in the dark when I boot up, so I asked for help on the mailing list. And got some help from Gerd Hoffmann, here is what he said:
Following is what I did configuring the serial console:
With fbdev enabled a lot initialization happens with some important console lock taken, which has the effect that you don't see any kernel messages until it succeeded.He suggested me to configure a serial console for the virtual machine.
Following is what I did configuring the serial console:
- In the virtual machine, add a parament to the grub menuentry something like "console=ttyS0,9600n8"
- Add a parameter when start the qemu virtual machine, the command now looks like:
- qemu-system-x86_64 -m 1024 -smp 2 -hda ./linux-bochs.img -no-acpi -vga std -k en-us -serial pty
- and get the redirected device: "char device redirected to /dev/pts/2"
- Now I can see the kernel messages from the the virtual machine using the following command:
- cat /dev/pts/2
This is trivial, post it here if anyone came across the same problem.
2015/06/11
After email with Gred, here is what he suggested:
2015/06/11
After email with Gred, here is what he suggested:
- use 115200 as line speed to speedup the console a bit
- -serial stdio might be more convenient, so that we don't need the "cat /dev/pts/2" step, the messages from the virtual machine serial console will display to the qemu terminal of the host machine.
- on modern linux distros (anything systemd-based) you should automatically get a login prompt on the serial line in case it is configured as console. Try adding "ignore_loglevel" and "drm.debug=0x07" to the kernel command line.
- we can blacklist the module in modprobe.conf (or /etc/modprobe.d) to prevent it from autoloading.
Wednesday, June 3, 2015
GSoC: Update kernel on qemu virtual machine with bochs and Set up the Github repo
1.Update kernel on qemu virtual machine with bochs
The origin kernel version is 3.2.0, and I am working on airlied's repo:
git://anongit.freedesktop.org/drm-intel
I don't change kernel very often, usually when a new Linux distribution(e.g. Ubuntu 15.04) is out, I will download that and set up a new Virtual Machine, not smart and nothing to do with kernel update. After days of google and trying, finally I set up the new kernel, which is 4.0.0-rc4+.
Following is what I do setting up the new kernel:
I compile the linux source code on the host machine(even though it is a VMware VM, compile on it is far more quicker than compile on the qemu VM, which is running on the host VMware VM).
Working dir is ~/work
- use the kernel config of host VM(same as the qemu VM)
#cp /boot/config-3.2.0-4-amd64 ~/work/linux/.config
- select 'M' for Bochs and Cirrus driver
#make menuconfig
- compile and install (This takes the longest time)
#make bzImage
#make modules
#make modules_install
#make modules_install
#make install
After these operations, we got the following files(or directory) install in the host VM:
/lib/modules/4.0.0-rc4+/
/boot/initrd.img-4.0.0-rc4+
/boot/System.map-4.0.0-rc4+
/boot/vmlinuz-4.0.0-rc4+
These are what we need to set up the new kernel for the qemu VM, we compress them in a single file and scp it from the host to qemu VM, decompress it and put them in the right places(same as the host).
We still need some other operations:
#cd /lib/modules/4.0.0-rc4+/
#depmod -a -v 4.0.0-rc4+
and update the grup menuentry:
#update-grub
Ok, now reboot, choose the newly installed kernel entry, it works!
And check the kernel version:
#uname -r
I got 4.0.0-rc4+
check the modules running on the qemu virtual machine:
#lsmod
got the following modules related to bochs:
bochs_drm
ttm
drm_kms_helper
drm
i2c_core
syscopyarea
sysfillrect
sysimgblt
And then I checked if there was any error in dmesg, got the following warning:
[ 302.072360] ------------[ cut here ]------------ [ 302.076145] WARNING: CPU: 0 PID: 2907 at drivers/gpu/drm/ttm/ttm_bo_vm.c:265 ttm_bo_vm_open+0x34/0x3b [ttm]() [ 302.076465] Modules linked in: rfcomm bnep bluetooth rfkill uinput nfsd auth_rpcgss oid_registry nfs_acl nfs lockd grace fscache sunrpc loop bochs_drm ttm drm_kms_helper drm kvm_amd kvm psmouse i2c_core evdev syscopyarea sysfillrect pcspkr serio_raw sysimgblt ext4 crc16 jbd2 mbcache sg sr_mod cdrom sd_mod ata_generic ata_piix e1000 libata scsi_mod [ 302.077427] CPU: 0 PID: 2907 Comm: Xorg Not tainted 4.0.0-rc4+ #1 [ 302.077458] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2007 [ 302.077647] 0000000000000000 0000000000000009 ffffffff813b526d 0000000000000000 [ 302.077698] ffffffff8103e8c3 00000000810f6832 ffffffffa021df5a ffff880027100400 [ 302.077724] ffff88001ae5c800 ffff880027100400 ffff88002f87c3b0 ffff88002f8b50c0 [ 302.077778] Call Trace: [ 302.078839] [<ffffffff813b526d>] ? dump_stack+0x40/0x50 [ 302.078946] [<ffffffff8103e8c3>] ? warn_slowpath_common+0x98/0xb0 [ 302.079076] [<ffffffffa021df5a>] ? ttm_bo_vm_open+0x34/0x3b [ttm] [ 302.079117] [<ffffffffa021df5a>] ? ttm_bo_vm_open+0x34/0x3b [ttm] [ 302.079146] [<ffffffff8103d242>] ? copy_process.part.32+0xbe0/0x1689 [ 302.079175] [<ffffffff8111caae>] ? get_empty_filp+0xef/0x174 [ 302.079201] [<ffffffff8103de35>] ? do_fork+0xb4/0x25e [ 302.079230] [<ffffffff813b960d>] ? stub_clone+0x6d/0x90 [ 302.079255] [<ffffffff813b9332>] ? system_call_fastpath+0x12/0x17 [ 302.079435] ---[ end trace d4b7cc30b85ed796 ]---
I am not sure if this warining is fatal, post it here just for later compare with the bochs driver after converting to atomic mode-setting.
2.Set up the Github repo
Firstly create a new empty repository on github, then you got the repo's url:
https://github.com/zhjwpku/gsoc.git
Since currently my origin is airlied's, I changed it by:
#git remote rename origin airlied
Then I add some remotes:
#git remote add origin https://github.com/zhjwpku/gsoc.git
#git push
#git remote add drm-intel git://anongit.freedesktop.org/drm-intel
Finish setting up the github repo.
Monday, May 11, 2015
GSoC: Qemu setup with bochs/cirrus + linux guest
I am now trying to setup qemu with bochs/cirrus.
As I didn't use qemu that much, I searched the internet to set up the qemu, there might be some mistakes, if I am wrong, please tell me.
I intended to use the machine of the laboratory, but unfortunately someone else was using it doing some test, and made it unable to run qemu-system-x86_64, there are too many depends problems. Then I came back to my PC with Windows 7 running on it, and I set up a VirtualMachine on the VMware workstation using the debian 7 iso.
After that, I installed qemu, and run the following command to create another two VMs on the former VM, this is slow and sometimes lost the mouse, but it works.
1. create a virtual disk
# qemu-img create linux-bochs.img 40G
2. install from iso
# qemu-system-x86_64 -m 1024 -smp 2 -boot d -hda ./linux-bochs.img -no-acpi -vga std -k en-us -cdrom ./debian-live-7.8.0-amd64-xfce-desktop.iso
3. boot from linux-bochs.img
# qemu-system-x86_64 -m 1024 -smp 2 -hda ./linux-bochs.img -no-acpi -vga std -k en-us
Same for the other VM, just post it here:
1. create a virtual disk
# qemu-img create linux-cirrus.img 40G
2. install from iso
# qemu-system-x86_64 -m 1024 -smp 2 -boot d -hda ./linux-cirrus.img -no-acpi -vga cirrus -k en-us -cdrom ./debian-live-7.8.0-amd64-xfce-desktop.iso
3. boot from linux-bochs.img
# qemu-system-x86_64 -m 1024 -smp 2 -hda ./linux-cirrus.img -no-acpi -vga cirrus -k en-us
Now, both work :)
Problems:
But then I got a problem, when I check the dmesg, I try to search some information related to bochs or cirrus, for the bochs virtual machine, I got the following information:
I thought maybe the DMI line means something.
But when it comes to cirrus virtual machine, got the following:
Still Bochs, that's odd, where is the cirrus? Why no information related to cirrus.
note: After talking to Daniel on IRC, I got to know that DMI is the overall machine, that means it will always be Bochs for qemu.
DMI is often used for blacklists and quirks since it's machine-dependent.
After that I run lspci, for bochs got:
For cirrus I got:
The information above makes me happy :)
As I didn't use qemu that much, I searched the internet to set up the qemu, there might be some mistakes, if I am wrong, please tell me.
I intended to use the machine of the laboratory, but unfortunately someone else was using it doing some test, and made it unable to run qemu-system-x86_64, there are too many depends problems. Then I came back to my PC with Windows 7 running on it, and I set up a VirtualMachine on the VMware workstation using the debian 7 iso.
After that, I installed qemu, and run the following command to create another two VMs on the former VM, this is slow and sometimes lost the mouse, but it works.
1. create a virtual disk
# qemu-img create linux-bochs.img 40G
2. install from iso
# qemu-system-x86_64 -m 1024 -smp 2 -boot d -hda ./linux-bochs.img -no-acpi -vga std -k en-us -cdrom ./debian-live-7.8.0-amd64-xfce-desktop.iso
3. boot from linux-bochs.img
# qemu-system-x86_64 -m 1024 -smp 2 -hda ./linux-bochs.img -no-acpi -vga std -k en-us
Same for the other VM, just post it here:
1. create a virtual disk
# qemu-img create linux-cirrus.img 40G
2. install from iso
# qemu-system-x86_64 -m 1024 -smp 2 -boot d -hda ./linux-cirrus.img -no-acpi -vga cirrus -k en-us -cdrom ./debian-live-7.8.0-amd64-xfce-desktop.iso
3. boot from linux-bochs.img
# qemu-system-x86_64 -m 1024 -smp 2 -hda ./linux-cirrus.img -no-acpi -vga cirrus -k en-us
Now, both work :)
Problems:
But then I got a problem, when I check the dmesg, I try to search some information related to bochs or cirrus, for the bochs virtual machine, I got the following information:
[ 0.000000] Initializing cgroup subsys cpuset [ 0.000000] Initializing cgroup subsys cpu [ 0.000000] Linux version 3.2.0-4-amd64 (debian-kernel@lists.debian.org) (gcc version 4.6.3 (Debian 4.6.3-14) ) #1 SMP Debian 3.2.65-1 [ 0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-3.2.0-4-amd64 root=UUID=0e31ae86-cebe-4a89-b335-7b235dd671a0 ro initrd=/install/gtk/initrd.gz quiet [ 0.000000] BIOS-provided physical RAM map: [ 0.000000] BIOS-e820: 0000000000000000 - 000000000009f400 (usable) [ 0.000000] BIOS-e820: 000000000009f400 - 00000000000a0000 (reserved) [ 0.000000] BIOS-e820: 00000000000f0000 - 0000000000100000 (reserved) [ 0.000000] BIOS-e820: 0000000000100000 - 0000000040000000 (usable) [ 0.000000] BIOS-e820: 00000000fffc0000 - 0000000100000000 (reserved) [ 0.000000] NX (Execute Disable) protection: active [ 0.000000] SMBIOS 2.4 present. [ 0.000000] DMI: Bochs Bochs, BIOS Bochs 01/01/2007
I thought maybe the DMI line means something.
But when it comes to cirrus virtual machine, got the following:
[ 0.000000] Initializing cgroup subsys cpuset [ 0.000000] Initializing cgroup subsys cpu [ 0.000000] Linux version 3.2.0-4-amd64 (debian-kernel@lists.debian.org) (gcc version 4.6.3 (Debian 4.6.3-14) ) #1 SMP Debian 3.2.65-1 [ 0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-3.2.0-4-amd64 root=UUID=64a91cb7-eead-4d10-9edf-091f31a2a590 ro initrd=/install/gtk/initrd.gz quiet [ 0.000000] BIOS-provided physical RAM map: [ 0.000000] BIOS-e820: 0000000000000000 - 000000000009f400 (usable) [ 0.000000] BIOS-e820: 000000000009f400 - 00000000000a0000 (reserved) [ 0.000000] BIOS-e820: 00000000000f0000 - 0000000000100000 (reserved) [ 0.000000] BIOS-e820: 0000000000100000 - 0000000040000000 (usable) [ 0.000000] BIOS-e820: 00000000fffc0000 - 0000000100000000 (reserved) [ 0.000000] NX (Execute Disable) protection: active [ 0.000000] SMBIOS 2.4 present. [ 0.000000] DMI: Bochs Bochs, BIOS Bochs 01/01/2007
Still Bochs, that's odd, where is the cirrus? Why no information related to cirrus.
note: After talking to Daniel on IRC, I got to know that DMI is the overall machine, that means it will always be Bochs for qemu.
DMI is often used for blacklists and quirks since it's machine-dependent.
After that I run lspci, for bochs got:
00:00.0 Host bridge: Intel Corporation 440FX - 82441FX PMC [Natoma] (rev 02) 00:01.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II] 00:01.1 IDE interface: Intel Corporation 82371SB PIIX3 IDE [Natoma/Triton II] 00:02.0 VGA compatible controller: Device 1234:1111 00:03.0 Ethernet controller: Intel Corporation 82540EM Gigabit Ethernet Controller (rev 03)
For cirrus I got:
00:00.0 Host bridge: Intel Corporation 440FX - 82441FX PMC [Natoma] (rev 02) 00:01.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II] 00:01.1 IDE interface: Intel Corporation 82371SB PIIX3 IDE [Natoma/Triton II] 00:02.0 VGA compatible controller: Cirrus Logic GD 5446 00:03.0 Ethernet controller: Intel Corporation 82540EM Gigabit Ethernet Controller (rev 03)
The information above makes me happy :)
Monday, April 27, 2015
GSoC: Convert the BOCHS and CIRRUS drivers to atomic mode-setting
This is my first blog on the project Google Summer of Code. I just post my proposal below:
Organization: X.Org Foundation
Mentor: Daniel Vetter
Mentor: Daniel Vetter
Abstract: Atomic mode-setting has been discussed and designed for literally years, now it's finally there, it is not only necessary but allows a bunch of nice and long overdue cleanup and unification. There are a lot ongoing atomic mode-setting conversions and some already committed to drm-next ones, while there still are some subsystems haven't started the work, as far as I know, radeon, udl, bochs and cirrus are some optional drivers. I will take DRM_BOCHS and DRM_CIRRUS_QEMU as my converting goals.
Introduction to the Project
This project aims to convert two existing KMS drivers to atomic mode-setting, DRM_BOCHS and DRM_CIRRUS_QEMU.
BOCHS stands for standard VGA card with Bochs VBE extensions, we can emulate it in qemu by adding the option '-vga std'. While CIRRUS is the default Video card that QEMU emulated.
For these two drivers used by KVM/QEMU, they are still in the Renaissace era of KMS, something not perfect:
- mode sets fail too late, if the mode-setting fails, there's no way to rollback
- KMS does not guarantee that a configuration is applied in totality for the next frame
- no VBLANK-synchronized page-flips for planes
- not perfect frames
As we all know the weaknesses in the legacy KMS drivers now, we should overcome them by convert the drivers into Atomic Mode-Setting. The Atomic Mode-Setting
- allows an output configuration to be validated before it is applied:
- no hardware is touched before the driver acknowleges that the configuration is valid and can be applied
- no need for rollback
- allows atomic updates of an output configuration:
- multiple planes updated at the same time
- we got perfect frames show at the same time
- allows for unification and simplification of drivers
- legacy code can be removed from drivers
- much of the handling moves into helpers (core DRM)
Project Goals
The project shall complete two legacy KMS drivers conversion individually:
- convert DRM_BOCHS driver into Atomic Mode-Setting driver
- convert DRM_CIRRUS_QEMU driver into Atomic Mode-Setting driver
Since Daniel did most of the Transtional and atomic helpers work, so the conversion is surprisingly painless.
Quantifiable Results for the DRI Community
- Make it a more complete ecosystem for the atomic mode-setting
- Use unified helpers will make it more concise for the subsystem, less code
Project Details
Since radeon support about 18 years of asics and 8 generations of display hardwares, the conversion will be a huge amout of work and there is a huge potential regressions, so I choose two drivers used by kvm/qeum, which are a lot simpler than mordern GPUs.
The following specified what needs to be done to support atomic modeset updates using Daniel's new helper libraries.
Phase 1 - Reworking the Driver Backend Functions for Planes
There are two big mismatches between the new atomic semantics and the legacy ioctl interfaces:
1) The primary plane is no longer tied to CRTC.
2) Atomic updates of multiple planes isn't supported at all.
Both issuse are addressed by adding new driver backend callbacks. So we should implement legacy entry points in term of new atomic callbacks.
The first step is to rework the ->disable/update_plane hooks using the transitional helper implementations drm_plane_helper_update/disable. The following new driver callbacks are needed:
- CRTCs
- ->atomic_check() - validate state
- ->atomic_begin() - prepare for updates
- ->atomic_flush() - apply updates atomically
- ->atomic_set_nofb - apply CRTC timings, this callback must be implement
- planes
- ->prepare_fb() - setup the framebuffers, e.g. pin backing storage into memory and setup any needed hardware resources
- ->cleanup_fb() - e.g. unpi backing storage
- ->atomic_check() - validate state
- ->atomic_update() - per-plane update, like setting up the new viewport or the new base address of the framebuffer for each plane
- ->atomic_disable() - disable plane
The provided helpers functions drm_helper_crtc_mode_set and drm_helper_crtc_mode_set_base then implement the callbacks required by the CRTC helpers in terms of new ->mode_set_nofb callback and the the above newly implmented plane helper callbacks.
Phase 2 - Wire up the Atomic State Object Scaffolding
The goal of this phase is to get all the state object handing needed for atomic updates into place.
- wire up state callbacks for planes, CRTCs and connectors:
- ->reset()
- drm_atomic_helper_*_reset()
- ->atomic_duplicate_state()
- drm_atomic_helper_*_duplicate_state()
- ->atomic_destroy_state()
- drm_atomic_helper_*_destroy_state()
- patching up the state objects in legacy code paths
- make sure that we can partially transition to atomic updates.
- drm_atomic_set_fb_for_plane
- usually the only place this is need to be manually added is the ->page_flip callback.
- all ->mode_fixup callbacks need to be audited
- not depend upon any state which is only set in the various CRTC helpers.
- not tracked by the atomic state objects.
Phase 3 - Rolling out Atomic Support
Replace all the legacy entry pointers with the corresponding functions from the atomic helper library to implement them in terms of atomic.
- switch to atomic helpers internally (after this Drivers uses only atomic interfaces internally):
- Planes:
- drm_atomic_helper_update_plane()
- drm_atomic_helper_disable_plane()
- Drivers
- drm_atomic_helper_check()
- drm_atomic_helper_commit()
- Planes:
- switch to atomic helpers for userspace IOCTLs (after this Drivers is fully atomic):
- drm_atomic_helper_set_config(): DRM_MODE_IOCTL_SET_CRTC
- provide a customer ->atomic_commit() implementation to support asynchronous commits, required for page-flipping
- drm_atomic_helper_page_flip(): DRM_MODE_IOCTL_PAGE_FLIP
Rip out Cruft
There is quite a bit of cleanup work possible afterwards.
- ->mode_set() and ->mode_set_base() are no longer used, ->mode_set_nofb() does what is necessary to set a mode.
- atomic DPMS, DPMS standby and suspend are no more, ->disable() and ->enable() callbacks are used now, atomic DPMS is a full off or on cycle
References
Approximative Schedule
(now - 15 April)
- get familiar with the Atomic Modeset Support for KMS Drivers
- take a look at the ongoing atomic mode-setting conversations and those already committed to drm-next
- discuss with the mentor about some confusing details on the code
(16 April - 27 April )
- get to know more about the DRM_BOCHS and DRM_CIRRUS_QEMU subsystem driver code
- setup the kvm/qemu environment for further test
(28 April - 18 May)
- code: write my first version of the atomic mode-setting conversion for DRM_BOCHS driver
- discuss with the mentor about the conversion if the patches meet the demand
(19 May - 15 June)
- code: write my second version of the atomic mode-setting conversion for DRM_BOCHS driver
- test: test the new converted Bochs driver on qemu, using the '-vga std' option
(16 June - 25 June)
- submit patches to the dri-devel@lists.freedesktop.org, if anything wrong, modify it
- get to know more about the DRM_CIRRUS_QEMU subsystem
(26 June - 30 June)
- arrange documentations for mid-term evaluations
(1 July - 3 July)
- submit mid-term evaluations
(4 July - 17 August)
- code: write the atomic mode-setting conversion for DRM_CIRRUS_QEMU (same schedule with DRM_BOCHS)
- do more test to assure the correctness and check the code.
(18 August - 21 August)
- arrange documets for reports, scub code, write tests, improve documentation, etc.
(22 August - 27 August)
- submit final evaluations.
(28 August - 30 August)
- submit required code samples to Google.
(after GSoC)
- as Alex Deucher suggest, in additon to the two virtual drivers I am going to convert, udl (KMS driver for the USB displaylink video adapters) is another choice for me, as I am still not that skilled in Atomic Modeset Support for KMS Drivers, I will give it a shot after GSoC.
- as for the Radeon, since Alex said the community have no immediate plans to convert it to atomic, I hope when it is on the agenda in the future, I can do something helpful.
Stretch Goals
If time permits,
- I will convert these two drivers to explicitly set up the primary plane, or at least have the appropriate list of supported pixel formats.
- I will also try to convert the DRM_UDL(KMS driver for the USB displaylink video adapter) to atomic mode-setting which I mentioned before.
About me
I am studying for my Master Degree in Peking University, where I am majoring in Computer Architecture. In the last semester, my lab mentor arrange me to look into the DRM ecosystem, so I can write a Geode LX drm driver later on. I am not sure whether this is significant, but this GSoC project will definitely helps me a lot on understanding the whole ecosystem. Some of my contributions can be found here:
Thank you for reading. Have a nice day.
Subscribe to:
Posts (Atom)