18c2ecf20Sopenharmony_ciFPGA Manager 28c2ecf20Sopenharmony_ci============ 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ciOverview 58c2ecf20Sopenharmony_ci-------- 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ciThe FPGA manager core exports a set of functions for programming an FPGA with 88c2ecf20Sopenharmony_cian image. The API is manufacturer agnostic. All manufacturer specifics are 98c2ecf20Sopenharmony_cihidden away in a low level driver which registers a set of ops with the core. 108c2ecf20Sopenharmony_ciThe FPGA image data itself is very manufacturer specific, but for our purposes 118c2ecf20Sopenharmony_ciit's just binary data. The FPGA manager core won't parse it. 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ciThe FPGA image to be programmed can be in a scatter gather list, a single 148c2ecf20Sopenharmony_cicontiguous buffer, or a firmware file. Because allocating contiguous kernel 158c2ecf20Sopenharmony_cimemory for the buffer should be avoided, users are encouraged to use a scatter 168c2ecf20Sopenharmony_cigather list instead if possible. 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ciThe particulars for programming the image are presented in a structure (struct 198c2ecf20Sopenharmony_cifpga_image_info). This struct contains parameters such as pointers to the 208c2ecf20Sopenharmony_ciFPGA image as well as image-specific particulars such as whether the image was 218c2ecf20Sopenharmony_cibuilt for full or partial reconfiguration. 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ciHow to support a new FPGA device 248c2ecf20Sopenharmony_ci-------------------------------- 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ciTo add another FPGA manager, write a driver that implements a set of ops. The 278c2ecf20Sopenharmony_ciprobe function calls fpga_mgr_register(), such as:: 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci static const struct fpga_manager_ops socfpga_fpga_ops = { 308c2ecf20Sopenharmony_ci .write_init = socfpga_fpga_ops_configure_init, 318c2ecf20Sopenharmony_ci .write = socfpga_fpga_ops_configure_write, 328c2ecf20Sopenharmony_ci .write_complete = socfpga_fpga_ops_configure_complete, 338c2ecf20Sopenharmony_ci .state = socfpga_fpga_ops_state, 348c2ecf20Sopenharmony_ci }; 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci static int socfpga_fpga_probe(struct platform_device *pdev) 378c2ecf20Sopenharmony_ci { 388c2ecf20Sopenharmony_ci struct device *dev = &pdev->dev; 398c2ecf20Sopenharmony_ci struct socfpga_fpga_priv *priv; 408c2ecf20Sopenharmony_ci struct fpga_manager *mgr; 418c2ecf20Sopenharmony_ci int ret; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 448c2ecf20Sopenharmony_ci if (!priv) 458c2ecf20Sopenharmony_ci return -ENOMEM; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci /* 488c2ecf20Sopenharmony_ci * do ioremaps, get interrupts, etc. and save 498c2ecf20Sopenharmony_ci * them in priv 508c2ecf20Sopenharmony_ci */ 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci mgr = devm_fpga_mgr_create(dev, "Altera SOCFPGA FPGA Manager", 538c2ecf20Sopenharmony_ci &socfpga_fpga_ops, priv); 548c2ecf20Sopenharmony_ci if (!mgr) 558c2ecf20Sopenharmony_ci return -ENOMEM; 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci platform_set_drvdata(pdev, mgr); 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci return fpga_mgr_register(mgr); 608c2ecf20Sopenharmony_ci } 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci static int socfpga_fpga_remove(struct platform_device *pdev) 638c2ecf20Sopenharmony_ci { 648c2ecf20Sopenharmony_ci struct fpga_manager *mgr = platform_get_drvdata(pdev); 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci fpga_mgr_unregister(mgr); 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci return 0; 698c2ecf20Sopenharmony_ci } 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ciThe ops will implement whatever device specific register writes are needed to 738c2ecf20Sopenharmony_cido the programming sequence for this particular FPGA. These ops return 0 for 748c2ecf20Sopenharmony_cisuccess or negative error codes otherwise. 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ciThe programming sequence is:: 778c2ecf20Sopenharmony_ci 1. .write_init 788c2ecf20Sopenharmony_ci 2. .write or .write_sg (may be called once or multiple times) 798c2ecf20Sopenharmony_ci 3. .write_complete 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ciThe .write_init function will prepare the FPGA to receive the image data. The 828c2ecf20Sopenharmony_cibuffer passed into .write_init will be at most .initial_header_size bytes long; 838c2ecf20Sopenharmony_ciif the whole bitstream is not immediately available then the core code will 848c2ecf20Sopenharmony_cibuffer up at least this much before starting. 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ciThe .write function writes a buffer to the FPGA. The buffer may be contain the 878c2ecf20Sopenharmony_ciwhole FPGA image or may be a smaller chunk of an FPGA image. In the latter 888c2ecf20Sopenharmony_cicase, this function is called multiple times for successive chunks. This interface 898c2ecf20Sopenharmony_ciis suitable for drivers which use PIO. 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ciThe .write_sg version behaves the same as .write except the input is a sg_table 928c2ecf20Sopenharmony_ciscatter list. This interface is suitable for drivers which use DMA. 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ciThe .write_complete function is called after all the image has been written 958c2ecf20Sopenharmony_cito put the FPGA into operating mode. 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ciThe ops include a .state function which will determine the state the FPGA is in 988c2ecf20Sopenharmony_ciand return a code of type enum fpga_mgr_states. It doesn't result in a change 998c2ecf20Sopenharmony_ciin state. 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ciAPI for implementing a new FPGA Manager driver 1028c2ecf20Sopenharmony_ci---------------------------------------------- 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci* ``fpga_mgr_states`` — Values for :c:expr:`fpga_manager->state`. 1058c2ecf20Sopenharmony_ci* struct fpga_manager — the FPGA manager struct 1068c2ecf20Sopenharmony_ci* struct fpga_manager_ops — Low level FPGA manager driver ops 1078c2ecf20Sopenharmony_ci* devm_fpga_mgr_create() — Allocate and init a manager struct 1088c2ecf20Sopenharmony_ci* fpga_mgr_register() — Register an FPGA manager 1098c2ecf20Sopenharmony_ci* fpga_mgr_unregister() — Unregister an FPGA manager 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci.. kernel-doc:: include/linux/fpga/fpga-mgr.h 1128c2ecf20Sopenharmony_ci :functions: fpga_mgr_states 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci.. kernel-doc:: include/linux/fpga/fpga-mgr.h 1158c2ecf20Sopenharmony_ci :functions: fpga_manager 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci.. kernel-doc:: include/linux/fpga/fpga-mgr.h 1188c2ecf20Sopenharmony_ci :functions: fpga_manager_ops 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci.. kernel-doc:: drivers/fpga/fpga-mgr.c 1218c2ecf20Sopenharmony_ci :functions: devm_fpga_mgr_create 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci.. kernel-doc:: drivers/fpga/fpga-mgr.c 1248c2ecf20Sopenharmony_ci :functions: fpga_mgr_register 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci.. kernel-doc:: drivers/fpga/fpga-mgr.c 1278c2ecf20Sopenharmony_ci :functions: fpga_mgr_unregister 128