diff --git a/drivers/devicetree/fdt.c b/drivers/devicetree/fdt.c index f842e5dc712..059e18a2198 100644 --- a/drivers/devicetree/fdt.c +++ b/drivers/devicetree/fdt.c @@ -43,6 +43,20 @@ static FAR const char *g_fdt_base = NULL; * Public Functions ****************************************************************************/ +/**************************************************************************** + * Name: fdt_register + * + * Description: + * Store the pointer to the flattened device tree and verify that it at + * least appears to be valid. This function will not fully parse the FDT. + * + * Return: + * Return -EINVAL if the fdt header does not have the expected magic value. + * otherwise return OK. If OK is not returned the existing entry for FDT + * is not modified. + * + ****************************************************************************/ + int fdt_register(FAR const char *fdt_base) { struct fdt_header_s *fdt_header; @@ -59,11 +73,28 @@ int fdt_register(FAR const char *fdt_base) return OK; } +/**************************************************************************** + * Name: fdt_get + * + * Description: + * Return the pointer to a raw FDT. NULL is returned if no FDT has been + * loaded. + * + ****************************************************************************/ + FAR const char *fdt_get(void) { return g_fdt_base; } +/**************************************************************************** + * Name: fdt_get_irq + * + * Description: + * Get the interrupt number of the node + * + ****************************************************************************/ + int fdt_get_irq(FAR const void *fdt, int nodeoffset, int offset, int irqbase) { @@ -79,12 +110,50 @@ int fdt_get_irq(FAR const void *fdt, int nodeoffset, return irq; } +/**************************************************************************** + * Name: fdt_get_irq_by_path + * + * Description: + * Get the interrupt number of the node + * + ****************************************************************************/ + int fdt_get_irq_by_path(FAR const void *fdt, int offset, - FAR const char *path, int irqbase) + const char *path, int irqbase) { return fdt_get_irq(fdt, fdt_path_offset(fdt, path), offset, irqbase); } +/**************************************************************************** + * Name: fdt_get_bankwidth + * + * Description: + * Get the value of bankwidth + * + ****************************************************************************/ + +uint32_t fdt_get_bankwidth(FAR const void *fdt, int offset) +{ + FAR const void *reg; + uint32_t bankwidth = 0; + + reg = fdt_getprop(fdt, offset, "bank-width", NULL); + if (reg != NULL) + { + bankwidth = fdt32_ld(reg); + } + + return bankwidth; +} + +/**************************************************************************** + * Name: fdt_get_parent_address_cells + * + * Description: + * Get the parent address of the register space + * + ****************************************************************************/ + int fdt_get_parent_address_cells(FAR const void *fdt, int offset) { int parentoff; @@ -98,6 +167,14 @@ int fdt_get_parent_address_cells(FAR const void *fdt, int offset) return fdt_address_cells(fdt, parentoff); } +/**************************************************************************** + * Name: fdt_get_parent_size_cells + * + * Description: + * Get the parent size of the register space + * + ****************************************************************************/ + int fdt_get_parent_size_cells(FAR const void *fdt, int offset) { int parentoff; @@ -111,6 +188,15 @@ int fdt_get_parent_size_cells(FAR const void *fdt, int offset) return fdt_size_cells(fdt, parentoff); } +/**************************************************************************** + * Name: fdt_ld_by_cells + * + * Description: + * Load a 32-bit or 64-bit value from a buffer, depending on the number + * of address cells. + * + ****************************************************************************/ + uintptr_t fdt_ld_by_cells(FAR const void *value, int cells) { if (cells == 2) @@ -123,6 +209,28 @@ uintptr_t fdt_ld_by_cells(FAR const void *value, int cells) } } +/**************************************************************************** + * Name: fdt_get_reg_count + * + * Description: + * Get the count (in bytes) of the register space + * + ****************************************************************************/ + +uint32_t fdt_get_reg_count(FAR const void *fdt, int offset) +{ + FAR const struct fdt_property *reg; + uint32_t count = 0; + + reg = fdt_get_property(fdt, offset, "reg", NULL); + if (reg != NULL) + { + count = fdt32_ld(®->len); + } + + return count; +} + uintptr_t fdt_get_reg_base_by_name(FAR const void *fdt, int offset, FAR const char *reg_name) { @@ -138,6 +246,14 @@ uintptr_t fdt_get_reg_base_by_name(FAR const void *fdt, int offset, return fdt_get_reg_base(fdt, offset, reg_index); } +/**************************************************************************** + * Name: fdt_get_reg_base + * + * Description: + * Get the base address of the register space + * + ****************************************************************************/ + uintptr_t fdt_get_reg_base(FAR const void *fdt, int offset, int index) { FAR const void *reg; @@ -163,10 +279,48 @@ uintptr_t fdt_get_reg_base(FAR const void *fdt, int offset, int index) return addr; } -uintptr_t fdt_get_reg_size(FAR const void *fdt, int offset) +/**************************************************************************** + * Name: fdt_get_reg_base_by_index + * + * Description: + * Get the base address of the register space by index + * + ****************************************************************************/ + +uintptr_t fdt_get_reg_base_by_index(FAR const void *fdt, int offset, + int index) { FAR const void *reg; - uintptr_t size = 0; + uintptr_t addr = 0; + + reg = fdt_getprop(fdt, offset, "reg", NULL); + if (reg != NULL) + { + int address_cell; + int size_cell; + + address_cell = fdt_get_parent_address_cells(fdt, offset); + size_cell = fdt_get_parent_size_cells(fdt, offset); + addr = fdt_ld_by_cells((FAR fdt32_t *)reg + + (address_cell + size_cell) * index, + address_cell); + } + + return addr; +} + +/**************************************************************************** + * Name: fdt_get_reg_size + * + * Description: + * Get the size of the register space + * + ****************************************************************************/ + +size_t fdt_get_reg_size(FAR const void *fdt, int offset) +{ + FAR const void *reg; + size_t size = 0; reg = fdt_getprop(fdt, offset, "reg", NULL); if (reg != NULL) @@ -177,6 +331,42 @@ uintptr_t fdt_get_reg_size(FAR const void *fdt, int offset) return size; } +/**************************************************************************** + * Name: fdt_get_reg_size_by_index + * + * Description: + * Get the size of the register space by index + * + ****************************************************************************/ + +size_t fdt_get_reg_size_by_index(FAR const void *fdt, int offset, int index) +{ + FAR const void *reg; + size_t size = 0; + + reg = fdt_getprop(fdt, offset, "reg", NULL); + if (reg != NULL) + { + int address_cell; + int size_cell; + + address_cell = fdt_get_parent_address_cells(fdt, offset); + size_cell = fdt_get_parent_size_cells(fdt, offset); + size = fdt_ld_by_cells((FAR fdt32_t *)reg + + (address_cell + size_cell) * index + address_cell, size_cell); + } + + return size; +} + +/**************************************************************************** + * Name: fdt_get_reg_base_by_path + * + * Description: + * Get the base address of the register space + * + ****************************************************************************/ + uintptr_t fdt_get_reg_base_by_path(FAR const void *fdt, FAR const char *path) { return fdt_get_reg_base(fdt, fdt_path_offset(fdt, path), 0); diff --git a/include/nuttx/fdt.h b/include/nuttx/fdt.h index 47c7b5bf449..23b939bc45e 100644 --- a/include/nuttx/fdt.h +++ b/include/nuttx/fdt.h @@ -137,6 +137,16 @@ int fdt_get_irq(FAR const void *fdt, int nodeoffset, int fdt_get_irq_by_path(FAR const void *fdt, int offset, FAR const char *path, int irqbase); +/**************************************************************************** + * Name: fdt_get_bankwidth + * + * Description: + * Get the value of bankwidth + * + ****************************************************************************/ + +uint32_t fdt_get_bankwidth(FAR const void *fdt, int offset); + /**************************************************************************** * Name: fdt_get_parent_address_cells * @@ -189,6 +199,16 @@ int fdt_get_parent_size_cells(FAR const void *fdt, int offset); uintptr_t fdt_ld_by_cells(FAR const void *value, int cells); +/**************************************************************************** + * Name: fdt_get_reg_count + * + * Description: + * Get the count (in bytes) of the register space + * + ****************************************************************************/ + +uint32_t fdt_get_reg_count(FAR const void *fdt, int offset); + /**************************************************************************** * Name: fdt_get_reg_base_by_name * @@ -232,6 +252,17 @@ uintptr_t fdt_get_reg_base_by_name(FAR const void *fdt, int offset, uintptr_t fdt_get_reg_base(FAR const void *fdt, int offset, int index); +/**************************************************************************** + * Name: fdt_get_reg_base_by_index + * + * Description: + * Get the base address of the register space by index + * + ****************************************************************************/ + +uintptr_t fdt_get_reg_base_by_index(FAR const void *fdt, int offset, + int index); + /**************************************************************************** * Name: fdt_get_reg_size * @@ -249,6 +280,17 @@ uintptr_t fdt_get_reg_base(FAR const void *fdt, int offset, int index); uintptr_t fdt_get_reg_size(FAR const void *fdt, int offset); +/**************************************************************************** + * Name: fdt_get_reg_size_by_index + * + * Description: + * Get the size of the register space by index + * + ****************************************************************************/ + +uintptr_t fdt_get_reg_size_by_index(FAR const void *fdt, int offset, + int index); + /**************************************************************************** * Name: fdt_get_reg_base_by_path *