drivers/devicetree/fdt: get 'reg' property

Original code can only deal with single 'address & size' cell
Add function dealing with multiple 'address & size' cell
Add function getting 'bankwidth' property, for cfi-flash device

Signed-off-by: zhengyu9 <zhengyu9@xiaomi.com>
Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
zhengyu9 2024-07-19 17:44:14 +08:00 committed by Xiang Xiao
parent cd03ec3266
commit 323e2518d9
2 changed files with 235 additions and 3 deletions

View file

@ -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(&reg->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);

View file

@ -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
*