public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Dalon L Westergreen <dalon.westergreen@linux.intel.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v7 3/7] ARM: socfpga: Add FPGA drivers for Arria 10 FPGA bitstream loading
Date: Fri, 01 Feb 2019 12:12:39 -0800	[thread overview]
Message-ID: <edc96b13cf16e87f3fa16029b82577a3cd24758c.camel@linux.intel.com> (raw)
In-Reply-To: <1548946304-17460-4-git-send-email-tien.fong.chee@intel.com>

On Thu, 2019-01-31 at 22:51 +0800, tien.fong.chee at intel.com wrote:
> From: Tien Fong Chee <tien.fong.chee@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.chee@intel.com>
> 
> ---
> 
> 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       |  18 +
>  .../include/mach/fpga_manager_arria10.h            |  39 +-
>  drivers/fpga/socfpga_arria10.c                     | 417
> ++++++++++++++++++++-
>  3 files changed, 457 insertions(+), 17 deletions(-)
> 
> diff --git a/arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts
> b/arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts
> index 998d811..dc55618 100644
> --- a/arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts
> +++ b/arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts
> @@ -18,6 +18,24 @@
>  /dts-v1/;
>  #include "socfpga_arria10_socdk.dtsi"
>  
> +/ {
> +	chosen {
> +		firmware-loader = &fs_loader0;
> +	};
> +
> +	fs_loader0: fs-loader at 0 {
> +		u-boot,dm-pre-reloc;
> +		compatible = "u-boot,fs-loader";
> +		phandlepart = <&mmc 1>;
> +	};
> +};
> +
> +&fpga_mgr {
> +	u-boot,dm-pre-reloc;
> +	altr,bitstream = "fit_spl_fpga.itb";
> +	altr,bitstream-core = "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..683c84c 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.
>   */
>  
> 
[...]	}
> +
> +	if (!is_fpgamgr_early_user_mode() || is_fpgamgr_user_mode()) {
> +		fpga_node_name = "fpga-1";
> +		printf("FPGA: Start to program peripheral bitstream ...\n");
> +	} else if (!is_fpgamgr_user_mode()) {
> +		fpga_node_name = "fpga-2";
> +		printf("FPGA: Start to program core bitstream ...\n");
> +	}

Why are you relying on the node name to define the core / periph RBF? Would
it not be better to define this in a property?  how would one have multiple
core and periph rbfs in a single fit image?

--dalon

> +
> +	node_offset = fit_image_get_node(buffer_p, fpga_node_name);
> +	if (node_offset < 0) {
> +		debug("FPGA: Could not find node '%s' in FIT\n",
> +		     fpga_node_name);
> +		return -ENOENT;
> +	}
> +
> +	const char *uname = fit_get_name(buffer_p, node_offset, NULL);
> +
> +	if (uname)
> +		debug("FPGA: %s\n", uname);
> +
> +	ret = fit_image_get_data_position(buffer_p, node_offset, &rbf_offset);
> +	if (ret < 0) {
> +		debug("FPGA: Could not find data position (err=%d)\n", ret);
> +		return -ENOENT;
> +	}
> +
> +	ret = fit_image_get_data_size(buffer_p, node_offset, &rbf_size);
> +	if (ret < 0) {
> +		debug("FPGA: Could not find data size (err=%d)\n", ret);
> +		return -ENOENT;
> +	}
> +
> +	ret = fit_image_get_load(buffer_p, node_offset, (ulong *)loadable);
> +	if (ret < 0) {
> +		debug("FPGA: Could not find loadable (err=%d)\n", ret);
> +		debug("FPGA: Using default buffer and size\n");
> +	} else {
> +		buffer_p = (u32 *)*loadable;
> +		buffer_size = rbf_size;
> +		debug("FPGA: Found loadable address = 0x%x\n", *loadable);
> +	}
> +
> +	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;
> +	}
> +
> +	/* Update next reading bitstream offset */
> +	fpga_loadfs->offset += buffer_size;
> +
> +	/* Getting info about bitstream types */
> +	get_rbf_image_info(&fpga_loadfs->rbfinfo, (u16 *)buffer_p);
> +
> +	/* 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;
> +	u32 buffer = (u32)buf;
> +	size_t buffer_sizebytes = bsize;
> +	size_t buffer_sizebytes_ori = bsize;
> +	size_t total_sizeof_image = 0;
> +	struct udevice *dev;
> +
> +	ret = uclass_get_device(UCLASS_FS_FIRMWARE_LOADER, 0, &dev);
> +	if (ret)
> +		return ret;
> +
> +	memset(&fpga_loadfs, 0, sizeof(fpga_loadfs));
> +
> +	WATCHDOG_RESET();
> +
> +	fpga_loadfs.fpga_fsinfo = fpga_fsinfo;
> +	fpga_loadfs.offset = offset;
> +
> +	printf("FPGA: Start to program ...\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)
> +		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;
> +	}
> +
> +	/* 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;
> +		}
> +	}
> +
> +	WATCHDOG_RESET();
> +
> +	/* Transfer bitstream to FPGA Manager */
> +	fpgamgr_program_write((void *)buffer, buffer_sizebytes);
> +
> +	total_sizeof_image += buffer_sizebytes;
> +
> +	WATCHDOG_RESET();
> +
> +	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;
> +}
> +#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;
>  
> -	/* disable all signals from hps peripheral controller to fpga */
> +	memset(&rbfinfo, 0, sizeof(rbfinfo));
> +
> +	/* 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) */
>  	socfpga_bridges_reset();
>  
> -	/* Initialize the FPGA Manager */
> -	status = fpgamgr_program_init((u32 *)rbf_data, rbf_size);
> -	if (status)
> -		return status;
> +	/* Getting info about bitstream types */
> +	get_rbf_image_info(&rbfinfo, (u16 *)rbf_data);
> +
> +	if (rbfinfo.section == periph_section) {
> +		/* Initialize the FPGA Manager */
> +		status = fpgamgr_program_init((u32 *)rbf_data, rbf_size);
> +		if (status)
> +			return status;
> +	}
> +
> +	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;
> +	}
>  
> -	/* Write the RBF data to FPGA Manager */
> +	/* 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;
>  }

  parent reply	other threads:[~2019-02-01 20:12 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-31 14:51 [U-Boot] [PATCH v7 0/7] Add support for loading FPGA bitstream tien.fong.chee at intel.com
2019-01-31 14:51 ` [U-Boot] [PATCH v7 1/7] ARM: socfpga: Description on FPGA bitstream type and file name for Arria 10 tien.fong.chee at intel.com
2019-01-31 14:54   ` Marek Vasut
2019-02-01  3:48     ` Chee, Tien Fong
2019-02-01  8:25       ` Marek Vasut
2019-02-01 16:02         ` Chee, Tien Fong
2019-02-01 20:02           ` Dalon L Westergreen
2019-02-01 20:29             ` Dalon L Westergreen
2019-02-02  2:37               ` Chee, Tien Fong
2019-02-05  8:46           ` Marek Vasut
2019-02-11  5:36             ` Chee, Tien Fong
2019-02-11 11:01               ` Marek Vasut
2019-02-11 16:33                 ` Dalon L Westergreen
2019-02-11 17:01                 ` Chee, Tien Fong
2019-02-11 17:19                   ` Westergreen, Dalon
2019-02-12  9:35                     ` Chee, Tien Fong
2019-02-12  9:43                       ` Marek Vasut
2019-02-12 10:13                         ` Chee, Tien Fong
2019-02-12 10:17                           ` Marek Vasut
2019-02-12 13:49                             ` Dalon L Westergreen
2019-02-12 14:06                               ` Chee, Tien Fong
2019-01-31 14:51 ` [U-Boot] [PATCH v7 2/7] ARM: socfpga: Add default FPGA bitstream fitImage for Arria10 SoCDK tien.fong.chee at intel.com
2019-01-31 14:54   ` Marek Vasut
2019-02-01  3:59     ` Chee, Tien Fong
2019-02-01  8:29       ` Marek Vasut
2019-02-01 16:50         ` Chee, Tien Fong
2019-02-05  8:51           ` Marek Vasut
2019-02-11  6:23             ` Chee, Tien Fong
2019-02-11 11:06               ` Marek Vasut
2019-02-11 16:20                 ` Chee, Tien Fong
2019-01-31 14:51 ` [U-Boot] [PATCH v7 3/7] ARM: socfpga: Add FPGA drivers for Arria 10 FPGA bitstream loading tien.fong.chee at intel.com
2019-01-31 14:55   ` Marek Vasut
2019-02-01  4:04     ` Chee, Tien Fong
2019-02-01  8:29       ` Marek Vasut
2019-02-01 16:50         ` Chee, Tien Fong
2019-02-13  8:22         ` Chee, Tien Fong
2019-02-13 12:00           ` Marek Vasut
2019-02-13 12:15             ` Chee, Tien Fong
2019-02-13 12:34               ` Marek Vasut
2019-02-01 20:12   ` Dalon L Westergreen [this message]
2019-02-02  3:27     ` Chee, Tien Fong
2019-02-05  8:41       ` Marek Vasut
2019-02-11 11:19         ` Chee, Tien Fong
2019-01-31 14:51 ` [U-Boot] [PATCH v7 4/7] ARM: socfpga: Add the configuration for FPGA SoCFPGA A10 SoCDK tien.fong.chee at intel.com
2019-01-31 14:57   ` Marek Vasut
2019-02-01  4:07     ` Chee, Tien Fong
2019-01-31 14:51 ` [U-Boot] [PATCH v7 5/7] spl : socfpga: Implement fpga bitstream loading with socfpga loadfs tien.fong.chee at intel.com
2019-01-31 14:51 ` [U-Boot] [PATCH v7 6/7] ARM: socfpga: Synchronize the configuration for A10 SoCDK tien.fong.chee at intel.com
2019-01-31 14:51 ` [U-Boot] [PATCH v7 7/7] ARM: socfpga: Increase Malloc pool size to support FAT filesystem in SPL tien.fong.chee at intel.com
2019-01-31 14:58   ` Marek Vasut
2019-02-01  4:11     ` Chee, Tien Fong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=edc96b13cf16e87f3fa16029b82577a3cd24758c.camel@linux.intel.com \
    --to=dalon.westergreen@linux.intel.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox