Back to home page

OSCL-LXR

 
 

    


0001 In-kernel API for FPGA Programming
0002 ==================================
0003 
0004 Overview
0005 --------
0006 
0007 The in-kernel API for FPGA programming is a combination of APIs from
0008 FPGA manager, bridge, and regions.  The actual function used to
0009 trigger FPGA programming is fpga_region_program_fpga().
0010 
0011 fpga_region_program_fpga() uses functionality supplied by
0012 the FPGA manager and bridges.  It will:
0013 
0014  * lock the region's mutex
0015  * lock the mutex of the region's FPGA manager
0016  * build a list of FPGA bridges if a method has been specified to do so
0017  * disable the bridges
0018  * program the FPGA using info passed in :c:expr:`fpga_region->info`.
0019  * re-enable the bridges
0020  * release the locks
0021 
0022 The struct fpga_image_info specifies what FPGA image to program.  It is
0023 allocated/freed by fpga_image_info_alloc() and freed with
0024 fpga_image_info_free()
0025 
0026 How to program an FPGA using a region
0027 -------------------------------------
0028 
0029 When the FPGA region driver probed, it was given a pointer to an FPGA manager
0030 driver so it knows which manager to use.  The region also either has a list of
0031 bridges to control during programming or it has a pointer to a function that
0032 will generate that list.  Here's some sample code of what to do next::
0033 
0034         #include <linux/fpga/fpga-mgr.h>
0035         #include <linux/fpga/fpga-region.h>
0036 
0037         struct fpga_image_info *info;
0038         int ret;
0039 
0040         /*
0041          * First, alloc the struct with information about the FPGA image to
0042          * program.
0043          */
0044         info = fpga_image_info_alloc(dev);
0045         if (!info)
0046                 return -ENOMEM;
0047 
0048         /* Set flags as needed, such as: */
0049         info->flags = FPGA_MGR_PARTIAL_RECONFIG;
0050 
0051         /*
0052          * Indicate where the FPGA image is. This is pseudo-code; you're
0053          * going to use one of these three.
0054          */
0055         if (image is in a scatter gather table) {
0056 
0057                 info->sgt = [your scatter gather table]
0058 
0059         } else if (image is in a buffer) {
0060 
0061                 info->buf = [your image buffer]
0062                 info->count = [image buffer size]
0063 
0064         } else if (image is in a firmware file) {
0065 
0066                 info->firmware_name = devm_kstrdup(dev, firmware_name,
0067                                                    GFP_KERNEL);
0068 
0069         }
0070 
0071         /* Add info to region and do the programming */
0072         region->info = info;
0073         ret = fpga_region_program_fpga(region);
0074 
0075         /* Deallocate the image info if you're done with it */
0076         region->info = NULL;
0077         fpga_image_info_free(info);
0078 
0079         if (ret)
0080                 return ret;
0081 
0082         /* Now enumerate whatever hardware has appeared in the FPGA. */
0083 
0084 API for programming an FPGA
0085 ---------------------------
0086 
0087 * fpga_region_program_fpga() -  Program an FPGA
0088 * fpga_image_info() -  Specifies what FPGA image to program
0089 * fpga_image_info_alloc() -  Allocate an FPGA image info struct
0090 * fpga_image_info_free() -  Free an FPGA image info struct
0091 
0092 .. kernel-doc:: drivers/fpga/fpga-region.c
0093    :functions: fpga_region_program_fpga
0094 
0095 FPGA Manager flags
0096 
0097 .. kernel-doc:: include/linux/fpga/fpga-mgr.h
0098    :doc: FPGA Manager flags
0099 
0100 .. kernel-doc:: include/linux/fpga/fpga-mgr.h
0101    :functions: fpga_image_info
0102 
0103 .. kernel-doc:: drivers/fpga/fpga-mgr.c
0104    :functions: fpga_image_info_alloc
0105 
0106 .. kernel-doc:: drivers/fpga/fpga-mgr.c
0107    :functions: fpga_image_info_free