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