Documentation/driver-api/fpga/fpga-mgr.rst GitHub 원문 ↗

Linux 6.18.37 · Driver API

FPGA Manager

Manufacturer-agnostic FPGA programming core, image source, callback sequence와 manager driver registration을 설명합니다.

Source pathDocumentation/driver-api/fpga/fpga-mgr.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약과 해설

fpga-mgr.rst:1-168

FPGA manager core는 image 형식을 해석하지 않는 manufacturer-neutral programming framework입니다. Low-level driver가 parse·init·write·complete·state operation을 구현하며, 큰 contiguous allocation 대신 scatter-gather image가 권장됩니다.

Driver는 일반 또는 devm registration을 선택할 수 있습니다. `.parse_header`는 더 많은 header가 필요하면 `-EAGAIN`으로 재호출을 요청하고, PIO driver는 `.write`, DMA driver는 `.write_sg`를 사용합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 FPGA Manager
2 ============
3
4 Overview
5 --------
6
7 The FPGA manager core exports a set of functions for programming an FPGA with
8 an image. The API is manufacturer agnostic. All manufacturer specifics are
9 hidden away in a low level driver which registers a set of ops with the core.
10 The FPGA image data itself is very manufacturer specific, but for our purposes
11 it's just binary data. The FPGA manager core won't parse it.
12
13 The FPGA image to be programmed can be in a scatter gather list, a single
14 contiguous buffer, or a firmware file. Because allocating contiguous kernel
15 memory for the buffer should be avoided, users are encouraged to use a scatter
16 gather list instead if possible.
17
18 The particulars for programming the image are presented in a structure (struct
19 fpga_image_info). This struct contains parameters such as pointers to the
20 FPGA image as well as image-specific particulars such as whether the image was
21 built for full or partial reconfiguration.
22
23 How to support a new FPGA device
24 --------------------------------
25
26 To add another FPGA manager, write a driver that implements a set of ops. The
27 probe function calls ``fpga_mgr_register()`` or ``fpga_mgr_register_full()``,
28 such as::
29
30 static const struct fpga_manager_ops socfpga_fpga_ops = {
31 .write_init = socfpga_fpga_ops_configure_init,
32 .write = socfpga_fpga_ops_configure_write,
33 .write_complete = socfpga_fpga_ops_configure_complete,
34 .state = socfpga_fpga_ops_state,
35 };
36
37 static int socfpga_fpga_probe(struct platform_device *pdev)
38 {
39 struct device *dev = &pdev->dev;
40 struct socfpga_fpga_priv *priv;
41 struct fpga_manager *mgr;
42 int ret;
43
44 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
45 if (!priv)
46 return -ENOMEM;
47
48 /*
49 * do ioremaps, get interrupts, etc. and save
50 * them in priv
51 */
52
53 mgr = fpga_mgr_register(dev, "Altera SOCFPGA FPGA Manager",
54 &socfpga_fpga_ops, priv);
55 if (IS_ERR(mgr))
56 return PTR_ERR(mgr);
57
58 platform_set_drvdata(pdev, mgr);
59
60 return 0;
61 }
62
63 static int socfpga_fpga_remove(struct platform_device *pdev)
64 {
65 struct fpga_manager *mgr = platform_get_drvdata(pdev);
66
67 fpga_mgr_unregister(mgr);
68
69 return 0;
70 }
71
72 Alternatively, the probe function could call one of the resource managed
73 register functions, ``devm_fpga_mgr_register()`` or
74 ``devm_fpga_mgr_register_full()``. When these functions are used, the
75 parameter syntax is the same, but the call to ``fpga_mgr_unregister()`` should be
76 removed. In the above example, the ``socfpga_fpga_remove()`` function would not be
77 required.
78
79 The ops will implement whatever device specific register writes are needed to
80 do the programming sequence for this particular FPGA. These ops return 0 for
81 success or negative error codes otherwise.
82
83 The programming sequence is::
84 1. .parse_header (optional, may be called once or multiple times)
85 2. .write_init
86 3. .write or .write_sg (may be called once or multiple times)
87 4. .write_complete
88
89 The .parse_header function will set header_size and data_size to
90 struct fpga_image_info. Before parse_header call, header_size is initialized
91 with initial_header_size. If flag skip_header of fpga_manager_ops is true,
92 .write function will get image buffer starting at header_size offset from the
93 beginning. If data_size is set, .write function will get data_size bytes of
94 the image buffer, otherwise .write will get data up to the end of image buffer.
95 This will not affect .write_sg, .write_sg will still get whole image in
96 sg_table form. If FPGA image is already mapped as a single contiguous buffer,
97 whole buffer will be passed into .parse_header. If image is in scatter-gather
98 form, core code will buffer up at least .initial_header_size before the first
99 call of .parse_header, if it is not enough, .parse_header should set desired
100 size into info->header_size and return -EAGAIN, then it will be called again
101 with greater part of image buffer on the input.
102
103 The .write_init function will prepare the FPGA to receive the image data. The
104 buffer passed into .write_init will be at least info->header_size bytes long;
105 if the whole bitstream is not immediately available then the core code will
106 buffer up at least this much before starting.
107
108 The .write function writes a buffer to the FPGA. The buffer may be contain the
109 whole FPGA image or may be a smaller chunk of an FPGA image. In the latter
110 case, this function is called multiple times for successive chunks. This interface
111 is suitable for drivers which use PIO.
112
113 The .write_sg version behaves the same as .write except the input is a sg_table
114 scatter list. This interface is suitable for drivers which use DMA.
115
116 The .write_complete function is called after all the image has been written
117 to put the FPGA into operating mode.
118
119 The ops include a .state function which will determine the state the FPGA is in
120 and return a code of type enum fpga_mgr_states. It doesn't result in a change
121 in state.
122
123 API for implementing a new FPGA Manager driver
124 ----------------------------------------------
125
126 * ``fpga_mgr_states`` - Values for :c:expr:`fpga_manager->state`.
127 * struct fpga_manager - the FPGA manager struct
128 * struct fpga_manager_ops - Low level FPGA manager driver ops
129 * struct fpga_manager_info - Parameter structure for fpga_mgr_register_full()
130 * __fpga_mgr_register_full() - Create and register an FPGA manager using the
131 fpga_mgr_info structure to provide the full flexibility of options
132 * __fpga_mgr_register() - Create and register an FPGA manager using standard
133 arguments
134 * __devm_fpga_mgr_register_full() - Resource managed version of
135 __fpga_mgr_register_full()
136 * __devm_fpga_mgr_register() - Resource managed version of __fpga_mgr_register()
137 * fpga_mgr_unregister() - Unregister an FPGA manager
138
139 Helper macros ``fpga_mgr_register_full()``, ``fpga_mgr_register()``,
140 ``devm_fpga_mgr_register_full()``, and ``devm_fpga_mgr_register()`` are available
141 to ease the registration.
142
143 .. kernel-doc:: include/linux/fpga/fpga-mgr.h
144 :functions: fpga_mgr_states
145
146 .. kernel-doc:: include/linux/fpga/fpga-mgr.h
147 :functions: fpga_manager
148
149 .. kernel-doc:: include/linux/fpga/fpga-mgr.h
150 :functions: fpga_manager_ops
151
152 .. kernel-doc:: include/linux/fpga/fpga-mgr.h
153 :functions: fpga_manager_info
154
155 .. kernel-doc:: drivers/fpga/fpga-mgr.c
156 :functions: __fpga_mgr_register_full
157
158 .. kernel-doc:: drivers/fpga/fpga-mgr.c
159 :functions: __fpga_mgr_register
160
161 .. kernel-doc:: drivers/fpga/fpga-mgr.c
162 :functions: __devm_fpga_mgr_register_full
163
164 .. kernel-doc:: drivers/fpga/fpga-mgr.c
165 :functions: __devm_fpga_mgr_register
166
167 .. kernel-doc:: drivers/fpga/fpga-mgr.c
168 :functions: fpga_mgr_unregister
169

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

FPGA manager 개요

1-22

문서 제목은 `FPGA Manager`입니다.

FPGA manager core는 image로 FPGA를 programming하는 function 집합을 export합니다. API는 manufacturer-agnostic이며, manufacturer별 세부 사항은 core에 operation 집합을 등록하는 low-level driver 안에 숨깁니다.

FPGA image data 자체는 manufacturer별로 매우 다르지만 manager core 관점에서는 binary data일 뿐이며 core가 이를 parse하지 않습니다.

Programming할 FPGA image는 scatter-gather list, 하나의 contiguous buffer 또는 firmware file에 있을 수 있습니다. Contiguous kernel memory allocation은 피해야 하므로 가능하면 scatter-gather list 사용을 권장합니다.

Programming 세부 사항은 `struct fpga_image_info`에 전달합니다. 이 structure에는 FPGA image pointer와 image가 full reconfiguration용인지 partial reconfiguration용인지 같은 image별 parameter가 들어 있습니다.

FPGA image source 형식
형식특징권장
Scatter-gather list비연속 memory page가능하면 우선 사용
Contiguous buffer연속 kernel memory큰 allocation을 피해야 함
Firmware fileFirmware loader에서 제공일반 file 기반 image

Manager core가 받을 수 있는 image storage와 사용상 권장 사항입니다.

새 FPGA manager driver 지원

23-78

새 FPGA manager를 추가하려면 operation 집합을 구현하는 driver를 작성합니다. Probe function은 `fpga_mgr_register()` 또는 `fpga_mgr_register_full()`을 호출합니다.

예제는 `write_init`, `write`, `write_complete`, `state` callback을 `socfpga_fpga_ops`에 연결하고, probe에서 private data를 준비해 manager를 등록한 뒤 remove에서 `fpga_mgr_unregister()`를 호출합니다.

static const struct fpga_manager_ops socfpga_fpga_ops = {
        .write_init = socfpga_fpga_ops_configure_init,
        .write = socfpga_fpga_ops_configure_write,
        .write_complete = socfpga_fpga_ops_configure_complete,
        .state = socfpga_fpga_ops_state,
};

static int socfpga_fpga_probe(struct platform_device *pdev)
{
        struct device *dev = &pdev->dev;
        struct socfpga_fpga_priv *priv;
        struct fpga_manager *mgr;
        int ret;

        priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;

        /*
         * do ioremaps, get interrupts, etc. and save
         * them in priv
         */

        mgr = fpga_mgr_register(dev, "Altera SOCFPGA FPGA Manager",
                                &socfpga_fpga_ops, priv);
        if (IS_ERR(mgr))
                return PTR_ERR(mgr);

        platform_set_drvdata(pdev, mgr);

        return 0;
}

static int socfpga_fpga_remove(struct platform_device *pdev)
{
        struct fpga_manager *mgr = platform_get_drvdata(pdev);

        fpga_mgr_unregister(mgr);

        return 0;
}

대신 resource-managed function인 `devm_fpga_mgr_register()` 또는 `devm_fpga_mgr_register_full()`을 호출할 수 있습니다. Parameter syntax는 같지만 이 경우 `fpga_mgr_unregister()` 호출을 제거해야 하며 위 예제의 `socfpga_fpga_remove()`도 필요하지 않습니다.

FPGA manager driver 등록 생명주기
Low-level fpga_manager_ops 구현Probe에서 private data 준비fpga_mgr_register() 또는 devm_fpga_mgr_register()Manager core가 programming request 처리일반 등록은 remove에서 fpga_mgr_unregister()devm 등록은 device resource가 자동 해제

일반 등록과 devm 등록의 resource 해제 차이를 보여줍니다.

Programming sequence와 parse_header

79-102

Operation은 해당 FPGA의 programming sequence에 필요한 device-specific register write를 구현합니다. 성공하면 0, 실패하면 negative error code를 반환합니다.

Programming 순서는 optional `.parse_header`, `.write_init`, 한 번 이상 호출될 수 있는 `.write` 또는 `.write_sg`, 마지막 `.write_complete`입니다.

`.parse_header`는 `struct fpga_image_info`의 `header_size`와 `data_size`를 설정합니다. 호출 전 `header_size`는 `initial_header_size`로 초기화됩니다.

`fpga_manager_ops.skip_header`가 true이면 `.write`에는 image 시작에서 `header_size`만큼 지난 buffer가 전달됩니다. `data_size`가 설정되면 그 byte 수만 전달하고, 설정하지 않으면 image 끝까지 전달합니다. 이 규칙은 `.write_sg`에는 영향을 주지 않아 `.write_sg`는 전체 image를 `sg_table` 형식으로 받습니다.

Image가 contiguous buffer이면 전체 buffer를 `.parse_header`에 전달합니다. Scatter-gather 형식이면 core가 첫 호출 전에 최소 `.initial_header_size`만큼 buffer를 모읍니다. 부족하면 `.parse_header`가 원하는 크기를 `info->header_size`에 설정하고 `-EAGAIN`을 반환하며, 더 큰 image 부분으로 다시 호출됩니다.

FPGA programming operation 순서
.parse_header (optional, 반복 가능)필요하면 header_size 증가 후 -EAGAIN.write_init.write 또는 .write_sg (반복 가능).write_completeFPGA operating mode

Header parsing에서 image write와 operating mode 전환까지의 callback 흐름입니다.

Write operation과 state

103-122

`.write_init`은 FPGA가 image data를 받을 준비를 하게 합니다. 전달되는 buffer는 최소 `info->header_size` byte이며 전체 bitstream이 바로 준비되지 않으면 core가 시작 전에 이 크기 이상을 모읍니다.

`.write`는 buffer를 FPGA에 기록합니다. Buffer는 전체 image 또는 더 작은 chunk일 수 있으며, chunk이면 연속 부분마다 여러 번 호출됩니다. 이 interface는 PIO를 사용하는 driver에 적합합니다.

`.write_sg`는 input이 `sg_table` scatter list라는 점을 제외하면 `.write`와 같으며 DMA를 사용하는 driver에 적합합니다.

`.write_complete`는 모든 image 기록이 끝난 뒤 FPGA를 operating mode로 전환하도록 호출됩니다.

`.state`는 FPGA의 현재 state를 판별해 `enum fpga_mgr_states` code를 반환하며 state 자체를 변경하지 않습니다.

FPGA manager operation contract
OperationInput·책임적합한 전송
parse_headerHeader size·data size 분석Contiguous 또는 buffered SG header
write_initFPGA 수신 준비Programming 시작
writeBuffer 또는 chunk 기록PIO
write_sgsg_table 전체 image 기록DMA
write_completeOperating mode 전환Programming 종료
state현재 state 조회상태 변경 없음

각 callback의 input 형식과 책임입니다.

새 manager driver 구현 API

123-142

새 FPGA manager driver 구현에 사용하는 API는 state enum, manager·operation·registration info structure, 일반·full·devm registration function과 unregister function으로 구성됩니다.

  • `fpga_mgr_states`: `fpga_manager->state` 값
  • `struct fpga_manager`: manager structure
  • `struct fpga_manager_ops`: low-level driver operation
  • `struct fpga_manager_info`: `fpga_mgr_register_full()` parameter structure
  • `__fpga_mgr_register_full()`과 `__fpga_mgr_register()`: manager 생성·등록
  • `__devm_fpga_mgr_register_full()`과 `__devm_fpga_mgr_register()`: resource-managed 등록
  • `fpga_mgr_unregister()`: manager 등록 해제

Registration을 쉽게 하도록 `fpga_mgr_register_full()`, `fpga_mgr_register()`, `devm_fpga_mgr_register_full()`, `devm_fpga_mgr_register()` helper macro를 제공합니다.

FPGA manager registration 선택
RegistrationParameterResource 관리
fpga_mgr_registerStandard argumentsDriver가 unregister
fpga_mgr_register_fullfpga_manager_infoDriver가 unregister
devm_fpga_mgr_registerStandard argumentsDevice-managed
devm_fpga_mgr_register_fullfpga_manager_infoDevice-managed

Parameter 유연성과 resource 관리 여부에 따른 helper입니다.

FPGA manager kernel-doc

143-168

State, manager, operation과 registration info 문서는 `include/linux/fpga/fpga-mgr.h`에서 가져옵니다.

.. kernel-doc:: include/linux/fpga/fpga-mgr.h
   :functions: fpga_mgr_states
.. kernel-doc:: include/linux/fpga/fpga-mgr.h
   :functions: fpga_manager
.. kernel-doc:: include/linux/fpga/fpga-mgr.h
   :functions: fpga_manager_ops
.. kernel-doc:: include/linux/fpga/fpga-mgr.h
   :functions: fpga_manager_info

Registration과 unregister function 문서는 `drivers/fpga/fpga-mgr.c`에서 가져옵니다.

.. kernel-doc:: drivers/fpga/fpga-mgr.c
   :functions: __fpga_mgr_register_full
.. kernel-doc:: drivers/fpga/fpga-mgr.c
   :functions: __fpga_mgr_register
.. kernel-doc:: drivers/fpga/fpga-mgr.c
   :functions: __devm_fpga_mgr_register_full
.. kernel-doc:: drivers/fpga/fpga-mgr.c
   :functions: __devm_fpga_mgr_register
.. kernel-doc:: drivers/fpga/fpga-mgr.c
   :functions: fpga_mgr_unregister