Re: [RFC PATCH] fpga: region: Add support for FPGA region variants

Xu Yilun <[email protected]> Fri, 26 Jun 2026 20:58:54 +0800
Newsgroups org.kernel.vger.linux-fpga,org.kernel.vger.linux-kernel
Message-ID <aj53joym0YpoYXWQ@yilunxu-OptiPlex-7050>
On Mon, Jun 08, 2026 at 06:42:45PM +0200, Marco Pagani wrote:
> This RFC proposes a proof-of-concept implementation of FPGA region
> variants, a mechanism that introduces a common way to handle
> dynamic partial reconfiguration from userspace. The proposed approach

There are many threads talking about userspace reconfiguration, the
latest one is this:

https://lore.kernel.org/linux-fpga/[email protected]/

Before we dive into detail, could you help tell why the previous one
won't work so we must switch to the new interface.

> is safe and aligned with the mainline kernel's stance on hardware
> management by constraining the hardware to a mutually exclusive set
> of configurations (variants) defined upfront. This is a realistic
> assumption for FPGAs, as regions are typically statically defined and
> synthesized during the system design phase. To keep the architecture
> realistic, the following additional constraints are introduced:
> (i) variants cannot be nested, and (ii) variants cannot contain FPGA
> bridges.
> 
> The interface and core logic for the variant mechanism are defined
> in the fpga-region and implemented in a backwards-compatible way.
> The fpga-region now optionally exports sysfs attributes that allow
> the user to reconfigure a region that supports variants by selecting
> one variant a list of pre-defined variants. Concrete regions can enable
> variant support by implementing the new apply_variant and remove_variant
> methods and adding them to fpga_region_info before registration.
> 
> As part of this RFC, the of-fpga-region concrete region has been extended
> to implement the variant interface. Variants are statically specified in
> the device tree using an fpga-variants node. Additionally, it introduces
> a firmware-cached property to cache bitstreams in memory, enabling a fast
> reconfiguration path for real-time (latency-sensitive) applications.
> 
> Below is an example of how variants can be statically defined in the
> device tree under this architecture:
> 
> fake_mgr: fpga-mgr@0 {
>         compatible = "linux,fake-fpga-mgr";
> };
> 
> fpga_region: fpga-region@0 {
>         compatible = "fpga-region";
>         #address-cells = <2>;
>         #size-cells = <2>;
>         ranges;
> 
>         /* FPGA region properties */
>         fpga-mgr = <&fake_mgr>;
>         partial-fpga-config;
>         region-unfreeze-timeout-us = <10000>;
> 
>         /* Base variant */
>         base-variant = "variant-1";

Previously we use DT-overlay file, here we use a list of variants. I'm
actually not sure why it is safer or better managed. As far as I can
tell, the only difference is that DT-overlay puts the region descriptions
in different files/blobs, while your fpga-variant puts them together in
one file/node, and we switch from choosing a file/blob to choosing a
string, is it?

> 
>         /* Variants container node */
>         fpga-variants {
>                 #address-cells = <2>;
>                 #size-cells = <2>;
>                 ranges;
> 
>                 variant-1 {
>                         firmware-name = "variant1-image.bin";
> 
>                         #address-cells = <2>;
>                         #size-cells = <2>;
>                         ranges;
> 
>                         variant_1_ip: ip_1@10000 {
>                                 compatible = "fake,ip_1";
>                                 reg = <0x0 0x10000 0x0 0x1000>;
>                         };
>                 };
> 
>                 variant-2 {
>                         firmware-name = "variant2-image.bin";
>                         firmware-cached;
> 
>                         #address-cells = <2>;
>                         #size-cells = <2>;
>                         ranges;
> 
>                         variant_2_ip: ip_2@10000 {
>                                 compatible = "fake,ip_2";
>                                 reg = <0x0 0x20000 0x0 0x1000>;
>                         };
>                 };
>         };
> };