1.. SPDX-License-Identifier: GPL-2.0+ 2.. Copyright (C) 2018-2019 Intel Corporation <www.intel.com> 3 4File System Firmware Loader 5=========================== 6 7This is file system firmware loader for U-Boot framework, which has very close 8to some Linux Firmware API. For the details of Linux Firmware API, you can refer 9to https://01.org/linuxgraphics/gfx-docs/drm/driver-api/firmware/index.html. 10 11File system firmware loader can be used to load whatever(firmware, image, 12and binary) from the storage device in file system format into target location 13such as memory, then consumer driver such as FPGA driver can program FPGA image 14from the target location into FPGA. 15 16To enable firmware loader, CONFIG_FS_LOADER need to be set at 17<board_name>_defconfig such as "CONFIG_FS_LOADER=y". 18 19Firmware Loader API core features 20--------------------------------- 21 22Firmware storage device described in device tree source 23------------------------------------------------------- 24For passing data like storage device phandle and partition where the 25firmware loading from to the firmware loader driver, those data could be 26defined in fs-loader node as shown in below: 27 28Example for block device:: 29 30 fs_loader0: fs-loader { 31 u-boot,dm-pre-reloc; 32 compatible = "u-boot,fs-loader"; 33 phandlepart = <&mmc 1>; 34 }; 35 36<&mmc 1> means block storage device pointer and its partition. 37 38Above example is a description for block storage, but for UBI storage 39device, it can be described in FDT as shown in below: 40 41Example for ubi:: 42 43 fs_loader1: fs-loader { 44 u-boot,dm-pre-reloc; 45 compatible = "u-boot,fs-loader"; 46 mtdpart = "UBI", 47 ubivol = "ubi0"; 48 }; 49 50Then, firmware-loader property can be added with any device node, which 51driver would use the firmware loader for loading. 52 53The value of the firmware-loader property should be set with phandle 54of the fs-loader node. For example:: 55 56 firmware-loader = <&fs_loader0>; 57 58If there are majority of devices using the same fs-loader node, then 59firmware-loader property can be added under /chosen node instead of 60adding to each of device node. 61 62For example:: 63 64 /{ 65 chosen { 66 firmware-loader = <&fs_loader0>; 67 }; 68 }; 69 70In each respective driver of devices using firmware loader, the firmware 71loaded instance should be created by DT phandle. 72 73For example of getting DT phandle from /chosen and creating instance: 74 75.. code-block:: c 76 77 chosen_node = ofnode_path("/chosen"); 78 if (!ofnode_valid(chosen_node)) { 79 debug("/chosen node was not found.\n"); 80 return -ENOENT; 81 } 82 83 phandle_p = ofnode_get_property(chosen_node, "firmware-loader", &size); 84 if (!phandle_p) { 85 debug("firmware-loader property was not found.\n"); 86 return -ENOENT; 87 } 88 89 phandle = fdt32_to_cpu(*phandle_p); 90 ret = uclass_get_device_by_phandle_id(UCLASS_FS_FIRMWARE_LOADER, 91 phandle, &dev); 92 if (ret) 93 return ret; 94 95Firmware loader driver is also designed to support U-boot environment 96variables, so all these data from FDT can be overwritten 97through the U-boot environment variable during run time. 98 99For examples: 100 101storage_interface: 102 Storage interface, it can be "mmc", "usb", "sata" or "ubi". 103fw_dev_part: 104 Block device number and its partition, it can be "0:1". 105fw_ubi_mtdpart: 106 UBI device mtd partition, it can be "UBI". 107fw_ubi_volume: 108 UBI volume, it can be "ubi0". 109 110When above environment variables are set, environment values would be 111used instead of data from FDT. 112The benefit of this design allows user to change storage attribute data 113at run time through U-boot console and saving the setting as default 114environment values in the storage for the next power cycle, so no 115compilation is required for both driver and FDT. 116 117File system firmware Loader API 118------------------------------- 119 120.. code-block:: c 121 122 int request_firmware_into_buf(struct udevice *dev, 123 const char *name, 124 void *buf, size_t size, u32 offset) 125 126Load firmware into a previously allocated buffer 127 128Parameters: 129 130* struct udevice \*dev: An instance of a driver 131* const char \*name: name of firmware file 132* void \*buf: address of buffer to load firmware into 133* size_t size: size of buffer 134* u32 offset: offset of a file for start reading into buffer 135 136Returns: 137 size of total read 138 -ve when error 139 140Description: 141 The firmware is loaded directly into the buffer pointed to by buf 142 143Example of calling request_firmware_into_buf API after creating firmware loader 144instance: 145 146.. code-block:: c 147 148 ret = uclass_get_device_by_phandle_id(UCLASS_FS_FIRMWARE_LOADER, 149 phandle, &dev); 150 if (ret) 151 return ret; 152 153 request_firmware_into_buf(dev, filename, buffer_location, buffer_size, 154 offset_ofreading); 155