Forum Discussion
qwitza
Occasional Contributor
7 months agoHello,
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; }