Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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