From mboxrd@z Thu Jan 1 00:00:00 1970 From: Chee, Tien Fong Date: Thu, 2 May 2019 07:49:38 +0000 Subject: [U-Boot] [PATCH v12 5/9] ARM: socfpga: Add FPGA drivers for Arria 10 FPGA bitstream loading In-Reply-To: References: <20190319085019.6647-1-tien.fong.chee@intel.com> <20190319085019.6647-6-tien.fong.chee@intel.com> <564c9ef8-5ac0-79f1-f5b0-51b5e1890409@gmail.com> <1556626148.9946.3.camel@intel.com> Message-ID: <1556783376.9984.4.camel@intel.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit To: u-boot@lists.denx.de On Tue, 2019-04-30 at 14:24 +0200, Simon Goldschmidt wrote: > On Tue, Apr 30, 2019 at 2:09 PM Chee, Tien Fong > wrote: > > > > > > On Sat, 2019-04-27 at 21:57 +0200, Simon Goldschmidt wrote: > > > > > > > > > On 19.03.19 09:50, tien.fong.chee at intel.com wrote: > > > > > > > > > > > > From: Tien Fong Chee > > > > > > > > Add FPGA driver to support program FPGA with FPGA bitstream > > > > loading > > > > from > > > > filesystem. The driver are designed based on generic firmware > > > > loader > > > > framework. The driver can handle FPGA program operation from > > > > loading FPGA > > > > bitstream in flash to memory and then to program FPGA. > > > > > > > > Signed-off-by: Tien Fong Chee > > > > > > > > --- > > > > > > > > changes for v12 > > > > - No changes. > > > > > > > > changes for v11 > > > > - No changes. > > > > > > > > changes for v10 > > > > -Cleaned up the codes. > > > > -Return -EPERM when programing core on non early IO release > > > > mode. > > > > > -Using live function to get rid of gd-> > > > You got rid of gd-> in v10? How come I see numerous references to > > > it > > > below? > > get rid of using gd->fdt_blob for finding the node_offset. > > Details in https://patchwork.ozlabs.org/patch/1044415/ > Ah, ok. But still, here you're introducing yet more references to gd- > >fdt_blob. > That wouldn't work with a live tree, either, or would it? Yeah, few direct call to config_pin function are still using gd- fdt_blob as argument. But, i'm not sure i should fix this function in this series patch set, or separately patch after this series patch set? What do you think? Thanks, TF > > > > > > > -/* > > - * FPGA Manager to program the FPGA. This is the interface used by > > FPGA driver. > > - * Return 0 for sucess, non-zero for error. > > - */ > > +ofnode get_fpga_mgr_ofnode(void) > > +{ > > +       int node_offset; > > + > > +       fdtdec_find_aliases_for_id(gd->fdt_blob, "fpga_mgr", > > > > nit: using of live functions would be better to get rid of gd->. > > > > +                               COMPAT_ALTERA_SOCFPGA_FPGA0, > > +                               &node_offset, 1); > > > > Thanks. > > > > > > > > > > > > > > > > > > -Removed @0 for fs-loader node > > > > > > > > changes for v9 > > > > - Support data offset > > > > - Added default DDR load address > > > > - Squashed the image.h > > > > - Changed to phandle > > > > - Ensure the DDR is fully up running by checking the gd->ram > > > > > > > > changes for v8 > > > > - Added codes to discern bitstream type based on fpga node > > > > name. > > > > > > > > changes for v7 > > > > - Restructure the FPGA driver to support both peripheral > > > > bitstream > > > > and core > > > >    bitstream bundled into FIT image. > > > > - Support loadable property for core bitstream. User can set > > > > loadable > > > >    in DDR for better performance. This loading would be done in > > > > one > > > > large > > > >    chunk instead of chunk by chunk loading with small memory > > > > buffer. > > > > --- > > > >   arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts       |  17 + > > > >   .../include/mach/fpga_manager_arria10.h            |  39 +- > > > >   drivers/fpga/socfpga_arria10.c                     | 497 > > > > ++++++++++++++++++++- > > > >   include/image.h                                    |   4 + > > > >   4 files changed, 542 insertions(+), 15 deletions(-) > > > > > > > > diff --git a/arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts > > > > b/arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts > > > > index 998d811210..cc761967c7 100644 > > > > --- a/arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts > > > > +++ b/arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts > > > > @@ -18,6 +18,23 @@ > > > >   /dts-v1/; > > > >   #include "socfpga_arria10_socdk.dtsi" > > > > > > > > +/ { > > > > +   chosen { > > > > +           firmware-loader = <&fs_loader0>; > > > > +   }; > > > > + > > > > +   fs_loader0: fs-loader { > > > > +           u-boot,dm-pre-reloc; > > > > +           compatible = "u-boot,fs-loader"; > > > > +           phandlepart = <&mmc 1>; > > > > +   }; > > > > +}; > > > > + > > > > +&fpga_mgr { > > > > +   u-boot,dm-pre-reloc; > > > > +   altr,bitstream = "fit_spl_fpga.itb"; > > > > +}; > > > > + > > > >   &mmc { > > > >     u-boot,dm-pre-reloc; > > > >     status = "okay"; > > > > diff --git a/arch/arm/mach- > > > > socfpga/include/mach/fpga_manager_arria10.h b/arch/arm/mach- > > > > socfpga/include/mach/fpga_manager_arria10.h > > > > index 09d13f6fd3..c5f67714aa 100644 > > > > --- a/arch/arm/mach-socfpga/include/mach/fpga_manager_arria10.h > > > > +++ b/arch/arm/mach-socfpga/include/mach/fpga_manager_arria10.h > > > > @@ -1,9 +1,13 @@ > > > >   /* SPDX-License-Identifier: GPL-2.0 */ > > > >   /* > > > > - * Copyright (C) 2017 Intel Corporation > > > > + * Copyright (C) 2017-2019 Intel Corporation > > > >    * All rights reserved. > > > >    */ > > > > > > > > +#include > > > > +#include > > > > +#include > > > > + > > > >   #ifndef _FPGA_MANAGER_ARRIA10_H_ > > > >   #define _FPGA_MANAGER_ARRIA10_H_ > > > > > > > > @@ -51,6 +55,10 @@ > > > >   #define ALT_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH_SET_MSK > > > > BIT(24) > > > >   #define ALT_FPGAMGR_IMGCFG_CTL_02_CDRATIO_LSB > > > > 16 > > > > > > > > +#define FPGA_SOCFPGA_A10_RBF_UNENCRYPTED   0xa65c > > > > +#define FPGA_SOCFPGA_A10_RBF_ENCRYPTED             0xa65d > > > > +#define FPGA_SOCFPGA_A10_RBF_PERIPH                0x0001 > > > > +#define FPGA_SOCFPGA_A10_RBF_CORE          0x8001 > > > >   #ifndef __ASSEMBLY__ > > > > > > > >   struct socfpga_fpga_manager { > > > > @@ -88,12 +96,39 @@ struct socfpga_fpga_manager { > > > >     u32  imgcfg_fifo_status; > > > >   }; > > > > > > > > +enum rbf_type { > > > > +   unknown, > > > > +   periph_section, > > > > +   core_section > > > > +}; > > > > + > > > > +enum rbf_security { > > > > +   invalid, > > > > +   unencrypted, > > > > +   encrypted > > > > +}; > > > > + > > > > +struct rbf_info { > > > > +   enum rbf_type section; > > > > +   enum rbf_security security; > > > > +}; > > > > + > > > > +struct fpga_loadfs_info { > > > > +   fpga_fs_info *fpga_fsinfo; > > > > +   u32 remaining; > > > > +   u32 offset; > > > > +   struct rbf_info rbfinfo; > > > > +}; > > > > + > > > >   /* Functions */ > > > >   int fpgamgr_program_init(u32 * rbf_data, size_t rbf_size); > > > >   int fpgamgr_program_finish(void); > > > >   int is_fpgamgr_user_mode(void); > > > >   int fpgamgr_wait_early_user_mode(void); > > > > - > > > > +const char *get_fpga_filename(void); > > > > +int socfpga_loadfs(fpga_fs_info *fpga_fsinfo, const void *buf, > > > > size_t bsize, > > > > +             u32 offset); > > > > +void fpgamgr_program(const void *buf, size_t bsize, u32 > > > > offset); > > > >   #endif /* __ASSEMBLY__ */ > > > > > > > >   #endif /* _FPGA_MANAGER_ARRIA10_H_ */ > > > > diff --git a/drivers/fpga/socfpga_arria10.c > > > > b/drivers/fpga/socfpga_arria10.c > > > > index 9499d1a014..9df2c430d7 100644 > > > > --- a/drivers/fpga/socfpga_arria10.c > > > > +++ b/drivers/fpga/socfpga_arria10.c > > > > @@ -1,8 +1,7 @@ > > > >   // SPDX-License-Identifier: GPL-2.0 > > > >   /* > > > > - * Copyright (C) 2017 Intel Corporation > > > > + * Copyright (C) 2017-2019 Intel Corporation > > > >    */ > > > > - > > > >   #include > > > >   #include > > > >   #include > > > > @@ -10,8 +9,11 @@ > > > >   #include > > > >   #include > > > >   #include > > > > +#include > > > >   #include > > > > +#include > > > >   #include > > > > +#include > > > >   #include > > > >   #include > > > > > > > > @@ -21,6 +23,9 @@ > > > >   #define COMPRESSION_OFFSET        229 > > > >   #define FPGA_TIMEOUT_MSEC 1000  /* timeout in ms */ > > > >   #define FPGA_TIMEOUT_CNT  0x1000000 > > > > +#define DEFAULT_DDR_LOAD_ADDRESS   0x400 > > > > + > > > > +DECLARE_GLOBAL_DATA_PTR; > > > > > > > >   static const struct socfpga_fpga_manager *fpga_manager_base = > > > >             (void *)SOCFPGA_FPGAMGRREGS_ADDRESS; > > > > @@ -448,13 +453,461 @@ int fpgamgr_program_finish(void) > > > >     return 0; > > > >   } > > > > > > > > -/* > > > > - * FPGA Manager to program the FPGA. This is the interface > > > > used by > > > > FPGA driver. > > > > - * Return 0 for sucess, non-zero for error. > > > > - */ > > > > +ofnode get_fpga_mgr_ofnode(ofnode from) > > > > +{ > > > > +   return ofnode_by_compatible(from, "altr,socfpga-a10-fpga- > > > > mgr"); > > > > +} > > > > + > > > > +const char *get_fpga_filename(void) > > > > +{ > > > > +   const char *fpga_filename = NULL; > > > > + > > > > +   ofnode fpgamgr_node = get_fpga_mgr_ofnode(ofnode_null()); > > > > + > > > > +   if (ofnode_valid(fpgamgr_node)) > > > > +           fpga_filename = ofnode_read_string(fpgamgr_node, > > > > +                                           "altr,bitstream"); > > > > + > > > > +   return fpga_filename; > > > > +} > > > > + > > > > +static void get_rbf_image_info(struct rbf_info *rbf, u16 > > > > *buffer) > > > > +{ > > > > +   /* > > > > +    * Magic ID starting at: > > > > +    * -> 1st dword[15:0] in periph.rbf > > > > +    * -> 2nd dword[15:0] in core.rbf > > > > +    * Note: dword == 32 bits > > > > +    */ > > > > +   u32 word_reading_max = 2; > > > > +   u32 i; > > > > + > > > > +   for (i = 0; i < word_reading_max; i++) { > > > > +           if (*(buffer + i) == > > > > FPGA_SOCFPGA_A10_RBF_UNENCRYPTED) { > > > > +                   rbf->security = unencrypted; > > > > +           } else if (*(buffer + i) == > > > > FPGA_SOCFPGA_A10_RBF_ENCRYPTED) { > > > > +                   rbf->security = encrypted; > > > > +           } else if (*(buffer + i + 1) == > > > > +                           FPGA_SOCFPGA_A10_RBF_UNENCRYPTED) > > > > { > > > > +                   rbf->security = unencrypted; > > > > +           } else if (*(buffer + i + 1) == > > > > +                           FPGA_SOCFPGA_A10_RBF_ENCRYPTED) { > > > > +                   rbf->security = encrypted; > > > > +           } else { > > > > +                   rbf->security = invalid; > > > > +                   continue; > > > > +           } > > > > + > > > > +           /* PERIPH RBF(buffer + i + 1), CORE RBF(buffer + i > > > > + 2) */ > > > > +           if (*(buffer + i + 1) == > > > > FPGA_SOCFPGA_A10_RBF_PERIPH) { > > > > +                   rbf->section = periph_section; > > > > +                   break; > > > > +           } else if (*(buffer + i + 1) == > > > > FPGA_SOCFPGA_A10_RBF_CORE) { > > > > +                   rbf->section = core_section; > > > > +                   break; > > > > +           } else if (*(buffer + i + 2) == > > > > FPGA_SOCFPGA_A10_RBF_PERIPH) { > > > > +                   rbf->section = periph_section; > > > > +                   break; > > > > +           } else if (*(buffer + i + 2) == > > > > FPGA_SOCFPGA_A10_RBF_CORE) { > > > > +                   rbf->section = core_section; > > > > +                   break; > > > > +           } > > > > + > > > > +           rbf->section = unknown; > > > > +           break; > > > > + > > > > +           WATCHDOG_RESET(); > > > > +   } > > > > +} > > > > + > > > > +#ifdef CONFIG_FS_LOADER > > > > +static int first_loading_rbf_to_buffer(struct udevice *dev, > > > > +                           struct fpga_loadfs_info > > > > *fpga_loadfs, > > > > +                           u32 *buffer, size_t *buffer_bsize) > > > > +{ > > > > +   u32 *buffer_p = (u32 *)*buffer; > > > > +   u32 *loadable = buffer_p; > > > > +   size_t buffer_size = *buffer_bsize; > > > > +   size_t fit_size; > > > > +   int ret, i, count, confs_noffset, images_noffset, > > > > rbf_offset, rbf_size; > > > > +   const char *fpga_node_name = NULL; > > > > +   const char *uname = NULL; > > > > + > > > > +   /* Load image header into buffer */ > > > > +   ret = request_firmware_into_buf(dev, > > > > +                                   fpga_loadfs->fpga_fsinfo- > > > > > > > > > > filename, > > > > +                                   buffer_p, sizeof(struct > > > > image_header), > > > > +                                   0); > > > > +   if (ret < 0) { > > > > +           debug("FPGA: Failed to read image header from > > > > flash.\n"); > > > > +           return -ENOENT; > > > > +   } > > > > + > > > > +   if (image_get_magic((struct image_header *)buffer_p) != > > > > FDT_MAGIC) { > > > > +           debug("FPGA: No FDT magic was found.\n"); > > > > +           return -EBADF; > > > > +   } > > > > + > > > > +   fit_size = fdt_totalsize(buffer_p); > > > > + > > > > +   if (fit_size > buffer_size) { > > > > +           debug("FPGA: FIT image is larger than available > > > > buffer.\n"); > > > > +           debug("Please use FIT external data or increasing > > > > buffer.\n"); > > > > +           return -ENOMEM; > > > > +   } > > > > + > > > > +   /* Load entire FIT into buffer */ > > > > +   ret = request_firmware_into_buf(dev, > > > > +                                   fpga_loadfs->fpga_fsinfo- > > > > > > > > > > filename, > > > > +                                   buffer_p, fit_size, 0); > > > > +   if (ret < 0) > > > > +           return ret; > > > > + > > > > +   ret = fit_check_format(buffer_p); > > > > +   if (!ret) { > > > > +           debug("FPGA: No valid FIT image was found.\n"); > > > > +           return -EBADF; > > > > +   } > > > > + > > > > +   confs_noffset = fdt_path_offset(buffer_p, FIT_CONFS_PATH); > > > > +   images_noffset = fdt_path_offset(buffer_p, > > > > FIT_IMAGES_PATH); > > > > +   if (confs_noffset < 0 || images_noffset < 0) { > > > > +           debug("FPGA: No Configurations or images nodes > > > > were found.\n"); > > > > +           return -ENOENT; > > > > +   } > > > > + > > > > +   /* Get default configuration unit name from default > > > > property */ > > > > +   confs_noffset = fit_conf_get_node(buffer_p, NULL); > > > > +   if (confs_noffset < 0) { > > > > +           debug("FPGA: No default configuration was found in > > > > config.\n"); > > > > +           return -ENOENT; > > > > +   } > > > > + > > > > +   count = fit_conf_get_prop_node_count(buffer_p, > > > > confs_noffset, > > > > +                                       FIT_FPGA_PROP); > > > > +   if (count < 0) { > > > > +           debug("FPGA: Invalid configuration format for FPGA > > > > node.\n"); > > > > +           return count; > > > > +   } > > > > +   debug("FPGA: FPGA node count: %d\n", count); > > > > + > > > > +   for (i = 0; i < count; i++) { > > > > +           images_noffset = > > > > fit_conf_get_prop_node_index(buffer_p, > > > > +                                                        confs > > > > _noffset, > > > > +                                                        FIT_F > > > > PGA_PROP, i); > > > > +           uname = fit_get_name(buffer_p, images_noffset, > > > > NULL); > > > > +           if (uname) { > > > > +                   debug("FPGA: %s\n", uname); > > > > + > > > > +                   if (strstr(uname, "fpga-periph") && > > > > +                           (!is_fpgamgr_early_user_mode() || > > > > +                           is_fpgamgr_user_mode())) { > > > > +                           fpga_node_name = uname; > > > > +                           printf("FPGA: Start to program "); > > > > +                           printf("peripheral/full bitstream > > > > ...\n"); > > > > +                           break; > > > > +                   } else if (strstr(uname, "fpga-core") && > > > > +                                   (is_fpgamgr_early_user_mod > > > > e() && > > > > +                                   !is_fpgamgr_user_mode())) > > > > { > > > > +                           fpga_node_name = uname; > > > > +                           printf("FPGA: Start to program > > > > core "); > > > > +                           printf("bitstream ...\n"); > > > > +                           break; > > > > +                   } > > > > +           } > > > > +           WATCHDOG_RESET(); > > > > +   } > > > > + > > > > +   if (!fpga_node_name) { > > > > +           debug("FPGA: No suitable bitstream was found, > > > > count: %d.\n", i); > > > > +           return 1; > > > > +   } > > > > + > > > > +   images_noffset = fit_image_get_node(buffer_p, > > > > fpga_node_name); > > > > +   if (images_noffset < 0) { > > > > +           debug("FPGA: No node '%s' was found in FIT.\n", > > > > +                fpga_node_name); > > > > +           return -ENOENT; > > > > +   } > > > > + > > > > +   if (!fit_image_get_data_position(buffer_p, images_noffset, > > > > +                                   &rbf_offset)) { > > > > +           debug("FPGA: Data position was found.\n"); > > > > +   } else if (!fit_image_get_data_offset(buffer_p, > > > > images_noffset, > > > > +             &rbf_offset)) { > > > > +           /* > > > > +            * For FIT with external data, figure out where > > > > +            * the external images start. This is the base > > > > +            * for the data-offset properties in each image. > > > > +            */ > > > > +           rbf_offset += ((fdt_totalsize(buffer_p) + 3) & > > > > ~3); > > > > +           debug("FPGA: Data offset was found.\n"); > > > > +   } else { > > > > +           debug("FPGA: No data position/offset was > > > > found.\n"); > > > > +           return -ENOENT; > > > > +   } > > > > + > > > > +   ret = fit_image_get_data_size(buffer_p, images_noffset, > > > > &rbf_size); > > > > +   if (ret < 0) { > > > > +           debug("FPGA: No data size was found (err=%d).\n", > > > > ret); > > > > +           return -ENOENT; > > > > +   } > > > > + > > > > +   if (gd->ram_size < rbf_size) { > > > > +           debug("FPGA: Using default OCRAM buffer and > > > > size.\n"); > > > > +   } else { > > > > +           ret = fit_image_get_load(buffer_p, images_noffset, > > > > +                                   (ulong *)loadable); > > > > +           if (ret < 0) { > > > > +                   buffer_p = (u32 > > > > *)DEFAULT_DDR_LOAD_ADDRESS; > > > > +                   debug("FPGA: No loadable was found.\n"); > > > > +                   debug("FPGA: Using default DDR load > > > > address: 0x%x .\n", > > > > +                        DEFAULT_DDR_LOAD_ADDRESS); > > > > +           } else { > > > > +                   buffer_p = (u32 *)*loadable; > > > > +                   debug("FPGA: Found loadable address = > > > > 0x%x.\n", > > > > +                        *loadable); > > > > +           } > > > > + > > > > +           buffer_size = rbf_size; > > > > +   } > > > > + > > > > +   debug("FPGA: External data: offset = 0x%x, size = > > > > 0x%x.\n", > > > > +         rbf_offset, rbf_size); > > > > + > > > > +   fpga_loadfs->remaining = rbf_size; > > > > + > > > > +   /* > > > > +    * Determine buffer size vs bitstream size, and > > > > calculating number of > > > > +    * chunk by chunk transfer is required due to smaller > > > > buffer size > > > > +    * compare to bitstream > > > > +    */ > > > > +   if (rbf_size <= buffer_size) { > > > > +           /* Loading whole bitstream into buffer */ > > > > +           buffer_size = rbf_size; > > > > +           fpga_loadfs->remaining = 0; > > > > +   } else { > > > > +           fpga_loadfs->remaining -= buffer_size; > > > > +   } > > > > + > > > > +   fpga_loadfs->offset = rbf_offset; > > > > +   /* Loading bitstream into buffer */ > > > > +   ret = request_firmware_into_buf(dev, > > > > +                                   fpga_loadfs->fpga_fsinfo- > > > > > > > > > > filename, > > > > +                                   buffer_p, buffer_size, > > > > +                                   fpga_loadfs->offset); > > > > +   if (ret < 0) { > > > > +           debug("FPGA: Failed to read bitstream from > > > > flash.\n"); > > > > +           return -ENOENT; > > > > +   } > > > > + > > > > +   /* Getting info about bitstream types */ > > > > +   get_rbf_image_info(&fpga_loadfs->rbfinfo, (u16 > > > > *)buffer_p); > > > > + > > > > +   /* Update next reading bitstream offset */ > > > > +   fpga_loadfs->offset += buffer_size; > > > > + > > > > +   /* Update the final addr for bitstream */ > > > > +   *buffer = (u32)buffer_p; > > > > + > > > > +   /* Update the size of bitstream to be programmed into FPGA > > > > */ > > > > +   *buffer_bsize = buffer_size; > > > > + > > > > +   return 0; > > > > +} > > > > + > > > > +static int subsequent_loading_rbf_to_buffer(struct udevice > > > > *dev, > > > > +                                   struct fpga_loadfs_info > > > > *fpga_loadfs, > > > > +                                   u32 *buffer, size_t > > > > *buffer_bsize) > > > > +{ > > > > +   int ret = 0; > > > > +   u32 *buffer_p = (u32 *)*buffer; > > > > + > > > > +   /* Read the bitstream chunk by chunk. */ > > > > +   if (fpga_loadfs->remaining > *buffer_bsize) { > > > > +           fpga_loadfs->remaining -= *buffer_bsize; > > > > +   } else { > > > > +           *buffer_bsize = fpga_loadfs->remaining; > > > > +           fpga_loadfs->remaining = 0; > > > > +   } > > > > + > > > > +   ret = request_firmware_into_buf(dev, > > > > +                                   fpga_loadfs->fpga_fsinfo- > > > > > > > > > > filename, > > > > +                                   buffer_p, *buffer_bsize, > > > > +                                   fpga_loadfs->offset); > > > > +   if (ret < 0) { > > > > +           debug("FPGA: Failed to read bitstream from > > > > flash.\n"); > > > > +           return -ENOENT; > > > > +   } > > > > + > > > > +   /* Update next reading bitstream offset */ > > > > +   fpga_loadfs->offset += *buffer_bsize; > > > > + > > > > +   return 0; > > > > +} > > > > + > > > > +int socfpga_loadfs(fpga_fs_info *fpga_fsinfo, const void *buf, > > > > size_t bsize, > > > > +                   u32 offset) > > > > +{ > > > > +   struct fpga_loadfs_info fpga_loadfs; > > > > +   struct udevice *dev; > > > > +   int status, ret, size; > > > > +   u32 buffer = (uintptr_t)buf; > > > > +   size_t buffer_sizebytes = bsize; > > > > +   size_t buffer_sizebytes_ori = bsize; > > > > +   size_t total_sizeof_image = 0; > > > > +   ofnode node; > > > > +   const fdt32_t *phandle_p; > > > > +   u32 phandle; > > > > + > > > > +   node = get_fpga_mgr_ofnode(ofnode_null()); > > > > + > > > > +   if (ofnode_valid(node)) { > > > > +           phandle_p = ofnode_get_property(node, "firmware- > > > > loader", &size); > > > > +           if (!phandle_p) { > > > > +                   node = ofnode_path("/chosen"); > > > > +                   if (!ofnode_valid(node)) { > > > > +                           debug("FPGA: /chosen node was not > > > > found.\n"); > > > > +                           return -ENOENT; > > > > +                   } > > > > + > > > > +                   phandle_p = ofnode_get_property(node, > > > > "firmware-loader", > > > > +                                                  &size); > > > > +                   if (!phandle_p) { > > > > +                           debug("FPGA: firmware-loader > > > > property was not"); > > > > +                           debug(" found.\n"); > > > > +                           return -ENOENT; > > > > +                   } > > > > +           } > > > > +   } else { > > > > +           debug("FPGA: FPGA manager node was not found.\n"); > > > > +           return -ENOENT; > > > > +   } > > > > + > > > > +   phandle = fdt32_to_cpu(*phandle_p); > > > > +   ret = > > > > uclass_get_device_by_phandle_id(UCLASS_FS_FIRMWARE_LOADER, > > > > +                                        phandle, &dev); > > > > +   if (ret) > > > > +           return ret; > > > > + > > > > +   memset(&fpga_loadfs, 0, sizeof(fpga_loadfs)); > > > > + > > > > +   fpga_loadfs.fpga_fsinfo = fpga_fsinfo; > > > > +   fpga_loadfs.offset = offset; > > > > + > > > > +   printf("FPGA: Checking FPGA configuration setting ...\n"); > > > > + > > > > +   /* > > > > +    * Note: Both buffer and buffer_sizebytes values can be > > > > altered by > > > > +    * function below. > > > > +    */ > > > > +   ret = first_loading_rbf_to_buffer(dev, &fpga_loadfs, > > > > &buffer, > > > > +                                      &buffer_sizebytes); > > > > +   if (ret == 1) { > > > > +           printf("FPGA: Skipping configuration ...\n"); > > > > +           return 0; > > > > +   } else if (ret) { > > > > +           return ret; > > > > +   } > > > > + > > > > +   if (fpga_loadfs.rbfinfo.section == core_section && > > > > +           !(is_fpgamgr_early_user_mode() && > > > > !is_fpgamgr_user_mode())) { > > > > +           debug("FPGA : Must be in Early Release mode to > > > > program "); > > > > +           debug("core bitstream.\n"); > > > > +           return -EPERM; > > > > +   } > > > > + > > > > +   /* Disable all signals from HPS peripheral controller to > > > > FPGA */ > > > > +   writel(0, &system_manager_base->fpgaintf_en_global); > > > > + > > > > +   /* Disable all axi bridges (hps2fpga, lwhps2fpga & > > > > fpga2hps) */ > > > > +   socfpga_bridges_reset(); > > > > + > > > > +   if (fpga_loadfs.rbfinfo.section == periph_section) { > > > > +           /* Initialize the FPGA Manager */ > > > > +           status = fpgamgr_program_init((u32 *)buffer, > > > > buffer_sizebytes); > > > > +           if (status) { > > > > +                   debug("FPGA: Init with peripheral > > > > bitstream failed.\n"); > > > > +                   return -EPERM; > > > > +           } > > > > +   } > > > > + > > > > +   /* Transfer bitstream to FPGA Manager */ > > > > +   fpgamgr_program_write((void *)buffer, buffer_sizebytes); > > > > + > > > > +   total_sizeof_image += buffer_sizebytes; > > > > + > > > > +   while (fpga_loadfs.remaining) { > > > > +           ret = subsequent_loading_rbf_to_buffer(dev, > > > > +                                                   &fpga_load > > > > fs, > > > > +                                                   &buffer, > > > > +                                                   &buffer_si > > > > zebytes_ori); > > > > + > > > > +           if (ret) > > > > +                   return ret; > > > > + > > > > +           /* Transfer data to FPGA Manager */ > > > > +           fpgamgr_program_write((void *)buffer, > > > > +                                   buffer_sizebytes_ori); > > > > + > > > > +           total_sizeof_image += buffer_sizebytes_ori; > > > > + > > > > +           WATCHDOG_RESET(); > > > > +   } > > > > + > > > > +   if (fpga_loadfs.rbfinfo.section == periph_section) { > > > > +           if (fpgamgr_wait_early_user_mode() != -ETIMEDOUT) > > > > { > > > > +                   config_pins(gd->fdt_blob, "shared"); > > > > +                   puts("FPGA: Early Release Succeeded.\n"); > > > > +           } else { > > > > +                   debug("FPGA: Failed to see Early > > > > Release.\n"); > > > > +                   return -EIO; > > > > +           } > > > > + > > > > +           /* For monolithic bitstream */ > > > > +           if (is_fpgamgr_user_mode()) { > > > > +                   /* Ensure the FPGA entering config done */ > > > > +                   status = fpgamgr_program_finish(); > > > > +                   if (status) > > > > +                           return status; > > > > + > > > > +                   config_pins(gd->fdt_blob, "fpga"); > > > > +                   puts("FPGA: Enter user mode.\n"); > > > > +           } > > > > +   } else if (fpga_loadfs.rbfinfo.section == core_section) { > > > > +           /* Ensure the FPGA entering config done */ > > > > +           status = fpgamgr_program_finish(); > > > > +           if (status) > > > > +                   return status; > > > > + > > > > +           config_pins(gd->fdt_blob, "fpga"); > > > > +           puts("FPGA: Enter user mode.\n"); > > > > +   } else { > > > > +           debug("FPGA: Config Error: Unsupported bitstream > > > > type.\n"); > > > > +           return -ENOEXEC; > > > > +   } > > > > + > > > > +   return (int)total_sizeof_image; > > > > +} > > > > + > > > > +void fpgamgr_program(const void *buf, size_t bsize, u32 > > > > offset) > > > > +{ > > > > +   fpga_fs_info fpga_fsinfo; > > > > + > > > > +   fpga_fsinfo.filename = get_fpga_filename(); > > > > + > > > > +   if (fpga_fsinfo.filename) > > > > +           socfpga_loadfs(&fpga_fsinfo, buf, bsize, offset); > > > > +} > > > > +#endif > > > > + > > > > +/* This function is used to load the core bitstream from the > > > > OCRAM. */ > > > >   int socfpga_load(Altera_desc *desc, const void *rbf_data, > > > > size_t > > > > rbf_size) > > > >   { > > > > -   int status; > > > > +   unsigned long status; > > > > +   struct rbf_info rbfinfo; > > > > + > > > > +   memset(&rbfinfo, 0, sizeof(rbfinfo)); > > > > > > > >     /* Disable all signals from hps peripheral controller to > > > > fpga */ > > > >     writel(0, &system_manager_base->fpgaintf_en_global); > > > > @@ -462,13 +915,31 @@ int socfpga_load(Altera_desc *desc, const > > > > void *rbf_data, size_t rbf_size) > > > >     /* Disable all axi bridge (hps2fpga, lwhps2fpga & > > > > fpga2hps) */ > > > >     socfpga_bridges_reset(); > > > > > > > > -   /* Initialize the FPGA Manager */ > > > > -   status = fpgamgr_program_init((u32 *)rbf_data, rbf_size); > > > > -   if (status) > > > > -           return status; > > > > +   /* Getting info about bitstream types */ > > > > +   get_rbf_image_info(&rbfinfo, (u16 *)rbf_data); > > > > + > > > > +   if (rbfinfo.section == periph_section) { > > > > +           /* Initialize the FPGA Manager */ > > > > +           status = fpgamgr_program_init((u32 *)rbf_data, > > > > rbf_size); > > > > +           if (status) > > > > +                   return status; > > > > +   } > > > > > > > > -   /* Write the RBF data to FPGA Manager */ > > > > +   if (rbfinfo.section == core_section && > > > > +           !(is_fpgamgr_early_user_mode() && > > > > !is_fpgamgr_user_mode())) { > > > > +           debug("FPGA : Must be in early release mode to > > > > program "); > > > > +           debug("core bitstream.\n"); > > > > +           return -EPERM; > > > > +   } > > > > + > > > > +   /* Write the bitstream to FPGA Manager */ > > > >     fpgamgr_program_write(rbf_data, rbf_size); > > > > > > > > -   return fpgamgr_program_finish(); > > > > +   status = fpgamgr_program_finish(); > > > > +   if (status) { > > > > +           config_pins(gd->fdt_blob, "fpga"); > > > > +           puts("FPGA: Enter user mode.\n"); > > > > +   } > > > > + > > > > +   return status; > > > >   } > > > > diff --git a/include/image.h b/include/image.h > > > > index 765ffecee0..cc976f70ce 100644 > > > > --- a/include/image.h > > > > +++ b/include/image.h > > > > @@ -1046,6 +1046,10 @@ int fit_check_format(const void *fit); > > > > > > > >   int fit_conf_find_compat(const void *fit, const void *fdt); > > > >   int fit_conf_get_node(const void *fit, const char > > > > *conf_uname); > > > > +int fit_conf_get_prop_node_count(const void *fit, int noffset, > > > > +           const char *prop_name); > > > > +int fit_conf_get_prop_node_index(const void *fit, int noffset, > > > > +           const char *prop_name, int index); > > > > > > > >   /** > > > >    * fit_conf_get_prop_node() - Get node refered to by a > > > > configuration > > > >