xref: /dpdk/drivers/common/dpaax/dpaa_of.h (revision 6ae4ce8942f6353db614242e2f150de390f4232e)
18c83f28cSHemant Agrawal /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
28c83f28cSHemant Agrawal  *
38c83f28cSHemant Agrawal  * Copyright 2010-2016 Freescale Semiconductor, Inc.
48c83f28cSHemant Agrawal  * Copyright 2017 NXP
58c83f28cSHemant Agrawal  *
68c83f28cSHemant Agrawal  */
78c83f28cSHemant Agrawal 
88c83f28cSHemant Agrawal #ifndef __OF_H
98c83f28cSHemant Agrawal #define	__OF_H
108c83f28cSHemant Agrawal 
118c83f28cSHemant Agrawal #include <unistd.h>
128c83f28cSHemant Agrawal #include <stdio.h>
138c83f28cSHemant Agrawal #include <string.h>
148c83f28cSHemant Agrawal #include <stdbool.h>
158c83f28cSHemant Agrawal #include <stdlib.h>
168c83f28cSHemant Agrawal #include <inttypes.h>
178c83f28cSHemant Agrawal #include <sys/stat.h>
188c83f28cSHemant Agrawal #include <sys/types.h>
198c83f28cSHemant Agrawal #include <dirent.h>
208c83f28cSHemant Agrawal #include <fcntl.h>
218c83f28cSHemant Agrawal #include <glob.h>
228c83f28cSHemant Agrawal #include <errno.h>
238c83f28cSHemant Agrawal #include <ctype.h>
248c83f28cSHemant Agrawal #include <limits.h>
258c83f28cSHemant Agrawal #include <rte_common.h>
268c83f28cSHemant Agrawal #include <dpaa_list.h>
27*6ae4ce89SHemant Agrawal #include <rte_compat.h>
288c83f28cSHemant Agrawal 
298c83f28cSHemant Agrawal #ifndef OF_INIT_DEFAULT_PATH
308c83f28cSHemant Agrawal #define OF_INIT_DEFAULT_PATH "/proc/device-tree"
318c83f28cSHemant Agrawal #endif
328c83f28cSHemant Agrawal 
338c83f28cSHemant Agrawal #define OF_DEFAULT_NA 1
348c83f28cSHemant Agrawal #define OF_DEFAULT_NS 1
358c83f28cSHemant Agrawal 
368c83f28cSHemant Agrawal #define OF_FILE_BUF_MAX 256
378c83f28cSHemant Agrawal 
388c83f28cSHemant Agrawal /**
398c83f28cSHemant Agrawal  * Layout of Device Tree:
408c83f28cSHemant Agrawal  * dt_dir
418c83f28cSHemant Agrawal  *  |- dt_dir
428c83f28cSHemant Agrawal  *  |   |- dt_dir
438c83f28cSHemant Agrawal  *  |   |  |- dt_dir
448c83f28cSHemant Agrawal  *  |   |  |  |- dt_file
458c83f28cSHemant Agrawal  *  |   |  |  ``- dt_file
468c83f28cSHemant Agrawal  *  |   |  ``- dt_file
478c83f28cSHemant Agrawal  *  |   `-dt_file`
488c83f28cSHemant Agrawal  *  ``- dt_file
498c83f28cSHemant Agrawal  *
508c83f28cSHemant Agrawal  *  +------------------+
518c83f28cSHemant Agrawal  *  |dt_dir            |
528c83f28cSHemant Agrawal  *  |+----------------+|
538c83f28cSHemant Agrawal  *  ||dt_node         ||
548c83f28cSHemant Agrawal  *  ||+--------------+||
558c83f28cSHemant Agrawal  *  |||device_node   |||
568c83f28cSHemant Agrawal  *  ||+--------------+||
578c83f28cSHemant Agrawal  *  || list_dt_nodes  ||
588c83f28cSHemant Agrawal  *  |+----------------+|
598c83f28cSHemant Agrawal  *  | list of subdir   |
608c83f28cSHemant Agrawal  *  | list of files    |
618c83f28cSHemant Agrawal  *  +------------------+
628c83f28cSHemant Agrawal  */
638c83f28cSHemant Agrawal 
648c83f28cSHemant Agrawal /**
658c83f28cSHemant Agrawal  * Device description on of a device node in device tree.
668c83f28cSHemant Agrawal  */
678c83f28cSHemant Agrawal struct device_node {
688c83f28cSHemant Agrawal 	char name[NAME_MAX];
698c83f28cSHemant Agrawal 	char full_name[PATH_MAX];
708c83f28cSHemant Agrawal };
718c83f28cSHemant Agrawal 
728c83f28cSHemant Agrawal /**
738c83f28cSHemant Agrawal  * List of device nodes available in a device tree layout
748c83f28cSHemant Agrawal  */
758c83f28cSHemant Agrawal struct dt_node {
768c83f28cSHemant Agrawal 	struct device_node node; /**< Property of node */
778c83f28cSHemant Agrawal 	int is_file; /**< FALSE==dir, TRUE==file */
788c83f28cSHemant Agrawal 	struct list_head list; /**< Nodes within a parent subdir */
798c83f28cSHemant Agrawal };
808c83f28cSHemant Agrawal 
818c83f28cSHemant Agrawal /**
828c83f28cSHemant Agrawal  * Types we use to represent directories and files
838c83f28cSHemant Agrawal  */
848c83f28cSHemant Agrawal struct dt_file;
858c83f28cSHemant Agrawal struct dt_dir {
868c83f28cSHemant Agrawal 	struct dt_node node;
878c83f28cSHemant Agrawal 	struct list_head subdirs;
888c83f28cSHemant Agrawal 	struct list_head files;
898c83f28cSHemant Agrawal 	struct list_head linear;
908c83f28cSHemant Agrawal 	struct dt_dir *parent;
918c83f28cSHemant Agrawal 	struct dt_file *compatible;
928c83f28cSHemant Agrawal 	struct dt_file *status;
938c83f28cSHemant Agrawal 	struct dt_file *lphandle;
948c83f28cSHemant Agrawal 	struct dt_file *a_cells;
958c83f28cSHemant Agrawal 	struct dt_file *s_cells;
968c83f28cSHemant Agrawal 	struct dt_file *reg;
978c83f28cSHemant Agrawal };
988c83f28cSHemant Agrawal 
998c83f28cSHemant Agrawal struct dt_file {
1008c83f28cSHemant Agrawal 	struct dt_node node;
1018c83f28cSHemant Agrawal 	struct dt_dir *parent;
1028c83f28cSHemant Agrawal 	ssize_t len;
1038c83f28cSHemant Agrawal 	uint64_t buf[OF_FILE_BUF_MAX >> 3];
1048c83f28cSHemant Agrawal };
1058c83f28cSHemant Agrawal 
106*6ae4ce89SHemant Agrawal __rte_internal
1078c83f28cSHemant Agrawal const struct device_node *of_find_compatible_node(
1088c83f28cSHemant Agrawal 					const struct device_node *from,
1098c83f28cSHemant Agrawal 					const char *type __rte_unused,
1108c83f28cSHemant Agrawal 					const char *compatible)
1118c83f28cSHemant Agrawal 	__attribute__((nonnull(3)));
1128c83f28cSHemant Agrawal 
1138c83f28cSHemant Agrawal #define for_each_compatible_node(dev_node, type, compatible) \
1148c83f28cSHemant Agrawal 	for (dev_node = of_find_compatible_node(NULL, type, compatible); \
1158c83f28cSHemant Agrawal 		dev_node != NULL; \
1168c83f28cSHemant Agrawal 		dev_node = of_find_compatible_node(dev_node, type, compatible))
1178c83f28cSHemant Agrawal 
118*6ae4ce89SHemant Agrawal __rte_internal
1198c83f28cSHemant Agrawal const void *of_get_property(const struct device_node *from, const char *name,
1208c83f28cSHemant Agrawal 			    size_t *lenp) __attribute__((nonnull(2)));
121*6ae4ce89SHemant Agrawal __rte_internal
1228c83f28cSHemant Agrawal bool of_device_is_available(const struct device_node *dev_node);
1238c83f28cSHemant Agrawal 
124*6ae4ce89SHemant Agrawal __rte_internal
1258c83f28cSHemant Agrawal const struct device_node *of_find_node_by_phandle(uint64_t ph);
1268c83f28cSHemant Agrawal 
127*6ae4ce89SHemant Agrawal __rte_internal
1288c83f28cSHemant Agrawal const struct device_node *of_get_parent(const struct device_node *dev_node);
1298c83f28cSHemant Agrawal 
130*6ae4ce89SHemant Agrawal __rte_internal
1318c83f28cSHemant Agrawal const struct device_node *of_get_next_child(const struct device_node *dev_node,
1328c83f28cSHemant Agrawal 					    const struct device_node *prev);
1338c83f28cSHemant Agrawal 
134*6ae4ce89SHemant Agrawal __rte_internal
1358c83f28cSHemant Agrawal const void *of_get_mac_address(const struct device_node *np);
1368c83f28cSHemant Agrawal 
1378c83f28cSHemant Agrawal #define for_each_child_node(parent, child) \
1388c83f28cSHemant Agrawal 	for (child = of_get_next_child(parent, NULL); child != NULL; \
1398c83f28cSHemant Agrawal 			child = of_get_next_child(parent, child))
1408c83f28cSHemant Agrawal 
141*6ae4ce89SHemant Agrawal __rte_internal
1428c83f28cSHemant Agrawal uint32_t of_n_addr_cells(const struct device_node *dev_node);
1438c83f28cSHemant Agrawal uint32_t of_n_size_cells(const struct device_node *dev_node);
1448c83f28cSHemant Agrawal 
145*6ae4ce89SHemant Agrawal __rte_internal
1468c83f28cSHemant Agrawal const uint32_t *of_get_address(const struct device_node *dev_node, size_t idx,
1478c83f28cSHemant Agrawal 			       uint64_t *size, uint32_t *flags);
1488c83f28cSHemant Agrawal 
149*6ae4ce89SHemant Agrawal __rte_internal
1508c83f28cSHemant Agrawal uint64_t of_translate_address(const struct device_node *dev_node,
1518c83f28cSHemant Agrawal 			      const uint32_t *addr) __attribute__((nonnull));
1528c83f28cSHemant Agrawal 
153*6ae4ce89SHemant Agrawal __rte_internal
1548c83f28cSHemant Agrawal bool of_device_is_compatible(const struct device_node *dev_node,
1558c83f28cSHemant Agrawal 			     const char *compatible);
1568c83f28cSHemant Agrawal 
1578c83f28cSHemant Agrawal /* of_init() must be called prior to initialisation or use of any driver
1588c83f28cSHemant Agrawal  * subsystem that is device-tree-dependent. Eg. Qman/Bman, config layers, etc.
1598c83f28cSHemant Agrawal  * The path should usually be "/proc/device-tree".
1608c83f28cSHemant Agrawal  */
161*6ae4ce89SHemant Agrawal __rte_internal
1628c83f28cSHemant Agrawal int of_init_path(const char *dt_path);
1638c83f28cSHemant Agrawal 
1648c83f28cSHemant Agrawal /* of_finish() allows a controlled tear-down of the device-tree layer, eg. if a
1658c83f28cSHemant Agrawal  * full reload is desired without a process exit.
1668c83f28cSHemant Agrawal  */
1678c83f28cSHemant Agrawal void of_finish(void);
1688c83f28cSHemant Agrawal 
1698c83f28cSHemant Agrawal /* Use of this wrapper is recommended. */
of_init(void)1708c83f28cSHemant Agrawal static inline int of_init(void)
1718c83f28cSHemant Agrawal {
1728c83f28cSHemant Agrawal 	return of_init_path(OF_INIT_DEFAULT_PATH);
1738c83f28cSHemant Agrawal }
1748c83f28cSHemant Agrawal 
1758c83f28cSHemant Agrawal /* Read a numeric property according to its size and return it as a 64-bit
1768c83f28cSHemant Agrawal  * value.
1778c83f28cSHemant Agrawal  */
of_read_number(const uint32_t * cell,int size)1788c83f28cSHemant Agrawal static inline uint64_t of_read_number(const uint32_t *cell, int size)
1798c83f28cSHemant Agrawal {
1808c83f28cSHemant Agrawal 	uint64_t r = 0;
1818c83f28cSHemant Agrawal 
1828c83f28cSHemant Agrawal 	while (size--)
1838c83f28cSHemant Agrawal 		r = (r << 32) | be32toh(*(cell++));
1848c83f28cSHemant Agrawal 	return r;
1858c83f28cSHemant Agrawal }
1868c83f28cSHemant Agrawal 
1878c83f28cSHemant Agrawal #endif	/*  __OF_H */
188