Skip to contentSkip to conversation

Example of using generic FS loader with FPGA manager

PATCH New tien.fong.chee at intel.com 5 participants 9 messages Jul 26, 2018 – Jul 30, 2018

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

cover Example of using generic FS loader with FPGA manager

From: Tien Fong Chee <[email protected]>

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(-)
Signature · 1 line
1.7.7.4
#1 lore raw

PATCH 1/3 ARM: socfpga: Add FPGA drivers for Arria 10 FPGA loadfs

From: Tien Fong Chee <[email protected]>

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.

---
 .../include/mach/fpga_manager_arria10.h            |   22 +
 drivers/fpga/socfpga_arria10.c                     |  402 ++++++++++++++++++++
 include/altera.h                                   |    4 +
 3 files changed, 428 insertions(+), 0 deletions(-)
arch/arm/mach-socfpga/include/mach/fpga_manager_arria10.h +22 -0
index a112453..743d6b7 100644
@@ -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);
drivers/fpga/socfpga_arria10.c +402 -0

423 lines not on this page · raw message

include/altera.h +4 -0
index ead5d3d..cf0c021 100644
@@ -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
  *********************************************************************/
Signature · 1 line
1.7.7.4
#2 lore raw

PATCH 1/3 ARM: socfpga: Add FPGA drivers for Arria 10 FPGA loadfs

Quoted 195 lines · tien.fong.chee at intel.com

From: Tien Fong Chee <[email protected]>

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.

---
 .../include/mach/fpga_manager_arria10.h            |   22 +
 drivers/fpga/socfpga_arria10.c                     |  402 ++++++++++++++++++++
 include/altera.h                                   |    4 +
 3 files changed, 428 insertions(+), 0 deletions(-)
arch/arm/mach-socfpga/include/mach/fpga_manager_arria10.h +22 -0
index a112453..743d6b7 100644
@@ -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);
drivers/fpga/socfpga_arria10.c +111 -0
index c0252fb..2f9006f 100644
@@ -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 */

drivers/fpga/socfpga_arria10.c int socfpga_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size) · line 594

Quoted 10 lines
drivers/fpga/socfpga_arria10.c +10 -0
+	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.

drivers/fpga/socfpga_arria10.c int socfpga_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size) · line 598

Quoted 4 lines
drivers/fpga/socfpga_arria10.c +4 -0
+
+	WATCHDOG_RESET();
+
+	memcpy(header, (u_char *)buffer_ptr, sizeof(*header));

any reason not to copy that header directly to your structure?

Quoted 170 lines
drivers/fpga/socfpga_arria10.c +167 -0
+
+	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)

drivers/fpga/socfpga_arria10.c int socfpga_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size) · line 775

Quoted 10 lines
drivers/fpga/socfpga_arria10.c +10 -0
+		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.

Quoted 6 lines
drivers/fpga/socfpga_arria10.c +6 -0
+	if (!strcmp("default", fpga_fsinfo->filename)) {
+		filename = env_get("CORE_RBF");
+		if (filename)
+			fpga_fsinfo->filename = filename;
+		else {
+			fpga_fsinfo->filename =

drivers/fpga/socfpga_arria10.c int socfpga_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size) · line 791

Quoted 10 lines
drivers/fpga/socfpga_arria10.c +10 -0
+				(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.

Quoted 90 lines
drivers/fpga/socfpga_arria10.c +84 -0
+
+	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
include/altera.h +0 -0
index ead5d3d..cf0c021 100644

include/altera.h typedef struct { · line 92

Quoted 10 lines
include/altera.h +4 -0
@@ -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

#3 lore raw

PATCH 2/3 enable fpga loadfs

In reply to tien.fong.chee at intel.com

From: Tien Fong Chee <[email protected]>

---
 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(-)
arch/arm/dts/socfpga_arria10.dtsi +12 -0
index b51febd..45aef6a 100644
@@ -48,6 +48,12 @@
 		      <0xffffc100 0x100>;
 	};
 
+	fs_loader0: fs-loader at 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 at 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 at ffc02200 {
arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts +6 -0
index 9c6070d..4b9705b 100644
@@ -18,6 +18,12 @@
 /dts-v1/;
 #include "socfpga_arria10_socdk.dtsi"
 
+/ {
+	chosen {
+		firmware-loader = &fs_loader0;
+	};
+};
+
 &mmc {
 	u-boot,dm-pre-reloc;
 	status = "okay";
configs/socfpga_arria10_defconfig +12 -0
index f24ea77..675f4da 100644
@@ -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
Signature · 1 line
1.7.7.4
#4 lore raw

PATCH 2/3 enable fpga loadfs

Quoted 14 lines · tien.fong.chee at intel.com

From: Tien Fong Chee <[email protected]>

---
 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(-)
arch/arm/dts/socfpga_arria10.dtsi +0 -0
index b51febd..45aef6a 100644

arch/arm/dts/socfpga_arria10.dtsi line 54

Quoted 7 lines
arch/arm/dts/socfpga_arria10.dtsi +4 -0
@@ -48,6 +48,12 @@
 		      <0xffffc100 0x100>;
 	};
 
+	fs_loader0: fs-loader at 0 {
+		u-boot,dm-pre-reloc;
+		compatible = "u-boot,fs-loader";
+		phandlepart = <&mmc 1>;

Which hardware does this describe ?
DT is hardware description ...

Quoted 1 line
arch/arm/dts/socfpga_arria10.dtsi +1 -0
+	};

[...]

Signature · 2 lines
Best regards,
Marek Vasut
#5 lore raw

PATCH 2/3 enable fpga loadfs

Quoted 11 lines · Marek Vasut
Quoted 10 lines · tien.fong.chee at intel.com

From: Tien Fong Chee <[email protected]>

---
 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(-)
Quoted 15 lines

arch/arm/dts/socfpga_arria10.dtsi line 54

Quoted 13 lines
arch/arm/dts/socfpga_arria10.dtsi +0 -0
index b51febd..45aef6a 100644
@@ -48,6 +48,12 @@
  		      <0xffffc100 0x100>;
  	};

arch/arm/dts/socfpga_arria10.dtsi +4 -0
+	fs_loader0: fs-loader at 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.

Quoted 4 lines
Quoted 3 lines
arch/arm/dts/socfpga_arria10.dtsi +1 -0
+	};

[...]

#6 lore raw

PATCH 2/3 enable fpga loadfs

Hi,

Quoted 27 lines · Tien Fong
Quoted 20 lines · Marek Vasut
Quoted 19 lines · tien.fong.chee at intel.com

From: Tien Fong Chee <[email protected]>

---
 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(-)
arch/arm/dts/socfpga_arria10.dtsi +0 -0
index b51febd..45aef6a 100644
@@ -48,6 +48,12 @@
                  <0xffffc100 0x100>;
    };
 
Quoted 6 lines

arch/arm/dts/socfpga_arria10.dtsi line 54

Quoted 4 lines
arch/arm/dts/socfpga_arria10.dtsi +4 -0
+   fs_loader0: fs-loader at 0 {
+           u-boot,dm-pre-reloc;
+           compatible = "u-boot,fs-loader";
+           phandlepart = <&mmc 1>;

Which hardware does this describe ?
DT is hardware description ...

Quoted 3 lines

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

#7 lore raw

PATCH 3/3 arm: socfpga: Add Arria 10 SoCFPGA programming interface

In reply to tien.fong.chee at intel.com

From: Tien Fong Chee <[email protected]>

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.

---
 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(-)
cmd/fpga.c +1 -1
index 14ad4e5..207cec3 100644
@@ -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
drivers/fpga/altera.c +33 -8

67 lines not on this page · raw message

drivers/fpga/fpga.c +8 -0
index 55bdf9e..67b772d 100644
@@ -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);
include/altera.h +2 -0
index cf0c021..b641b8a 100644
@@ -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
include/fpga.h +2 -0
index f444093..eee6fed 100644
@@ -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);
Signature · 1 line
1.7.7.4
#8 lore raw

PATCH 3/3 arm: socfpga: Add Arria 10 SoCFPGA programming interface

Quoted 41 lines · tien.fong.chee at intel.com

From: Tien Fong Chee <[email protected]>

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.

---
 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(-)
cmd/fpga.c +1 -1
index 14ad4e5..207cec3 100644
@@ -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
drivers/fpga/altera.c +1 -0
index 9605554..3c9474c 100644
@@ -12,6 +12,7 @@
  */
 #include <common.h>
 #include <errno.h>
+#include <altera.h>             /* altera specific definitions */
 #include <ACEX1K.h>
 #include <stratixII.h>
 

drivers/fpga/altera.c static const struct altera_fpga { · line 26

Quoted 4 lines
drivers/fpga/altera.c +1 -0
@@ -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.

Quoted 95 lines
drivers/fpga/altera.c +31 -8
 	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
drivers/fpga/fpga.c +8 -0
index 55bdf9e..67b772d 100644
@@ -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);
include/altera.h +2 -0
index cf0c021..b641b8a 100644
@@ -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
include/fpga.h +0 -0
index f444093..eee6fed 100644

include/fpga.h const fpga_desc *const fpga_get_desc(int devnum); · line 65

Quoted 10 lines
include/fpga.h +2 -0
@@ -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