On Wed, Sep 30, 2026 at 03:36:36PM +0200, Neil Armstrong wrote: > On 9/29/26 09:41, Maxime Ripard wrote: > > On Mon, Sep 28, 2026 at 10:36:18PM +0200, Neil Armstrong wrote: > > > On 9/28/26 21:48, Benjamin Tissoires wrote: > > > > On Sep 28 2026, Neil Armstrong wrote: > > > > > On 9/28/26 19:24, Benjamin Tissoires wrote: > > > > > > On Sep 28 2026, Neil Armstrong wrote: > > > > > > > Hi, > > > > > > > > > > > > > > On 9/28/26 18:22, Maxime Ripard wrote: > > > > > > > > Hi, > > > > > > > > > > > > > > > > Panels in general, and MIPI-DSI panels in particular, are pretty > > > > > > > > difficult to support and require pretty much a panel driver for each > > > > > > > > panel produced. Most of them are pretty simple, and require an opaque > > > > > > > > initialization sequence that is usually poorly documented. > > > > > > > > > > > > > > > > This creates a tension between OEMs and distros because OEMs will > > > > > > > > typically get a new panel to react to a sourcing issue during > > > > > > > > production, and thus need some swift turnaround between getting their > > > > > > > > new panel and it being operational in the OS. Distributions on the other > > > > > > > > hand can take years to ship a kernel with that new panel driver. > > > > > > > > > > > > > > > > To solve this, I followed the example of HID-BPF and wrote a panel > > > > > > > > driver that will rely on BPF programs to perform the panel > > > > > > > > initialization. That way, we can ship the programs separately from the > > > > > > > > kernel, and with a different lifecycle. If this driver is accepted, the > > > > > > > > plan is to have a userspace component started by udev to identify and > > > > > > > > load the right BPF program for the panels found on the device. > > > > > > > > > > > > > > This is kind of late for serious applications except if we manage to > > > > > > > solve the bootloader to Linux display engine transition. > > > > > > > > > > > > > > > > > > > > > > > This driver is fully functional and works with both 5" and 7" Touch > > > > > > > > Display 2 panels for the RaspberryPi. However, it breaks away from the > > > > > > > > typical panel driver in multiple ways: > > > > > > > > > > > > > > > > - BPF programs can only be loaded by userspace. This leaves us with two > > > > > > > > choices: > > > > > > > > > > > > > > > > * We prevent the driver from loading until the script itself is > > > > > > > > loaded. This has the side effect of preventing any other output to > > > > > > > > be used until the initramfs is ran at the earliest, and possibly > > > > > > > > ever if the loader isn't installed for example. > > > > > > > > > > > > > > This adds a dependency on user-space behavior and if somehow the > > > > > > > initramfs doesn't load for a reason we won't have a way to display > > > > > > > an error. > > > > > > > > > > > > > > > > > > > > > > > * Or we probe the driver all the time, but only report it as connected > > > > > > > > once a program has been registered. This is somewhat unconventional, > > > > > > > > but allows the other outputs to be functional, *and* allows the user > > > > > > > > to force the output if their panel doesn't require any > > > > > > > > initialization or during debugging. I chose this solution. > > > > > > > > > > > > > > Both options are not really great... > > > > > > > > > > > > > > > > > > > > > > > - It's not a panel driver, but a bridge one, which is also pretty > > > > > > > > unconventional. This is required because panel drivers don't have > > > > > > > > access to a detect callback that is required for the above, but I also > > > > > > > > think that the recent work from Luca blurs the line from panels and > > > > > > > > bridges and we'll end up going that road anyway. > > > > > > > > > > > > > > On this point, DDIC _are_ bridges, but in the current panel API we blur the line between > > > > > > > the panel and the DDIC. So being a bridge is fine, but in a general way we lack > > > > > > > a proper way to describe the display/panel/monitor independently of the DDIC. > > > > > > > > > > > > > > At first glance it's a nice driver, but moving the timings into a blob moves something > > > > > > > into possible proprietary binaries with possible closed licence and distribution > > > > > > > restriction so it's a downgrade for the same of bringing up a panel faster. > > > > > > > > > > > > Quick answer on this, because I had the very same questions regarding > > > > > > HID-BPF: > > > > > > - in BPF, you can require (and by default it does) that only GPL > > > > > > compatible BPF programs are loaded, closing the argument of "closed > > > > > > licence and distribution restriction" > > > > > > - also, a BPF program can be disassembled much easier than a binary > > > > > > blob, and I remember Alexei showing me an example where you get almost > > > > > > the source code from the BPF object in just one pass. > > > > > > > > > > Right, it "solve" one of my question, but doesn't really solve the issue > > > > > of vendors providing "GPL" bpf programs with source available "somewhere". > > > > > > > > > > Another big issue is the API, I don't want to keep the current API as-is, > > > > > we plan to support more advanced panel features and use try to use the > > > > > atomic states to support rate switching for example, and I'm not confident > > > > > it's a good idea since there's no "simple" and "forever valid" API > > > > > to initialize panels... > > > > > > > > > > > > > That's exactly where BPF shines. The simple rule of thumb is: there is > > > > no API stability guaranteed. Basically, thanks to the verifier and CORE > > > > (Compile Once Run Everywhere), you don't need to keep the API stable and > > > > available forever. There are multiple ways of dealing with it, but the > > > > gist is that if a BPF is trying to load an "old" API, it will be > > > > rejected by the verifier. > > > > > > > > Then it's a matter of being nice enough in the kernel and provide ways > > > > to deal with those. > > > > > > > > To give you a few examples: > > > > > > > > - in HID-BPF, in userspace, we keep old versions of APIs in separate > > > > compiled objects. Each is incremented (by 10 so we have a little bit > > > > of room in the middle). Then the loader tries first > > > > 0020-device-with-new-api.bpf.o, and if it fails, it tries > > > > 0010-device-with-old-api.bpf.o > > > > > > > > I'm not saying we should do the same here, but that's one idea > > > > > > > > - recently, a BPF commit broke the ABI of a function while removing > > > > implicits: bpf_wq_set_callback_impl() was replaced by > > > > bpf_wq_set_callback() with a different number of arguments. I simply > > > > had to add a new function in my header which basically does: > > > > > > > > static inline int > > > > hid_bpf_wq_set_callback(struct bpf_wq *wq, > > > > int (*callback_fn)(void *, int *, void *), > > > > unsigned int flags) > > > > { > > > > if (bpf_ksym_exists(bpf_wq_set_callback)) > > > > return bpf_wq_set_callback(wq, callback_fn, flags); > > > > if (bpf_ksym_exists(bpf_wq_set_callback_impl)) > > > > return bpf_wq_set_callback_impl(wq, callback_fn, flags, NULL); > > > > } > > > > > > > > And then I changed the bpf.c to use hid_bpf_wq_set_callback() and the > > > > bpf is compatible with both APIs > > > > > > > > - with CORE, struct fields are relocated on the fly when you load the BPF > > > > So for instance, if my BPF only accesses fields .name, .phys and .id > > > > in the BPF, I can define: > > > > struct hid_device { > > > > char name[128]; > > > > char phys[64]; > > > > unsigned int id; > > > > } > > > > > > > > Then when loading the bpf, the verifier replaces all offset to the > > > > ones actually used by the running kernel, and the program loads > > > > transparently, even if you add fields before/after or change the > > > > fields order in the kernel. > > > > > > > > Changing the mindset is the hardest part of it. But once you are making > > > > the shift, it's actually much better to work with. It doesn't mean you > > > > can go yolo. You still need to be careful in your choices knowing the > > > > impact on your users. But the API at version 0 is not frozen and you > > > > don't need to maintain it forever, especially if you control the loader > > > > and the headers used to compile the BPFs. > > > > > > It's really impressive, but there's no way this would become the de-facto > > > way to program the panels > > > > Nobody said it would? And like I said in my previous mail, I actually > > expect us to keep merging panel drivers. Do I think it should become the > > go-to solution for simple panels? yes. But we can always make > > exceptions, and for more complex panels we should totally do a more > > complex driver. Like HID has been doing. > > > > > and if the motivation is to make it simpler this implementation > > > requires adding bindings and bpf programs which that are the same as > > > native panel drivers, but won't be able to work until user-space > > > starts and will require to be in initramfs or rootfs to have > > > functional display. > > > > > > Not sure to understand what are the positive features here except > > > isolating the panel code in a safe bpf program (is this really needed > > > ?). > > > > From the cover letter: > > > > """ > > Panels in general, and MIPI-DSI panels in particular, are pretty > > difficult to support and require pretty much a panel driver for each > > panel produced. Most of them are pretty simple, and require an opaque > > initialization sequence that is usually poorly documented. > > > > This creates a tension between OEMs and distros because OEMs will > > typically get a new panel to react to a sourcing issue during > > production, and thus need some swift turnaround between getting their > > new panel and it being operational in the OS. Distributions on the other > > hand can take years to ship a kernel with that new panel driver. > > > > To solve this, I followed the example of HID-BPF and wrote a panel > > driver that will rely on BPF programs to perform the panel > > initialization. That way, we can ship the programs separately from the > > kernel, and with a different lifecycle. > > """ > > > > You can disagree with the solution, that's fair, we can also discuss on > > how to solve this problem, but I'd appreciate it if you weren't claiming > > it's all useless. > > I did read the cover-letter and I got the arguments from Benjamin, and > while in theory it could indeed solve the issue described, in reality > it won't for the reasons I exposed. > > And since it's basically allowing to accept out-of-tree downstream > driver instead of upstreaming, I'm kind against TBH. I'm confused, is it something we do not allow today? Maxime