On 19. 02. 19 4:47, tien.fong.c...@intel.com wrote: > From: Tien Fong Chee <tien.fong.c...@intel.com> > > 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 <tien.fong.c...@intel.com> > > --- > > 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 | 40 +- > drivers/fpga/socfpga_arria10.c | 533 > ++++++++++++++++++++- > include/image.h | 4 + > 4 files changed, 571 insertions(+), 23 deletions(-) > > diff --git a/arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts > b/arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts > index 998d811..9d43111 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@0 {
again @0 without reg properly is wrong. > + u-boot,dm-pre-reloc; > + compatible = "u-boot,fs-loader"; > + phandlepart = <&mmc 1>; > + }; I think that this will be nacked by DT guys. > +}; > + > +&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 09d13f6..7a4f723 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 <www.intel.com> > + * Copyright (C) 2017-2019 Intel Corporation <www.intel.com> > * All rights reserved. > */ > > +#include <asm/cache.h> > +#include <altera.h> > +#include <image.h> > + > #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,40 @@ 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); > - > +int is_fpgamgr_early_user_mode(void); > +const char *get_fpga_filename(const void *fdt, int *len); > +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 114dd91..9936b69 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 <www.intel.com> > + * Copyright (C) 2017-2019 Intel Corporation <www.intel.com> > */ > - > #include <asm/io.h> > #include <asm/arch/fpga_manager.h> > #include <asm/arch/reset_manager.h> > @@ -10,8 +9,11 @@ > #include <asm/arch/sdram.h> > #include <asm/arch/misc.h> > #include <altera.h> > +#include <asm/arch/pinmux.h> > #include <common.h> > +#include <dm/ofnode.h> > #include <errno.h> > +#include <fs_loader.h> > #include <wait_bit.h> > #include <watchdog.h> > > @@ -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; > @@ -64,7 +69,7 @@ static int wait_for_user_mode(void) > 1, FPGA_TIMEOUT_MSEC, false); > } > > -static int is_fpgamgr_early_user_mode(void) > +int is_fpgamgr_early_user_mode(void) This is called inside the same file that's why no reason for this change. Maybe you are using that later but it just suggest incorrect split. > { > return (readl(&fpga_manager_base->imgcfg_stat) & > ALT_FPGAMGR_IMGCFG_STAT_F2S_EARLY_USERMODE_SET_MSK) != 0; > @@ -94,7 +99,7 @@ int fpgamgr_wait_early_user_mode(void) > i++; > } > > - debug("Additional %i sync word needed\n", i); > + debug("FPGA: Additional %i sync word needed\n", i); it should be separate patch. > > /* restoring original CDRATIO */ > fpgamgr_set_cd_ratio(cd_ratio); > @@ -172,9 +177,10 @@ static int fpgamgr_set_cdratio_cdwidth(unsigned int > cfg_width, u32 *rbf_data, > compress = (rbf_data[COMPRESSION_OFFSET] >> 1) & 1; > compress = !compress; > > - debug("header word %d = %08x\n", 69, rbf_data[69]); > - debug("header word %d = %08x\n", 229, rbf_data[229]); > - debug("read from rbf header: encrypt=%d compress=%d\n", encrypt, > compress); > + debug("FPGA: Header word %d = %08x.\n", 69, rbf_data[69]); > + debug("FPGA: Header word %d = %08x.\n", 229, rbf_data[229]); > + debug("FPGA: Read from rbf header: encrypt=%d compress=%d.\n", encrypt, > + compress); separate patch - just disturbing reviewers and you are not saying nothing about it in commit message. > > /* > * from the register map description of cdratio in imgcfg_ctrl_02: > @@ -359,6 +365,7 @@ static int fpgamgr_program_poll_cd(void) > printf("nstatus == 0 while waiting for condone\n"); > return -EPERM; > } > + WATCHDOG_RESET(); > } > > if (i == FPGA_TIMEOUT_CNT) > @@ -432,7 +439,6 @@ int fpgamgr_program_finish(void) > printf("FPGA: Poll CD failed with error code %d\n", status); > return -EPERM; > } > - WATCHDOG_RESET(); These two looks like separate patch too. > > /* Ensure the FPGA entering user mode */ > status = fpgamgr_program_poll_usermode(); > @@ -447,27 +453,512 @@ 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(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); > + > + return offset_to_ofnode(node_offset); > +} > + > +const char *get_fpga_filename(const void *fdt, int *len) > +{ > + const char *fpga_filename = NULL; > + > + ofnode fpgamgr_node = get_fpga_mgr_ofnode(); > + > + 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; > + int confs_noffset, images_noffset; > + int rbf_offset; > + int rbf_size; put them on the same line. > + 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); nit: better buffer_p, fit_size, 0); > + nit: remove empty line above > + 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); > + nit: remove empty line. > + 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_FPGA_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_mode() && > + !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; > + int status = 0; > + int ret = 0; no reason to initiate here. > + u32 buffer = (uintptr_t)buf; > + size_t buffer_sizebytes = bsize; > + size_t buffer_sizebytes_ori = bsize; > + size_t total_sizeof_image = 0; > + struct udevice *dev; > + ofnode node; > + int size; another int - just put them on the same line. > + const fdt32_t *phandle_p; > + u32 phandle; > + > + node = get_fpga_mgr_ofnode(); > + > + 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 0; This doesn't look like pass. 0 means pass but it should fail. > + } > + > + /* 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_loadfs, > + &buffer, > + &buffer_sizebytes_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; > + int len; > + > + fpga_fsinfo.filename = get_fpga_filename(gd->fdt_blob, &len); > + > + 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 */ > + /* Disable all signals from hps peripheral controller to fpga */ > writel(0, &system_manager_base->fpgaintf_en_global); > > - /* disable all axi bridge (hps2fpga, lwhps2fpga & fpga2hps) */ > + /* Disable all axi bridge (hps2fpga, lwhps2fpga & fpga2hps) */ separate changes. > 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); > > - /* Write the RBF data to FPGA Manager */ > + if (rbfinfo.section == periph_section) { > + /* Initialize the FPGA Manager */ > + status = fpgamgr_program_init((u32 *)rbf_data, rbf_size); > + if (status) > + return status; > + } > + > + 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 0; 0 is supposed to be pass. This looks like a fail. > + } > + > + /* 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 83a2d41..f839443 100644 > --- a/include/image.h > +++ b/include/image.h > @@ -1041,6 +1041,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); This should be separate patch. > > /** > * fit_conf_get_prop_node() - Get node refered to by a configuration > M -- Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91 w: www.monstr.eu p: +42-0-721842854 Maintainer of Linux kernel - Xilinx Microblaze Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs
signature.asc
Description: OpenPGP digital signature
_______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot