xref: /optee_os/core/include/kernel/dt.h (revision e789ada3f9c0e021452d6d933b284388a1e0f88f)
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 <stdint.h>
11 #include <types_ext.h>
12 #include <util.h>
13 
14 /*
15  * Bitfield to reflect status and secure-status values ("okay", "disabled"
16  * or not present)
17  */
18 #define DT_STATUS_DISABLED 0
19 #define DT_STATUS_OK_NSEC  BIT(0)
20 #define DT_STATUS_OK_SEC   BIT(1)
21 
22 #if defined(CFG_DT)
23 
24 /*
25  * DT-aware drivers
26  */
27 
28 struct dt_device_match {
29 	const char *compatible;
30 };
31 
32 struct dt_driver {
33 	const char *name;
34 	const struct dt_device_match *match_table; /* null-terminated */
35 	const void *driver;
36 };
37 
38 #define __dt_driver __section(".rodata.dtdrv" __SECTION_FLAGS_RODATA)
39 
40 /*
41  * Find a driver that is suitable for the given DT node, that is, with
42  * a matching "compatible" property.
43  *
44  * @fdt: pointer to the device tree
45  * @offs: node offset
46  */
47 const struct dt_driver *dt_find_compatible_driver(const void *fdt, int offs);
48 
49 const struct dt_driver *__dt_driver_start(void);
50 
51 const struct dt_driver *__dt_driver_end(void);
52 
53 /*
54  * Map a device into secure or non-secure memory and return the base VA and
55  * the mapping size. The mapping is done with type MEM_AREA_IO_SEC or
56  * MEM_AREA_IO_NSEC, depending on the device status.
57  * If the mapping already exists, the function simply returns the @vbase and
58  * @size information.
59  *
60  * @offs is the offset of the node that describes the device in @fdt.
61  * @base receives the base virtual address corresponding to the base physical
62  * address of the "reg" property
63  * @size receives the size of the mapping
64  *
65  * Returns 0 on success or -1 in case of error.
66  */
67 int dt_map_dev(const void *fdt, int offs, vaddr_t *base, size_t *size);
68 
69 /*
70  * Check whether the node at @offs contains the property with propname or not.
71  *
72  * @offs is the offset of the node that describes the device in @fdt.
73  * @propname is the property that need to check
74  *
75  * Returns true on success or false if no propname.
76  */
77 bool dt_have_prop(const void *fdt, int offs, const char *propname);
78 
79 /*
80  * FDT manipulation functions, not provided by <libfdt.h>
81  */
82 
83 /*
84  * Return the base address for the "reg" property of the specified node or
85  * (paddr_t)-1 in case of error
86  */
87 paddr_t _fdt_reg_base_address(const void *fdt, int offs);
88 
89 /*
90  * Return the reg size for the reg property of the specified node or -1 in case
91  * of error
92  */
93 ssize_t _fdt_reg_size(const void *fdt, int offs);
94 
95 /*
96  * Read the status and secure-status properties into a bitfield.
97  * @status is set to DT_STATUS_DISABLED or a combination of DT_STATUS_OK_NSEC
98  * and DT_STATUS_OK_SEC
99  * Returns 0 on success or -1 in case of error.
100  */
101 int _fdt_get_status(const void *fdt, int offs);
102 
103 #else /* !CFG_DT */
104 
105 static inline const struct dt_driver *__dt_driver_start(void)
106 {
107 	return NULL;
108 }
109 
110 static inline const struct dt_driver *__dt_driver_end(void)
111 {
112 	return NULL;
113 }
114 
115 static inline const struct dt_driver *dt_find_compatible_driver(
116 					const void *fdt __unused,
117 					int offs __unused)
118 {
119 	return NULL;
120 }
121 
122 static inline int dt_map_dev(const void *fdt __unused, int offs __unused,
123 			     vaddr_t *vbase __unused, size_t *size __unused)
124 {
125 	return -1;
126 }
127 
128 static inline paddr_t _fdt_reg_base_address(const void *fdt __unused,
129 					    int offs __unused)
130 {
131 	return (paddr_t)-1;
132 }
133 
134 static inline ssize_t _fdt_reg_size(const void *fdt __unused,
135 				    int offs __unused)
136 {
137 	return -1;
138 }
139 
140 static inline int _fdt_get_status(const void *fdt __unused, int offs __unused)
141 {
142 	return -1;
143 }
144 
145 #endif /* !CFG_DT */
146 
147 #define for_each_dt_driver(drv) \
148 	for (drv = __dt_driver_start(); drv < __dt_driver_end(); drv++)
149 
150 #endif /* KERNEL_DT_H */
151