xref: /optee_os/core/include/kernel/dt.h (revision f6e2b9e2d1a270542c6f6f5e36ed4e36abe18256)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * Copyright (c) 2016, Linaro Limited
4  */
5 
6 #ifndef KERNEL_DT_H
7 #define KERNEL_DT_H
8 
9 #include <compiler.h>
10 #include <kernel/panic.h>
11 #include <stdint.h>
12 #include <types_ext.h>
13 #include <util.h>
14 
15 /*
16  * Bitfield to reflect status and secure-status values ("okay", "disabled"
17  * or not present)
18  */
19 #define DT_STATUS_DISABLED		0
20 #define DT_STATUS_OK_NSEC		BIT(0)
21 #define DT_STATUS_OK_SEC		BIT(1)
22 
23 #define DT_INFO_INVALID_REG		((paddr_t)-1)
24 #define DT_INFO_INVALID_REG_SIZE	((ssize_t)-1)
25 #define DT_INFO_INVALID_CLOCK		-1
26 #define DT_INFO_INVALID_RESET		-1
27 #define DT_INFO_INVALID_INTERRUPT	-1
28 
29 /*
30  * @status: Bit mask for DT_STATUS_*
31  * @reg: Device register physical base address or DT_INFO_INVALID_REG
32  * @clock: Device identifier (positive value) or DT_INFO_INVALID_CLOCK
33  * @reset: Device reset identifier (positive value) or DT_INFO_INVALID_CLOCK
34  * @interrupt: Device interrupt identifier (positive value) or
35  * DT_INFO_INVALID_INTERRUPT
36  */
37 struct dt_node_info {
38 	unsigned int status;
39 	paddr_t reg;
40 	int clock;
41 	int reset;
42 	int interrupt;
43 };
44 
45 #if defined(CFG_DT)
46 
47 /*
48  * DT-aware drivers
49  */
50 
51 struct dt_device_match {
52 	const char *compatible;
53 };
54 
55 struct dt_driver {
56 	const char *name;
57 	const struct dt_device_match *match_table; /* null-terminated */
58 	const void *driver;
59 };
60 
61 #define __dt_driver __section(".rodata.dtdrv" __SECTION_FLAGS_RODATA)
62 
63 /*
64  * Find a driver that is suitable for the given DT node, that is, with
65  * a matching "compatible" property.
66  *
67  * @fdt: pointer to the device tree
68  * @offs: node offset
69  */
70 const struct dt_driver *dt_find_compatible_driver(const void *fdt, int offs);
71 
72 const struct dt_driver *__dt_driver_start(void);
73 
74 const struct dt_driver *__dt_driver_end(void);
75 
76 /*
77  * Map a device into secure or non-secure memory and return the base VA and
78  * the mapping size. The mapping is done with type MEM_AREA_IO_SEC or
79  * MEM_AREA_IO_NSEC, depending on the device status.
80  * If the mapping already exists, the function simply returns the @vbase and
81  * @size information.
82  *
83  * @offs is the offset of the node that describes the device in @fdt.
84  * @base receives the base virtual address corresponding to the base physical
85  * address of the "reg" property
86  * @size receives the size of the mapping
87  *
88  * Returns 0 on success or -1 in case of error.
89  */
90 int dt_map_dev(const void *fdt, int offs, vaddr_t *base, size_t *size);
91 
92 /*
93  * Check whether the node at @offs contains the property with propname or not.
94  *
95  * @offs is the offset of the node that describes the device in @fdt.
96  * @propname is the property that need to check
97  *
98  * Returns true on success or false if no propname.
99  */
100 bool dt_have_prop(const void *fdt, int offs, const char *propname);
101 
102 /*
103  * Modify or add "status" property to "disabled"
104  *
105  * @fdt reference to the Device Tree
106  * @node is the node offset to modify
107  *
108  * Returns 0 on success or -1 on failure
109  */
110 int dt_disable_status(void *fdt, int node);
111 
112 /*
113  * Force secure-status = "okay" and status="disabled" for the target node.
114  *
115  * @fdt reference to the Device Tree
116  * @node is the node offset to modify
117  *
118  * Returns 0 on success or -1 on failure
119  */
120 int dt_enable_secure_status(void *fdt, int node);
121 
122 /*
123  * FDT manipulation functions, not provided by <libfdt.h>
124  */
125 
126 /*
127  * Return the base address for the "reg" property of the specified node or
128  * (paddr_t)-1 in case of error
129  */
130 paddr_t _fdt_reg_base_address(const void *fdt, int offs);
131 
132 /*
133  * Return the reg size for the reg property of the specified node or -1 in case
134  * of error
135  */
136 ssize_t _fdt_reg_size(const void *fdt, int offs);
137 
138 /*
139  * Read the status and secure-status properties into a bitfield.
140  * @status is set to DT_STATUS_DISABLED or a combination of DT_STATUS_OK_NSEC
141  * and DT_STATUS_OK_SEC.
142  */
143 int _fdt_get_status(const void *fdt, int offs);
144 
145 /*
146  * fdt_fill_device_info - Get generic device info from a node
147  *
148  * This function fills the generic information from a given node.
149  * Currently supports a single base register, a single clock,
150  * a single reset ID line and a single interrupt ID.
151  * Default DT_INFO_* macros are used when the relate property is not found.
152  */
153 void _fdt_fill_device_info(void *fdt, struct dt_node_info *info, int node);
154 
155 #else /* !CFG_DT */
156 
157 static inline const struct dt_driver *__dt_driver_start(void)
158 {
159 	return NULL;
160 }
161 
162 static inline const struct dt_driver *__dt_driver_end(void)
163 {
164 	return NULL;
165 }
166 
167 static inline const struct dt_driver *dt_find_compatible_driver(
168 					const void *fdt __unused,
169 					int offs __unused)
170 {
171 	return NULL;
172 }
173 
174 static inline int dt_map_dev(const void *fdt __unused, int offs __unused,
175 			     vaddr_t *vbase __unused, size_t *size __unused)
176 {
177 	return -1;
178 }
179 
180 static inline paddr_t _fdt_reg_base_address(const void *fdt __unused,
181 					    int offs __unused)
182 {
183 	return (paddr_t)-1;
184 }
185 
186 static inline ssize_t _fdt_reg_size(const void *fdt __unused,
187 				    int offs __unused)
188 {
189 	return -1;
190 }
191 
192 static inline int _fdt_get_status(const void *fdt __unused, int offs __unused)
193 {
194 	return -1;
195 }
196 
197 __noreturn
198 static inline void _fdt_fill_device_info(void *fdt __unused,
199 					 struct dt_node_info *info __unused,
200 					 int node __unused)
201 {
202 	panic();
203 }
204 #endif /* !CFG_DT */
205 
206 #define for_each_dt_driver(drv) \
207 	for (drv = __dt_driver_start(); drv < __dt_driver_end(); drv++)
208 
209 #endif /* KERNEL_DT_H */
210