[U-Boot] [PATCH 0/3] Example of using generic FS loader with FPGA manager

From: Tien Fong Chee tien.fong.chee@intel.com
The purpose of this patchset provides example of using the generic FS loader which is currently under review at /data/tfchee/a10_upstreaming/mainstream/17_1_18/patches/firmware_loader_usage .
Basically, the whole machanism is working in two ways: 1. SPL -> spl_board_init -> fpga_fsload -> socfpga_loadfs -> fs_flash_preinit( process rbf mkimage header with loader) -> init FPGA -> chunk by chunk to program FPGA using loader
The patchset include this : 2. U-Boot console -> fpga loadfs command -> fpga_fsload -> socfpga_loadfs -> fs_flash_preinit(process rbf mkimage header with loader) -> init FPGA -> chunk by chunk to program FPGA using loader
Tien Fong Chee (3): ARM: socfpga: Add FPGA drivers for Arria 10 FPGA loadfs enable fpga loadfs arm: socfpga: Add Arria 10 SoCFPGA programming interface
arch/arm/dts/socfpga_arria10.dtsi | 12 + arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts | 6 + .../include/mach/fpga_manager_arria10.h | 22 + cmd/fpga.c | 2 +- configs/socfpga_arria10_defconfig | 12 + drivers/fpga/altera.c | 41 ++- drivers/fpga/fpga.c | 8 + drivers/fpga/socfpga_arria10.c | 402 ++++++++++++++++++++ include/altera.h | 6 + include/fpga.h | 2 + 10 files changed, 504 insertions(+), 9 deletions(-)

From: Tien Fong Chee tien.fong.chee@intel.com
Add FPGA drivers to support FPGA loadfs to program FPGA. The drivers are designed based on generic firmware loader framework, specific firmware loader handling is defined in fpga_manager_arria10.c. These drivers can handle FPGA program operation from loading RBF image in flash to memory and then to program FPGA.
Signed-off-by: Tien Fong Chee tien.fong.chee@intel.com --- .../include/mach/fpga_manager_arria10.h | 22 + drivers/fpga/socfpga_arria10.c | 402 ++++++++++++++++++++ include/altera.h | 4 + 3 files changed, 428 insertions(+), 0 deletions(-)
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 a112453..743d6b7 100644 --- a/arch/arm/mach-socfpga/include/mach/fpga_manager_arria10.h +++ b/arch/arm/mach-socfpga/include/mach/fpga_manager_arria10.h @@ -7,6 +7,9 @@ #ifndef _FPGA_MANAGER_ARRIA10_H_ #define _FPGA_MANAGER_ARRIA10_H_
+#include <asm/cache.h> +#include <fs_loader.h> + #define ALT_FPGAMGR_IMGCFG_STAT_F2S_CRC_ERROR_SET_MSK BIT(0) #define ALT_FPGAMGR_IMGCFG_STAT_F2S_EARLY_USERMODE_SET_MSK BIT(1) #define ALT_FPGAMGR_IMGCFG_STAT_F2S_USERMODE_SET_MSK BIT(2) @@ -88,6 +91,25 @@ struct socfpga_fpga_manager { u32 imgcfg_fifo_status; };
+#if defined(CONFIG_CMD_FPGA_LOADFS) +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_info { + char *filename; + int fstype; + u32 remaining; + u32 offset; + struct rbf_info rbfinfo; + struct image_header header; +}; +#endif + /* Functions */ int fpgamgr_program_init(u32 * rbf_data, size_t rbf_size); int fpgamgr_program_finish(void); diff --git a/drivers/fpga/socfpga_arria10.c b/drivers/fpga/socfpga_arria10.c index c0252fb..2f9006f 100644 --- a/drivers/fpga/socfpga_arria10.c +++ b/drivers/fpga/socfpga_arria10.c @@ -12,6 +12,13 @@ #include <altera.h> #include <common.h> #include <errno.h> +#include <fat.h> +#include <fs.h> +#include <fdtdec.h> +#include <malloc.h> +#include <part.h> +#include <spl.h> +#include <dm.h> #include <wait_bit.h> #include <watchdog.h>
@@ -21,6 +28,12 @@ #define COMPRESSION_OFFSET 229 #define FPGA_TIMEOUT_MSEC 1000 /* timeout in ms */ #define FPGA_TIMEOUT_CNT 0x1000000 +#define RBF_UNENCRYPTED 0xa65c +#define RBF_ENCRYPTED 0xa65d +#define ARRIA10RBF_PERIPH 0x0001 +#define ARRIA10RBF_CORE 0x8001 +#define PERIPH_RBF 0 +#define CORE_RBF 1
static const struct socfpga_fpga_manager *fpga_manager_base = (void *)SOCFPGA_FPGAMGRREGS_ADDRESS; @@ -30,6 +43,8 @@ static const struct socfpga_system_manager *system_manager_base =
static void fpgamgr_set_cd_ratio(unsigned long ratio);
+struct firmware *fw = NULL; + static uint32_t fpgamgr_get_msel(void) { u32 reg; @@ -471,3 +486,390 @@ int socfpga_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size)
return fpgamgr_program_finish(); } + +#if defined(CONFIG_CMD_FPGA_LOADFS) +const char *get_fpga_filename(const void *fdt, int *len, u32 core) +{ + const char *fpga_filename = NULL; + const char *cell; + int nodeoffset; + + nodeoffset = fdtdec_next_compatible(fdt, 0, + COMPAT_ALTERA_SOCFPGA_FPGA0); + if (nodeoffset >= 0) { + if (core) { + cell = fdt_getprop(fdt, + nodeoffset, + "altr,bitstream_core", + len); + } + else { + cell = fdt_getprop(fdt, nodeoffset, + "altr,bitstream_periph", len); + } + + if (cell) + fpga_filename = cell; + } + + return fpga_filename; +} + +void get_rbf_image_info(struct rbf_info *rbf, u16 *buffer) +{ + /* + * Magic ID starting at: + * -> 1st dword in periph.rbf + * -> 2nd dword in core.rbf + */ + u32 word_reading_max = 2; + u32 i; + + for (i = 0; i < word_reading_max; i++) { + if (*(buffer + i) == RBF_UNENCRYPTED) { /* PERIPH RBF */ + rbf->security = unencrypted; + } + else if (*(buffer + i) == RBF_ENCRYPTED) { + rbf->security = encrypted; + } + else if (*(buffer + i + 1) == RBF_UNENCRYPTED) { /* CORE RBF */ + rbf->security = unencrypted; + } + else if (*(buffer + i + 1) == RBF_ENCRYPTED) { + rbf->security = encrypted; + } + else { + rbf->security = invalid; + continue; + } + + /* PERIPH RBF(buffer + i + 1), CORE RBF(buffer + i + 2) */ + if (*(buffer + i + 1) == ARRIA10RBF_PERIPH) { + rbf->section = periph_section; + break; + } else if (*(buffer + i + 1) == ARRIA10RBF_CORE) { + rbf->section = core_section; + break; + } else if (*(buffer + i + 2) == ARRIA10RBF_PERIPH) { + rbf->section = periph_section; + break; + } else if (*(buffer + i + 2) == ARRIA10RBF_CORE) { + rbf->section = core_section; + break; + } else { + rbf->section = unknown; + break; + } + } + + return; +} + +int fs_flash_preinit(struct device_platdata *plat, + struct fpga_info *fpgainfo, + u32 *buffer, u32 *buffer_sizebytes) +{ + u32 *bufferptr_after_header = NULL; + u32 buffersize_after_header = 0; + u32 rbf_header_data_size = 0; + int ret = 0; + + fpgainfo->offset = 0; + + /* To avoid from keeping re-read the contents */ + struct image_header *header = &(fpgainfo->header); + size_t buffer_size = *buffer_sizebytes; + u32 *buffer_ptr = (u32 *)*buffer; + + /* Load mkimage header into buffer */ + ret = request_firmware_into_buf(plat, + fpgainfo->filename, + buffer_ptr, + sizeof(struct image_header), + fpgainfo->offset, + &fw); + if (ret < 0) { + puts("Failed to read mkimage header from flash.\n"); + return -ENOENT; + } + + WATCHDOG_RESET(); + + memcpy(header, (u_char *)buffer_ptr, sizeof(*header)); + + if (!image_check_magic(header)) { + puts("FPGA: Bad Magic Number.\n"); + return -EBADF; + } + + if (!image_check_hcrc(header)) { + puts("FPGA: Bad Header Checksum.\n"); + return -EPERM; + } + + /* Getting rbf data size */ + fpgainfo->remaining = + image_get_data_size(header); + + /* Calculate total size of both rbf data with mkimage header */ + rbf_header_data_size = fpgainfo->remaining + + sizeof(struct image_header); + + /* Loading to buffer chunk by chunk, normally for OCRAM buffer */ + if (rbf_header_data_size > buffer_size) { + /* Calculate size of rbf data in the buffer */ + buffersize_after_header = + buffer_size - sizeof(struct image_header); + fpgainfo->remaining -= buffersize_after_header; + } else { + /* Loading whole rbf image into buffer, normally for DDR buffer */ + buffer_size = rbf_header_data_size; + /* Calculate size of rbf data in the buffer */ + buffersize_after_header = + buffer_size - sizeof(struct image_header); + fpgainfo->remaining = 0; + } + + /* Loading mkimage header and rbf data into buffer */ + ret = request_firmware_into_buf(plat, + fpgainfo->filename, + buffer_ptr, + buffer_size, + fpgainfo->offset, + &fw); + if (ret < 0) { + puts(" Failed to read mkimage header and rbf data "); + puts("from flash.\n"); + return -ENOENT; + } + + /* + * Getting pointer of rbf data starting address where is it + * right after mkimage header + */ + bufferptr_after_header = + (u32 *)((u_char *)buffer_ptr + sizeof(struct image_header)); + + /* Update next reading rbf data flash offset */ + fpgainfo->offset += buffer_size; + + /* + * Update the starting addr of rbf data to init FPGA & programming + * into FPGA + */ + *buffer = (u32)bufferptr_after_header; + + get_rbf_image_info(&fpgainfo->rbfinfo, (u16 *)bufferptr_after_header); + + /* Update the size of rbf data to be programmed into FPGA */ + *buffer_sizebytes = buffersize_after_header; + +#ifdef CONFIG_CHECK_FPGA_DATA_CRC + fpgainfo->datacrc = + crc32(fpgainfo->datacrc, + (u_char *)bufferptr_after_header, + buffersize_after_header); +#endif + +if (fpgainfo->remaining == 0) { +#ifdef CONFIG_CHECK_FPGA_DATA_CRC + if (fpgainfo->datacrc != + image_get_dcrc(&(fpgainfo->header))) { + puts("FPGA: Bad Data Checksum.\n"); + return -EPERM; + } +#endif +} + return 0; +} + +int fs_flash_read(struct device_platdata *plat, + struct fpga_info *fpgainfo, u32 *buffer, + u32 *buffer_sizebytes) +{ + int ret = 0; + /* To avoid from keeping re-read the contents */ + size_t buffer_size = *buffer_sizebytes; + u32 *buffer_ptr = (u32 *)*buffer; + u32 flash_addr = fpgainfo->offset; + + /* Buffer allocated in OCRAM */ + /* Read the data by small chunk by chunk. */ + if (fpgainfo->remaining > buffer_size) { + fpgainfo->remaining -= buffer_size; + } + else { + /* + * Buffer allocated in DDR, larger than rbf data most + * of the time + */ + buffer_size = fpgainfo->remaining; + fpgainfo->remaining = 0; + } + + ret = request_firmware_into_buf(plat, + fpgainfo->filename, + buffer_ptr, + buffer_size, + fpgainfo->offset, + &fw); + if (ret < 0) { + puts(" Failed to read rbf data from flash.\n"); + return -ENOENT; + } + +#ifdef CONFIG_CHECK_FPGA_DATA_CRC + fpgainfo->datacrc = + crc32(fpgainfo->datacrc, + (unsigned char *)buffer_ptr, buffer_size); +#endif + +if (fpgainfo->remaining == 0) { +#ifdef CONFIG_CHECK_FPGA_DATA_CRC + if (fpgainfo->datacrc != + image_get_dcrc(&(fpgainfo->header))) { + puts("FPGA: Bad Data Checksum.\n"); + return -EPERM; + } +#endif +} + /* Update next reading rbf data flash offset */ + flash_addr += buffer_size; + + fpgainfo->offset = flash_addr; + + /* Update the size of rbf data to be programmed into FPGA */ + *buffer_sizebytes = buffer_size; + + return 0; +} + +int socfpga_loadfs(Altera_desc *desc, const void *buf, size_t bsize, + fpga_fs_info *fpga_fsinfo) +{ + struct fpga_info fpgainfo; + u32 status = 0; + int ret = 0; + int len = 0; + u32 buffer = 0; + u32 buffer_ori = 0; + size_t buffer_sizebytes = 0; + size_t buffer_sizebytes_ori = 0; + buffer_sizebytes = buffer_sizebytes_ori = bsize; + buffer = buffer_ori = (u32) buf; + struct udevice *dev; + struct device_platdata *plat; + char *filename = NULL; + + ret = uclass_get_device(UCLASS_FS_FIRMWARE_LOADER, 0, &dev); + if (ret) + return ret; + + plat = dev->platdata; +/* + if (strcmp("default", fpga_fsinfo->interface)) + env_set("storage_interface", fpga_fsinfo->interface); + + if (strcmp("default", fpga_fsinfo->dev_part)) + env_set("fw_dev_part", fpga_fsinfo->dev_part); +*/ + if (!strcmp("default", fpga_fsinfo->filename)) { + filename = env_get("CORE_RBF"); + if (filename) + fpga_fsinfo->filename = filename; + else { + fpga_fsinfo->filename = + (char *)get_fpga_filename(gd->fdt_blob, + &len, + CORE_RBF); + } + } + + memset(&fpgainfo, 0, sizeof(fpgainfo)); + + fpgainfo.filename = fpga_fsinfo->filename; + fpgainfo.fstype = fpga_fsinfo->fstype; + + WATCHDOG_RESET(); + + /* + * Note: Both buffer and buffer_sizebytes values can be altered by + * function below. + */ + ret = fs_flash_preinit(plat, &fpgainfo, &buffer, &buffer_sizebytes); + if (ret) { + release_firmware(fw); + fw = NULL; + return ret; + } + + if (fpgainfo.rbfinfo.section == periph_section) { + /* Initialize the FPGA Manager */ + status = fpgamgr_program_init((u32 *)buffer, buffer_sizebytes); + if (status) { + puts("FPGA: Init with periph rbf failed.\n"); + release_firmware(fw); + fw = NULL; + return -EPERM; + } + } + + WATCHDOG_RESET(); + + /* Transfer data to FPGA Manager */ + fpgamgr_program_write((void *)buffer, + buffer_sizebytes); + + WATCHDOG_RESET(); + + while (fpgainfo.remaining) { + ret = fs_flash_read(plat, &fpgainfo, &buffer_ori, + &buffer_sizebytes_ori); + + if (ret) { + release_firmware(fw); + fw = NULL; + return ret; + } + + /* transfer data to FPGA Manager */ + fpgamgr_program_write((void *)buffer_ori, + buffer_sizebytes_ori); + + WATCHDOG_RESET(); + } + + if (fpgainfo.rbfinfo.section == periph_section) { + if (fpgamgr_wait_early_user_mode() != -ETIMEDOUT) { + puts("FPGA: Early Release Succeeded.\n"); + } + else { + puts("FPGA: Failed to see Early Release.\n"); + release_firmware(fw); + fw = NULL; + return -EIO; + } + } else if (fpgainfo.rbfinfo.section == core_section) { + /* Ensure the FPGA entering config done */ + status = fpgamgr_program_finish(); + if (status) { + release_firmware(fw); + fw = NULL; + return status; + } + else { + puts("FPGA: Enter user mode.\n"); + } + + } else { + puts("Config Error: Unsupported FGPA raw binary type.\n"); + release_firmware(fw); + fw = NULL; + return -ENOEXEC; + } + + release_firmware(fw); + fw = NULL; + return 0; +} +#endif diff --git a/include/altera.h b/include/altera.h index ead5d3d..cf0c021 100644 --- a/include/altera.h +++ b/include/altera.h @@ -83,6 +83,10 @@ typedef struct { extern int altera_load(Altera_desc *desc, const void *image, size_t size); extern int altera_dump(Altera_desc *desc, const void *buf, size_t bsize); extern int altera_info(Altera_desc *desc); +#if defined(CONFIG_CMD_FPGA_LOADFS) +int altera_loadfs(Altera_desc *desc, const void *buf, size_t bsize, + fpga_fs_info *fpga_fsinfo); +#endif
/* Board specific implementation specific function types *********************************************************************/

On 26.7.2018 09:54, tien.fong.chee@intel.com wrote:
From: Tien Fong Chee tien.fong.chee@intel.com
Add FPGA drivers to support FPGA loadfs to program FPGA. The drivers are designed based on generic firmware loader framework, specific firmware loader handling is defined in fpga_manager_arria10.c. These drivers can handle FPGA program operation from loading RBF image in flash to memory and then to program FPGA.
Signed-off-by: Tien Fong Chee tien.fong.chee@intel.com
.../include/mach/fpga_manager_arria10.h | 22 + drivers/fpga/socfpga_arria10.c | 402 ++++++++++++++++++++ include/altera.h | 4 + 3 files changed, 428 insertions(+), 0 deletions(-)
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 a112453..743d6b7 100644 --- a/arch/arm/mach-socfpga/include/mach/fpga_manager_arria10.h +++ b/arch/arm/mach-socfpga/include/mach/fpga_manager_arria10.h @@ -7,6 +7,9 @@ #ifndef _FPGA_MANAGER_ARRIA10_H_ #define _FPGA_MANAGER_ARRIA10_H_
+#include <asm/cache.h> +#include <fs_loader.h>
#define ALT_FPGAMGR_IMGCFG_STAT_F2S_CRC_ERROR_SET_MSK BIT(0) #define ALT_FPGAMGR_IMGCFG_STAT_F2S_EARLY_USERMODE_SET_MSK BIT(1) #define ALT_FPGAMGR_IMGCFG_STAT_F2S_USERMODE_SET_MSK BIT(2) @@ -88,6 +91,25 @@ struct socfpga_fpga_manager { u32 imgcfg_fifo_status; };
+#if defined(CONFIG_CMD_FPGA_LOADFS) +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_info {
- char *filename;
- int fstype;
- u32 remaining;
- u32 offset;
- struct rbf_info rbfinfo;
- struct image_header header;
+}; +#endif
/* Functions */ int fpgamgr_program_init(u32 * rbf_data, size_t rbf_size); int fpgamgr_program_finish(void); diff --git a/drivers/fpga/socfpga_arria10.c b/drivers/fpga/socfpga_arria10.c index c0252fb..2f9006f 100644 --- a/drivers/fpga/socfpga_arria10.c +++ b/drivers/fpga/socfpga_arria10.c @@ -12,6 +12,13 @@ #include <altera.h> #include <common.h> #include <errno.h> +#include <fat.h> +#include <fs.h> +#include <fdtdec.h> +#include <malloc.h> +#include <part.h> +#include <spl.h> +#include <dm.h> #include <wait_bit.h> #include <watchdog.h>
@@ -21,6 +28,12 @@ #define COMPRESSION_OFFSET 229 #define FPGA_TIMEOUT_MSEC 1000 /* timeout in ms */ #define FPGA_TIMEOUT_CNT 0x1000000 +#define RBF_UNENCRYPTED 0xa65c +#define RBF_ENCRYPTED 0xa65d +#define ARRIA10RBF_PERIPH 0x0001 +#define ARRIA10RBF_CORE 0x8001 +#define PERIPH_RBF 0 +#define CORE_RBF 1
static const struct socfpga_fpga_manager *fpga_manager_base = (void *)SOCFPGA_FPGAMGRREGS_ADDRESS; @@ -30,6 +43,8 @@ static const struct socfpga_system_manager *system_manager_base =
static void fpgamgr_set_cd_ratio(unsigned long ratio);
+struct firmware *fw = NULL;
static uint32_t fpgamgr_get_msel(void) { u32 reg; @@ -471,3 +486,390 @@ int socfpga_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size)
return fpgamgr_program_finish(); }
+#if defined(CONFIG_CMD_FPGA_LOADFS) +const char *get_fpga_filename(const void *fdt, int *len, u32 core) +{
- const char *fpga_filename = NULL;
- const char *cell;
- int nodeoffset;
- nodeoffset = fdtdec_next_compatible(fdt, 0,
COMPAT_ALTERA_SOCFPGA_FPGA0);
- if (nodeoffset >= 0) {
if (core) {
cell = fdt_getprop(fdt,
nodeoffset,
"altr,bitstream_core",
len);
}
else {
cell = fdt_getprop(fdt, nodeoffset,
"altr,bitstream_periph", len);
}
if (cell)
fpga_filename = cell;
- }
- return fpga_filename;
+}
+void get_rbf_image_info(struct rbf_info *rbf, u16 *buffer) +{
- /*
* Magic ID starting at:
* -> 1st dword in periph.rbf
* -> 2nd dword in core.rbf
*/
- u32 word_reading_max = 2;
- u32 i;
- for (i = 0; i < word_reading_max; i++) {
if (*(buffer + i) == RBF_UNENCRYPTED) { /* PERIPH RBF */
rbf->security = unencrypted;
}
else if (*(buffer + i) == RBF_ENCRYPTED) {
rbf->security = encrypted;
}
else if (*(buffer + i + 1) == RBF_UNENCRYPTED) { /* CORE RBF */
rbf->security = unencrypted;
}
else if (*(buffer + i + 1) == RBF_ENCRYPTED) {
rbf->security = encrypted;
}
else {
rbf->security = invalid;
continue;
}
/* PERIPH RBF(buffer + i + 1), CORE RBF(buffer + i + 2) */
if (*(buffer + i + 1) == ARRIA10RBF_PERIPH) {
rbf->section = periph_section;
break;
} else if (*(buffer + i + 1) == ARRIA10RBF_CORE) {
rbf->section = core_section;
break;
} else if (*(buffer + i + 2) == ARRIA10RBF_PERIPH) {
rbf->section = periph_section;
break;
} else if (*(buffer + i + 2) == ARRIA10RBF_CORE) {
rbf->section = core_section;
break;
} else {
rbf->section = unknown;
break;
}
- }
- return;
+}
+int fs_flash_preinit(struct device_platdata *plat,
struct fpga_info *fpgainfo,
u32 *buffer, u32 *buffer_sizebytes)
+{
- u32 *bufferptr_after_header = NULL;
- u32 buffersize_after_header = 0;
- u32 rbf_header_data_size = 0;
- int ret = 0;
- fpgainfo->offset = 0;
- /* To avoid from keeping re-read the contents */
- struct image_header *header = &(fpgainfo->header);
- size_t buffer_size = *buffer_sizebytes;
- u32 *buffer_ptr = (u32 *)*buffer;
- /* Load mkimage header into buffer */
- ret = request_firmware_into_buf(plat,
fpgainfo->filename,
buffer_ptr,
sizeof(struct image_header),
fpgainfo->offset,
&fw);
- if (ret < 0) {
puts("Failed to read mkimage header from flash.\n");
return -ENOENT;
- }
This is suggesting that you are working with legacy uimage not with file itself. It means this is mix between legacy fpga loadmk and fpga loadfs.
- WATCHDOG_RESET();
- memcpy(header, (u_char *)buffer_ptr, sizeof(*header));
any reason not to copy that header directly to your structure?
- if (!image_check_magic(header)) {
puts("FPGA: Bad Magic Number.\n");
return -EBADF;
- }
- if (!image_check_hcrc(header)) {
puts("FPGA: Bad Header Checksum.\n");
return -EPERM;
- }
- /* Getting rbf data size */
- fpgainfo->remaining =
image_get_data_size(header);
- /* Calculate total size of both rbf data with mkimage header */
- rbf_header_data_size = fpgainfo->remaining +
sizeof(struct image_header);
- /* Loading to buffer chunk by chunk, normally for OCRAM buffer */
- if (rbf_header_data_size > buffer_size) {
/* Calculate size of rbf data in the buffer */
buffersize_after_header =
buffer_size - sizeof(struct image_header);
fpgainfo->remaining -= buffersize_after_header;
- } else {
- /* Loading whole rbf image into buffer, normally for DDR buffer */
buffer_size = rbf_header_data_size;
/* Calculate size of rbf data in the buffer */
buffersize_after_header =
buffer_size - sizeof(struct image_header);
fpgainfo->remaining = 0;
- }
- /* Loading mkimage header and rbf data into buffer */
- ret = request_firmware_into_buf(plat,
fpgainfo->filename,
buffer_ptr,
buffer_size,
fpgainfo->offset,
&fw);
- if (ret < 0) {
puts(" Failed to read mkimage header and rbf data ");
puts("from flash.\n");
return -ENOENT;
- }
- /*
* Getting pointer of rbf data starting address where is it
* right after mkimage header
*/
- bufferptr_after_header =
(u32 *)((u_char *)buffer_ptr + sizeof(struct image_header));
- /* Update next reading rbf data flash offset */
- fpgainfo->offset += buffer_size;
- /*
* Update the starting addr of rbf data to init FPGA & programming
* into FPGA
*/
- *buffer = (u32)bufferptr_after_header;
- get_rbf_image_info(&fpgainfo->rbfinfo, (u16 *)bufferptr_after_header);
- /* Update the size of rbf data to be programmed into FPGA */
- *buffer_sizebytes = buffersize_after_header;
+#ifdef CONFIG_CHECK_FPGA_DATA_CRC
- fpgainfo->datacrc =
crc32(fpgainfo->datacrc,
(u_char *)bufferptr_after_header,
buffersize_after_header);
+#endif
+if (fpgainfo->remaining == 0) { +#ifdef CONFIG_CHECK_FPGA_DATA_CRC
- if (fpgainfo->datacrc !=
image_get_dcrc(&(fpgainfo->header))) {
puts("FPGA: Bad Data Checksum.\n");
return -EPERM;
- }
+#endif +}
- return 0;
+}
+int fs_flash_read(struct device_platdata *plat,
struct fpga_info *fpgainfo, u32 *buffer,
u32 *buffer_sizebytes)
+{
- int ret = 0;
- /* To avoid from keeping re-read the contents */
- size_t buffer_size = *buffer_sizebytes;
- u32 *buffer_ptr = (u32 *)*buffer;
- u32 flash_addr = fpgainfo->offset;
- /* Buffer allocated in OCRAM */
- /* Read the data by small chunk by chunk. */
- if (fpgainfo->remaining > buffer_size) {
fpgainfo->remaining -= buffer_size;
- }
- else {
/*
* Buffer allocated in DDR, larger than rbf data most
* of the time
*/
buffer_size = fpgainfo->remaining;
fpgainfo->remaining = 0;
- }
- ret = request_firmware_into_buf(plat,
fpgainfo->filename,
buffer_ptr,
buffer_size,
fpgainfo->offset,
&fw);
- if (ret < 0) {
puts(" Failed to read rbf data from flash.\n");
return -ENOENT;
- }
+#ifdef CONFIG_CHECK_FPGA_DATA_CRC
- fpgainfo->datacrc =
crc32(fpgainfo->datacrc,
(unsigned char *)buffer_ptr, buffer_size);
+#endif
+if (fpgainfo->remaining == 0) { +#ifdef CONFIG_CHECK_FPGA_DATA_CRC
- if (fpgainfo->datacrc !=
image_get_dcrc(&(fpgainfo->header))) {
puts("FPGA: Bad Data Checksum.\n");
return -EPERM;
- }
+#endif +}
- /* Update next reading rbf data flash offset */
- flash_addr += buffer_size;
- fpgainfo->offset = flash_addr;
- /* Update the size of rbf data to be programmed into FPGA */
- *buffer_sizebytes = buffer_size;
- return 0;
+}
+int socfpga_loadfs(Altera_desc *desc, const void *buf, size_t bsize,
fpga_fs_info *fpga_fsinfo)
+{
- struct fpga_info fpgainfo;
- u32 status = 0;
- int ret = 0;
- int len = 0;
- u32 buffer = 0;
- u32 buffer_ori = 0;
- size_t buffer_sizebytes = 0;
- size_t buffer_sizebytes_ori = 0;
- buffer_sizebytes = buffer_sizebytes_ori = bsize;
- buffer = buffer_ori = (u32) buf;
- struct udevice *dev;
- struct device_platdata *plat;
- char *filename = NULL;
- ret = uclass_get_device(UCLASS_FS_FIRMWARE_LOADER, 0, &dev);
- if (ret)
return ret;
- plat = dev->platdata;
+/*
- if (strcmp("default", fpga_fsinfo->interface))
env_set("storage_interface", fpga_fsinfo->interface);
- if (strcmp("default", fpga_fsinfo->dev_part))
env_set("fw_dev_part", fpga_fsinfo->dev_part);
+*/
no dead code please.
- if (!strcmp("default", fpga_fsinfo->filename)) {
filename = env_get("CORE_RBF");
if (filename)
fpga_fsinfo->filename = filename;
else {
fpga_fsinfo->filename =
(char *)get_fpga_filename(gd->fdt_blob,
&len,
CORE_RBF);
}
- }
- memset(&fpgainfo, 0, sizeof(fpgainfo));
- fpgainfo.filename = fpga_fsinfo->filename;
- fpgainfo.fstype = fpga_fsinfo->fstype;
This is IMHO not the right way how this should be handled. fpga loadfs command requires this to be passed. If you want to use some default variables I am fine with that but then use generic name and add them to cmd/fpga.c (on the top of my series now) which will be common for all.
- WATCHDOG_RESET();
- /*
* Note: Both buffer and buffer_sizebytes values can be altered by
* function below.
*/
- ret = fs_flash_preinit(plat, &fpgainfo, &buffer, &buffer_sizebytes);
- if (ret) {
release_firmware(fw);
fw = NULL;
return ret;
- }
- if (fpgainfo.rbfinfo.section == periph_section) {
/* Initialize the FPGA Manager */
status = fpgamgr_program_init((u32 *)buffer, buffer_sizebytes);
if (status) {
puts("FPGA: Init with periph rbf failed.\n");
release_firmware(fw);
fw = NULL;
return -EPERM;
}
- }
- WATCHDOG_RESET();
- /* Transfer data to FPGA Manager */
- fpgamgr_program_write((void *)buffer,
buffer_sizebytes);
- WATCHDOG_RESET();
- while (fpgainfo.remaining) {
ret = fs_flash_read(plat, &fpgainfo, &buffer_ori,
&buffer_sizebytes_ori);
if (ret) {
release_firmware(fw);
fw = NULL;
return ret;
}
/* transfer data to FPGA Manager */
fpgamgr_program_write((void *)buffer_ori,
buffer_sizebytes_ori);
WATCHDOG_RESET();
- }
- if (fpgainfo.rbfinfo.section == periph_section) {
if (fpgamgr_wait_early_user_mode() != -ETIMEDOUT) {
puts("FPGA: Early Release Succeeded.\n");
}
else {
puts("FPGA: Failed to see Early Release.\n");
release_firmware(fw);
fw = NULL;
return -EIO;
}
- } else if (fpgainfo.rbfinfo.section == core_section) {
/* Ensure the FPGA entering config done */
status = fpgamgr_program_finish();
if (status) {
release_firmware(fw);
fw = NULL;
return status;
}
else {
puts("FPGA: Enter user mode.\n");
}
- } else {
puts("Config Error: Unsupported FGPA raw binary type.\n");
release_firmware(fw);
fw = NULL;
return -ENOEXEC;
- }
- release_firmware(fw);
- fw = NULL;
- return 0;
+} +#endif diff --git a/include/altera.h b/include/altera.h index ead5d3d..cf0c021 100644 --- a/include/altera.h +++ b/include/altera.h @@ -83,6 +83,10 @@ typedef struct { extern int altera_load(Altera_desc *desc, const void *image, size_t size); extern int altera_dump(Altera_desc *desc, const void *buf, size_t bsize); extern int altera_info(Altera_desc *desc); +#if defined(CONFIG_CMD_FPGA_LOADFS) +int altera_loadfs(Altera_desc *desc, const void *buf, size_t bsize,
fpga_fs_info *fpga_fsinfo);
+#endif
/* Board specific implementation specific function types *********************************************************************/
What I see above doesn't look quite good. First think what I want to know is the flow you want to use. If this is based on legacy uimage. That CRC calculation is interesting too.
One thing what I don't like is that we use this command differently then your implementation which is the thing which needs to be fixed. Right now there is no support for load by chunks mkimage image format directly from filesystem and maybe we should create different command for that. In SPL case there should be clear function which should be called to do that. Because right now your flow is more or less duplicating things which are already in SPL.
Thanks, Michal

From: Tien Fong Chee tien.fong.chee@intel.com
Signed-off-by: Tien Fong Chee tien.fong.chee@intel.com --- arch/arm/dts/socfpga_arria10.dtsi | 12 ++++++++++++ arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts | 6 ++++++ configs/socfpga_arria10_defconfig | 12 ++++++++++++ 3 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/arch/arm/dts/socfpga_arria10.dtsi b/arch/arm/dts/socfpga_arria10.dtsi index b51febd..45aef6a 100644 --- a/arch/arm/dts/socfpga_arria10.dtsi +++ b/arch/arm/dts/socfpga_arria10.dtsi @@ -48,6 +48,12 @@ <0xffffc100 0x100>; };
+ fs_loader0: fs-loader@0 { + u-boot,dm-pre-reloc; + compatible = "u-boot,fs-loader"; + phandlepart = <&mmc 1>; + }; + soc { #address-cells = <1>; #size-cells = <1>; @@ -532,12 +538,18 @@ };
fpga_mgr: fpga-mgr@ffd03000 { + u-boot,dm-pre-reloc; compatible = "altr,socfpga-a10-fpga-mgr"; reg = <0xffd03000 0x100 0xffcfe400 0x20>; clocks = <&l4_mp_clk>; resets = <&rst FPGAMGR_RESET>; reset-names = "fpgamgr"; + altr,bitstream_periph = + "ghrd_10as066n2.periph.rbf.mkimage"; + altr,bitstream_core = + "ghrd_10as066n2.core.rbf.mkimage"; + altr,bitstream_devpart = "0:1"; };
i2c0: i2c@ffc02200 { diff --git a/arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts b/arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts index 9c6070d..4b9705b 100644 --- a/arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts +++ b/arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts @@ -18,6 +18,12 @@ /dts-v1/; #include "socfpga_arria10_socdk.dtsi"
+/ { + chosen { + firmware-loader = &fs_loader0; + }; +}; + &mmc { u-boot,dm-pre-reloc; status = "okay"; diff --git a/configs/socfpga_arria10_defconfig b/configs/socfpga_arria10_defconfig index f24ea77..675f4da 100644 --- a/configs/socfpga_arria10_defconfig +++ b/configs/socfpga_arria10_defconfig @@ -4,6 +4,8 @@ CONFIG_SYS_TEXT_BASE=0x01000040 CONFIG_SYS_MALLOC_F_LEN=0x8000 CONFIG_TARGET_SOCFPGA_ARRIA10_SOCDK=y CONFIG_SPL=y +CONFIG_HUSH_PARSER=y +CONFIG_CMD_PART=y CONFIG_IDENT_STRING="socfpga_arria10" CONFIG_DEFAULT_DEVICE_TREE="socfpga_arria10_socdk_sdmmc" CONFIG_DISTRO_DEFAULTS=y @@ -18,6 +20,8 @@ CONFIG_SYS_CONSOLE_IS_IN_ENV=y CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y CONFIG_SYS_CONSOLE_ENV_OVERWRITE=y CONFIG_DEFAULT_FDT_FILE="socfpga_arria10_socdk_sdmmc.dtb" +# CONFIG_OF_LIVE=y +CONFIG_SPL_DRIVERS_MISC_SUPPORT=y CONFIG_VERSION_VARIABLE=y CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x800 @@ -39,12 +43,20 @@ CONFIG_CMD_EXT4_WRITE=y CONFIG_MTDIDS_DEFAULT="nor0=ff705000.spi.0" CONFIG_OF_SPL_REMOVE_PROPS="clocks clock-names interrupts interrupt-parent dmas dma-names" CONFIG_ENV_IS_IN_MMC=y +CONFIG_SPL_DOS_PARTITION=y +CONFIG_CMD_FAT=y CONFIG_SPL_DM=y CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_DFU_MMC=y CONFIG_FPGA_SOCFPGA=y CONFIG_DM_GPIO=y CONFIG_DWAPB_GPIO=y +CONFIG_FS_LOADER=y +CONFIG_SPL_DM_MMC=y +CONFIG_SPL_MMC_SUPPORT=y +CONFIG_FPGA=y +CONFIG_FPGA_ALTERA=y +CONFIG_CMD_FPGA_LOADFS=y CONFIG_SYS_I2C_DW=y CONFIG_DM_MMC=y CONFIG_MMC_DW=y

On 07/26/2018 09:54 AM, tien.fong.chee@intel.com wrote:
From: Tien Fong Chee tien.fong.chee@intel.com
Signed-off-by: Tien Fong Chee tien.fong.chee@intel.com
arch/arm/dts/socfpga_arria10.dtsi | 12 ++++++++++++ arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts | 6 ++++++ configs/socfpga_arria10_defconfig | 12 ++++++++++++ 3 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/arch/arm/dts/socfpga_arria10.dtsi b/arch/arm/dts/socfpga_arria10.dtsi index b51febd..45aef6a 100644 --- a/arch/arm/dts/socfpga_arria10.dtsi +++ b/arch/arm/dts/socfpga_arria10.dtsi @@ -48,6 +48,12 @@ <0xffffc100 0x100>; };
- fs_loader0: fs-loader@0 {
u-boot,dm-pre-reloc;
compatible = "u-boot,fs-loader";
phandlepart = <&mmc 1>;
Which hardware does this describe ? DT is hardware description ...
- };
[...]

On Thu, 2018-07-26 at 10:10 +0200, Marek Vasut wrote:
On 07/26/2018 09:54 AM, tien.fong.chee@intel.com wrote:
From: Tien Fong Chee tien.fong.chee@intel.com
Signed-off-by: Tien Fong Chee tien.fong.chee@intel.com
arch/arm/dts/socfpga_arria10.dtsi | 12 ++++++++++++ arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts | 6 ++++++ configs/socfpga_arria10_defconfig | 12 ++++++++++++ 3 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/arch/arm/dts/socfpga_arria10.dtsi b/arch/arm/dts/socfpga_arria10.dtsi index b51febd..45aef6a 100644 --- a/arch/arm/dts/socfpga_arria10.dtsi +++ b/arch/arm/dts/socfpga_arria10.dtsi @@ -48,6 +48,12 @@ <0xffffc100 0x100>; };
- fs_loader0: fs-loader@0 {
u-boot,dm-pre-reloc;
compatible = "u-boot,fs-loader";
phandlepart = <&mmc 1>;
Which hardware does this describe ? DT is hardware description ...
I agree with Simon, it still describes some hardware information required for this whole mechanism to work although this pointer is not represent a real hardware.
- };
[...]

Hi,
On 27 July 2018 at 02:57, Chee, Tien Fong tien.fong.chee@intel.com wrote:
On Thu, 2018-07-26 at 10:10 +0200, Marek Vasut wrote:
On 07/26/2018 09:54 AM, tien.fong.chee@intel.com wrote:
From: Tien Fong Chee tien.fong.chee@intel.com
Signed-off-by: Tien Fong Chee tien.fong.chee@intel.com
arch/arm/dts/socfpga_arria10.dtsi | 12 ++++++++++++ arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts | 6 ++++++ configs/socfpga_arria10_defconfig | 12 ++++++++++++ 3 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/arch/arm/dts/socfpga_arria10.dtsi b/arch/arm/dts/socfpga_arria10.dtsi index b51febd..45aef6a 100644 --- a/arch/arm/dts/socfpga_arria10.dtsi +++ b/arch/arm/dts/socfpga_arria10.dtsi @@ -48,6 +48,12 @@ <0xffffc100 0x100>; };
- fs_loader0: fs-loader@0 {
u-boot,dm-pre-reloc;
compatible = "u-boot,fs-loader";
phandlepart = <&mmc 1>;
Which hardware does this describe ? DT is hardware description ...
I agree with Simon, it still describes some hardware information required for this whole mechanism to work although this pointer is not represent a real hardware.
Right, I would like to drop the 'DT is a hardware description' meme :-) See the other thread about this.
Regards, Simon

From: Tien Fong Chee tien.fong.chee@intel.com
Add code necessary into the FPGA driver framework in U-Boot so it can be used via the 'fpga' command for programing Arria 10 SoCFPGA.
Signed-off-by: Tien Fong Chee tien.fong.chee@intel.com --- cmd/fpga.c | 2 +- drivers/fpga/altera.c | 41 +++++++++++++++++++++++++++++++++-------- drivers/fpga/fpga.c | 8 ++++++++ include/altera.h | 2 ++ include/fpga.h | 2 ++ 5 files changed, 46 insertions(+), 9 deletions(-)
diff --git a/cmd/fpga.c b/cmd/fpga.c index 14ad4e5..207cec3 100644 --- a/cmd/fpga.c +++ b/cmd/fpga.c @@ -362,7 +362,7 @@ U_BOOT_CMD(fpga, 6, 1, do_fpga, "(Xilinx only)\n" #endif #if defined(CONFIG_CMD_FPGA_LOADFS) - "Load device from filesystem (FAT by default) (Xilinx only)\n" + "Load device from filesystem (FAT by default)\n" " loadfs [dev] [address] [image size] [blocksize] <interface>\n" " [<dev[:part]>] <filename>\n" #endif diff --git a/drivers/fpga/altera.c b/drivers/fpga/altera.c index 9605554..3c9474c 100644 --- a/drivers/fpga/altera.c +++ b/drivers/fpga/altera.c @@ -12,6 +12,7 @@ */ #include <common.h> #include <errno.h> +#include <altera.h> /* altera specific definitions */ #include <ACEX1K.h> #include <stratixII.h>
@@ -22,25 +23,31 @@ static const struct altera_fpga { enum altera_family family; const char *name; int (*load)(Altera_desc *, const void *, size_t); + int (*loadfs)(Altera_desc *, const void *, size_t, fpga_fs_info *); int (*dump)(Altera_desc *, const void *, size_t); int (*info)(Altera_desc *); } altera_fpga[] = { #if defined(CONFIG_FPGA_ACEX1K) - { Altera_ACEX1K, "ACEX1K", ACEX1K_load, ACEX1K_dump, ACEX1K_info }, - { Altera_CYC2, "ACEX1K", ACEX1K_load, ACEX1K_dump, ACEX1K_info }, + { Altera_ACEX1K, "ACEX1K", ACEX1K_load, NULL, ACEX1K_dump, + ACEX1K_info }, + { Altera_CYC2, "ACEX1K", ACEX1K_load, NULL, ACEX1K_dump, + ACEX1K_info }, #elif defined(CONFIG_FPGA_CYCLON2) - { Altera_ACEX1K, "CycloneII", CYC2_load, CYC2_dump, CYC2_info }, - { Altera_CYC2, "CycloneII", CYC2_load, CYC2_dump, CYC2_info }, + { Altera_ACEX1K, "CycloneII", CYC2_load, NULL, CYC2_dump, CYC2_info }, + { Altera_CYC2, "CycloneII", CYC2_load, NULL, CYC2_dump, CYC2_info }, #endif #if defined(CONFIG_FPGA_STRATIX_II) - { Altera_StratixII, "StratixII", StratixII_load, + { Altera_StratixII, "StratixII", StratixII_load, NULL, StratixII_dump, StratixII_info }, #endif #if defined(CONFIG_FPGA_STRATIX_V) - { Altera_StratixV, "StratixV", stratixv_load, NULL, NULL }, + { Altera_StratixV, "StratixV", stratixv_load, NULL, NULL, NULL }, #endif -#if defined(CONFIG_FPGA_SOCFPGA) - { Altera_SoCFPGA, "SoC FPGA", socfpga_load, NULL, NULL }, +#if defined(CONFIG_FPGA_SOCFPGA) && defined(CONFIG_CMD_FPGA_LOADFS) + { Altera_SoCFPGA, "SoC FPGA", socfpga_load, socfpga_loadfs, NULL, + NULL }, +#elif defined(CONFIG_FPGA_SOCFPGA) + { Altera_SoCFPGA, "SoC FPGA", socfpga_load, NULL, NULL, NULL }, #endif };
@@ -173,3 +180,21 @@ int altera_info(Altera_desc *desc)
return FPGA_SUCCESS; } + +#if defined(CONFIG_CMD_FPGA_LOADFS) +int altera_loadfs(Altera_desc *desc, const void *buf, size_t bsize, + fpga_fs_info *fpga_fsinfo) +{ + const struct altera_fpga *fpga = altera_desc_to_fpga(desc, __func__); + + if (!fpga) + return FPGA_FAIL; + + debug_cond(FPGA_DEBUG, "%s: Launching the %s FS Loader...\n", + __func__, fpga->name); + if (fpga->loadfs) + return fpga->loadfs(desc, buf, bsize, fpga_fsinfo); + + return -EINVAL; +} +#endif diff --git a/drivers/fpga/fpga.c b/drivers/fpga/fpga.c index 55bdf9e..67b772d 100644 --- a/drivers/fpga/fpga.c +++ b/drivers/fpga/fpga.c @@ -207,6 +207,14 @@ int fpga_fsload(int devnum, const void *buf, size_t size, fpga_no_sup((char *)__func__, "Xilinx devices"); #endif break; +#if defined(CONFIG_FPGA_ALTERA) + case fpga_altera: + ret_val = altera_loadfs(desc->devdesc, buf, size, + fpga_fsinfo); +#else + fpga_no_sup((char *)__func__, "Altera devices"); +#endif + break; default: printf("%s: Invalid or unsupported device type %d\n", __func__, desc->devtype); diff --git a/include/altera.h b/include/altera.h index cf0c021..b641b8a 100644 --- a/include/altera.h +++ b/include/altera.h @@ -114,6 +114,8 @@ typedef struct {
#ifdef CONFIG_FPGA_SOCFPGA int socfpga_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size); +int socfpga_loadfs(Altera_desc *desc, const void *buf, size_t bsize, + fpga_fs_info *fpga_fsinfo); #endif
#ifdef CONFIG_FPGA_STRATIX_V diff --git a/include/fpga.h b/include/fpga.h index f444093..eee6fed 100644 --- a/include/fpga.h +++ b/include/fpga.h @@ -56,8 +56,10 @@ const fpga_desc *const fpga_get_desc(int devnum); int fpga_is_partial_data(int devnum, size_t img_len); int fpga_load(int devnum, const void *buf, size_t bsize, bitstream_type bstype); +#if defined(CONFIG_CMD_FPGA_LOADFS) int fpga_fsload(int devnum, const void *buf, size_t size, fpga_fs_info *fpga_fsinfo); +#endif int fpga_loadbitstream(int devnum, char *fpgadata, size_t size, bitstream_type bstype); int fpga_dump(int devnum, const void *buf, size_t bsize);

On 26.7.2018 09:54, tien.fong.chee@intel.com wrote:
From: Tien Fong Chee tien.fong.chee@intel.com
Add code necessary into the FPGA driver framework in U-Boot so it can be used via the 'fpga' command for programing Arria 10 SoCFPGA.
Signed-off-by: Tien Fong Chee tien.fong.chee@intel.com
cmd/fpga.c | 2 +- drivers/fpga/altera.c | 41 +++++++++++++++++++++++++++++++++-------- drivers/fpga/fpga.c | 8 ++++++++ include/altera.h | 2 ++ include/fpga.h | 2 ++ 5 files changed, 46 insertions(+), 9 deletions(-)
diff --git a/cmd/fpga.c b/cmd/fpga.c index 14ad4e5..207cec3 100644 --- a/cmd/fpga.c +++ b/cmd/fpga.c @@ -362,7 +362,7 @@ U_BOOT_CMD(fpga, 6, 1, do_fpga, "(Xilinx only)\n" #endif #if defined(CONFIG_CMD_FPGA_LOADFS)
"Load device from filesystem (FAT by default) (Xilinx only)\n"
"Load device from filesystem (FAT by default)\n" " loadfs [dev] [address] [image size] [blocksize] <interface>\n" " [<dev[:part]>] <filename>\n"
#endif diff --git a/drivers/fpga/altera.c b/drivers/fpga/altera.c index 9605554..3c9474c 100644 --- a/drivers/fpga/altera.c +++ b/drivers/fpga/altera.c @@ -12,6 +12,7 @@ */ #include <common.h> #include <errno.h> +#include <altera.h> /* altera specific definitions */ #include <ACEX1K.h> #include <stratixII.h>
@@ -22,25 +23,31 @@ static const struct altera_fpga { enum altera_family family; const char *name; int (*load)(Altera_desc *, const void *, size_t);
- int (*loadfs)(Altera_desc *, const void *, size_t, fpga_fs_info *);
when you put this as last then you don't need to fill NULLs below.
int (*dump)(Altera_desc *, const void *, size_t); int (*info)(Altera_desc *); } altera_fpga[] = { #if defined(CONFIG_FPGA_ACEX1K)
- { Altera_ACEX1K, "ACEX1K", ACEX1K_load, ACEX1K_dump, ACEX1K_info },
- { Altera_CYC2, "ACEX1K", ACEX1K_load, ACEX1K_dump, ACEX1K_info },
- { Altera_ACEX1K, "ACEX1K", ACEX1K_load, NULL, ACEX1K_dump,
ACEX1K_info },
- { Altera_CYC2, "ACEX1K", ACEX1K_load, NULL, ACEX1K_dump,
ACEX1K_info },
#elif defined(CONFIG_FPGA_CYCLON2)
- { Altera_ACEX1K, "CycloneII", CYC2_load, CYC2_dump, CYC2_info },
- { Altera_CYC2, "CycloneII", CYC2_load, CYC2_dump, CYC2_info },
- { Altera_ACEX1K, "CycloneII", CYC2_load, NULL, CYC2_dump, CYC2_info },
- { Altera_CYC2, "CycloneII", CYC2_load, NULL, CYC2_dump, CYC2_info },
#endif #if defined(CONFIG_FPGA_STRATIX_II)
- { Altera_StratixII, "StratixII", StratixII_load,
- { Altera_StratixII, "StratixII", StratixII_load, NULL, StratixII_dump, StratixII_info },
#endif #if defined(CONFIG_FPGA_STRATIX_V)
- { Altera_StratixV, "StratixV", stratixv_load, NULL, NULL },
- { Altera_StratixV, "StratixV", stratixv_load, NULL, NULL, NULL },
#endif -#if defined(CONFIG_FPGA_SOCFPGA)
- { Altera_SoCFPGA, "SoC FPGA", socfpga_load, NULL, NULL },
+#if defined(CONFIG_FPGA_SOCFPGA) && defined(CONFIG_CMD_FPGA_LOADFS)
- { Altera_SoCFPGA, "SoC FPGA", socfpga_load, socfpga_loadfs, NULL,
NULL },
+#elif defined(CONFIG_FPGA_SOCFPGA)
- { Altera_SoCFPGA, "SoC FPGA", socfpga_load, NULL, NULL, NULL },
#endif };
@@ -173,3 +180,21 @@ int altera_info(Altera_desc *desc)
return FPGA_SUCCESS; }
+#if defined(CONFIG_CMD_FPGA_LOADFS) +int altera_loadfs(Altera_desc *desc, const void *buf, size_t bsize,
fpga_fs_info *fpga_fsinfo)
+{
- const struct altera_fpga *fpga = altera_desc_to_fpga(desc, __func__);
- if (!fpga)
return FPGA_FAIL;
- debug_cond(FPGA_DEBUG, "%s: Launching the %s FS Loader...\n",
__func__, fpga->name);
- if (fpga->loadfs)
return fpga->loadfs(desc, buf, bsize, fpga_fsinfo);
- return -EINVAL;
+} +#endif diff --git a/drivers/fpga/fpga.c b/drivers/fpga/fpga.c index 55bdf9e..67b772d 100644 --- a/drivers/fpga/fpga.c +++ b/drivers/fpga/fpga.c @@ -207,6 +207,14 @@ int fpga_fsload(int devnum, const void *buf, size_t size, fpga_no_sup((char *)__func__, "Xilinx devices"); #endif break; +#if defined(CONFIG_FPGA_ALTERA)
case fpga_altera:
ret_val = altera_loadfs(desc->devdesc, buf, size,
fpga_fsinfo);
+#else
fpga_no_sup((char *)__func__, "Altera devices");
+#endif
default: printf("%s: Invalid or unsupported device type %d\n", __func__, desc->devtype);break;
diff --git a/include/altera.h b/include/altera.h index cf0c021..b641b8a 100644 --- a/include/altera.h +++ b/include/altera.h @@ -114,6 +114,8 @@ typedef struct {
#ifdef CONFIG_FPGA_SOCFPGA int socfpga_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size); +int socfpga_loadfs(Altera_desc *desc, const void *buf, size_t bsize,
fpga_fs_info *fpga_fsinfo);
#endif
#ifdef CONFIG_FPGA_STRATIX_V diff --git a/include/fpga.h b/include/fpga.h index f444093..eee6fed 100644 --- a/include/fpga.h +++ b/include/fpga.h @@ -56,8 +56,10 @@ const fpga_desc *const fpga_get_desc(int devnum); int fpga_is_partial_data(int devnum, size_t img_len); int fpga_load(int devnum, const void *buf, size_t bsize, bitstream_type bstype); +#if defined(CONFIG_CMD_FPGA_LOADFS) int fpga_fsload(int devnum, const void *buf, size_t size, fpga_fs_info *fpga_fsinfo); +#endif int fpga_loadbitstream(int devnum, char *fpgadata, size_t size, bitstream_type bstype); int fpga_dump(int devnum, const void *buf, size_t bsize);
M
participants (5)
-
Chee, Tien Fong
-
Marek Vasut
-
Michal Simek
-
Simon Glass
-
tien.fong.chee@intel.com