blob: bd0d151508aa52a8d3cc29d45df7900360a1d881 [file] [log] [blame]
Patrick Georgiafd4c872020-05-05 23:43:18 +02001/* Taken from depthcharge: src/base/device_tree.h */
Patrick Georgiac959032020-05-05 22:49:26 +02002/* SPDX-License-Identifier: GPL-2.0-or-later */
Patrick Rudolph67aca3e2018-04-12 11:44:43 +02003
Patrick Rudolph666c1722018-04-03 09:57:33 +02004#ifndef __DEVICE_TREE_H__
5#define __DEVICE_TREE_H__
Patrick Rudolph67aca3e2018-04-12 11:44:43 +02006
7#include <stdint.h>
Patrick Rudolph666c1722018-04-03 09:57:33 +02008#include <list.h>
Patrick Rudolph67aca3e2018-04-12 11:44:43 +02009
10/*
11 * Flattened device tree structures/constants.
12 */
13
Patrick Rudolph666c1722018-04-03 09:57:33 +020014struct fdt_header {
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020015 uint32_t magic;
16 uint32_t totalsize;
17 uint32_t structure_offset;
18 uint32_t strings_offset;
19 uint32_t reserve_map_offset;
20
21 uint32_t version;
Julius Werner73eaec82019-05-03 17:58:07 -070022 uint32_t last_comp_version;
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020023
24 uint32_t boot_cpuid_phys;
25
26 uint32_t strings_size;
27 uint32_t structure_size;
Patrick Rudolph666c1722018-04-03 09:57:33 +020028};
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020029
Patrick Rudolph666c1722018-04-03 09:57:33 +020030#define FDT_HEADER_MAGIC 0xd00dfeed
Julius Werner73eaec82019-05-03 17:58:07 -070031#define FDT_SUPPORTED_VERSION 17
Patrick Rudolph666c1722018-04-03 09:57:33 +020032#define FDT_TOKEN_BEGIN_NODE 1
33#define FDT_TOKEN_END_NODE 2
34#define FDT_TOKEN_PROPERTY 3
35#define FDT_TOKEN_END 9
Julius Werner6702b682019-05-03 18:13:53 -070036#define FDT_PHANDLE_ILLEGAL 0xdeadbeef
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020037
Patrick Rudolph666c1722018-04-03 09:57:33 +020038struct fdt_property
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020039{
40 const char *name;
Julius Werner0e9116f2019-05-13 17:30:31 -070041 void *data;
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020042 uint32_t size;
Patrick Rudolph666c1722018-04-03 09:57:33 +020043};
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020044
45
46
47/*
48 * Unflattened device tree structures.
49 */
50
Patrick Rudolph666c1722018-04-03 09:57:33 +020051struct device_tree_property
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020052{
Patrick Rudolph666c1722018-04-03 09:57:33 +020053 struct fdt_property prop;
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020054
Patrick Rudolph666c1722018-04-03 09:57:33 +020055 struct list_node list_node;
56};
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020057
Patrick Rudolph666c1722018-04-03 09:57:33 +020058struct device_tree_node
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020059{
60 const char *name;
Julius Werner6702b682019-05-03 18:13:53 -070061 uint32_t phandle;
62
Julius Werner23df4772019-05-17 22:50:18 -070063 /* List of struct device_tree_property-s. */
Patrick Rudolph666c1722018-04-03 09:57:33 +020064 struct list_node properties;
Julius Werner23df4772019-05-17 22:50:18 -070065 /* List of struct device_tree_nodes. */
Patrick Rudolph666c1722018-04-03 09:57:33 +020066 struct list_node children;
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020067
Patrick Rudolph666c1722018-04-03 09:57:33 +020068 struct list_node list_node;
69};
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020070
Patrick Rudolph666c1722018-04-03 09:57:33 +020071struct device_tree_reserve_map_entry
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020072{
73 uint64_t start;
74 uint64_t size;
75
Patrick Rudolph666c1722018-04-03 09:57:33 +020076 struct list_node list_node;
77};
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020078
Patrick Rudolph666c1722018-04-03 09:57:33 +020079struct device_tree
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020080{
Patrick Rudolph0a7d6902018-08-22 09:55:15 +020081 const void *header;
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020082 uint32_t header_size;
Julius Werner6702b682019-05-03 18:13:53 -070083 uint32_t max_phandle;
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020084
Patrick Rudolph666c1722018-04-03 09:57:33 +020085 struct list_node reserve_map;
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020086
Patrick Rudolph666c1722018-04-03 09:57:33 +020087 struct device_tree_node *root;
88};
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020089
90
91
92/*
93 * Flattened device tree functions. These generally return the number of bytes
94 * which were consumed reading the requested value.
95 */
96
Julius Werner23df4772019-05-17 22:50:18 -070097/* Read the property, if any, at offset offset. */
Patrick Rudolph0a7d6902018-08-22 09:55:15 +020098int fdt_next_property(const void *blob, uint32_t offset,
99 struct fdt_property *prop);
Julius Werner23df4772019-05-17 22:50:18 -0700100/* Read the name of the node, if any, at offset offset. */
Patrick Rudolph0a7d6902018-08-22 09:55:15 +0200101int fdt_node_name(const void *blob, uint32_t offset, const char **name);
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200102
Patrick Rudolph0a7d6902018-08-22 09:55:15 +0200103void fdt_print_node(const void *blob, uint32_t offset);
104int fdt_skip_node(const void *blob, uint32_t offset);
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200105
Elyes HAOUAS5f73e222020-01-15 21:13:45 +0100106/* Read a flattened device tree into a hierarchical structure which refers to
Julius Werner23df4772019-05-17 22:50:18 -0700107 the contents of the flattened tree in place. Modifying the flat tree
108 invalidates the unflattened one. */
Patrick Rudolph0a7d6902018-08-22 09:55:15 +0200109struct device_tree *fdt_unflatten(const void *blob);
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200110
111
112
113/*
114 * Unflattened device tree functions.
115 */
116
Julius Werner23df4772019-05-17 22:50:18 -0700117/* Figure out how big a device tree would be if it were flattened. */
Patrick Rudolph0a7d6902018-08-22 09:55:15 +0200118uint32_t dt_flat_size(const struct device_tree *tree);
Julius Werner23df4772019-05-17 22:50:18 -0700119/* Flatten a device tree into the buffer pointed to by dest. */
Patrick Rudolph0a7d6902018-08-22 09:55:15 +0200120void dt_flatten(const struct device_tree *tree, void *dest);
121void dt_print_node(const struct device_tree_node *node);
Julius Werner23df4772019-05-17 22:50:18 -0700122/* Read #address-cells and #size-cells properties from a node. */
Patrick Rudolph0a7d6902018-08-22 09:55:15 +0200123void dt_read_cell_props(const struct device_tree_node *node, u32 *addrcp,
124 u32 *sizecp);
Julius Werner23df4772019-05-17 22:50:18 -0700125/* Look up or create a node relative to a parent node, through its path
126 represented as an array of strings. */
Patrick Rudolph666c1722018-04-03 09:57:33 +0200127struct device_tree_node *dt_find_node(struct device_tree_node *parent, const char **path,
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200128 u32 *addrcp, u32 *sizecp, int create);
Julius Werner6702b682019-05-03 18:13:53 -0700129struct device_tree_node *dt_find_node_by_phandle(struct device_tree_node *root,
130 uint32_t phandle);
Julius Werner23df4772019-05-17 22:50:18 -0700131/* Look up or create a node in the tree, through its path
132 represented as a string of '/' separated node names. */
Julius Wernerf36d53c2019-05-03 18:23:34 -0700133struct device_tree_node *dt_find_node_by_path(struct device_tree *tree,
134 const char *path, u32 *addrcp, u32 *sizecp, int create);
Julius Werner23df4772019-05-17 22:50:18 -0700135/* Look up a node through an alias. */
Julius Werner6d5695f2019-05-06 19:23:28 -0700136struct device_tree_node *dt_find_node_by_alias(struct device_tree *tree,
137 const char *alias);
Julius Werner23df4772019-05-17 22:50:18 -0700138/* Look up a node relative to a parent node, through its compatible string. */
Patrick Rudolph666c1722018-04-03 09:57:33 +0200139struct device_tree_node *dt_find_compat(struct device_tree_node *parent, const char *compatible);
Julius Werner23df4772019-05-17 22:50:18 -0700140/* Look up the next child of a parent node, through its compatible string. It
141 uses child pointer as the marker to find next. */
Patrick Rudolph666c1722018-04-03 09:57:33 +0200142struct device_tree_node *dt_find_next_compat_child(struct device_tree_node *parent,
143 struct device_tree_node *child,
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200144 const char *compat);
Julius Werner23df4772019-05-17 22:50:18 -0700145/* Look up a node relative to a parent node, through its property value. */
Patrick Rudolph666c1722018-04-03 09:57:33 +0200146struct device_tree_node *dt_find_prop_value(struct device_tree_node *parent, const char *name,
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200147 void *data, size_t size);
Julius Werner23df4772019-05-17 22:50:18 -0700148/* Write src into *dest as a 'length'-byte big-endian integer. */
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200149void dt_write_int(u8 *dest, u64 src, size_t length);
Julius Werner23df4772019-05-17 22:50:18 -0700150/* Delete a property */
Patrick Rudolph5ccc7312018-05-30 15:05:28 +0200151void dt_delete_prop(struct device_tree_node *node, const char *name);
Julius Werner23df4772019-05-17 22:50:18 -0700152/* Add different kinds of properties to a node, or update existing ones. */
Patrick Rudolph0a7d6902018-08-22 09:55:15 +0200153void dt_add_bin_prop(struct device_tree_node *node, const char *name,
Julius Werner0e9116f2019-05-13 17:30:31 -0700154 void *data, size_t size);
Patrick Rudolph0a7d6902018-08-22 09:55:15 +0200155void dt_add_string_prop(struct device_tree_node *node, const char *name,
156 const char *str);
Patrick Rudolph666c1722018-04-03 09:57:33 +0200157void dt_add_u32_prop(struct device_tree_node *node, const char *name, u32 val);
Patrick Rudolph3fca4ed2018-08-10 10:12:35 +0200158void dt_add_u64_prop(struct device_tree_node *node, const char *name, u64 val);
Patrick Rudolph666c1722018-04-03 09:57:33 +0200159void dt_add_reg_prop(struct device_tree_node *node, u64 *addrs, u64 *sizes,
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200160 int count, u32 addr_cells, u32 size_cells);
Patrick Rudolph666c1722018-04-03 09:57:33 +0200161int dt_set_bin_prop_by_path(struct device_tree *tree, const char *path,
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200162 void *data, size_t size, int create);
163
Patrick Rudolph0a7d6902018-08-22 09:55:15 +0200164void dt_find_bin_prop(const struct device_tree_node *node, const char *name,
165 const void **data, size_t *size);
166const char *dt_find_string_prop(const struct device_tree_node *node,
167 const char *name);
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200168
Julius Werner735ddc92019-05-07 17:05:28 -0700169/* Apply an overlay to a base device tree. Ownership of the overlay data passes
170 to the newly combined base tree -- do not free() or access it afterwards! */
171int dt_apply_overlay(struct device_tree *tree, struct device_tree *overlay);
172
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200173/*
174 * Fixups to apply to a kernel's device tree before booting it.
175 */
176
Patrick Rudolph666c1722018-04-03 09:57:33 +0200177struct device_tree_fixup
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200178{
Patrick Rudolph666c1722018-04-03 09:57:33 +0200179 /**
180 * The function which does the fixing.
181 * 0 on success, non-zero on error.
182 */
183 int (*fixup)(struct device_tree_fixup *fixup,
184 struct device_tree *tree);
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200185
Patrick Rudolph666c1722018-04-03 09:57:33 +0200186 struct list_node list_node;
187};
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200188
Patrick Rudolph666c1722018-04-03 09:57:33 +0200189extern struct list_node device_tree_fixups;
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200190
Patrick Rudolph666c1722018-04-03 09:57:33 +0200191/**
192 * Function to apply fixups.
193 * 0 on success, non-zero on error.
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200194 */
Patrick Rudolph666c1722018-04-03 09:57:33 +0200195int dt_apply_fixups(struct device_tree *tree);
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200196
197/*
198 * Init/retrieve the /reserved-memory/ node.
199 */
Patrick Rudolph666c1722018-04-03 09:57:33 +0200200struct device_tree_node *dt_init_reserved_memory_node(struct device_tree *tree);
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200201
Patrick Rudolph666c1722018-04-03 09:57:33 +0200202#endif /* __DEVICE_TREE_H__ */