From patchwork Thu Apr 20 14:09:46 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Tull X-Patchwork-Id: 9690639 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 6FB1B60326 for ; Thu, 20 Apr 2017 14:16:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6675128471 for ; Thu, 20 Apr 2017 14:16:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5B68428478; Thu, 20 Apr 2017 14:16:20 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A748F28471 for ; Thu, 20 Apr 2017 14:16:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S966022AbdDTOKU (ORCPT ); Thu, 20 Apr 2017 10:10:20 -0400 Received: from mail.kernel.org ([198.145.29.136]:59726 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1032151AbdDTOKS (ORCPT ); Thu, 20 Apr 2017 10:10:18 -0400 Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id AE8DF20103; Thu, 20 Apr 2017 14:10:15 +0000 (UTC) Received: from localhost.localdomain (user-0ccsrjt.cable.mindspring.com [24.206.110.125]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 8D890201B9; Thu, 20 Apr 2017 14:10:13 +0000 (UTC) From: Alan Tull To: Moritz Fischer Cc: Alan Tull , linux-kernel@vger.kernel.org, linux-fpga@vger.kernel.org Subject: [PATCH v2 01/16] doc: fpga: update documents for the FPGA API Date: Thu, 20 Apr 2017 09:09:46 -0500 Message-Id: <1492697401-11211-2-git-send-email-atull@kernel.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1492697401-11211-1-git-send-email-atull@kernel.org> References: <1492697401-11211-1-git-send-email-atull@kernel.org> X-Virus-Scanned: ClamAV using ClamSMTP Sender: linux-fpga-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fpga@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The FPGA manager has been simplified to have a single fpga_mgr_load function which replaces the three fpga_mgr_*load* functions. The parameters presenting the FPGA image have been added to struct fpga_image_info. Additional functions have been added to alloc/free fpga_image_info. Getting a FPGA manager has been separated from locking it. So an unlocked reference can be saved and only locked when we're about to program. A document for fpga-region has been added as well. Signed-off-by: Alan Tull --- v1: fixed some nits v2: expanded to include other FPGA API changes besides locking --- Documentation/fpga/fpga-mgr.txt | 133 +++++++++++++++++++------------------ Documentation/fpga/fpga-region.txt | 54 +++++++++++++++ Documentation/fpga/overview.txt | 23 +++++++ 3 files changed, 147 insertions(+), 63 deletions(-) create mode 100644 Documentation/fpga/fpga-region.txt create mode 100644 Documentation/fpga/overview.txt diff --git a/Documentation/fpga/fpga-mgr.txt b/Documentation/fpga/fpga-mgr.txt index 78f197f..0fc41eb 100644 --- a/Documentation/fpga/fpga-mgr.txt +++ b/Documentation/fpga/fpga-mgr.txt @@ -11,61 +11,66 @@ hidden away in a low level driver which registers a set of ops with the core. The FPGA image data itself is very manufacturer specific, but for our purposes it's just binary data. The FPGA manager core won't parse it. +The FPGA image to be programmed can be in a scatter gather list, a single +contiguous buffer, or a firmware file. Because allocating contiguous kernel +memory for the buffer should be avoided, users are encouraged to use a scatter +gather list instead if possible. + +The particulars for programming the image are presented in a structure (struct +fpga_image_info). This struct contains parameters such as pointers to the +FPGA image as well as image-specific particulars such as whether the image was +built for full or partial reconfiguration. API Functions: ============== -To program the FPGA from a file or from a buffer: -------------------------------------------------- - - int fpga_mgr_buf_load(struct fpga_manager *mgr, - struct fpga_image_info *info, - const char *buf, size_t count); - -Load the FPGA from an image which exists as a contiguous buffer in -memory. Allocating contiguous kernel memory for the buffer should be avoided, -users are encouraged to use the _sg interface instead of this. - - int fpga_mgr_buf_load_sg(struct fpga_manager *mgr, - struct fpga_image_info *info, - struct sg_table *sgt); +To program the FPGA: +-------------------- -Load the FPGA from an image from non-contiguous in memory. Callers can -construct a sg_table using alloc_page backed memory. + int fpga_mgr_load(struct fpga_manager *mgr, + struct fpga_image_info *info); - int fpga_mgr_firmware_load(struct fpga_manager *mgr, - struct fpga_image_info *info, - const char *image_name); - -Load the FPGA from an image which exists as a file. The image file must be on -the firmware search path (see the firmware class documentation). If successful, +Load the FPGA from an image which is indicated in the info. If successful, the FPGA ends up in operating mode. Return 0 on success or a negative error code. -A FPGA design contained in a FPGA image file will likely have particulars that -affect how the image is programmed to the FPGA. These are contained in struct -fpga_image_info. Currently the only such particular is a single flag bit -indicating whether the image is for full or partial reconfiguration. +To allocate or free a struct fpga_image_info: +--------------------------------------------- + + struct fpga_image_info *fpga_image_info_alloc(struct device *dev); + + void fpga_image_info_free(struct device *dev, + struct fpga_image_info *info); To get/put a reference to a FPGA manager: ----------------------------------------- struct fpga_manager *of_fpga_mgr_get(struct device_node *node); struct fpga_manager *fpga_mgr_get(struct device *dev); + void fpga_mgr_put(struct fpga_manager *mgr); -Given a DT node or device, get an exclusive reference to a FPGA manager. +Given a DT node or device, get a reference to a FPGA manager. This pointer +can be saved until you are ready to program the FPGA. fpga_mgr_put +releases the reference. - void fpga_mgr_put(struct fpga_manager *mgr); -Release the reference. +To get exclusive control of a FPGA manager: +------------------------------------------- + + int fpga_mgr_lock(struct fpga_magager *mgr); + void fpga_mgr_unlock(struct fpga_magager *mgr); + +The user should call fpga_mgr_lock and verify that it returns 0 before +attempting to program the FPGA. Likeqise, the user should call +fpga_mgr_unlock when done programming the FPGA. To register or unregister the low level FPGA-specific driver: ------------------------------------------------------------- int fpga_mgr_register(struct device *dev, const char *name, - const struct fpga_manager_ops *mops, - void *priv); + const struct fpga_manager_ops *mops, + void *priv); void fpga_mgr_unregister(struct device *dev); @@ -78,59 +83,61 @@ How to write an image buffer to a supported FPGA /* Include to get the API */ #include -/* device node that specifies the FPGA manager to use */ -struct device_node *mgr_node = ... +struct fpga_manager *mgr; +struct fpga_image_info *info; +int ret; -/* FPGA image is in this buffer. count is size of the buffer. */ -char *buf = ... -int count = ... +/* + * Get a reference to FPGA manager. This example uses the device node of the + * manager. You could use fpga_mgr_get() instead if you have the device instead + * of the device node. + */ +mgr = of_fpga_mgr_get(mgr_node); /* struct with information about the FPGA image to program. */ -struct fpga_image_info info; +info = fpga_image_info_alloc(dev); /* flags indicates whether to do full or partial reconfiguration */ -info.flags = 0; +info->flags = FPGA_MGR_PARTIAL_RECONFIG; -int ret; +/* + * At this point, indicate where the image is. This is pseudo-code; you're + * probably going to use one of these three. + */ +if (using scatter gather) { -/* Get exclusive control of FPGA manager */ -struct fpga_manager *mgr = of_fpga_mgr_get(mgr_node); + info->sgt = [your scatter gather table] -/* Load the buffer to the FPGA */ -ret = fpga_mgr_buf_load(mgr, &info, buf, count); - -/* Release the FPGA manager */ -fpga_mgr_put(mgr); +} else if (using a buffer) { + info->buf = [your image buffer] + info->count = [image buffer size] -How to write an image file to a supported FPGA -============================================== -/* Include to get the API */ -#include - -/* device node that specifies the FPGA manager to use */ -struct device_node *mgr_node = ... +} else if (using a firmware file) { -/* FPGA image is in this file which is in the firmware search path */ -const char *path = "fpga-image-9.rbf" + info->firmware_name = devm_kstrdup(dev, firmware_name, GFP_KERNEL); -/* struct with information about the FPGA image to program. */ -struct fpga_image_info info; +} else { -/* flags indicates whether to do full or partial reconfiguration */ -info.flags = 0; + not implemented! -int ret; +} /* Get exclusive control of FPGA manager */ -struct fpga_manager *mgr = of_fpga_mgr_get(mgr_node); +ret = fpga_mgr_lock(mgr); -/* Get the firmware image (path) and load it to the FPGA */ -ret = fpga_mgr_firmware_load(mgr, &info, path); +/* Load the buffer to the FPGA */ +ret = fpga_mgr_buf_load(mgr, &info, buf, count); /* Release the FPGA manager */ +fpga_mgr_unlock(mgr); fpga_mgr_put(mgr); +/* Free your image storage in some appropriate way */ +... + +/* Deallocate the image info if you're done with it */ +fpga_image_info_free(dev, info); How to support a new FPGA device ================================ diff --git a/Documentation/fpga/fpga-region.txt b/Documentation/fpga/fpga-region.txt new file mode 100644 index 0000000..9d53559 --- /dev/null +++ b/Documentation/fpga/fpga-region.txt @@ -0,0 +1,54 @@ +FPGA Regions + +Alan Tull 2017 + +An fpga-region represents a reconfigurable region of a FPGA. It could be the +whole FPGA in the case of full reconfiguration or a partial reconfiguration area. + +An fpga-region will know which FPGA manager to use to do the programming as well +as which bridges are involved. The bridges exist to prevent junk data from +going out onto processor busses or out onto FPGA pins during programming. There +are currently a lot of variations of how these can be implemented. Some +implementations will include the bridge in the manager. The FPGA manager may be +fixed hardware in some cases, while other implemenatations have managers as part +of the static region of the FPGA to handle partial reconfiguration. Some +bridges are fixed hardware while other bridges exist in the FPGA fabric as a +ring surrounding the FPGA reconfiguration areas. + +This document is meant to be an overview of API usage. A more conceptual look +at regions can be found in [1]. + +=================== +The FPGA region API +=================== + +To register or unregister a region: +----------------------------------- + + int fpga_region_register(struct device *dev, + struct fpga_region *region); + int fpga_region_unregister(struct fpga_region *region); + +An example of usage can be seen in the probe function of [2] + +To program an FPGA: +------------------- + + int fpga_region_program_fpga(struct fpga_region *region, + struct fpga_image_info *image_info); + +image_info is described in [3] + +This function will attempt to: + * lock the region's mutex + * lock the region's FPGA manager + * build a list of FPGA bridges if a method has been specified to do so + * disable the bridges + * program the FPGA + * re-enable the bridges + * release the locks + +-- +[1] ../devicetree/bindings/fpga/fpga-region.txt +[2] ../../drivers/fpga/of-fpga-region.c +[3] ./fpga-mgr.txt diff --git a/Documentation/fpga/overview.txt b/Documentation/fpga/overview.txt new file mode 100644 index 0000000..149ac8a --- /dev/null +++ b/Documentation/fpga/overview.txt @@ -0,0 +1,23 @@ +Linux kernel FPGA support + +Alan Tull 2017 + +The main point of this project has been to separate the out the upper layers +that know when to reprogram a FPGA from the lower layers that know how to +reprogram a specific FPGA device. The intention is to make this manufacturor +agnostic, understanding that of course the FPGA images are very device specific +themselves. + +At this point it time, the framework in the kernel includes: +* low level FPGA manager drivers that know how to program a specific device +* the fpga-mgr framework they are registered with +* low level FPGA bridge drivers for hard/soft bridges which are intended to + be disable during FPGA programming +* the fpga-bridge framework they are registered with +* the fpga-region framework which associates and controls managers and bridges + as reconfigurable regions +* the of-fpga-region support for reprogramming FPGAs when device tree overlays + are applied. + +I would encourage you the user to add code that creates fpga regions rather +that trying to control managers and bridges separately.