| From 66eb655c5286bd01e7fbe9db237ed4cbde6c4857 Mon Sep 17 00:00:00 2001 |
| From: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> |
| Date: Tue, 22 Nov 2016 18:22:09 +0000 |
| Subject: [PATCH 040/103] fpga: Clarify how write_init works streaming modes |
| |
| This interface was designed for streaming, but write_init's buf |
| argument has an unclear purpose. Define it to be the first bytes |
| of the bitstream. Each driver gets to set how many bytes (at most) |
| it wants to see. Short bitstreams will be passed through as-is, while |
| long ones will be truncated. |
| |
| The intent is to allow drivers to peek at the header before the transfer |
| actually starts. |
| |
| Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> |
| Acked-by: Alan Tull <atull@opensource.altera.com> |
| --- |
| Documentation/fpga/fpga-mgr.txt | 5 ++++- |
| drivers/fpga/fpga-mgr.c | 6 ++++-- |
| drivers/fpga/socfpga-a10.c | 1 + |
| include/linux/fpga/fpga-mgr.h | 2 ++ |
| 4 files changed, 11 insertions(+), 3 deletions(-) |
| |
| --- a/Documentation/fpga/fpga-mgr.txt |
| +++ b/Documentation/fpga/fpga-mgr.txt |
| @@ -169,7 +169,10 @@ The programming sequence is: |
| 2. .write (may be called once or multiple times) |
| 3. .write_complete |
| |
| -The .write_init function will prepare the FPGA to receive the image data. |
| +The .write_init function will prepare the FPGA to receive the image data. The |
| +buffer passed into .write_init will be atmost .initial_header_size bytes long, |
| +if the whole bitstream is not immediately available then the core code will |
| +buffer up at least this much before starting. |
| |
| The .write function writes a buffer to the FPGA. The buffer may be contain the |
| whole FPGA image or may be a smaller chunk of an FPGA image. In the latter |
| --- a/drivers/fpga/fpga-mgr.c |
| +++ b/drivers/fpga/fpga-mgr.c |
| @@ -53,10 +53,12 @@ int fpga_mgr_buf_load(struct fpga_manage |
| /* |
| * Call the low level driver's write_init function. This will do the |
| * device-specific things to get the FPGA into the state where it is |
| - * ready to receive an FPGA image. |
| + * ready to receive an FPGA image. The low level driver only gets to |
| + * see the first initial_header_size bytes in the buffer. |
| */ |
| mgr->state = FPGA_MGR_STATE_WRITE_INIT; |
| - ret = mgr->mops->write_init(mgr, info, buf, count); |
| + ret = mgr->mops->write_init(mgr, info, buf, |
| + min(mgr->mops->initial_header_size, count)); |
| if (ret) { |
| dev_err(dev, "Error preparing FPGA for writing\n"); |
| mgr->state = FPGA_MGR_STATE_WRITE_INIT_ERR; |
| --- a/drivers/fpga/socfpga-a10.c |
| +++ b/drivers/fpga/socfpga-a10.c |
| @@ -470,6 +470,7 @@ static enum fpga_mgr_states socfpga_a10_ |
| } |
| |
| static const struct fpga_manager_ops socfpga_a10_fpga_mgr_ops = { |
| + .initial_header_size = (RBF_DECOMPRESS_OFFSET + 1) * 4, |
| .state = socfpga_a10_fpga_state, |
| .write_init = socfpga_a10_fpga_write_init, |
| .write = socfpga_a10_fpga_write, |
| --- a/include/linux/fpga/fpga-mgr.h |
| +++ b/include/linux/fpga/fpga-mgr.h |
| @@ -84,6 +84,7 @@ struct fpga_image_info { |
| |
| /** |
| * struct fpga_manager_ops - ops for low level fpga manager drivers |
| + * @initial_header_size: Maximum number of bytes that should be passed into write_init |
| * @state: returns an enum value of the FPGA's state |
| * @write_init: prepare the FPGA to receive confuration data |
| * @write: write count bytes of configuration data to the FPGA |
| @@ -95,6 +96,7 @@ struct fpga_image_info { |
| * called, so leaving them out is fine. |
| */ |
| struct fpga_manager_ops { |
| + size_t initial_header_size; |
| enum fpga_mgr_states (*state)(struct fpga_manager *mgr); |
| int (*write_init)(struct fpga_manager *mgr, |
| struct fpga_image_info *info, |