Merge patch series "dm: core: Avoid multiple calls to fdt_parent_offset()"
Jonas Karlman <jonas@kwiboo.se> says: Use of fdt_parent_offset() is very expensive as detailed by the function documentation: NOTE: This function is expensive, as it must scan the device tree structure from the start to nodeoffset, *twice*. This series remove multiple calls to fdt_parent_offset() or ofnode_get_parent() when instead a single call can be made and the returned value can be reused. This series help reduce boot time by around: - ~137ms on a Radxa ROCK Pi 4 (RK3399) - ~33ms on a Radxa ZERO 3W (RK3566)
This commit is contained in:
@@ -19,11 +19,10 @@
|
|||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
fdt_addr_t devfdt_get_addr_index(const struct udevice *dev, int index)
|
#if CONFIG_IS_ENABLED(OF_REAL) || CONFIG_IS_ENABLED(OF_CONTROL)
|
||||||
|
fdt_addr_t devfdt_get_addr_index_parent(const struct udevice *dev, int index,
|
||||||
|
int offset, int parent)
|
||||||
{
|
{
|
||||||
#if CONFIG_IS_ENABLED(OF_REAL)
|
|
||||||
int offset = dev_of_offset(dev);
|
|
||||||
int parent = fdt_parent_offset(gd->fdt_blob, offset);
|
|
||||||
fdt_addr_t addr;
|
fdt_addr_t addr;
|
||||||
|
|
||||||
if (CONFIG_IS_ENABLED(OF_TRANSLATE)) {
|
if (CONFIG_IS_ENABLED(OF_TRANSLATE)) {
|
||||||
@@ -89,6 +88,15 @@ fdt_addr_t devfdt_get_addr_index(const struct udevice *dev, int index)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
return addr;
|
return addr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fdt_addr_t devfdt_get_addr_index(const struct udevice *dev, int index)
|
||||||
|
{
|
||||||
|
#if CONFIG_IS_ENABLED(OF_REAL)
|
||||||
|
int offset = dev_of_offset(dev);
|
||||||
|
int parent = fdt_parent_offset(gd->fdt_blob, offset);
|
||||||
|
return devfdt_get_addr_index_parent(dev, index, offset, parent);
|
||||||
#else
|
#else
|
||||||
return FDT_ADDR_T_NONE;
|
return FDT_ADDR_T_NONE;
|
||||||
#endif
|
#endif
|
||||||
@@ -113,14 +121,16 @@ fdt_addr_t devfdt_get_addr_size_index(const struct udevice *dev, int index,
|
|||||||
* next call to the exisiting dev_get_xxx function which handles
|
* next call to the exisiting dev_get_xxx function which handles
|
||||||
* all config options.
|
* all config options.
|
||||||
*/
|
*/
|
||||||
fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, dev_of_offset(dev),
|
int offset = dev_of_offset(dev);
|
||||||
"reg", index, size, false);
|
int parent = fdt_parent_offset(gd->fdt_blob, offset);
|
||||||
|
fdtdec_get_addr_size_auto_parent(gd->fdt_blob, parent, offset,
|
||||||
|
"reg", index, size, false);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the base address via the existing function which handles
|
* Get the base address via the existing function which handles
|
||||||
* all Kconfig cases
|
* all Kconfig cases
|
||||||
*/
|
*/
|
||||||
return devfdt_get_addr_index(dev, index);
|
return devfdt_get_addr_index_parent(dev, index, offset, parent);
|
||||||
#else
|
#else
|
||||||
return FDT_ADDR_T_NONE;
|
return FDT_ADDR_T_NONE;
|
||||||
#endif
|
#endif
|
||||||
|
@@ -762,8 +762,9 @@ static fdt_addr_t __ofnode_get_addr_size_index(ofnode node, int index,
|
|||||||
return of_read_number(prop_val, na);
|
return of_read_number(prop_val, na);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
na = ofnode_read_simple_addr_cells(ofnode_get_parent(node));
|
ofnode parent = ofnode_get_parent(node);
|
||||||
ns = ofnode_read_simple_size_cells(ofnode_get_parent(node));
|
na = ofnode_read_simple_addr_cells(parent);
|
||||||
|
ns = ofnode_read_simple_size_cells(parent);
|
||||||
return fdtdec_get_addr_size_fixed(ofnode_to_fdt(node),
|
return fdtdec_get_addr_size_fixed(ofnode_to_fdt(node),
|
||||||
ofnode_to_offset(node), "reg",
|
ofnode_to_offset(node), "reg",
|
||||||
index, na, ns, size,
|
index, na, ns, size,
|
||||||
|
@@ -168,18 +168,21 @@ static int init_range(ofnode node, struct regmap_range *range, int addr_len,
|
|||||||
|
|
||||||
int regmap_init_mem_index(ofnode node, struct regmap **mapp, int index)
|
int regmap_init_mem_index(ofnode node, struct regmap **mapp, int index)
|
||||||
{
|
{
|
||||||
|
ofnode parent;
|
||||||
struct regmap *map;
|
struct regmap *map;
|
||||||
int addr_len, size_len;
|
int addr_len, size_len;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
addr_len = ofnode_read_simple_addr_cells(ofnode_get_parent(node));
|
parent = ofnode_get_parent(node);
|
||||||
|
|
||||||
|
addr_len = ofnode_read_simple_addr_cells(parent);
|
||||||
if (addr_len < 0) {
|
if (addr_len < 0) {
|
||||||
dm_warn("%s: Error while reading the addr length (ret = %d)\n",
|
dm_warn("%s: Error while reading the addr length (ret = %d)\n",
|
||||||
ofnode_get_name(node), addr_len);
|
ofnode_get_name(node), addr_len);
|
||||||
return addr_len;
|
return addr_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_len = ofnode_read_simple_size_cells(ofnode_get_parent(node));
|
size_len = ofnode_read_simple_size_cells(parent);
|
||||||
if (size_len < 0) {
|
if (size_len < 0) {
|
||||||
dm_warn("%s: Error while reading the size length: (ret = %d)\n",
|
dm_warn("%s: Error while reading the size length: (ret = %d)\n",
|
||||||
ofnode_get_name(node), size_len);
|
ofnode_get_name(node), size_len);
|
||||||
@@ -241,6 +244,7 @@ int regmap_init_mem_range(ofnode node, ulong r_start, ulong r_size,
|
|||||||
|
|
||||||
int regmap_init_mem(ofnode node, struct regmap **mapp)
|
int regmap_init_mem(ofnode node, struct regmap **mapp)
|
||||||
{
|
{
|
||||||
|
ofnode parent;
|
||||||
struct regmap_range *range;
|
struct regmap_range *range;
|
||||||
struct regmap *map;
|
struct regmap *map;
|
||||||
int count;
|
int count;
|
||||||
@@ -249,14 +253,16 @@ int regmap_init_mem(ofnode node, struct regmap **mapp)
|
|||||||
int index;
|
int index;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
addr_len = ofnode_read_simple_addr_cells(ofnode_get_parent(node));
|
parent = ofnode_get_parent(node);
|
||||||
|
|
||||||
|
addr_len = ofnode_read_simple_addr_cells(parent);
|
||||||
if (addr_len < 0) {
|
if (addr_len < 0) {
|
||||||
dm_warn("%s: Error while reading the addr length (ret = %d)\n",
|
dm_warn("%s: Error while reading the addr length (ret = %d)\n",
|
||||||
ofnode_get_name(node), addr_len);
|
ofnode_get_name(node), addr_len);
|
||||||
return addr_len;
|
return addr_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_len = ofnode_read_simple_size_cells(ofnode_get_parent(node));
|
size_len = ofnode_read_simple_size_cells(parent);
|
||||||
if (size_len < 0) {
|
if (size_len < 0) {
|
||||||
dm_warn("%s: Error while reading the size length: (ret = %d)\n",
|
dm_warn("%s: Error while reading the size length: (ret = %d)\n",
|
||||||
ofnode_get_name(node), size_len);
|
ofnode_get_name(node), size_len);
|
||||||
|
Reference in New Issue
Block a user