11bb92983SJerome Forissier /* SPDX-License-Identifier: BSD-2-Clause */ 2a4f139d7SJerome Forissier /* 3a4f139d7SJerome Forissier * Copyright (c) 2016, Linaro Limited 4a4f139d7SJerome Forissier */ 5a4f139d7SJerome Forissier 6a4f139d7SJerome Forissier #ifndef KERNEL_DT_H 7a4f139d7SJerome Forissier #define KERNEL_DT_H 8a4f139d7SJerome Forissier 9a4f139d7SJerome Forissier #include <compiler.h> 10a4f139d7SJerome Forissier #include <stdint.h> 11a4f139d7SJerome Forissier #include <types_ext.h> 129fe4c797SJerome Forissier #include <util.h> 139fe4c797SJerome Forissier 149fe4c797SJerome Forissier /* 1523b1daf4SPeng Fan * Bitfield to reflect status and secure-status values ("okay", "disabled" 1623b1daf4SPeng Fan * or not present) 179fe4c797SJerome Forissier */ 189fe4c797SJerome Forissier #define DT_STATUS_DISABLED 0 199fe4c797SJerome Forissier #define DT_STATUS_OK_NSEC BIT(0) 209fe4c797SJerome Forissier #define DT_STATUS_OK_SEC BIT(1) 21a4f139d7SJerome Forissier 22a4f139d7SJerome Forissier #if defined(CFG_DT) 23a4f139d7SJerome Forissier 24a4f139d7SJerome Forissier /* 25a4f139d7SJerome Forissier * DT-aware drivers 26a4f139d7SJerome Forissier */ 27a4f139d7SJerome Forissier 28a4f139d7SJerome Forissier struct dt_device_match { 29a4f139d7SJerome Forissier const char *compatible; 30a4f139d7SJerome Forissier }; 31a4f139d7SJerome Forissier 32a4f139d7SJerome Forissier struct dt_driver { 33a4f139d7SJerome Forissier const char *name; 34a4f139d7SJerome Forissier const struct dt_device_match *match_table; /* null-terminated */ 35a4f139d7SJerome Forissier const void *driver; 36a4f139d7SJerome Forissier }; 37a4f139d7SJerome Forissier 38*fd118772SJerome Forissier #define __dt_driver __section(".rodata.dtdrv" __SECTION_FLAGS_RODATA) 39a4f139d7SJerome Forissier 40a4f139d7SJerome Forissier /* 41a4f139d7SJerome Forissier * Find a driver that is suitable for the given DT node, that is, with 42a4f139d7SJerome Forissier * a matching "compatible" property. 43a4f139d7SJerome Forissier * 44a4f139d7SJerome Forissier * @fdt: pointer to the device tree 45a4f139d7SJerome Forissier * @offs: node offset 46a4f139d7SJerome Forissier */ 47a4f139d7SJerome Forissier const struct dt_driver *dt_find_compatible_driver(const void *fdt, int offs); 48a4f139d7SJerome Forissier 49a4f139d7SJerome Forissier const struct dt_driver *__dt_driver_start(void); 50a4f139d7SJerome Forissier 51a4f139d7SJerome Forissier const struct dt_driver *__dt_driver_end(void); 52a4f139d7SJerome Forissier 539fe4c797SJerome Forissier /* 547ba16abbSJerome Forissier * Map a device into secure or non-secure memory and return the base VA and 557ba16abbSJerome Forissier * the mapping size. The mapping is done with type MEM_AREA_IO_SEC or 567ba16abbSJerome Forissier * MEM_AREA_IO_NSEC, depending on the device status. 577ba16abbSJerome Forissier * If the mapping already exists, the function simply returns the @vbase and 587ba16abbSJerome Forissier * @size information. 597ba16abbSJerome Forissier * 607ba16abbSJerome Forissier * @offs is the offset of the node that describes the device in @fdt. 617ba16abbSJerome Forissier * @base receives the base virtual address corresponding to the base physical 627ba16abbSJerome Forissier * address of the "reg" property 637ba16abbSJerome Forissier * @size receives the size of the mapping 647ba16abbSJerome Forissier * 657ba16abbSJerome Forissier * Returns 0 on success or -1 in case of error. 667ba16abbSJerome Forissier */ 677ba16abbSJerome Forissier int dt_map_dev(const void *fdt, int offs, vaddr_t *base, size_t *size); 687ba16abbSJerome Forissier 697ba16abbSJerome Forissier /* 7050f3b323SPeng Fan * Check whether the node at @offs contains the property with propname or not. 7150f3b323SPeng Fan * 7250f3b323SPeng Fan * @offs is the offset of the node that describes the device in @fdt. 7350f3b323SPeng Fan * @propname is the property that need to check 7450f3b323SPeng Fan * 7550f3b323SPeng Fan * Returns true on success or false if no propname. 7650f3b323SPeng Fan */ 7750f3b323SPeng Fan bool dt_have_prop(const void *fdt, int offs, const char *propname); 7850f3b323SPeng Fan 7950f3b323SPeng Fan /* 809fe4c797SJerome Forissier * FDT manipulation functions, not provided by <libfdt.h> 819fe4c797SJerome Forissier */ 829fe4c797SJerome Forissier 839fe4c797SJerome Forissier /* 849fe4c797SJerome Forissier * Return the base address for the "reg" property of the specified node or 859fe4c797SJerome Forissier * (paddr_t)-1 in case of error 869fe4c797SJerome Forissier */ 879fe4c797SJerome Forissier paddr_t _fdt_reg_base_address(const void *fdt, int offs); 889fe4c797SJerome Forissier 899fe4c797SJerome Forissier /* 909fe4c797SJerome Forissier * Return the reg size for the reg property of the specified node or -1 in case 919fe4c797SJerome Forissier * of error 929fe4c797SJerome Forissier */ 939fe4c797SJerome Forissier ssize_t _fdt_reg_size(const void *fdt, int offs); 949fe4c797SJerome Forissier 959fe4c797SJerome Forissier /* 969fe4c797SJerome Forissier * Read the status and secure-status properties into a bitfield. 979fe4c797SJerome Forissier * @status is set to DT_STATUS_DISABLED or a combination of DT_STATUS_OK_NSEC 989fe4c797SJerome Forissier * and DT_STATUS_OK_SEC 999fe4c797SJerome Forissier * Returns 0 on success or -1 in case of error. 1009fe4c797SJerome Forissier */ 1019fe4c797SJerome Forissier int _fdt_get_status(const void *fdt, int offs); 1029fe4c797SJerome Forissier 1039fe4c797SJerome Forissier #else /* !CFG_DT */ 104a4f139d7SJerome Forissier 105a4f139d7SJerome Forissier static inline const struct dt_driver *__dt_driver_start(void) 106a4f139d7SJerome Forissier { 107a4f139d7SJerome Forissier return NULL; 108a4f139d7SJerome Forissier } 109a4f139d7SJerome Forissier 110a4f139d7SJerome Forissier static inline const struct dt_driver *__dt_driver_end(void) 111a4f139d7SJerome Forissier { 112a4f139d7SJerome Forissier return NULL; 113a4f139d7SJerome Forissier } 114a4f139d7SJerome Forissier 115a4f139d7SJerome Forissier static inline const struct dt_driver *dt_find_compatible_driver( 116a4f139d7SJerome Forissier const void *fdt __unused, 117a4f139d7SJerome Forissier int offs __unused) 118a4f139d7SJerome Forissier { 119a4f139d7SJerome Forissier return NULL; 120a4f139d7SJerome Forissier } 121a4f139d7SJerome Forissier 1227ba16abbSJerome Forissier static inline int dt_map_dev(const void *fdt __unused, int offs __unused, 1237ba16abbSJerome Forissier vaddr_t *vbase __unused, size_t *size __unused) 1247ba16abbSJerome Forissier { 1257ba16abbSJerome Forissier return -1; 1267ba16abbSJerome Forissier } 1277ba16abbSJerome Forissier 1289fe4c797SJerome Forissier static inline paddr_t _fdt_reg_base_address(const void *fdt __unused, 1299fe4c797SJerome Forissier int offs __unused) 1309fe4c797SJerome Forissier { 1319fe4c797SJerome Forissier return (paddr_t)-1; 1329fe4c797SJerome Forissier } 1339fe4c797SJerome Forissier 1349fe4c797SJerome Forissier static inline ssize_t _fdt_reg_size(const void *fdt __unused, 1359fe4c797SJerome Forissier int offs __unused) 1369fe4c797SJerome Forissier { 1379fe4c797SJerome Forissier return -1; 1389fe4c797SJerome Forissier } 1399fe4c797SJerome Forissier 1409fe4c797SJerome Forissier static inline int _fdt_get_status(const void *fdt __unused, int offs __unused) 1419fe4c797SJerome Forissier { 1429fe4c797SJerome Forissier return -1; 1439fe4c797SJerome Forissier } 1449fe4c797SJerome Forissier 145a4f139d7SJerome Forissier #endif /* !CFG_DT */ 146a4f139d7SJerome Forissier 147a4f139d7SJerome Forissier #define for_each_dt_driver(drv) \ 148a4f139d7SJerome Forissier for (drv = __dt_driver_start(); drv < __dt_driver_end(); drv++) 149a4f139d7SJerome Forissier 150a4f139d7SJerome Forissier #endif /* KERNEL_DT_H */ 151