^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) In-kernel API for FPGA Programming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) ==================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) Overview
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) --------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) The in-kernel API for FPGA programming is a combination of APIs from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) FPGA manager, bridge, and regions. The actual function used to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) trigger FPGA programming is fpga_region_program_fpga().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) fpga_region_program_fpga() uses functionality supplied by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) the FPGA manager and bridges. It will:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * lock the region's mutex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * lock the mutex of the region's FPGA manager
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * build a list of FPGA bridges if a method has been specified to do so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * disable the bridges
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * program the FPGA using info passed in :c:expr:`fpga_region->info`.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * re-enable the bridges
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * release the locks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) The struct fpga_image_info specifies what FPGA image to program. It is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) allocated/freed by fpga_image_info_alloc() and freed with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) fpga_image_info_free()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) How to program an FPGA using a region
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) -------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) When the FPGA region driver probed, it was given a pointer to an FPGA manager
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) driver so it knows which manager to use. The region also either has a list of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) bridges to control during programming or it has a pointer to a function that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) will generate that list. Here's some sample code of what to do next::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/fpga/fpga-mgr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/fpga/fpga-region.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct fpga_image_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * First, alloc the struct with information about the FPGA image to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * program.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) info = fpga_image_info_alloc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* Set flags as needed, such as: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) info->flags = FPGA_MGR_PARTIAL_RECONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * Indicate where the FPGA image is. This is pseudo-code; you're
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * going to use one of these three.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (image is in a scatter gather table) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) info->sgt = [your scatter gather table]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) } else if (image is in a buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) info->buf = [your image buffer]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) info->count = [image buffer size]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) } else if (image is in a firmware file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) info->firmware_name = devm_kstrdup(dev, firmware_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* Add info to region and do the programming */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) region->info = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) ret = fpga_region_program_fpga(region);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* Deallocate the image info if you're done with it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) region->info = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) fpga_image_info_free(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* Now enumerate whatever hardware has appeared in the FPGA. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) API for programming an FPGA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) ---------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * fpga_region_program_fpga() — Program an FPGA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * fpga_image_info() — Specifies what FPGA image to program
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * fpga_image_info_alloc() — Allocate an FPGA image info struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * fpga_image_info_free() — Free an FPGA image info struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) .. kernel-doc:: drivers/fpga/fpga-region.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) :functions: fpga_region_program_fpga
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) FPGA Manager flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) .. kernel-doc:: include/linux/fpga/fpga-mgr.h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) :doc: FPGA Manager flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .. kernel-doc:: include/linux/fpga/fpga-mgr.h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) :functions: fpga_image_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .. kernel-doc:: drivers/fpga/fpga-mgr.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) :functions: fpga_image_info_alloc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) .. kernel-doc:: drivers/fpga/fpga-mgr.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) :functions: fpga_image_info_free