"Das U-Boot" Source Tree
at master 510 lines 17 kB view raw
1/* SPDX-License-Identifier: GPL-2.0+ */ 2/* 3 * (C) Copyright 2007 4 * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com 5 */ 6 7#ifndef __FDT_SUPPORT_H 8#define __FDT_SUPPORT_H 9 10#if !defined(USE_HOSTCC) 11 12#include <asm/u-boot.h> 13#include <linux/libfdt.h> 14#include <abuf.h> 15 16/** 17 * arch_fixup_fdt() - write arch-specific information to fdt 18 * 19 * @blob: FDT blob to write to 20 * 21 * Defined in arch/$(ARCH)/lib/bootm-fdt.c 22 * 23 * Return: 0 if ok, or -ve FDT_ERR_... on failure 24 */ 25int arch_fixup_fdt(void *blob); 26 27void ft_cpu_setup(void *blob, struct bd_info *bd); 28 29void ft_pci_setup(void *blob, struct bd_info *bd); 30 31u32 fdt_getprop_u32_default_node(const void *fdt, int off, int cell, 32 const char *prop, const u32 dflt); 33u32 fdt_getprop_u32_default(const void *fdt, const char *path, 34 const char *prop, const u32 dflt); 35 36/** 37 * fdt_root() - add data to the root of the FDT before booting the OS 38 * 39 * @fdt: FDT address in memory 40 * 41 * See doc/device-tree-bindings/root.txt 42 * 43 * Return: 0 if ok, or -FDT_ERR_... on error 44 */ 45int fdt_root(void *fdt); 46 47/** 48 * fdt_chosen() - add chosen data the FDT before booting the OS 49 * 50 * @fdt: FDT address in memory 51 * 52 * In particular, this adds the kernel command line (bootargs) to the FDT. 53 * 54 * Return: 0 if ok, or -FDT_ERR_... on error 55 */ 56int fdt_chosen(void *fdt); 57 58/** 59 * fdt_initrd() - add initrd information to the FDT before booting the OS 60 * 61 * @fdt: Pointer to FDT in memory 62 * @initrd_start: Start of ramdisk 63 * @initrd_end: End of ramdisk 64 * 65 * Adds linux,initrd-start and linux,initrd-end properties to the /chosen node, 66 * creating it if necessary. 67 * 68 * A memory reservation for the ramdisk is added to the FDT, or an existing one 69 * (with matching @initrd_start) updated. 70 * 71 * If @initrd_start == @initrd_end this function does nothing and returns 0. 72 * 73 * Return: 0 if ok, or -FDT_ERR_... on error 74 */ 75int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end); 76 77void do_fixup_by_path(void *fdt, const char *path, const char *prop, 78 const void *val, int len, int create); 79void do_fixup_by_path_u32(void *fdt, const char *path, const char *prop, 80 u32 val, int create); 81 82static inline void do_fixup_by_path_string(void *fdt, const char *path, 83 const char *prop, const char *status) 84{ 85 do_fixup_by_path(fdt, path, prop, status, strlen(status) + 1, 1); 86} 87 88void do_fixup_by_prop(void *fdt, 89 const char *pname, const void *pval, int plen, 90 const char *prop, const void *val, int len, 91 int create); 92void do_fixup_by_prop_u32(void *fdt, 93 const char *pname, const void *pval, int plen, 94 const char *prop, u32 val, int create); 95void do_fixup_by_compat(void *fdt, const char *compat, 96 const char *prop, const void *val, int len, int create); 97void do_fixup_by_compat_u32(void *fdt, const char *compat, 98 const char *prop, u32 val, int create); 99/** 100 * fdt_fixup_memory() - setup the memory node in the DT 101 * 102 * @blob: FDT blob to update 103 * @start: Begin of DRAM mapping in physical memory 104 * @size: Size of the single memory bank 105 * 106 * Setup the memory node in the DT. Creates one if none was existing before. 107 * Calls fdt_fixup_memory_banks() to populate a single reg pair covering the 108 * whole memory. 109 * 110 * Return: 0 if ok, or -1 or -FDT_ERR_... on error 111 */ 112int fdt_fixup_memory(void *blob, u64 start, u64 size); 113 114/** 115 * fdt_fixup_memory_banks() - fill the DT mem node with multiple memory banks 116 * 117 * @blob: FDT blob to update 118 * @start: Array of size <banks> to hold the start addresses. 119 * @size: Array of size <banks> to hold the size of each region. 120 * @banks: Number of memory banks to create. If 0, the reg property 121 * will be left untouched. 122 * 123 * Fill the DT memory node with multiple memory banks. 124 * Creates the node if none was existing before. 125 * If banks is 0, it will not touch the existing reg property. This allows 126 * boards to not mess with the existing DT setup, which may have been 127 * filled in properly before. 128 * 129 * Return: 0 if ok, or -1 or -FDT_ERR_... on error 130 */ 131#ifdef CONFIG_ARCH_FIXUP_FDT_MEMORY 132int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[], int banks); 133int fdt_set_usable_memory(void *blob, u64 start[], u64 size[], int banks); 134#else 135static inline int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[], 136 int banks) 137{ 138 return 0; 139} 140#endif 141 142void fdt_fixup_ethernet(void *fdt); 143int fdt_find_and_setprop(void *fdt, const char *node, const char *prop, 144 const void *val, int len, int create); 145void fdt_fixup_qe_firmware(void *fdt); 146 147/** 148 * fdt_fixup_display() - update native-mode property of display-timings 149 * 150 * @blob: FDT blob to update 151 * @path: path within dt 152 * @display: name of display timing to match 153 * 154 * Update native-mode property of display-timings node to the phandle 155 * of the timings matching a display by name (case insensitive). 156 * 157 * see kernel Documentation/devicetree/bindings/video/display-timing.txt 158 * 159 * Return: 0 if ok, or -FDT_ERR_... on error 160 */ 161int fdt_fixup_display(void *blob, const char *path, const char *display); 162 163#if defined(CONFIG_USB_EHCI_FSL) || defined(CONFIG_USB_XHCI_FSL) 164void fsl_fdt_fixup_dr_usb(void *blob, struct bd_info *bd); 165#else 166static inline void fsl_fdt_fixup_dr_usb(void *blob, struct bd_info *bd) {} 167#endif /* defined(CONFIG_USB_EHCI_FSL) || defined(CONFIG_USB_XHCI_FSL) */ 168 169#if defined(CONFIG_SYS_FSL_SEC_COMPAT) 170void fdt_fixup_crypto_node(void *blob, int sec_rev); 171#else 172static inline void fdt_fixup_crypto_node(void *blob, int sec_rev) {} 173#endif 174 175/** 176 * fdt_record_loadable() - record info about a loadable in /fit-images 177 * 178 * @blob: FDT blob to update 179 * @index: index of this loadable 180 * @name: name of the loadable 181 * @load_addr: address the loadable was loaded to 182 * @size: number of bytes loaded 183 * @entry_point: entry point (if specified, otherwise pass -1) 184 * @type: type (if specified, otherwise pass NULL) 185 * @os: os-type (if specified, otherwise pass NULL) 186 * @arch: architecture (if specified, otherwise pass NULL) 187 * 188 * Record information about a processed loadable in /fit-images (creating 189 * /fit-images if necessary). 190 * 191 * Return: 0 if ok, or -1 or -FDT_ERR_... on error 192 */ 193int fdt_record_loadable(void *blob, u32 index, const char *name, 194 uintptr_t load_addr, u32 size, uintptr_t entry_point, 195 const char *type, const char *os, const char *arch); 196 197#ifdef CONFIG_PCI 198#include <pci.h> 199int fdt_pci_dma_ranges(void *blob, int phb_off, struct pci_controller *hose); 200#endif 201 202int fdt_find_or_add_subnode(void *fdt, int parentoffset, const char *name); 203 204/** 205 * ft_board_setup() - add board-specific data to the FDT before booting the OS 206 * 207 * @blob: FDT blob to update 208 * @bd: Pointer to board data 209 * 210 * Use CONFIG_SYS_FDT_PAD to ensure there is sufficient space. 211 * This function is called if CONFIG_OF_BOARD_SETUP is defined 212 * 213 * Return: 0 if ok, or -FDT_ERR_... on error 214 */ 215int ft_board_setup(void *blob, struct bd_info *bd); 216 217/** 218 * board_rng_seed() - provide a seed to be passed via /chosen/rng-seed 219 * 220 * @buf: a struct abuf for returning the seed and its size. 221 * 222 * This function is called if CONFIG_BOARD_RNG_SEED is set, and must 223 * be provided by the board. It should return, via @buf, some suitable 224 * seed value to pass to the kernel. Seed size could be set in a decimal 225 * environment variable rng_seed_size and it defaults to 64 bytes. 226 * 227 * Return: 0 if ok, negative on error. 228 */ 229int board_rng_seed(struct abuf *buf); 230 231/** 232 * board_fdt_chosen_bootargs() - arbitrarily amend fdt kernel command line 233 * 234 * @fdt_ba: FDT /chosen/bootargs property from the kernel image if available 235 * 236 * This is used for late modification of kernel command line arguments just 237 * before they are added into the /chosen node in flat device tree. 238 * 239 * Return: pointer to kernel command line arguments in memory 240 */ 241const char *board_fdt_chosen_bootargs(const struct fdt_property *fdt_ba); 242 243/* 244 * The keystone2 SOC requires all 32 bit aliased addresses to be converted 245 * to their 36 physical format. This has to happen after all fdt nodes 246 * are added or modified by the image_setup_libfdt(). The ft_board_setup_ex() 247 * called at the end of the image_setup_libfdt() is to do that convertion. 248 */ 249void ft_board_setup_ex(void *blob, struct bd_info *bd); 250 251/** 252 * ft_system_setup() - add system-specific data to the FDT before booting the OS 253 * 254 * @blob: FDT blob to update 255 * @bd: pointer to board data 256 * 257 * Use CONFIG_SYS_FDT_PAD to ensure there is sufficient space. 258 * This function is called if CONFIG_OF_SYSTEM_SETUP is defined 259 * 260 * Return: 0 if ok, or -FDT_ERR_... on error 261 */ 262int ft_system_setup(void *blob, struct bd_info *bd); 263 264void set_working_fdt_addr(ulong addr); 265 266/** 267 * fdt_shrink_to_minimum() - shrink FDT while allowing for some margin 268 * 269 * @blob: FDT blob to update 270 * @extrasize: additional bytes needed 271 * 272 * Shrink down the given blob to 'minimum' size + some extrasize. 273 * 274 * The new size is enough to hold the existing contents plus @extrasize bytes, 275 * plus 5 memory reservations. Also, the end of the FDT is aligned to a 4KB 276 * boundary, so it might end up up to 4KB larger than needed. 277 * 278 * If there is an existing memory reservation for @blob in the FDT, it is 279 * updated for the new size. 280 * 281 * Return: 0 if ok, or -FDT_ERR_... on error 282 */ 283int fdt_shrink_to_minimum(void *blob, uint extrasize); 284 285int fdt_increase_size(void *fdt, int add_len); 286 287int fdt_delete_disabled_nodes(void *blob); 288 289struct node_info; 290#if defined(CONFIG_FDT_FIXUP_PARTITIONS) 291void fdt_fixup_mtdparts(void *fdt, const struct node_info *node_info, 292 int node_info_size); 293#else 294static inline void fdt_fixup_mtdparts(void *fdt, 295 const struct node_info *node_info, 296 int node_info_size) 297{ 298} 299#endif 300 301/** 302 * fdt_copy_fixed_partitions() - copy the fixed-partition nodes 303 * 304 * @blob: FDT blob to update 305 * 306 * Copy the fixed-partition nodes from U-Boot device tree to external blob 307 * 308 * Return: 0 if ok, or non-zero on error 309 */ 310int fdt_copy_fixed_partitions(void *blob); 311 312void fdt_del_node_and_alias(void *blob, const char *alias); 313 314/** 315 * fdt_translate_address() - translate an addr from the DT into a CPU phys addr 316 * 317 * @blob: pointer to device tree blob 318 * @node_offset: node DT offset 319 * @in_addr: pointer to the address to translate 320 * 321 * The translation relies on the "ranges" property. 322 * 323 * Return: translated address or OF_BAD_ADDR on error 324 */ 325u64 fdt_translate_address(const void *blob, int node_offset, 326 const __be32 *in_addr); 327/** 328 * fdt_translate_dma_address() - translate a DMA address to a CPU phys address 329 * 330 * @blob: pointer to device tree blob 331 * @node_offset: node DT offset 332 * @in_addr: pointer to the DMA address to translate 333 * 334 * Translate a DMA address from the DT into a CPU physical address. 335 * The translation relies on the "dma-ranges" property. 336 * 337 * Return: translated DMA address or OF_BAD_ADDR on error 338 */ 339u64 fdt_translate_dma_address(const void *blob, int node_offset, 340 const __be32 *in_addr); 341 342/** 343 * fdt_get_dma_range() - get DMA ranges to perform bus/cpu translations 344 * 345 * @blob: pointer to device tree blob 346 * @node_offset: node DT offset 347 * @cpu: pointer to variable storing the range's cpu address 348 * @bus: pointer to variable storing the range's bus address 349 * @size: pointer to variable storing the range's size 350 * 351 * Get DMA ranges for a specifc node, this is useful to perform bus->cpu and 352 * cpu->bus address translations 353 * 354 * Return: translated DMA address or OF_BAD_ADDR on error 355 */ 356int fdt_get_dma_range(const void *blob, int node_offset, phys_addr_t *cpu, 357 dma_addr_t *bus, u64 *size); 358 359int fdt_node_offset_by_compat_reg(void *blob, const char *compat, 360 phys_addr_t compat_off); 361int fdt_node_offset_by_pathf(void *blob, const char *fmt, ...) 362 __attribute__ ((format (printf, 2, 3))); 363 364#define fdt_for_each_node_by_compatible(node, fdt, start, compat) \ 365 for (node = fdt_node_offset_by_compatible(fdt, start, compat); \ 366 node >= 0; \ 367 node = fdt_node_offset_by_compatible(fdt, node, compat)) 368 369int fdt_set_phandle(void *fdt, int nodeoffset, uint32_t phandle); 370unsigned int fdt_create_phandle(void *fdt, int nodeoffset); 371unsigned int fdt_create_phandle_by_compatible(void *fdt, const char *compat); 372unsigned int fdt_create_phandle_by_pathf(void *fdt, const char *fmt, ...) 373 __attribute__ ((format (printf, 2, 3))); 374int fdt_add_edid(void *blob, const char *compat, unsigned char *buf); 375 376int fdt_verify_alias_address(void *fdt, int anode, const char *alias, 377 u64 addr); 378u64 fdt_get_base_address(const void *fdt, int node); 379int fdt_read_range(void *fdt, int node, int n, uint64_t *child_addr, 380 uint64_t *addr, uint64_t *len); 381 382enum fdt_status { 383 FDT_STATUS_OKAY, 384 FDT_STATUS_DISABLED, 385 FDT_STATUS_FAIL, 386}; 387int fdt_set_node_status(void *fdt, int nodeoffset, enum fdt_status status); 388static inline int fdt_status_okay(void *fdt, int nodeoffset) 389{ 390 return fdt_set_node_status(fdt, nodeoffset, FDT_STATUS_OKAY); 391} 392static inline int fdt_status_disabled(void *fdt, int nodeoffset) 393{ 394 return fdt_set_node_status(fdt, nodeoffset, FDT_STATUS_DISABLED); 395} 396static inline int fdt_status_fail(void *fdt, int nodeoffset) 397{ 398 return fdt_set_node_status(fdt, nodeoffset, FDT_STATUS_FAIL); 399} 400 401int fdt_set_status_by_alias(void *fdt, const char *alias, 402 enum fdt_status status); 403static inline int fdt_status_okay_by_alias(void *fdt, const char *alias) 404{ 405 return fdt_set_status_by_alias(fdt, alias, FDT_STATUS_OKAY); 406} 407static inline int fdt_status_disabled_by_alias(void *fdt, const char *alias) 408{ 409 return fdt_set_status_by_alias(fdt, alias, FDT_STATUS_DISABLED); 410} 411static inline int fdt_status_fail_by_alias(void *fdt, const char *alias) 412{ 413 return fdt_set_status_by_alias(fdt, alias, FDT_STATUS_FAIL); 414} 415 416int fdt_set_status_by_compatible(void *fdt, const char *compat, 417 enum fdt_status status); 418static inline int fdt_status_okay_by_compatible(void *fdt, const char *compat) 419{ 420 return fdt_set_status_by_compatible(fdt, compat, FDT_STATUS_OKAY); 421} 422static inline int fdt_status_disabled_by_compatible(void *fdt, 423 const char *compat) 424{ 425 return fdt_set_status_by_compatible(fdt, compat, FDT_STATUS_DISABLED); 426} 427static inline int fdt_status_fail_by_compatible(void *fdt, const char *compat) 428{ 429 return fdt_set_status_by_compatible(fdt, compat, FDT_STATUS_FAIL); 430} 431 432int fdt_set_status_by_pathf(void *fdt, enum fdt_status status, const char *fmt, 433 ...) __attribute__ ((format (printf, 3, 4))); 434#define fdt_status_okay_by_pathf(fdt, fmt, ...) \ 435 fdt_set_status_by_pathf((fdt), FDT_STATUS_OKAY, (fmt), ##__VA_ARGS__) 436#define fdt_status_disabled_by_pathf(fdt, fmt, ...) \ 437 fdt_set_status_by_pathf((fdt), FDT_STATUS_DISABLED, (fmt), ##__VA_ARGS__) 438#define fdt_status_fail_by_pathf(fdt, fmt, ...) \ 439 fdt_set_status_by_pathf((fdt), FDT_STATUS_FAIL, (fmt), ##__VA_ARGS__) 440 441/* Helper to read a big number; size is in cells (not bytes) */ 442static inline u64 fdt_read_number(const fdt32_t *cell, int size) 443{ 444 u64 r = 0; 445 while (size--) 446 r = (r << 32) | fdt32_to_cpu(*(cell++)); 447 return r; 448} 449 450void fdt_support_default_count_cells(const void *blob, int parentoffset, 451 int *addrc, int *sizec); 452int ft_verify_fdt(void *fdt); 453int arch_fixup_memory_node(void *blob); 454 455int fdt_setup_simplefb_node(void *fdt, int node, u64 base_address, u32 width, 456 u32 height, u32 stride, const char *format); 457 458int fdt_add_fb_mem_rsv(void *blob); 459 460int fdt_overlay_apply_verbose(void *fdt, void *fdto); 461 462int fdt_valid(struct fdt_header **blobp); 463 464/** 465 * fdt_get_cells_len() - get the length of a type of cell in top-level nodes 466 * 467 * @blob: pointer to device tree blob 468 * @nr_cells_name: name to lookup, e.g. "#address-cells" 469 * 470 * Return: the length of the cell type in bytes (4 or 8). 471 */ 472int fdt_get_cells_len(const void *blob, char *nr_cells_name); 473 474#endif /* !USE_HOSTCC */ 475 476#ifdef USE_HOSTCC 477int fdtdec_get_int(const void *blob, int node, const char *prop_name, 478 int default_val); 479 480/** 481 * fdtdec_get_child_count() - count child nodes of one parent node 482 * 483 * @blob: FDT blob 484 * @node: parent node 485 * 486 * Return: number of child node; 0 if there is not child node 487 */ 488int fdtdec_get_child_count(const void *blob, int node); 489#endif 490#ifdef CONFIG_FMAN_ENET 491int fdt_update_ethernet_dt(void *blob); 492#endif 493#ifdef CONFIG_FSL_MC_ENET 494void fdt_fixup_board_enet(void *blob); 495#endif 496#ifdef CONFIG_CMD_PSTORE 497void fdt_fixup_pstore(void *blob); 498#endif 499 500/** 501 * fdt_kaslrseed() - create a 'kaslr-seed' node in chosen 502 * 503 * @blob: fdt blob 504 * @overwrite: do not overwrite existing non-zero node unless true 505 * 506 * Return: 0 if OK, -ve on error 507 */ 508int fdt_kaslrseed(void *blob, bool overwrite); 509 510#endif /* ifndef __FDT_SUPPORT_H */