用于 FPGA 编程的内核 API

概述

用于 FPGA 编程的内核 API 是来自 FPGA 管理器、桥接器和区域的 API 的组合。用于触发 FPGA 编程的实际函数是 fpga_region_program_fpga()

fpga_region_program_fpga() 使用 FPGA 管理器和桥接器提供的功能。它将

  • 锁定区域的互斥锁

  • 锁定区域的 FPGA 管理器的互斥锁

  • 如果已指定方法,则构建 FPGA 桥接器列表

  • 禁用桥接器

  • 使用 fpga_region->info 中传递的信息对 FPGA 进行编程。

  • 重新启用桥接器

  • 释放锁

struct fpga_image_info 指定要编程的 FPGA 映像。它由 fpga_image_info_alloc() 分配/释放,并使用 fpga_image_info_free() 释放

如何使用区域编程 FPGA

当 FPGA 区域驱动程序探测时,它会获得指向 FPGA 管理器驱动程序的指针,以便它知道要使用哪个管理器。该区域要么有一个要在编程期间控制的桥接器列表,要么有一个指向将生成该列表的函数的指针。以下是一些示例代码,说明接下来要做什么

#include <linux/fpga/fpga-mgr.h>
#include <linux/fpga/fpga-region.h>

struct fpga_image_info *info;
int ret;

/*
 * First, alloc the struct with information about the FPGA image to
 * program.
 */
info = fpga_image_info_alloc(dev);
if (!info)
        return -ENOMEM;

/* Set flags as needed, such as: */
info->flags = FPGA_MGR_PARTIAL_RECONFIG;

/*
 * Indicate where the FPGA image is. This is pseudo-code; you're
 * going to use one of these three.
 */
if (image is in a scatter gather table) {

        info->sgt = [your scatter gather table]

} else if (image is in a buffer) {

        info->buf = [your image buffer]
        info->count = [image buffer size]

} else if (image is in a firmware file) {

        info->firmware_name = devm_kstrdup(dev, firmware_name,
                                           GFP_KERNEL);

}

/* Add info to region and do the programming */
region->info = info;
ret = fpga_region_program_fpga(region);

/* Deallocate the image info if you're done with it */
region->info = NULL;
fpga_image_info_free(info);

if (ret)
        return ret;

/* Now enumerate whatever hardware has appeared in the FPGA. */

用于编程 FPGA 的 API

int fpga_region_program_fpga(struct fpga_region *region)

编程 FPGA

参数

struct fpga_region *region

FPGA 区域

描述

使用 FPGA 映像信息 (region->info) 编程 FPGA。如果区域具有 get_bridges 函数,则如果编程成功,将保留桥接器的独占引用。这旨在防止重新编程区域,直到调用者认为这样做是安全的。调用者需要在尝试重新编程区域之前调用 fpga_bridges_put()

返回值

成功返回 0 或负错误代码。

FPGA 管理器标志

fpga_image_info->flags 字段中使用的标志

FPGA_MGR_PARTIAL_RECONFIG:如果支持,则执行部分重新配置

FPGA_MGR_EXTERNAL_CONFIG:FPGA 已在 Linux 启动之前配置

FPGA_MGR_ENCRYPTED_BITSTREAM:指示比特流已加密

FPGA_MGR_BITSTREAM_LSB_FIRST:SPI 比特流位顺序为 LSB 优先

FPGA_MGR_COMPRESSED_BITSTREAM:FPGA 比特流已压缩

struct fpga_image_info

特定于 FPGA 映像的信息

定义:

struct fpga_image_info {
    u32 flags;
    u32 enable_timeout_us;
    u32 disable_timeout_us;
    u32 config_complete_timeout_us;
    char *firmware_name;
    struct sg_table *sgt;
    const char *buf;
    size_t count;
    size_t header_size;
    size_t data_size;
    int region_id;
    struct device *dev;
#ifdef CONFIG_OF;
    struct device_node *overlay;
#endif;
};

成员

flags

如上定义的布尔标志

enable_timeout_us

启用通过桥接器的最大时间(微秒)

disable_timeout_us

禁用通过桥接器的最大时间(微秒)

config_complete_timeout_us

在 write_complete 操作中,FPGA 切换到运行状态的最大时间。

firmware_name

FPGA 映像固件文件的名称

sgt

包含 FPGA 映像的散布/收集表

buf

包含 FPGA 映像的连续缓冲区

count

buf 的大小

header_size

映像头的大小。

data_size

要发送到设备映像数据的大小。如果未指定,将使用整个映像。在这两种情况下,都可能跳过头。

region_id

目标区域的 ID

dev

拥有此设备的设备

overlay

设备树覆盖

struct fpga_image_info *fpga_image_info_alloc(struct device *dev)

分配 FPGA 映像信息结构

参数

struct device *dev

所属设备

返回值

struct fpga_image_info 或 NULL

void fpga_image_info_free(struct fpga_image_info *info)

释放 FPGA 映像信息结构

参数

struct fpga_image_info *info

要释放的 FPGA 映像信息结构