1*1bb92983SJerome Forissier /* SPDX-License-Identifier: BSD-2-Clause */ 2a4f139d7SJerome Forissier /* 3a4f139d7SJerome Forissier * Copyright (c) 2016, Linaro Limited 4a4f139d7SJerome Forissier * All rights reserved. 5a4f139d7SJerome Forissier * 6a4f139d7SJerome Forissier * Redistribution and use in source and binary forms, with or without 7a4f139d7SJerome Forissier * modification, are permitted provided that the following conditions are met: 8a4f139d7SJerome Forissier * 9a4f139d7SJerome Forissier * 1. Redistributions of source code must retain the above copyright notice, 10a4f139d7SJerome Forissier * this list of conditions and the following disclaimer. 11a4f139d7SJerome Forissier * 12a4f139d7SJerome Forissier * 2. Redistributions in binary form must reproduce the above copyright notice, 13a4f139d7SJerome Forissier * this list of conditions and the following disclaimer in the documentation 14a4f139d7SJerome Forissier * and/or other materials provided with the distribution. 15a4f139d7SJerome Forissier * 16a4f139d7SJerome Forissier * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17a4f139d7SJerome Forissier * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18a4f139d7SJerome Forissier * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19a4f139d7SJerome Forissier * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20a4f139d7SJerome Forissier * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21a4f139d7SJerome Forissier * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22a4f139d7SJerome Forissier * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23a4f139d7SJerome Forissier * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24a4f139d7SJerome Forissier * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25a4f139d7SJerome Forissier * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26a4f139d7SJerome Forissier * POSSIBILITY OF SUCH DAMAGE. 27a4f139d7SJerome Forissier */ 28a4f139d7SJerome Forissier 29a4f139d7SJerome Forissier #ifndef KERNEL_DT_H 30a4f139d7SJerome Forissier #define KERNEL_DT_H 31a4f139d7SJerome Forissier 32a4f139d7SJerome Forissier #include <compiler.h> 33a4f139d7SJerome Forissier #include <stdint.h> 34a4f139d7SJerome Forissier #include <types_ext.h> 359fe4c797SJerome Forissier #include <util.h> 369fe4c797SJerome Forissier 379fe4c797SJerome Forissier /* 3823b1daf4SPeng Fan * Bitfield to reflect status and secure-status values ("okay", "disabled" 3923b1daf4SPeng Fan * or not present) 409fe4c797SJerome Forissier */ 419fe4c797SJerome Forissier #define DT_STATUS_DISABLED 0 429fe4c797SJerome Forissier #define DT_STATUS_OK_NSEC BIT(0) 439fe4c797SJerome Forissier #define DT_STATUS_OK_SEC BIT(1) 44a4f139d7SJerome Forissier 45a4f139d7SJerome Forissier #if defined(CFG_DT) 46a4f139d7SJerome Forissier 47a4f139d7SJerome Forissier /* 48a4f139d7SJerome Forissier * DT-aware drivers 49a4f139d7SJerome Forissier */ 50a4f139d7SJerome Forissier 51a4f139d7SJerome Forissier struct dt_device_match { 52a4f139d7SJerome Forissier const char *compatible; 53a4f139d7SJerome Forissier }; 54a4f139d7SJerome Forissier 55a4f139d7SJerome Forissier struct dt_driver { 56a4f139d7SJerome Forissier const char *name; 57a4f139d7SJerome Forissier const struct dt_device_match *match_table; /* null-terminated */ 58a4f139d7SJerome Forissier const void *driver; 59a4f139d7SJerome Forissier }; 60a4f139d7SJerome Forissier 61a4f139d7SJerome Forissier #define __dt_driver __section(".rodata.dtdrv") 62a4f139d7SJerome Forissier 63a4f139d7SJerome Forissier /* 64a4f139d7SJerome Forissier * Find a driver that is suitable for the given DT node, that is, with 65a4f139d7SJerome Forissier * a matching "compatible" property. 66a4f139d7SJerome Forissier * 67a4f139d7SJerome Forissier * @fdt: pointer to the device tree 68a4f139d7SJerome Forissier * @offs: node offset 69a4f139d7SJerome Forissier */ 70a4f139d7SJerome Forissier const struct dt_driver *dt_find_compatible_driver(const void *fdt, int offs); 71a4f139d7SJerome Forissier 72a4f139d7SJerome Forissier const struct dt_driver *__dt_driver_start(void); 73a4f139d7SJerome Forissier 74a4f139d7SJerome Forissier const struct dt_driver *__dt_driver_end(void); 75a4f139d7SJerome Forissier 769fe4c797SJerome Forissier /* 777ba16abbSJerome Forissier * Map a device into secure or non-secure memory and return the base VA and 787ba16abbSJerome Forissier * the mapping size. The mapping is done with type MEM_AREA_IO_SEC or 797ba16abbSJerome Forissier * MEM_AREA_IO_NSEC, depending on the device status. 807ba16abbSJerome Forissier * If the mapping already exists, the function simply returns the @vbase and 817ba16abbSJerome Forissier * @size information. 827ba16abbSJerome Forissier * 837ba16abbSJerome Forissier * @offs is the offset of the node that describes the device in @fdt. 847ba16abbSJerome Forissier * @base receives the base virtual address corresponding to the base physical 857ba16abbSJerome Forissier * address of the "reg" property 867ba16abbSJerome Forissier * @size receives the size of the mapping 877ba16abbSJerome Forissier * 887ba16abbSJerome Forissier * Returns 0 on success or -1 in case of error. 897ba16abbSJerome Forissier */ 907ba16abbSJerome Forissier int dt_map_dev(const void *fdt, int offs, vaddr_t *base, size_t *size); 917ba16abbSJerome Forissier 927ba16abbSJerome Forissier /* 9350f3b323SPeng Fan * Check whether the node at @offs contains the property with propname or not. 9450f3b323SPeng Fan * 9550f3b323SPeng Fan * @offs is the offset of the node that describes the device in @fdt. 9650f3b323SPeng Fan * @propname is the property that need to check 9750f3b323SPeng Fan * 9850f3b323SPeng Fan * Returns true on success or false if no propname. 9950f3b323SPeng Fan */ 10050f3b323SPeng Fan bool dt_have_prop(const void *fdt, int offs, const char *propname); 10150f3b323SPeng Fan 10250f3b323SPeng Fan /* 1039fe4c797SJerome Forissier * FDT manipulation functions, not provided by <libfdt.h> 1049fe4c797SJerome Forissier */ 1059fe4c797SJerome Forissier 1069fe4c797SJerome Forissier /* 1079fe4c797SJerome Forissier * Return the base address for the "reg" property of the specified node or 1089fe4c797SJerome Forissier * (paddr_t)-1 in case of error 1099fe4c797SJerome Forissier */ 1109fe4c797SJerome Forissier paddr_t _fdt_reg_base_address(const void *fdt, int offs); 1119fe4c797SJerome Forissier 1129fe4c797SJerome Forissier /* 1139fe4c797SJerome Forissier * Return the reg size for the reg property of the specified node or -1 in case 1149fe4c797SJerome Forissier * of error 1159fe4c797SJerome Forissier */ 1169fe4c797SJerome Forissier ssize_t _fdt_reg_size(const void *fdt, int offs); 1179fe4c797SJerome Forissier 1189fe4c797SJerome Forissier /* 1199fe4c797SJerome Forissier * Read the status and secure-status properties into a bitfield. 1209fe4c797SJerome Forissier * @status is set to DT_STATUS_DISABLED or a combination of DT_STATUS_OK_NSEC 1219fe4c797SJerome Forissier * and DT_STATUS_OK_SEC 1229fe4c797SJerome Forissier * Returns 0 on success or -1 in case of error. 1239fe4c797SJerome Forissier */ 1249fe4c797SJerome Forissier int _fdt_get_status(const void *fdt, int offs); 1259fe4c797SJerome Forissier 1269fe4c797SJerome Forissier #else /* !CFG_DT */ 127a4f139d7SJerome Forissier 128a4f139d7SJerome Forissier static inline const struct dt_driver *__dt_driver_start(void) 129a4f139d7SJerome Forissier { 130a4f139d7SJerome Forissier return NULL; 131a4f139d7SJerome Forissier } 132a4f139d7SJerome Forissier 133a4f139d7SJerome Forissier static inline const struct dt_driver *__dt_driver_end(void) 134a4f139d7SJerome Forissier { 135a4f139d7SJerome Forissier return NULL; 136a4f139d7SJerome Forissier } 137a4f139d7SJerome Forissier 138a4f139d7SJerome Forissier static inline const struct dt_driver *dt_find_compatible_driver( 139a4f139d7SJerome Forissier const void *fdt __unused, 140a4f139d7SJerome Forissier int offs __unused) 141a4f139d7SJerome Forissier { 142a4f139d7SJerome Forissier return NULL; 143a4f139d7SJerome Forissier } 144a4f139d7SJerome Forissier 1457ba16abbSJerome Forissier static inline int dt_map_dev(const void *fdt __unused, int offs __unused, 1467ba16abbSJerome Forissier vaddr_t *vbase __unused, size_t *size __unused) 1477ba16abbSJerome Forissier { 1487ba16abbSJerome Forissier return -1; 1497ba16abbSJerome Forissier } 1507ba16abbSJerome Forissier 1519fe4c797SJerome Forissier static inline paddr_t _fdt_reg_base_address(const void *fdt __unused, 1529fe4c797SJerome Forissier int offs __unused) 1539fe4c797SJerome Forissier { 1549fe4c797SJerome Forissier return (paddr_t)-1; 1559fe4c797SJerome Forissier } 1569fe4c797SJerome Forissier 1579fe4c797SJerome Forissier static inline ssize_t _fdt_reg_size(const void *fdt __unused, 1589fe4c797SJerome Forissier int offs __unused) 1599fe4c797SJerome Forissier { 1609fe4c797SJerome Forissier return -1; 1619fe4c797SJerome Forissier } 1629fe4c797SJerome Forissier 1639fe4c797SJerome Forissier static inline int _fdt_get_status(const void *fdt __unused, int offs __unused) 1649fe4c797SJerome Forissier { 1659fe4c797SJerome Forissier return -1; 1669fe4c797SJerome Forissier } 1679fe4c797SJerome Forissier 168a4f139d7SJerome Forissier #endif /* !CFG_DT */ 169a4f139d7SJerome Forissier 170a4f139d7SJerome Forissier #define for_each_dt_driver(drv) \ 171a4f139d7SJerome Forissier for (drv = __dt_driver_start(); drv < __dt_driver_end(); drv++) 172a4f139d7SJerome Forissier 173a4f139d7SJerome Forissier #endif /* KERNEL_DT_H */ 174