How to use AXI bridge with Arria10 HPS

Hi there,

I am trying to implement some features using AXI interface.(Lightweight HPS-to-FPGA)
The address of Lightweight AXI Bridge is 0xFF200000.
So, I modified the device tree for using Lightweight AXI bridge.
After that, I used mmap function and access led_pio offest(0x0010) to check whether AXI bridge is working.

I modified device tree like below.
(arch/arm/boot/dts/socfpga_arria10.dtsi)

/ {
...
    soc {
...
		fpga_mgr: fpga-mgr@ffd03000 {
			compatible = "altr,socfpga-a10-fpga-mgr";
			reg = <0xffd03000 0x100
			       0xffcfe400 0x20>;
			clocks = <&l4_mp_clk>;
			resets = <&rst FPGAMGR_RESET>;
			reset-names = "fpgamgr";
		};

+		fpga_bridge0: fpga-bridge@ff200000 {
+			compatible = "altr,socfpga-lwhps2fpga-bridge";
+			reg = <0xff200000 0x100000>;
+			resets = <&rst LWHPS2FPGA_RESET>;
+			clocks = <&l4_main_clk>;
+			bridge-enable = <1>;

			//linux-socfpga.a9/Documentation/devicetree/bindings/fpga/fpga-region.txt
+			#address-cells = <1>;			#size-cells = <1>;
+			ranges;
+
+			fpga_region0: fpga-region0 {
+				compatible = "fpga-region";
+				fpga-mgr = <&fpga_mgr>;
+
+				// linux-socfpga.a9/Documentation/devicetree/bindings/fpga/fpga-region.txt, Required properties:
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges;
+			};
+		};

+		// linux-socfpga.a9/Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt
+		fpga_bridge1: fpga-bridge@c0000000 {
+			compatible = "altr,socfpga-hps2fpga-bridge";
+			reg = <0xc0000000 0x10000>;
+			resets = <&rst HPS2FPGA_RESET>;
+			clocks = <&l4_main_clk>;
+			bridge-enable = <0>;
+		};
...
    };
...
};

And I also run my application(user space).

#define LW_HPS_TO_FPGA_BASE		0xFF200000
#define HW_REGS_BASE		LW_HPS_TO_FPGA_BASE
#define HW_REGS_SPAN		0x200000
#define LED_PIO_BASE		0x0010//0x120
#define LED_PIO_DATA_WIDITH	4


	void *virtual_base = NULL;
	int fd = 0;
	uint32_t *h2f_lw_led_pio_vaddr = NULL;

	fd = open("/dev/mem", O_RDWR | O_SYNC);

	virtual_base = mmap(NULL, HW_REGS_SPAN, ( PROT_READ | PROT_WRITE ), MAP_SHARED, fd, HW_REGS_BASE);
    
	if (virtual_base == (void*)-1 ) {
		perror("mmap()");
		exit(1);
	}

	h2f_lw_led_pio_vaddr = (uint32_t *)virtual_base + (LED_PIO_BASE);


	uint32_t val = 1;
	while(loop_count < 30)
	{
		if (loop_count % 2 == 0) {
			*h2f_lw_led_pio_vaddr = 0x0;
		}
		else {
			*h2f_lw_led_pio_vaddr = 0xF;
		}

		loop_count++;
		usleep(300 * 1000);
	}

	close(fd);

But, the led_pio wasn’t blinking.
Is there any example how to use axi interface?

Many thanks,
Jung.

After 2 month from writing this post, I still have same problem.
But I found a defectt in u-boot-socfpga code.
I found these several important points for using Bridge feature.

FPGA design files(core.rbf, periph.rbf)

In Arria 10 SoC, FPGA Design file is devided into two files.

  • xxx.core.rbf: the file related to FPGA design file.
  • xxx.periph.rbf: the file related to peripheral file(DDR, etc.)
    The periph.rbf file seems that important.
    Because Altera SoC use EMIF IP for using HPS-to-FPGA AXI bridges.

Early IO release Mode

In Arria 10 SoC, there is the Early IO release Mode.
This mode means that SPL loads rbf files for programming FPGA.
The Altera employees or GSRD documents said that this mode is run by default.
But, there is an customizing point for using this mode.
I think this below log(“Skipping configuration”) is strange.
Log said that skipping configuration. but Early Release Succeed?
I think this log is strange. So I looked into it deeper.

FPGA: Checking FPGA configuration setting ...
FPGA: Skipping configuration ...
FPGA: Early Release Succeeded.

(I am using Arria 10 Soc Development, QSPI boot mode.)

In this below code, spl load rbf files from flash by using configurations names(“fpga-periph”, “fpga-core”).
But in fit_spl_fpga.its, the configuration names are “fpga-periph-1”, “fpga-core-1”.
Because of this mismatch of configuration, rbf configuration is not completed properly.
But, error log is not printed. Because of the log level.
Error log is replaced with debug log. And error return is ignored. Althogh there is an error, it is disguised as successful operation.
But they said that regenerating is needed…
(u-boot-socfpga/drivers/fpga/socfpga_arria10.c)

static int first_loading_rbf_to_buffer(struct udevice *dev,
				struct fpga_loadfs_info *fpga_loadfs,
				u32 *buffer, size_t *buffer_bsize,
				size_t *buffer_bsize_ori)
{
//...

	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") && // "fpga-periph-1" in fit_spl_fpga.its
				(!is_fpgamgr_early_user_mode() ||
				is_fpgamgr_user_mode() ||
				is_periph_program_force())) {
				fpga_node_name = uname;
				printf("FPGA: Start to program ");
				printf("peripheral/full bitstream ...\n");
				break;
			} else if (strstr(uname, "fpga-core") && // "fpga-core-1" in fit_spl_fpga.its
					(is_fpgamgr_early_user_mode() &&
					!is_fpgamgr_user_mode())) {
				fpga_node_name = uname;
				printf("FPGA: Start to program core ");
				printf("bitstream ...\n");
				break;
			}
		}
		schedule();
	}
	
	if (!fpga_node_name) {//foga_node_name is null.
		debug("FPGA: No suitable bitstream was found, count: %d.\n", i);//because of log level, this log is not printed.
		return 1;
	}
//...
}

(Solved: Re:How to program FPGA in Arria 10 HPS? - Intel Community)
In conclusion, in ordered to run this mode properly,
fit_spl_fpga.its should be modified like below.
(u-boot-socfpga/board/altera/arria10-socdk/fit_spl_fpga.its)

/dts-v1/;

/ {
	description = "FIT image with FPGA bistream";
	#address-cells = <1>;

	images {
		fpga-periph {//modifed: "fpga-periph-1" -> "fpga-periph"
			description = "FPGA peripheral bitstream";
			data = /incbin/("../../../ghrd_10as066n2.periph.rbf");
			type = "fpga";
			arch = "arm";
			compression = "none";
		};

		fpga-core {//modified: "fpga-core-1" -> "fpga-core"
			description = "FPGA core bitstream";
			data = /incbin/("../../../ghrd_10as066n2.core.rbf");
			type = "fpga";
			arch = "arm";
			compression = "none";
		};
	};

	configurations {
		default = "config-1";
		config-1 {
			description = "Boot with FPGA early IO release config";
                        //"fpga-core-1" -> "fpga-core", "fpga-periph-1" -> "fpga-periph"
			fpga = "fpga-periph", "fpga-core";
		};
	};
};

further reference:
(Solved: Arria 10 SoC FPGA Remote update via HPS/linux - Intel Community)

Although there is a few people reading this community, I wish my experience will be helpful to somone.