xref: /linux/Documentation/driver-api/fpga/fpga-programming.rst (revision 762f99f4f3cb41a775b5157dd761217beba65873)
14a6ff3c9SAlan TullIn-kernel API for FPGA Programming
24a6ff3c9SAlan Tull==================================
34a6ff3c9SAlan Tull
44a6ff3c9SAlan TullOverview
54a6ff3c9SAlan Tull--------
64a6ff3c9SAlan Tull
74a6ff3c9SAlan TullThe in-kernel API for FPGA programming is a combination of APIs from
84a6ff3c9SAlan TullFPGA manager, bridge, and regions.  The actual function used to
978b8612eSPuranjay Mohantrigger FPGA programming is fpga_region_program_fpga().
104a6ff3c9SAlan Tull
1178b8612eSPuranjay Mohanfpga_region_program_fpga() uses functionality supplied by
124a6ff3c9SAlan Tullthe FPGA manager and bridges.  It will:
134a6ff3c9SAlan Tull
144a6ff3c9SAlan Tull * lock the region's mutex
154a6ff3c9SAlan Tull * lock the mutex of the region's FPGA manager
164a6ff3c9SAlan Tull * build a list of FPGA bridges if a method has been specified to do so
174a6ff3c9SAlan Tull * disable the bridges
1864d41516SMauro Carvalho Chehab * program the FPGA using info passed in :c:expr:`fpga_region->info`.
194a6ff3c9SAlan Tull * re-enable the bridges
204a6ff3c9SAlan Tull * release the locks
214a6ff3c9SAlan Tull
224a6ff3c9SAlan TullThe struct fpga_image_info specifies what FPGA image to program.  It is
2378b8612eSPuranjay Mohanallocated/freed by fpga_image_info_alloc() and freed with
2478b8612eSPuranjay Mohanfpga_image_info_free()
254a6ff3c9SAlan Tull
264a6ff3c9SAlan TullHow to program an FPGA using a region
274a6ff3c9SAlan Tull-------------------------------------
284a6ff3c9SAlan Tull
294a6ff3c9SAlan TullWhen the FPGA region driver probed, it was given a pointer to an FPGA manager
304a6ff3c9SAlan Tulldriver so it knows which manager to use.  The region also either has a list of
314a6ff3c9SAlan Tullbridges to control during programming or it has a pointer to a function that
324a6ff3c9SAlan Tullwill generate that list.  Here's some sample code of what to do next::
334a6ff3c9SAlan Tull
344a6ff3c9SAlan Tull	#include <linux/fpga/fpga-mgr.h>
354a6ff3c9SAlan Tull	#include <linux/fpga/fpga-region.h>
364a6ff3c9SAlan Tull
374a6ff3c9SAlan Tull	struct fpga_image_info *info;
384a6ff3c9SAlan Tull	int ret;
394a6ff3c9SAlan Tull
404a6ff3c9SAlan Tull	/*
414a6ff3c9SAlan Tull	 * First, alloc the struct with information about the FPGA image to
424a6ff3c9SAlan Tull	 * program.
434a6ff3c9SAlan Tull	 */
444a6ff3c9SAlan Tull	info = fpga_image_info_alloc(dev);
454a6ff3c9SAlan Tull	if (!info)
464a6ff3c9SAlan Tull		return -ENOMEM;
474a6ff3c9SAlan Tull
484a6ff3c9SAlan Tull	/* Set flags as needed, such as: */
494a6ff3c9SAlan Tull	info->flags = FPGA_MGR_PARTIAL_RECONFIG;
504a6ff3c9SAlan Tull
514a6ff3c9SAlan Tull	/*
524a6ff3c9SAlan Tull	 * Indicate where the FPGA image is. This is pseudo-code; you're
534a6ff3c9SAlan Tull	 * going to use one of these three.
544a6ff3c9SAlan Tull	 */
554a6ff3c9SAlan Tull	if (image is in a scatter gather table) {
564a6ff3c9SAlan Tull
574a6ff3c9SAlan Tull		info->sgt = [your scatter gather table]
584a6ff3c9SAlan Tull
594a6ff3c9SAlan Tull	} else if (image is in a buffer) {
604a6ff3c9SAlan Tull
614a6ff3c9SAlan Tull		info->buf = [your image buffer]
624a6ff3c9SAlan Tull		info->count = [image buffer size]
634a6ff3c9SAlan Tull
644a6ff3c9SAlan Tull	} else if (image is in a firmware file) {
654a6ff3c9SAlan Tull
664a6ff3c9SAlan Tull		info->firmware_name = devm_kstrdup(dev, firmware_name,
674a6ff3c9SAlan Tull						   GFP_KERNEL);
684a6ff3c9SAlan Tull
694a6ff3c9SAlan Tull	}
704a6ff3c9SAlan Tull
714a6ff3c9SAlan Tull	/* Add info to region and do the programming */
724a6ff3c9SAlan Tull	region->info = info;
734a6ff3c9SAlan Tull	ret = fpga_region_program_fpga(region);
744a6ff3c9SAlan Tull
754a6ff3c9SAlan Tull	/* Deallocate the image info if you're done with it */
764a6ff3c9SAlan Tull	region->info = NULL;
774a6ff3c9SAlan Tull	fpga_image_info_free(info);
784a6ff3c9SAlan Tull
794a6ff3c9SAlan Tull	if (ret)
804a6ff3c9SAlan Tull		return ret;
814a6ff3c9SAlan Tull
824a6ff3c9SAlan Tull	/* Now enumerate whatever hardware has appeared in the FPGA. */
834a6ff3c9SAlan Tull
844a6ff3c9SAlan TullAPI for programming an FPGA
854a6ff3c9SAlan Tull---------------------------
864a6ff3c9SAlan Tull
87*758f7467SMauro Carvalho Chehab* fpga_region_program_fpga() -  Program an FPGA
88*758f7467SMauro Carvalho Chehab* fpga_image_info() -  Specifies what FPGA image to program
89*758f7467SMauro Carvalho Chehab* fpga_image_info_alloc() -  Allocate an FPGA image info struct
90*758f7467SMauro Carvalho Chehab* fpga_image_info_free() -  Free an FPGA image info struct
914a6ff3c9SAlan Tull
924a6ff3c9SAlan Tull.. kernel-doc:: drivers/fpga/fpga-region.c
934a6ff3c9SAlan Tull   :functions: fpga_region_program_fpga
944a6ff3c9SAlan Tull
954a6ff3c9SAlan TullFPGA Manager flags
964a6ff3c9SAlan Tull
974a6ff3c9SAlan Tull.. kernel-doc:: include/linux/fpga/fpga-mgr.h
984a6ff3c9SAlan Tull   :doc: FPGA Manager flags
994a6ff3c9SAlan Tull
1004a6ff3c9SAlan Tull.. kernel-doc:: include/linux/fpga/fpga-mgr.h
1014a6ff3c9SAlan Tull   :functions: fpga_image_info
1024a6ff3c9SAlan Tull
1034a6ff3c9SAlan Tull.. kernel-doc:: drivers/fpga/fpga-mgr.c
1044a6ff3c9SAlan Tull   :functions: fpga_image_info_alloc
1054a6ff3c9SAlan Tull
1064a6ff3c9SAlan Tull.. kernel-doc:: drivers/fpga/fpga-mgr.c
1074a6ff3c9SAlan Tull   :functions: fpga_image_info_free
108