Hello,
here is more information
the device tree:
#include "socfpga_cyclone5.dtsi"
/ {
model = "Model";
compatible = "altr,socfpga-cyclone5", "altr,socfpga";
chosen {
bootargs = "earlyprintk";
stdout-path = "serial0:115200n8";
};
memory@0{
name = "memory";
device_type = "memory";
reg = <0x0 0x40000000>; /* 1GB */
};
aliases {
/* this allow the ethaddr uboot environmnet variable contents
* to be added to the gmac1 device tree blob.
*/
ethernet0 = &gmac1;
rtc0 = &mcp_rtc;
};
regulator_3_3v: vcc3p3-regulator {
compatible = "regulator-fixed";
regulator-name = "VCC3P3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
fpga_bridge3: fpga-bridge@ffc25080 {
compatible = "altr,socfpga-fpga2sdram-bridge";
reg = <0xffc25080 0x4>;
};
msgdma_wr: msgdma_wr@0xff204000 {
compatible = "msgdma_wr";
reg = <0xff204000 0x40>;
interrupt-parent = <&intc>;
interrupts = <0 40 4>;
};
msgdma_rd: msgdma_rd@0xff204040 {
compatible = "msgdma_rd";
reg = <0xff204040 0x40>;
interrupt-parent = <&intc>;
interrupts = <0 41 4>;
};
};
&gmac1 {
status = "okay";
phy-mode = "rgmii";
/* 0 bis 900*/
rxd0-skew-ps = <420>;
rxd1-skew-ps = <420>;
rxd2-skew-ps = <420>;
rxd3-skew-ps = <420>;
rxdv-skew-ps = <420>;
txd0-skew-ps = <360>;
txd1-skew-ps = <360>;
txd2-skew-ps = <360>;
txd3-skew-ps = <360>;
txen-skew-ps = <360>;
/* 0 bis 1860*/
rxc-skew-ps = <1680>;
txc-skew-ps = <1740>;
max-frame-size = <3800>;
};
&i2c0 {
status = "okay";
speed-mode = <0>;
i2c-switch@70 {
compatible = "nxp,pca9548";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x70>;
i2c@1{
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
mcp_rtc: rtc@6f{
compatible = "microchip,mcp7941x";
reg = <0x6F>;
};
};
};
};
&i2c1 {
status = "okay";
speed-mode = <0>;
gpioexp@20 {
compatible = "ti,tca6416";
reg = <0x20>;
};
e2prom@50 {
compatible = "at,24c01";
reg = <0x50>;
};
tempsens@48 {
compatible = "ti,tmp108";
reg = <0x48>;
status = "okay";
};
};
&mmc0 {
vmmc-supply = <®ulator_3_3v>;
vqmmc-supply = <®ulator_3_3v>;
status = "okay";
};
&usb1 {
status = "okay";
};
&gpio0 {
status = "okay";
};
&gpio1 {
status = "okay";
};
&gpio2 {
status = "okay";
};
the overlay file:
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target-path = "/soc/base-fpga-region";
__overlay__ {
firmware-name = "socfpga.rbf";
fpga-bridges = <&fpga_bridge0>, <&fpga_bridge1>, <&fpga_bridge3>;
};
};
};
the firmware is written at runtime.
I modified some code for publication purposes (not tested for compilation):
std::string fpga::write_firmware(void)
{
std::string msg;
char *dir = nullptr;
char *dir_ch = nullptr;
m_firmware_ok = false;
dir_ch = strdup("/sys/kernel/config/device-tree/overlays/m3/path");
if(dir_ch == nullptr)
msg ="Can not malloc memory for /sys/kernel/config/device-tree/overlays/m3/path";
if(msg.empty() == true)
{
dir = dirname(dir_ch);
if(dir == nullptr)
msg = "Can not malloc memory for dirname";
}
if(msg.empty() == true)
{
if(set_enable(false).is_error())
msg = "Enable not switched off";
}
if(msg.empty() == true)
{
if(chdir(dir) == 0)
{
if(rmdir(dir) != 0)
msg = "Could not delete sysfs";
}
}
if(msg.empty() == true)
{
if(mkdir(dir, S_IRWXU) != 0)
msg = "Could not create sysfs";
}
if(msg.empty() == true)
{
std::ofstream wpd("/sys/kernel/config/device-tree/overlays/m3/path");
wpd << socfpga_overlay.dtb";
wpd.close();
if(wpd.fail())
{
msg = "Could not open fpga fw errno: " + std::to_string(errno);
}
}
if(msg.is_no_error())
{
WORD timeout = 0;
bool finished_bridge = false;
bool finished_manager = false;
do
{
if(!(finished_bridge && finished_manager))
ica::chrono::sleep_for(std::chrono::milliseconds(3000));
finished_bridge = get_bridge_state();
finished_manager = get_fpga_manager_state();
timeout++;
}while(timeout < ica::fpga::timeout_bridge_restart && !(finished_bridge && finished_manager));
if(timeout == 10)
msg = "FPGA bridge or manager not okay";
}
if(msg.empty() == true)
{
if(set_enable(true).is_error())
msg = "FPGA enable not on";
}
if(msg.empty() == true)
m_firmware_ok = true;
if(dir_ch != nullptr)
free(dir_ch);
return msg;
}