用于 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 first

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;
};

成员

标志

如上定义的布尔标志

enable_timeout_us

通过桥启用流量的最大时间 (uSec)

disable_timeout_us

禁用通过桥的流量的最大时间 (uSec)

config_complete_timeout_us

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

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 设备 *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 镜像信息结构