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