dtoc: Add support for 64-bit addresses
Subsystems (3)
v2 cover dtoc: Add support for 64-bit addresses
This series updates dtoc to support 64-bit addresses automatically. These appear in C code as fdt64_t arrays:
struct dtd_test1 {
fdt64_t reg[2];};
static struct dtd_test1 dtv_test1 = {
.reg = {0x123400000000, 0x5678},
};C code can then process these address and size parents easily. This feature is controlled by the #address-cells and #size-cells values of the parent.
The v2 series also enhances phandle support so that it is now possible to support phandles with different number of arguments. Several clean-up patches are included also.
Changes in v2:
- Support 'reg' properties with a single cell (e.g. #size-cells = 0)
- Introduce an fdt_val_t type which is either 32- or 64-bits long
- Update rk3368 and rk3399 uses
- Drop review tags since there are significant changes in this patch
Simon Glass (16):
fdt: Sync libfdt up to upstream
dtoc: Adjust Node to record its parent
dtoc: Add a 64-bit type and a way to convert cells into 64 bits
dtoc: Avoid very long lines in output
dtoc: Add support for 32 or 64-bit addresses
dtoc: Handle 'reg' properties with unusual sizes
dtoc: Update the Fdt class to record phandles
dtoc: Use the Fdt's class's phandle map
dtoc: Make is_phandle() a member function
dtoc: Rename is_phandle() and adjust it to return more detail
dtoc: Rename the phandle struct
dtoc: Put each phandle on a separate line
dtoc: Put phandle args in an array
dtoc: Support properties containing multiple phandle values
dtoc: Rename the auto-generated dt-structs.h file
dtoc: Add a header to the generated files
doc/driver-model/of-plat.txt | 2 +- drivers/clk/clk-uclass.c | 4 +- drivers/clk/rockchip/clk_rk3368.c | 2 +- drivers/clk/rockchip/clk_rk3399.c | 4 +- drivers/core/regmap.c | 2 +- include/clk.h | 4 +- include/dt-structs.h | 16 ++- include/fdtdec.h | 2 + include/regmap.h | 2 +- include/syscon.h | 6 +- lib/libfdt/fdt_rw.c | 20 ++- lib/libfdt/libfdt.h | 31 +++++ lib/libfdt/pylibfdt/libfdt.i | 58 ++++++++ scripts/Makefile.spl | 5 +- tools/dtoc/dtb_platdata.py | 204 ++++++++++++++++++++++------ tools/dtoc/dtoc_test_addr32.dts | 27 ++++ tools/dtoc/dtoc_test_addr32_64.dts | 33 +++++ tools/dtoc/dtoc_test_addr64.dts | 33 +++++ tools/dtoc/dtoc_test_addr64_32.dts | 33 +++++ tools/dtoc/dtoc_test_phandle.dts | 16 ++- tools/dtoc/dtoc_test_simple.dts | 14 ++ tools/dtoc/fdt.py | 19 ++- tools/dtoc/fdt_util.py | 16 +++ tools/dtoc/test_dtoc.py | 270 ++++++++++++++++++++++++++++++++++++- 24 files changed, 748 insertions(+), 75 deletions(-) create mode 100644 tools/dtoc/dtoc_test_addr32.dts create mode 100644 tools/dtoc/dtoc_test_addr32_64.dts create mode 100644 tools/dtoc/dtoc_test_addr64.dts create mode 100644 tools/dtoc/dtoc_test_addr64_32.dts
Signature · 1 line
2.14.1.342.g6490525c54-goog
PATCH v2 1/16 fdt: Sync libfdt up to upstream
Add upstream changes to U-Boot:
- new pylibfdt functions
- fdt_setprop_placeholder()
---
Changes in v2: None
lib/libfdt/fdt_rw.c | 20 ++++++++++++--- lib/libfdt/libfdt.h | 31 +++++++++++++++++++++++ lib/libfdt/pylibfdt/libfdt.i | 58 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 3 deletions(-)
lib/libfdt/fdt_rw.c +17 -3
@@ -228,8 +228,8 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name)return 0 ; } -int fdt_setprop (void *fdt,int nodeoffset,const char *name, -const void *val,int len) +int fdt_setprop_placeholder (void *fdt,int nodeoffset,const char *name, +int len,void **prop_data) {struct fdt_property *prop;int err;
@@ -242,8 +242,22 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,if (err)return err; + *prop_data = prop->data; +return 0 ; +} + +int fdt_setprop (void *fdt,int nodeoffset,const char *name, +const void *val,int len) +{ +void *prop_data; +int err; + + err =fdt_setprop_placeholder (fdt, nodeoffset, name, len, &prop_data); +if (err) +return err; +if (len) -memcpy (prop->data, val, len); +memcpy (prop_data, val, len);return 0 ; }
lib/libfdt/libfdt.h +31 -0
@@ -1404,6 +1404,37 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name);int fdt_setprop (void *fdt,int nodeoffset,const char *name,const void *val,int len); +/** +* fdt_setprop _placeholder - allocate space for a property +* @fdt: pointer to the device tree blob +* @nodeoffset: offset of the node whose property to change +* @name: name of the property to change +* @len: length of the property value +* @prop_data: return pointer to property data +* +* fdt_setprop_placeholer() allocates the named property in the given node. +* If the property exists it is resized. In either case a pointer to the +* property data is returned. +* +* This function may insert or delete data from the blob, and will +* therefore change the offsets of some existing nodes. +* +* returns: +* 0, on success +* -FDT_ERR_NOSPACE, there is insufficient free space in the blob to +* contain the new property value +* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag +* -FDT_ERR_BADLAYOUT, +* -FDT_ERR_BADMAGIC, +* -FDT_ERR_BADVERSION, +* -FDT_ERR_BADSTATE, +* -FDT_ERR_BADSTRUCTURE, +* -FDT_ERR_BADLAYOUT, +* -FDT_ERR_TRUNCATED, standard meanings +*/ +int fdt_setprop_placeholder (void *fdt,int nodeoffset,const char *name, +int len,void **prop_data); +/** * fdt_setprop_u32 - set a property to a 32-bit integer * @fdt: pointer to the device tree blob
lib/libfdt/pylibfdt/libfdt.i +58 -0
70 lines not on this page · raw message
Signature · 1 line
2.14.1.342.g6490525c54-goog
PATCH v2 1/16 fdt: Sync libfdt up to upstream
Add upstream changes to U-Boot:
- new pylibfdt functions
- fdt_setprop_placeholder()
---
Changes in v2: None
lib/libfdt/fdt_rw.c | 20 ++++++++++++--- lib/libfdt/libfdt.h | 31 +++++++++++++++++++++++ lib/libfdt/pylibfdt/libfdt.i | 58 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 3 deletions(-)
Applied to u-boot-fdt thanks!
PATCH v2 2/16 dtoc: Adjust Node to record its parent
In reply to Simon GlassWe need to be able to search back up the tree for #address-cells and
#size-cells. Record the parent of each node to make this easier.
---
Changes in v2: None
tools/dtoc/fdt.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
tools/dtoc/fdt.py +7 -5
@@ -174,8 +174,9 @@ class Node: props: A dict of properties for this node, each a Prop object. Keyed by property name """ - def __init__(self, fdt, offset, name, path): + def __init__(self, fdt, parent, offset, name, path): self._fdt = fdt + self.parent = parent self._offset = offset self.name = name self.path = path
@@ -217,7 +218,7 @@ class Node: sep = '' if self.path[-1] == '/' else '/' name = self._fdt._fdt_obj.get_name(offset) path = self.path + sep + name - node = Node(self._fdt, offset, name, path) + node = Node(self._fdt, self, offset, name, path) self.subnodes.append(node) node.Scan()
@@ -279,7 +280,7 @@ class Fdt: TODO(sjg at chromium.org): Implement the 'root' parameter """ - self._root = self.Node(self, 0, '/', '/') + self._root = self.Node(self, None, 0, '/', '/') self._root.Scan() def GetRoot(self):
@@ -386,7 +387,7 @@ class Fdt: return libfdt.fdt_off_dt_struct(self._fdt) + offset @classmethod - def Node(self, fdt, offset, name, path): + def Node(self, fdt, parent, offset, name, path): """Create a new node This is used by Fdt.Scan() to create a new node using the correct
@@ -394,11 +395,12 @@ class Fdt: Args: fdt: Fdt object + parent: Parent node, or None if this is the root node offset: Offset of node name: Node name path: Full path to node """ - node = Node(fdt, offset, name, path) + node = Node(fdt, parent, offset, name, path) return node def FdtScan(fname):
Signature · 1 line
2.14.1.342.g6490525c54-goog
PATCH v2 2/16 dtoc: Adjust Node to record its parent
We need to be able to search back up the tree for #address-cells and
#size-cells. Record the parent of each node to make this easier.
---
Changes in v2: None
tools/dtoc/fdt.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
Applied to u-boot-fdt thanks!
PATCH v2 3/16 dtoc: Add a 64-bit type and a way to convert cells into 64 bits
In reply to Simon GlassWhen dealing with multi-cell values we need a type that can hold this value. Add this and a function to process it from a list of cell values.
---
Changes in v2: None
tools/dtoc/dtb_platdata.py | 3 +++ tools/dtoc/fdt.py | 2 +- tools/dtoc/fdt_util.py | 14 ++++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-)
tools/dtoc/dtb_platdata.py +3 -0
@@ -38,6 +38,7 @@ TYPE_NAMES = { fdt.TYPE_BYTE: 'unsigned char', fdt.TYPE_STRING: 'const char *', fdt.TYPE_BOOL: 'bool', + fdt.TYPE_INT64: 'fdt64_t', } STRUCT_PREFIX = 'dtd_'
@@ -95,6 +96,8 @@ def get_value(ftype, value): return '"%s"' % value elif ftype == fdt.TYPE_BOOL: return 'true' + elif ftype == fdt.TYPE_INT64: + return '%#x' % value def get_compat_name(node): """Get a node's first compatible string as a C identifier
tools/dtoc/fdt.py +1 -1
@@ -21,7 +21,7 @@ import libfdt # so it is fairly efficient. # A list of types we support -(TYPE_BYTE, TYPE_INT, TYPE_STRING, TYPE_BOOL) = range(4) +(TYPE_BYTE, TYPE_INT, TYPE_STRING, TYPE_BOOL, TYPE_INT64) = range(5) def CheckErr(errnum, msg): if errnum:
tools/dtoc/fdt_util.py +14 -0
@@ -29,6 +29,20 @@ def fdt32_to_cpu(val): val = val.encode('raw_unicode_escape') return struct.unpack('>I', val)[0] +def fdt_cells_to_cpu(val, cells): + """Convert one or two cells to a long integer + + Args: + Value to convert (array of one or more 4-character strings) + + Return: + A native-endian long value + """ + out = long(fdt32_to_cpu(val[0])) + if cells == 2: + out = out << 32 | fdt32_to_cpu(val[1]) + return out + def EnsureCompiled(fname): """Compile an fdt .dts source file into a .dtb binary blob if needed.
Signature · 1 line
2.14.1.342.g6490525c54-goog
PATCH v2 3/16 dtoc: Add a 64-bit type and a way to convert cells into 64 bits
When dealing with multi-cell values we need a type that can hold this value. Add this and a function to process it from a list of cell values.
---
Changes in v2: None
tools/dtoc/dtb_platdata.py | 3 +++ tools/dtoc/fdt.py | 2 +- tools/dtoc/fdt_util.py | 14 ++++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-)
Applied to u-boot-fdt thanks!
PATCH v2 4/16 dtoc: Avoid very long lines in output
In reply to Simon GlassLarge arrays can result in lines with hundreds or thousands of characters which is not very editor-friendly. To avoid this, addjust the tool to group values 8 per line.
---
Changes in v2: None
tools/dtoc/dtb_platdata.py | 7 ++++++- tools/dtoc/test_dtoc.py | 6 ++++-- 2 files changed, 10 insertions(+), 3 deletions(-)
tools/dtoc/dtb_platdata.py +6 -1
@@ -385,7 +385,12 @@ class DtbPlatdata(object): else: for val in prop.value: vals.append(get_value(prop.type, val)) - self.buf(', '.join(vals)) + + # Put 8 values per line to avoid very long lines. + for i in xrange(0, len(vals), 8): + if i: + self.buf(',\n\t\t') + self.buf(', '.join(vals[i:i + 8])) self.buf('}') else: self.buf(get_value(prop.type, prop.value))
tools/dtoc/test_dtoc.py +4 -2
@@ -146,7 +146,8 @@ static struct dtd_sandbox_spl_test dtv_spl_test = { \t.bytearray\t\t= {0x6, 0x0, 0x0}, \t.byteval\t\t= 0x5, \t.intval\t\t\t= 0x1, -\t.longbytearray\t\t= {0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11}, +\t.longbytearray\t\t= {0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, +\t\t0x11}, \t.stringval\t\t= "message", \t.boolval\t\t= true, \t.intarray\t\t= {0x2, 0x3, 0x4, 0x0},
@@ -162,7 +163,8 @@ static struct dtd_sandbox_spl_test dtv_spl_test2 = { \t.bytearray\t\t= {0x1, 0x23, 0x34}, \t.byteval\t\t= 0x8, \t.intval\t\t\t= 0x3, -\t.longbytearray\t\t= {0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, +\t.longbytearray\t\t= {0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +\t\t0x0}, \t.stringval\t\t= "message2", \t.intarray\t\t= {0x5, 0x0, 0x0, 0x0}, \t.stringarray\t\t= {"another", "multi-word", "message"},
Signature · 1 line
2.14.1.342.g6490525c54-goog
PATCH v2 4/16 dtoc: Avoid very long lines in output
Large arrays can result in lines with hundreds or thousands of characters which is not very editor-friendly. To avoid this, addjust the tool to group values 8 per line.
---
Changes in v2: None
tools/dtoc/dtb_platdata.py | 7 ++++++- tools/dtoc/test_dtoc.py | 6 ++++-- 2 files changed, 10 insertions(+), 3 deletions(-)
Applied to u-boot-fdt thanks!
PATCH v2 5/16 dtoc: Add support for 32 or 64-bit addresses
In reply to Simon GlassWhen using 32-bit addresses dtoc works correctly. For 64-bit addresses it does not since it ignores the #address-cells and #size-cells properties.
Update the tool to use fdt64_t as the element type for reg properties when either the address or size is larger than one cell. Use the correct value so that C code can obtain the information from the device tree easily.
Alos create a new type, fdt_val_t, which is defined to either fdt32_t or fdt64_t depending on the word size of the machine. This type corresponds to fdt_addr_t and fdt_size_t. Unfortunately we cannot just use those types since they are defined to phys_addr_t and phys_size_t which use 'unsigned long' in the 32-bit case, rather than 'unsigned int'.
Add tests for the four combinations of address and size values (32/32, 64/64, 32/64, 64/32). Also update existing uses for rk3399 and rk3368 which now need to use the new fdt_val_t type.
---
Changes in v2:
- Support 'reg' properties with a single cell (e.g. #size-cells = 0)
- Introduce an fdt_val_t type which is either 32- or 64-bits long
- Update rk3368 and rk3399 uses
- Drop review tags since there are significant changes in this patch
drivers/clk/rockchip/clk_rk3368.c | 2 +- drivers/clk/rockchip/clk_rk3399.c | 4 +- drivers/core/regmap.c | 2 +- include/fdtdec.h | 2 + include/regmap.h | 2 +- include/syscon.h | 6 +- tools/dtoc/dtb_platdata.py | 61 +++++++++++ tools/dtoc/dtoc_test_addr32.dts | 27 +++++ tools/dtoc/dtoc_test_addr32_64.dts | 33 ++++++ tools/dtoc/dtoc_test_addr64.dts | 33 ++++++ tools/dtoc/dtoc_test_addr64_32.dts | 33 ++++++ tools/dtoc/fdt_util.py | 2 + tools/dtoc/test_dtoc.py | 212 +++++++++++++++++++++++++++++++++++++ 13 files changed, 413 insertions(+), 6 deletions(-) create mode 100644 tools/dtoc/dtoc_test_addr32.dts create mode 100644 tools/dtoc/dtoc_test_addr32_64.dts create mode 100644 tools/dtoc/dtoc_test_addr64.dts create mode 100644 tools/dtoc/dtoc_test_addr64_32.dts
drivers/clk/rockchip/clk_rk3368.c +1 -1
@@ -471,7 +471,7 @@ static int rk3368_clk_probe(struct udevice *dev)#if CONFIG_IS_ENABLED (OF_PLATDATA )struct rk3368_clk_plat *plat =dev_get_platdata (dev); - priv->cru =map_sysmem (plat->dtd.reg[1 ], plat->dtd.reg[3 ]); + priv->cru =map_sysmem (plat->dtd.reg[0 ], plat->dtd.reg[1 ]);#endif #if IS_ENABLED (CONFIG_SPL_BUILD ) ||IS_ENABLED (CONFIG_TPL_BUILD )rkclk_init (priv->cru);
drivers/clk/rockchip/clk_rk3399.c +2 -2
@@ -963,7 +963,7 @@ static int rk3399_clk_probe(struct udevice *dev)#if CONFIG_IS_ENABLED (OF_PLATDATA )struct rk3399_clk_plat *plat =dev_get_platdata (dev); - priv->cru =map_sysmem (plat->dtd.reg[1 ], plat->dtd.reg[3 ]); + priv->cru =map_sysmem (plat->dtd.reg[0 ], plat->dtd.reg[0 ]);#endif rkclk_init (priv->cru);#endif
@@ -1145,7 +1145,7 @@ static int rk3399_pmuclk_probe(struct udevice *dev)#if CONFIG_IS_ENABLED (OF_PLATDATA )struct rk3399_pmuclk_plat *plat =dev_get_platdata (dev); - priv->pmucru =map_sysmem (plat->dtd.reg[1 ], plat->dtd.reg[3 ]); + priv->pmucru =map_sysmem (plat->dtd.reg[0 ], plat->dtd.reg[1 ]);#endif #ifndef CONFIG_SPL_BUILD
drivers/core/regmap.c +1 -1
@@ -40,7 +40,7 @@ static struct regmap *regmap_alloc_count(int count) }#if CONFIG_IS_ENABLED (OF_PLATDATA ) -int regmap_init_mem_platdata (struct udevice *dev,u32 *reg,int count, +int regmap_init_mem_platdata (struct udevice *dev,fdt_val_t *reg,int count,struct regmap **mapp) {struct regmap_range *range;
include/fdtdec.h +2 -0
@@ -27,10 +27,12 @@ typedef phys_size_t fdt_size_t;#define FDT_ADDR_T_NONE (-1ULL)#define fdt_addr_to_cpu (reg) be64_to_cpu(reg)#define fdt_size_to_cpu (reg) be64_to_cpu(reg) +typedef fdt64_t fdt_val_t ;#else #define FDT_ADDR_T_NONE (-1U)#define fdt_addr_to_cpu (reg) be32_to_cpu(reg)#define fdt_size_to_cpu (reg) be32_to_cpu(reg) +typedef fdt32_t fdt_val_t ;#endif /* Information obtained about memory from the FDT */
include/regmap.h +1 -1
@@ -69,7 +69,7 @@ int regmap_init_mem(struct udevice *dev, struct regmap **mapp);* @count: Number of pairs (e.g. 1 if the regmap has a single entry) * @mapp: Returns allocated map */ -int regmap_init_mem_platdata (struct udevice *dev,u32 *reg,int count, +int regmap_init_mem_platdata (struct udevice *dev,fdt_val_t *reg,int count,struct regmap **mapp);/**
include/syscon.h +5 -1
@@ -8,6 +8,8 @@#ifndef __SYSCON_H#define __SYSCON_H +#include <fdtdec.h> +/** * struct syscon_uc_info - Information stored by the syscon UCLASS_UCLASS *
@@ -28,9 +30,11 @@ struct syscon_ops {* We don't support 64-bit machines. If they are so resource-contrained that * they need to use OF_PLATDATA, something is horribly wrong with the * education of our hardware engineers. +* +* Update: 64-bit is now supported and we have an education crisis. */ struct syscon_base_platdata { -u32 reg[2 ]; +fdt_val_t reg[2 ]; };#endif
tools/dtoc/dtb_platdata.py +61 -0
73 lines not on this page · raw message
tools/dtoc/dtoc_test_addr32.dts new file +27 -0
@@ -0,0 +1,27 @@ +/* + * Test device tree file for dtoc + * + * Copyright 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + /dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + test1 { + u-boot,dm-pre-reloc; + compatible = "test1"; + reg = <0x1234 0x5678>; + }; + + test2 { + u-boot,dm-pre-reloc; + compatible = "test2"; + reg = <0x12345678 0x98765432 2 3>; + }; + +};
tools/dtoc/dtoc_test_addr32_64.dts new file +33 -0
@@ -0,0 +1,33 @@ +/* + * Test device tree file for dtoc + * + * Copyright 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + /dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <2>; + + test1 { + u-boot,dm-pre-reloc; + compatible = "test1"; + reg = <0x1234 0x5678 0x0>; + }; + + test2 { + u-boot,dm-pre-reloc; + compatible = "test2"; + reg = <0x12345678 0x98765432 0x10987654>; + }; + + test3 { + u-boot,dm-pre-reloc; + compatible = "test3"; + reg = <0x12345678 0x98765432 0x10987654 2 0 3>; + }; + +};
tools/dtoc/dtoc_test_addr64.dts new file +33 -0
@@ -0,0 +1,33 @@ +/* + * Test device tree file for dtoc + * + * Copyright 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + /dts-v1/; + +/ { + #address-cells = <2>; + #size-cells = <2>; + + test1 { + u-boot,dm-pre-reloc; + compatible = "test1"; + reg = /bits/ 64 <0x1234 0x5678>; + }; + + test2 { + u-boot,dm-pre-reloc; + compatible = "test2"; + reg = /bits/ 64 <0x1234567890123456 0x9876543210987654>; + }; + + test3 { + u-boot,dm-pre-reloc; + compatible = "test3"; + reg = /bits/ 64 <0x1234567890123456 0x9876543210987654 2 3>; + }; + +};
tools/dtoc/dtoc_test_addr64_32.dts new file +33 -0
@@ -0,0 +1,33 @@ +/* + * Test device tree file for dtoc + * + * Copyright 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + /dts-v1/; + +/ { + #address-cells = <2>; + #size-cells = <1>; + + test1 { + u-boot,dm-pre-reloc; + compatible = "test1"; + reg = <0x1234 0x0 0x5678>; + }; + + test2 { + u-boot,dm-pre-reloc; + compatible = "test2"; + reg = <0x12345678 0x90123456 0x98765432>; + }; + + test3 { + u-boot,dm-pre-reloc; + compatible = "test3"; + reg = <0x12345678 0x90123456 0x98765432 0 2 3>; + }; + +};
tools/dtoc/fdt_util.py +2 -0
@@ -38,6 +38,8 @@ def fdt_cells_to_cpu(val, cells): Return: A native-endian long value """ + if not cells: + return 0 out = long(fdt32_to_cpu(val[0])) if cells == 2: out = out << 32 | fdt32_to_cpu(val[1])
tools/dtoc/test_dtoc.py +212 -0
216 lines not on this page · raw message
Signature · 1 line
2.14.1.342.g6490525c54-goog
PATCH v2 5/16 dtoc: Add support for 32 or 64-bit addresses
Quoted 16 lines · Simon Glass
When using 32-bit addresses dtoc works correctly. For 64-bit addresses it does not since it ignores the #address-cells and #size-cells properties.
Update the tool to use
fdt64_tas the element type for reg properties when either the address or size is larger than one cell. Use the correct value so that C code can obtain the information from the device tree easily.Alos create a new type,
fdt_val_t, which is defined to eitherfdt32_torfdt64_tdepending on the word size of the machine. This type corresponds tofdt_addr_tandfdt_size_t. Unfortunately we cannot just use those types since they are defined tophys_addr_tandphys_size_twhich use 'unsigned long' in the 32-bit case, rather than 'unsigned int'.
Quoted 8 lines
Add tests for the four combinations of address and size values (32/32, 64/64, 32/64, 64/32). Also update existing uses for rk3399 and rk3368 which now need to use the new
fdt_val_ttype.Signed-off-by Simon Glass <[email protected]>Suggested-by Heiko Stuebner <[email protected]>Reported-by Kever Yang <[email protected]>
See below.
Quoted 45 lines
---
Changes in v2:
- Support 'reg' properties with a single cell (e.g. #size-cells = 0)
- Introduce anfdt_val_ttype which is either 32- or 64-bits long
- Update rk3368 and rk3399 uses
- Drop review tags since there are significant changes in this patchdrivers/clk/rockchip/clk_rk3368.c | 2 +- drivers/clk/rockchip/clk_rk3399.c | 4 +- drivers/core/regmap.c | 2 +- include/fdtdec.h | 2 + include/regmap.h | 2 +- include/syscon.h | 6 +- tools/dtoc/dtb_platdata.py | 61 +++++++++++ tools/dtoc/dtoc_test_addr32.dts | 27 +++++ tools/dtoc/dtoc_test_addr32_64.dts | 33 ++++++ tools/dtoc/dtoc_test_addr64.dts | 33 ++++++ tools/dtoc/dtoc_test_addr64_32.dts | 33 ++++++ tools/dtoc/fdt_util.py | 2 + tools/dtoc/test_dtoc.py | 212 +++++++++++++++++++++++++++++++++++++ 13 files changed, 413 insertions(+), 6 deletions(-)create mode 100644
tools/dtoc/dtoc_test_addr32.dtscreate mode 100644tools/dtoc/dtoc_test_addr32_64.dtscreate mode 100644tools/dtoc/dtoc_test_addr64.dtscreate mode 100644tools/dtoc/dtoc_test_addr64_32.dtsdrivers/clk/rockchip/clk_rk3368.c +1
-1@@ -471,7 +471,7 @@ static int rk3368_clk_probe(struct udevice *dev)#if CONFIG_IS_ENABLED (OF_PLATDATA )struct rk3368_clk_plat *plat =dev_get_platdata (dev); - priv->cru =map_sysmem (plat->dtd.reg[1 ], plat->dtd.reg[3 ]); + priv->cru =map_sysmem (plat->dtd.reg[0 ], plat->dtd.reg[1 ]);#endif #if IS_ENABLED (CONFIG_SPL_BUILD ) ||IS_ENABLED (CONFIG_TPL_BUILD )rkclk_init (priv->cru);drivers/clk/rockchip/clk_rk3399.c +0
-0
drivers/clk/rockchip/clk_rk3399.c static int rk3399_clk_probe(struct udevice *dev) · line 966
Quoted 5 lines
drivers/clk/rockchip/clk_rk3399.c +1
-1@@ -963,7 +963,7 @@ static int rk3399_clk_probe(struct udevice *dev)#if CONFIG_IS_ENABLED (OF_PLATDATA )struct rk3399_clk_plat *plat =dev_get_platdata (dev); - priv->cru =map_sysmem (plat->dtd.reg[1 ], plat->dtd.reg[3 ]); + priv->cru =map_sysmem (plat->dtd.reg[0 ], plat->dtd.reg[0 ]);
The second argument needs to be reg[1].
Quoted 547 lines
drivers/clk/rockchip/clk_rk3399.c +1
-1#endif rkclk_init (priv->cru);#endif @@ -1145,7 +1145,7 @@ static int rk3399_pmuclk_probe(struct udevice *dev)#if CONFIG_IS_ENABLED (OF_PLATDATA )struct rk3399_pmuclk_plat *plat =dev_get_platdata (dev); - priv->pmucru =map_sysmem (plat->dtd.reg[1 ], plat->dtd.reg[3 ]); + priv->pmucru =map_sysmem (plat->dtd.reg[0 ], plat->dtd.reg[1 ]);#endif #ifndef CONFIG_SPL_BUILD drivers/core/regmap.c +1
-1@@ -40,7 +40,7 @@ static struct regmap *regmap_alloc_count(int count) }#if CONFIG_IS_ENABLED (OF_PLATDATA ) -int regmap_init_mem_platdata (struct udevice *dev,u32 *reg,int count, +int regmap_init_mem_platdata (struct udevice *dev,fdt_val_t *reg,int count,struct regmap **mapp) {struct regmap_range *range;include/fdtdec.h +2
-0@@ -27,10 +27,12 @@ typedef phys_size_t fdt_size_t;#define FDT_ADDR_T_NONE (-1ULL)#define fdt_addr_to_cpu (reg) be64_to_cpu(reg)#define fdt_size_to_cpu (reg) be64_to_cpu(reg) +typedef fdt64_t fdt_val_t ;#else #define FDT_ADDR_T_NONE (-1U)#define fdt_addr_to_cpu (reg) be32_to_cpu(reg)#define fdt_size_to_cpu (reg) be32_to_cpu(reg) +typedef fdt32_t fdt_val_t ;#endif /* Information obtained about memory from the FDT */ include/regmap.h +1
-1@@ -69,7 +69,7 @@ int regmap_init_mem(struct udevice *dev, struct regmap **mapp);* @count: Number of pairs (e.g. 1 if the regmap has a single entry) * @mapp: Returns allocated map */ -int regmap_init_mem_platdata (struct udevice *dev,u32 *reg,int count, +int regmap_init_mem_platdata (struct udevice *dev,fdt_val_t *reg,int count,struct regmap **mapp);/** include/syscon.h +5
-1@@ -8,6 +8,8 @@#ifndef __SYSCON_H#define __SYSCON_H +#include <fdtdec.h> +/** * struct syscon_uc_info - Information stored by the syscon UCLASS_UCLASS * @@ -28,9 +30,11 @@ struct syscon_ops {* We don't support 64-bit machines. If they are so resource-contrained that * they need to use OF_PLATDATA, something is horribly wrong with the * education of our hardware engineers. +* +* Update: 64-bit is now supported and we have an education crisis. */ struct syscon_base_platdata { -u32 reg[2 ]; +fdt_val_t reg[2 ]; };#endif tools/dtoc/dtb_platdata.py +61
-0@@ -242,6 +242,66 @@ class DtbPlatdata(object): self._valid_nodes = [] return self.scan_node(self._fdt.GetRoot()) + @staticmethod + def get_num_cells(node): + """Get the number of cells in addresses and sizes for this node + + Args: + node: Node to check + + Returns: + Tuple: + Number of address cells for this node + Number of size cells for this node + """ + parent = node.parent + na, ns = 2, 2 + if parent: + na_prop = parent.props.get('#address-cells') + ns_prop = parent.props.get('#size-cells') + if na_prop: + na = fdt_util.fdt32_to_cpu(na_prop.value) + if ns_prop: + ns = fdt_util.fdt32_to_cpu(ns_prop.value) + return na, ns + + def scan_reg_sizes(self): + """Scan for 64-bit 'reg' properties and update the values + + This finds 'reg' properties with 64-bit data and converts the value to + an array of 64-values. This allows it to be output in a way that the + C code can read. + """ + for node in self._valid_nodes: + reg = node.props.get('reg') + if not reg: + continue + na, ns = self.get_num_cells(node) + total = na + ns + + if reg.type != fdt.TYPE_INT: + raise ValueError("Node '%s' reg property is not an int") + if len(reg.value) % total: + raise ValueError("Node '%s' reg property has %d cells " + 'which is not a multiple of na + ns = %d + %d)' % + (node.name, len(reg.value), na, ns)) + reg.na = na + reg.ns = ns + if na != 1 or ns != 1: + reg.type = fdt.TYPE_INT64 + i = 0 + new_value = [] + val = reg.value + if not isinstance(val, list): + val = [val] + while i < len(val): + addr = fdt_util.fdt_cells_to_cpu(val[i:], reg.na) + i += na + size = fdt_util.fdt_cells_to_cpu(val[i:], reg.ns) + i += ns + new_value += [addr, size] + reg.value = new_value + def scan_structs(self): """Scan the device tree building up the C structures we will use.@@ -450,6 +510,7 @@ def run_steps(args, dtb_file, include_disabled, output): plat = DtbPlatdata(dtb_file, include_disabled) plat.scan_dtb() plat.scan_tree() + plat.scan_reg_sizes() plat.setup_output(output) structs = plat.scan_structs() plat.scan_phandles()tools/dtoc/dtoc_test_addr32.dts new file +27
-0@@ -0,0 +1,27 @@ +/* + * Test device tree file for dtoc + * + * Copyright 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + /dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + test1 { + u-boot,dm-pre-reloc; + compatible = "test1"; + reg = <0x1234 0x5678>; + }; + + test2 { + u-boot,dm-pre-reloc; + compatible = "test2"; + reg = <0x12345678 0x98765432 2 3>; + }; + +};tools/dtoc/dtoc_test_addr32_64.dts new file +33
-0@@ -0,0 +1,33 @@ +/* + * Test device tree file for dtoc + * + * Copyright 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + /dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <2>; + + test1 { + u-boot,dm-pre-reloc; + compatible = "test1"; + reg = <0x1234 0x5678 0x0>; + }; + + test2 { + u-boot,dm-pre-reloc; + compatible = "test2"; + reg = <0x12345678 0x98765432 0x10987654>; + }; + + test3 { + u-boot,dm-pre-reloc; + compatible = "test3"; + reg = <0x12345678 0x98765432 0x10987654 2 0 3>; + }; + +};tools/dtoc/dtoc_test_addr64.dts new file +33
-0@@ -0,0 +1,33 @@ +/* + * Test device tree file for dtoc + * + * Copyright 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + /dts-v1/; + +/ { + #address-cells = <2>; + #size-cells = <2>; + + test1 { + u-boot,dm-pre-reloc; + compatible = "test1"; + reg = /bits/ 64 <0x1234 0x5678>; + }; + + test2 { + u-boot,dm-pre-reloc; + compatible = "test2"; + reg = /bits/ 64 <0x1234567890123456 0x9876543210987654>; + }; + + test3 { + u-boot,dm-pre-reloc; + compatible = "test3"; + reg = /bits/ 64 <0x1234567890123456 0x9876543210987654 2 3>; + }; + +};tools/dtoc/dtoc_test_addr64_32.dts new file +33
-0@@ -0,0 +1,33 @@ +/* + * Test device tree file for dtoc + * + * Copyright 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + /dts-v1/; + +/ { + #address-cells = <2>; + #size-cells = <1>; + + test1 { + u-boot,dm-pre-reloc; + compatible = "test1"; + reg = <0x1234 0x0 0x5678>; + }; + + test2 { + u-boot,dm-pre-reloc; + compatible = "test2"; + reg = <0x12345678 0x90123456 0x98765432>; + }; + + test3 { + u-boot,dm-pre-reloc; + compatible = "test3"; + reg = <0x12345678 0x90123456 0x98765432 0 2 3>; + }; + +};tools/dtoc/fdt_util.py +2
-0@@ -38,6 +38,8 @@ def fdt_cells_to_cpu(val, cells): Return: A native-endian long value """ + if not cells: + return 0 out = long(fdt32_to_cpu(val[0])) if cells == 2: out = out << 32 | fdt32_to_cpu(val[1])tools/dtoc/test_dtoc.py +212
-0@@ -270,4 +270,216 @@ U_BOOT_DEVICE(spl_test) = { \t.platdata_size\t= sizeof(dtv_spl_test), }; +''', data) + + def test_addresses64(self): + """Test output from a node with a 'reg' property with na=2, ns=2""" + dtb_file = get_dtb_file('dtoc_test_addr64.dts') + output = tools.GetOutputFilename('output') + dtb_platdata.run_steps(['struct'], dtb_file, False, output) + with open(output) as infile: + data = infile.read() + self.assertEqual('''#include <stdbool.h> +#include <libfdt.h> +struct dtd_test1 { +\tfdt64_t\t\treg[2]; +}; +struct dtd_test2 { +\tfdt64_t\t\treg[2]; +}; +struct dtd_test3 { +\tfdt64_t\t\treg[4]; +}; +''', data) + + dtb_platdata.run_steps(['platdata'], dtb_file, False, output) + with open(output) as infile: + data = infile.read() + self.assertEqual('''#include <common.h> +#include <dm.h> +#include <dt-structs.h> + +static struct dtd_test1 dtv_test1 = { +\t.reg\t\t\t= {0x1234, 0x5678}, +}; +U_BOOT_DEVICE(test1) = { +\t.name\t\t= "test1", +\t.platdata\t= &dtv_test1, +\t.platdata_size\t= sizeof(dtv_test1), +}; + +static struct dtd_test2 dtv_test2 = { +\t.reg\t\t\t= {0x1234567890123456, 0x9876543210987654}, +}; +U_BOOT_DEVICE(test2) = { +\t.name\t\t= "test2", +\t.platdata\t= &dtv_test2, +\t.platdata_size\t= sizeof(dtv_test2), +}; + +static struct dtd_test3 dtv_test3 = { +\t.reg\t\t\t= {0x1234567890123456, 0x9876543210987654, 0x2, 0x3}, +}; +U_BOOT_DEVICE(test3) = { +\t.name\t\t= "test3", +\t.platdata\t= &dtv_test3, +\t.platdata_size\t= sizeof(dtv_test3), +}; + +''', data) + + def test_addresses32(self): + """Test output from a node with a 'reg' property with na=1, ns=1""" + dtb_file = get_dtb_file('dtoc_test_addr32.dts') + output = tools.GetOutputFilename('output') + dtb_platdata.run_steps(['struct'], dtb_file, False, output) + with open(output) as infile: + data = infile.read() + self.assertEqual('''#include <stdbool.h> +#include <libfdt.h> +struct dtd_test1 { +\tfdt32_t\t\treg[2]; +}; +struct dtd_test2 { +\tfdt32_t\t\treg[4]; +}; +''', data) + + dtb_platdata.run_steps(['platdata'], dtb_file, False, output) + with open(output) as infile: + data = infile.read() + self.assertEqual('''#include <common.h> +#include <dm.h> +#include <dt-structs.h> + +static struct dtd_test1 dtv_test1 = { +\t.reg\t\t\t= {0x1234, 0x5678}, +}; +U_BOOT_DEVICE(test1) = { +\t.name\t\t= "test1", +\t.platdata\t= &dtv_test1, +\t.platdata_size\t= sizeof(dtv_test1), +}; + +static struct dtd_test2 dtv_test2 = { +\t.reg\t\t\t= {0x12345678, 0x98765432, 0x2, 0x3}, +}; +U_BOOT_DEVICE(test2) = { +\t.name\t\t= "test2", +\t.platdata\t= &dtv_test2, +\t.platdata_size\t= sizeof(dtv_test2), +}; + +''', data) + + def test_addresses64_32(self): + """Test output from a node with a 'reg' property with na=2, ns=1""" + dtb_file = get_dtb_file('dtoc_test_addr64_32.dts') + output = tools.GetOutputFilename('output') + dtb_platdata.run_steps(['struct'], dtb_file, False, output) + with open(output) as infile: + data = infile.read() + self.assertEqual('''#include <stdbool.h> +#include <libfdt.h> +struct dtd_test1 { +\tfdt64_t\t\treg[2]; +}; +struct dtd_test2 { +\tfdt64_t\t\treg[2]; +}; +struct dtd_test3 { +\tfdt64_t\t\treg[4]; +}; +''', data) + + dtb_platdata.run_steps(['platdata'], dtb_file, False, output) + with open(output) as infile: + data = infile.read() + self.assertEqual('''#include <common.h> +#include <dm.h> +#include <dt-structs.h> + +static struct dtd_test1 dtv_test1 = { +\t.reg\t\t\t= {0x123400000000, 0x5678}, +}; +U_BOOT_DEVICE(test1) = { +\t.name\t\t= "test1", +\t.platdata\t= &dtv_test1, +\t.platdata_size\t= sizeof(dtv_test1), +}; + +static struct dtd_test2 dtv_test2 = { +\t.reg\t\t\t= {0x1234567890123456, 0x98765432}, +}; +U_BOOT_DEVICE(test2) = { +\t.name\t\t= "test2", +\t.platdata\t= &dtv_test2, +\t.platdata_size\t= sizeof(dtv_test2), +}; + +static struct dtd_test3 dtv_test3 = { +\t.reg\t\t\t= {0x1234567890123456, 0x98765432, 0x2, 0x3}, +}; +U_BOOT_DEVICE(test3) = { +\t.name\t\t= "test3", +\t.platdata\t= &dtv_test3, +\t.platdata_size\t= sizeof(dtv_test3), +}; + +''', data) + + def test_addresses32_64(self): + """Test output from a node with a 'reg' property with na=1, ns=2""" + dtb_file = get_dtb_file('dtoc_test_addr32_64.dts') + output = tools.GetOutputFilename('output') + dtb_platdata.run_steps(['struct'], dtb_file, False, output) + with open(output) as infile: + data = infile.read() + self.assertEqual('''#include <stdbool.h> +#include <libfdt.h> +struct dtd_test1 { +\tfdt64_t\t\treg[2]; +}; +struct dtd_test2 { +\tfdt64_t\t\treg[2]; +}; +struct dtd_test3 { +\tfdt64_t\t\treg[4]; +}; +''', data) + + dtb_platdata.run_steps(['platdata'], dtb_file, False, output) + with open(output) as infile: + data = infile.read() + self.assertEqual('''#include <common.h> +#include <dm.h> +#include <dt-structs.h> + +static struct dtd_test1 dtv_test1 = { +\t.reg\t\t\t= {0x1234, 0x567800000000}, +}; +U_BOOT_DEVICE(test1) = { +\t.name\t\t= "test1", +\t.platdata\t= &dtv_test1, +\t.platdata_size\t= sizeof(dtv_test1), +}; + +static struct dtd_test2 dtv_test2 = { +\t.reg\t\t\t= {0x12345678, 0x9876543210987654}, +}; +U_BOOT_DEVICE(test2) = { +\t.name\t\t= "test2", +\t.platdata\t= &dtv_test2, +\t.platdata_size\t= sizeof(dtv_test2), +}; + +static struct dtd_test3 dtv_test3 = { +\t.reg\t\t\t= {0x12345678, 0x9876543210987654, 0x2, 0x3}, +}; +U_BOOT_DEVICE(test3) = { +\t.name\t\t= "test3", +\t.platdata\t= &dtv_test3, +\t.platdata_size\t= sizeof(dtv_test3), +}; + ''', data)Signature · 1 line
2.14.1.342.g6490525c54-goog
PATCH v2 5/16 dtoc: Add support for 32 or 64-bit addresses
Quoted 77 lines · Dr. Philipp Tomsich
Quoted 16 lines · Simon Glass
When using 32-bit addresses dtoc works correctly. For 64-bit addresses it does not since it ignores the #address-cells and #size-cells properties.
Update the tool to use
fdt64_tas the element type for reg properties when either the address or size is larger than one cell. Use the correct value so that C code can obtain the information from the device tree easily.Alos create a new type,
fdt_val_t, which is defined to eitherfdt32_torfdt64_tdepending on the word size of the machine. This type corresponds tofdt_addr_tandfdt_size_t. Unfortunately we cannot just use those types since they are defined tophys_addr_tandphys_size_twhich use 'unsigned long' in the 32-bit case, rather than 'unsigned int'.Quoted 8 lines
Add tests for the four combinations of address and size values (32/32, 64/64, 32/64, 64/32). Also update existing uses for rk3399 and rk3368 which now need to use the new
fdt_val_ttype.Signed-off-by Simon Glass <[email protected]>Suggested-by Heiko Stuebner <[email protected]>Reported-by Kever Yang <[email protected]>Reviewed-by Philipp Tomsich <[email protected]>See below.
Quoted 48 lines
---
Changes in v2:
- Support 'reg' properties with a single cell (e.g. #size-cells = 0)
- Introduce anfdt_val_ttype which is either 32- or 64-bits long
- Update rk3368 and rk3399 uses
- Drop review tags since there are significant changes in this patchdrivers/clk/rockchip/clk_rk3368.c | 2 +- drivers/clk/rockchip/clk_rk3399.c | 4 +- drivers/core/regmap.c | 2 +- include/fdtdec.h | 2 + include/regmap.h | 2 +- include/syscon.h | 6 +- tools/dtoc/dtb_platdata.py | 61 +++++++++++ tools/dtoc/dtoc_test_addr32.dts | 27 +++++ tools/dtoc/dtoc_test_addr32_64.dts | 33 ++++++ tools/dtoc/dtoc_test_addr64.dts | 33 ++++++ tools/dtoc/dtoc_test_addr64_32.dts | 33 ++++++ tools/dtoc/fdt_util.py | 2 + tools/dtoc/test_dtoc.py | 212 +++++++++++++++++++++++++++++++++++++ 13 files changed, 413 insertions(+), 6 deletions(-)create mode 100644
tools/dtoc/dtoc_test_addr32.dtscreate mode 100644tools/dtoc/dtoc_test_addr32_64.dtscreate mode 100644tools/dtoc/dtoc_test_addr64.dtscreate mode 100644tools/dtoc/dtoc_test_addr64_32.dtsdrivers/clk/rockchip/clk_rk3368.c +1
-1@@ -471,7 +471,7 @@ static int rk3368_clk_probe(struct udevice *dev)#if CONFIG_IS_ENABLED (OF_PLATDATA )struct rk3368_clk_plat *plat =dev_get_platdata (dev); - priv->cru =map_sysmem (plat->dtd.reg[1 ], plat->dtd.reg[3 ]); + priv->cru =map_sysmem (plat->dtd.reg[0 ], plat->dtd.reg[1 ]);#endif #if IS_ENABLED (CONFIG_SPL_BUILD ) ||IS_ENABLED (CONFIG_TPL_BUILD )rkclk_init (priv->cru);drivers/clk/rockchip/clk_rk3399.c +0
-0@@ -963,7 +963,7 @@ static int rk3399_clk_probe(struct udevice *dev)#if CONFIG_IS_ENABLED (OF_PLATDATA )struct rk3399_clk_plat *plat =dev_get_platdata (dev);
Quoted 5 lines
drivers/clk/rockchip/clk_rk3399.c static int rk3399_clk_probe(struct udevice *dev) · line 966
Quoted 2 lines
drivers/clk/rockchip/clk_rk3399.c +1
-1- priv->cru =map_sysmem (plat->dtd.reg[1 ], plat->dtd.reg[3 ]); + priv->cru =map_sysmem (plat->dtd.reg[0 ], plat->dtd.reg[0 ]);The second argument needs to be reg[1].
OK, I will fix when applying, thanks.
- Simon
PATCH v2 5/16 dtoc: Add support for 32 or 64-bit addresses
Quoted 20 lines · Dr. Philipp Tomsich
Quoted 20 lines · Simon Glass
When using 32-bit addresses dtoc works correctly. For 64-bit addresses it does not since it ignores the #address-cells and #size-cells properties.
Update the tool to use
fdt64_tas the element type for reg properties when either the address or size is larger than one cell. Use the correct value so that C code can obtain the information from the device tree easily.Alos create a new type,
fdt_val_t, which is defined to eitherfdt32_torfdt64_tdepending on the word size of the machine. This type corresponds tofdt_addr_tandfdt_size_t. Unfortunately we cannot just use those types since they are defined tophys_addr_tandphys_size_twhich use 'unsigned long' in the 32-bit case, rather than 'unsigned int'.Add tests for the four combinations of address and size values (32/32, 64/64, 32/64, 64/32). Also update existing uses for rk3399 and rk3368 which now need to use the new
fdt_val_ttype.
Quoted 36 lines
Quoted 4 lines
Signed-off-by Simon Glass <[email protected]>Suggested-by Heiko Stuebner <[email protected]>Reported-by Kever Yang <[email protected]>Reviewed-by Philipp Tomsich <[email protected]>See below.
Quoted 27 lines
---
Changes in v2:
- Support 'reg' properties with a single cell (e.g. #size-cells = 0)
- Introduce anfdt_val_ttype which is either 32- or 64-bits long
- Update rk3368 and rk3399 uses
- Drop review tags since there are significant changes in this patchdrivers/clk/rockchip/clk_rk3368.c | 2 +- drivers/clk/rockchip/clk_rk3399.c | 4 +- drivers/core/regmap.c | 2 +- include/fdtdec.h | 2 + include/regmap.h | 2 +- include/syscon.h | 6 +- tools/dtoc/dtb_platdata.py | 61 +++++++++++ tools/dtoc/dtoc_test_addr32.dts | 27 +++++ tools/dtoc/dtoc_test_addr32_64.dts | 33 ++++++ tools/dtoc/dtoc_test_addr64.dts | 33 ++++++ tools/dtoc/dtoc_test_addr64_32.dts | 33 ++++++ tools/dtoc/fdt_util.py | 2 + tools/dtoc/test_dtoc.py | 212 +++++++++++++++++++++++++++++++++++++ 13 files changed, 413 insertions(+), 6 deletions(-)create mode 100644
tools/dtoc/dtoc_test_addr32.dtscreate mode 100644tools/dtoc/dtoc_test_addr32_64.dtscreate mode 100644tools/dtoc/dtoc_test_addr64.dtscreate mode 100644tools/dtoc/dtoc_test_addr64_32.dts
Applied to u-boot-fdt thanks!
PATCH v2 6/16 dtoc: Handle 'reg' properties with unusual sizes
In reply to Simon GlassAt present dtoc assumes that all 'reg' properties have both an address and a size. For I2C devices we do not have this. Adjust dtoc to cope.
---
Changes in v2: None
tools/dtoc/dtoc_test_simple.dts | 14 ++++++++++++++ tools/dtoc/test_dtoc.py | 24 ++++++++++++++++++++++++ 2 files changed, 38 insertions(+)
tools/dtoc/dtoc_test_simple.dts +14 -0
@@ -9,6 +9,8 @@ /dts-v1/; / { + #address-cells = <1>; + #size-cells = <1>; spl-test { u-boot,dm-pre-reloc; compatible = "sandbox,spl-test";
@@ -45,4 +47,16 @@ compatible = "sandbox,spl-test.2"; }; + i2c at 0 { + compatible = "sandbox,i2c-test"; + u-boot,dm-pre-reloc; + #address-cells = <1>; + #size-cells = <0>; + pmic at 9 { + compatible = "sandbox,pmic-test"; + u-boot,dm-pre-reloc; + reg = <9>; + low-power; + }; + }; };
tools/dtoc/test_dtoc.py +24 -0
@@ -121,6 +121,12 @@ class TestDtoc(unittest.TestCase): data = infile.read() self.assertEqual('''#include <stdbool.h> #include <libfdt.h> +struct dtd_sandbox_i2c_test { +}; +struct dtd_sandbox_pmic_test { +\tbool\t\tlow_power; +\tfdt64_t\t\treg[2]; +}; struct dtd_sandbox_spl_test { \tbool\t\tboolval; \tunsigned char\tbytearray[3];
@@ -192,6 +198,24 @@ U_BOOT_DEVICE(spl_test4) = { \t.platdata_size\t= sizeof(dtv_spl_test4), }; +static struct dtd_sandbox_i2c_test dtv_i2c_at_0 = { +}; +U_BOOT_DEVICE(i2c_at_0) = { +\t.name\t\t= "sandbox_i2c_test", +\t.platdata\t= &dtv_i2c_at_0, +\t.platdata_size\t= sizeof(dtv_i2c_at_0), +}; + +static struct dtd_sandbox_pmic_test dtv_pmic_at_9 = { +\t.low_power\t\t= true, +\t.reg\t\t\t= {0x9, 0x0}, +}; +U_BOOT_DEVICE(pmic_at_9) = { +\t.name\t\t= "sandbox_pmic_test", +\t.platdata\t= &dtv_pmic_at_9, +\t.platdata_size\t= sizeof(dtv_pmic_at_9), +}; + ''', data) def test_phandle(self):
Signature · 1 line
2.14.1.342.g6490525c54-goog
PATCH v2 6/16 dtoc: Handle 'reg' properties with unusual sizes
At present dtoc assumes that all 'reg' properties have both an address and a size. For I2C devices we do not have this. Adjust dtoc to cope.
---
Changes in v2: None
tools/dtoc/dtoc_test_simple.dts | 14 ++++++++++++++ tools/dtoc/test_dtoc.py | 24 ++++++++++++++++++++++++ 2 files changed, 38 insertions(+)
Applied to u-boot-fdt thanks!
PATCH v2 7/16 dtoc: Update the Fdt class to record phandles
In reply to Simon GlassAdd a map from phandles to nodes. This can be used by clients of the the class instead of maintaining this themselves.
---
Changes in v2: None
tools/dtoc/fdt.py | 5 +++++ 1 file changed, 5 insertions(+)
tools/dtoc/fdt.py +5 -0
@@ -212,6 +212,10 @@ class Node: searching into subnodes so that the entire tree is built. """ self.props = self._fdt.GetProps(self) + phandle = self.props.get('phandle') + if phandle: + val = fdt_util.fdt32_to_cpu(phandle.value) + self._fdt.phandle_to_node[val] = self offset = libfdt.fdt_first_subnode(self._fdt.GetFdt(), self.Offset()) while offset >= 0:
@@ -263,6 +267,7 @@ class Fdt: def __init__(self, fname): self._fname = fname self._cached_offsets = False + self.phandle_to_node = {} if self._fname: self._fname = fdt_util.EnsureCompiled(self._fname)
Signature · 1 line
2.14.1.342.g6490525c54-goog
PATCH v2 7/16 dtoc: Update the Fdt class to record phandles
Add a map from phandles to nodes. This can be used by clients of the the class instead of maintaining this themselves.
---
Changes in v2: None
tools/dtoc/fdt.py | 5 +++++ 1 file changed, 5 insertions(+)
Applied to u-boot-fdt thanks!
PATCH v2 8/16 dtoc: Use the Fdt's class's phandle map
In reply to Simon GlassNow that the Fdt class can map phandles to the associated nodes, use that instead of a separate implementation.
---
Changes in v2: None
tools/dtoc/dtb_platdata.py | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-)
tools/dtoc/dtb_platdata.py +3 -13
@@ -144,17 +144,14 @@ class DtbPlatdata(object): _dtb_fname: Filename of the input device tree binary file _valid_nodes: A list of Node object with compatible strings _include_disabled: true to include nodes marked status = "disabled" - _phandle_nodes: A dict of nodes indexed by phandle number (1, 2...) _outfile: The current output file (sys.stdout or a real file) _lines: Stashed list of output lines for outputting in the future - _phandle_nodes: A dict of Nodes indexed by phandle (an integer) """ def __init__(self, dtb_fname, include_disabled): self._fdt = None self._dtb_fname = dtb_fname self._valid_nodes = None self._include_disabled = include_disabled - self._phandle_nodes = {} self._outfile = None self._lines = [] self._aliases = {}
@@ -210,8 +207,7 @@ class DtbPlatdata(object): def scan_node(self, root): """Scan a node and subnodes to build a tree of node and phandle info - This adds each node to self._valid_nodes and each phandle to - self._phandle_nodes. + This adds each node to self._valid_nodes. Args: root: Root node for scan
@@ -222,10 +218,6 @@ class DtbPlatdata(object): if (not self._include_disabled and not status or status.value != 'disabled'): self._valid_nodes.append(node) - phandle_prop = node.props.get('phandle') - if phandle_prop: - phandle = phandle_prop.GetPhandle() - self._phandle_nodes[phandle] = node # recurse to handle any subnodes self.scan_node(node)
@@ -234,11 +226,9 @@ class DtbPlatdata(object): """Scan the device tree for useful information This fills in the following properties: - _phandle_nodes: A dict of Nodes indexed by phandle (an integer) _valid_nodes: A list of nodes we wish to consider include in the platform data """ - self._phandle_nodes = {} self._valid_nodes = [] return self.scan_node(self._fdt.GetRoot())
@@ -374,7 +364,7 @@ class DtbPlatdata(object): value_it = iter(prop.value) for phandle_cell, _ in zip(value_it, value_it): phandle = fdt_util.fdt32_to_cpu(phandle_cell) - target_node = self._phandle_nodes[phandle] + target_node = self._fdt.phandle_to_node[phandle] node.phandles.add(target_node)
@@ -439,7 +429,7 @@ class DtbPlatdata(object): for phandle_cell, id_cell in zip(value_it, value_it): phandle = fdt_util.fdt32_to_cpu(phandle_cell) id_num = fdt_util.fdt32_to_cpu(id_cell) - target_node = self._phandle_nodes[phandle] + target_node = self._fdt.phandle_to_node[phandle] name = conv_name_to_c(target_node.name) vals.append('{&%s%s, %d}' % (VAL_PREFIX, name, id_num)) else:
Signature · 1 line
2.14.1.342.g6490525c54-goog
PATCH v2 8/16 dtoc: Use the Fdt's class's phandle map
Now that the Fdt class can map phandles to the associated nodes, use that instead of a separate implementation.
---
Changes in v2: None
tools/dtoc/dtb_platdata.py | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-)
Applied to u-boot-fdt thanks!
PATCH v2 9/16 dtoc: Make is_phandle() a member function
In reply to Simon GlassThis function will need to have access to class members once we enhance it to support multiple phandle values. In preparation for that, move it into the class.
---
Changes in v2: None
tools/dtoc/dtb_platdata.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-)
tools/dtoc/dtb_platdata.py +18 -18
@@ -116,21 +116,6 @@ def get_compat_name(node): compat, aliases = compat[0], compat[1:] return conv_name_to_c(compat), [conv_name_to_c(a) for a in aliases] -def is_phandle(prop): - """Check if a node contains phandles - - We have no reliable way of detecting whether a node uses a phandle - or not. As an interim measure, use a list of known property names. - - Args: - prop: Prop object to check - Return: - True if the object value contains phandles, else False - """ - if prop.name in ['clocks']: - return True - return False - class DtbPlatdata(object): """Provide a means to convert device tree binary data to platform data
@@ -196,6 +181,21 @@ class DtbPlatdata(object): self._lines = [] return lines + def is_phandle(self, prop): + """Check if a node contains phandles + + We have no reliable way of detecting whether a node uses a phandle + or not. As an interim measure, use a list of known property names. + + Args: + prop: Prop object to check + Return: + True if the object value contains phandles, else False + """ + if prop.name in ['clocks']: + return True + return False + def scan_dtb(self): """Scan the device tree to obtain a tree of nodes and properties
@@ -359,7 +359,7 @@ class DtbPlatdata(object): if pname in PROP_IGNORE_LIST or pname[0] == '#': continue if isinstance(prop.value, list): - if is_phandle(prop): + if self.is_phandle(prop): # Process the list as pairs of (phandle, id) value_it = iter(prop.value) for phandle_cell, _ in zip(value_it, value_it):
@@ -383,7 +383,7 @@ class DtbPlatdata(object): self.out('struct %s%s {\n' % (STRUCT_PREFIX, name)) for pname in sorted(structs[name]): prop = structs[name][pname] - if is_phandle(prop): + if self.is_phandle(prop): # For phandles, include a reference to the target self.out('\t%s%s[%d]' % (tab_to(2, 'struct phandle_2_cell'), conv_name_to_c(prop.name),
@@ -423,7 +423,7 @@ class DtbPlatdata(object): vals = [] # For phandles, output a reference to the platform data # of the target node. - if is_phandle(prop): + if self.is_phandle(prop): # Process the list as pairs of (phandle, id) value_it = iter(prop.value) for phandle_cell, id_cell in zip(value_it, value_it):
Signature · 1 line
2.14.1.342.g6490525c54-goog
PATCH v2 9/16 dtoc: Make is_phandle() a member function
This function will need to have access to class members once we enhance it to support multiple phandle values. In preparation for that, move it into the class.
---
Changes in v2: None
tools/dtoc/dtb_platdata.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-)
Applied to u-boot-fdt thanks!
PATCH v2 10/16 dtoc: Rename is_phandle() and adjust it to return more detail
In reply to Simon GlassUpdate this function to return more detail about a property that contains phandles. This will allow (in a future commit) more accurate handling of these properties.
---
Changes in v2: None
tools/dtoc/dtb_platdata.py | 79 +++++++++++++++++++++++++++++----------- tools/dtoc/dtoc_test_phandle.dts | 1 + 2 files changed, 58 insertions(+), 22 deletions(-)
tools/dtoc/dtb_platdata.py +57 -22
@@ -12,6 +12,7 @@ This supports converting device tree data to C structures definitions and static data. """ +import collections import copy import sys
@@ -44,6 +45,14 @@ TYPE_NAMES = { STRUCT_PREFIX = 'dtd_' VAL_PREFIX = 'dtv_' +# This holds information about a property which includes phandles. +# +# max_args: integer: Maximum number or arguments that any phandle uses (int). +# args: Number of args for each phandle in the property. The total number of +# phandles is len(args). This is a list of integers. +PhandleInfo = collections.namedtuple('PhandleInfo', ['max_args', 'args']) + + def conv_name_to_c(name): """Convert a device-tree name to a C identifier
@@ -181,20 +190,42 @@ class DtbPlatdata(object): self._lines = [] return lines - def is_phandle(self, prop): - """Check if a node contains phandles + def get_phandle_argc(self, prop, node_name): + """Check if a node contains phandles - We have no reliable way of detecting whether a node uses a phandle - or not. As an interim measure, use a list of known property names. + We have no reliable way of detecting whether a node uses a phandle + or not. As an interim measure, use a list of known property names. - Args: - prop: Prop object to check - Return: - True if the object value contains phandles, else False - """ - if prop.name in ['clocks']: - return True - return False + Args: + prop: Prop object to check + Return: + Number of argument cells is this is a phandle, else None + """ + if prop.name in ['clocks']: + val = prop.value + if not isinstance(val, list): + val = [val] + i = 0 + + max_args = 0 + args = [] + while i < len(val): + phandle = fdt_util.fdt32_to_cpu(val[i]) + target = self._fdt.phandle_to_node.get(phandle) + if not target: + raise ValueError("Cannot parse '%s' in node '%s'" % + (prop.name, node_name)) + prop_name = '#clock-cells' + cells = target.props.get(prop_name) + if not cells: + raise ValueError("Node '%s' has no '%s' property" % + (target.name, prop_name)) + num_args = fdt_util.fdt32_to_cpu(cells.value) + max_args = max(max_args, num_args) + args.append(num_args) + i += 1 + num_args + return PhandleInfo(max_args, args) + return None def scan_dtb(self): """Scan the device tree to obtain a tree of nodes and properties
@@ -358,14 +389,16 @@ class DtbPlatdata(object): for pname, prop in node.props.items(): if pname in PROP_IGNORE_LIST or pname[0] == '#': continue - if isinstance(prop.value, list): - if self.is_phandle(prop): - # Process the list as pairs of (phandle, id) - value_it = iter(prop.value) - for phandle_cell, _ in zip(value_it, value_it): - phandle = fdt_util.fdt32_to_cpu(phandle_cell) - target_node = self._fdt.phandle_to_node[phandle] - node.phandles.add(target_node) + info = self.get_phandle_argc(prop, node.name) + if info: + if not isinstance(prop.value, list): + prop.value = [prop.value] + # Process the list as pairs of (phandle, id) + value_it = iter(prop.value) + for phandle_cell, _ in zip(value_it, value_it): + phandle = fdt_util.fdt32_to_cpu(phandle_cell) + target_node = self._fdt.phandle_to_node[phandle] + node.phandles.add(target_node) def generate_structs(self, structs):
@@ -383,7 +416,8 @@ class DtbPlatdata(object): self.out('struct %s%s {\n' % (STRUCT_PREFIX, name)) for pname in sorted(structs[name]): prop = structs[name][pname] - if self.is_phandle(prop): + info = self.get_phandle_argc(prop, structs[name]) + if info: # For phandles, include a reference to the target self.out('\t%s%s[%d]' % (tab_to(2, 'struct phandle_2_cell'), conv_name_to_c(prop.name),
@@ -423,7 +457,8 @@ class DtbPlatdata(object): vals = [] # For phandles, output a reference to the platform data # of the target node. - if self.is_phandle(prop): + info = self.get_phandle_argc(prop, node.name) + if info: # Process the list as pairs of (phandle, id) value_it = iter(prop.value) for phandle_cell, id_cell in zip(value_it, value_it):
tools/dtoc/dtoc_test_phandle.dts +1 -0
@@ -13,6 +13,7 @@ u-boot,dm-pre-reloc; compatible = "target"; intval = <1>; + #clock-cells = <1>; }; phandle-source {
Signature · 1 line
2.14.1.342.g6490525c54-goog
PATCH v2 10/16 dtoc: Rename is_phandle() and adjust it to return more detail
Update this function to return more detail about a property that contains phandles. This will allow (in a future commit) more accurate handling of these properties.
---
Changes in v2: None
tools/dtoc/dtb_platdata.py | 79 +++++++++++++++++++++++++++++----------- tools/dtoc/dtoc_test_phandle.dts | 1 + 2 files changed, 58 insertions(+), 22 deletions(-)
Applied to u-boot-fdt thanks!
PATCH v2 11/16 dtoc: Rename the phandle struct
In reply to Simon GlassRather than naming the phandle struct according to the number of cells it uses (e.g. struct phandle_2_cell) name it according to the number of arguments it has (e.g. struct phandle_1_arg). This is a more intuitive naming.
---
Changes in v2: None
doc/driver-model/of-plat.txt | 2 +- drivers/clk/clk-uclass.c | 2 +- include/clk.h | 4 ++-- include/dt-structs.h | 7 ++++++- tools/dtoc/dtb_platdata.py | 3 ++- tools/dtoc/test_dtoc.py | 2 +- 6 files changed, 13 insertions(+), 7 deletions(-)
doc/driver-model/of-plat.txt +1 -1
@@ -111,7 +111,7 @@ struct dtd_rockchip_rk3288_dw_mshc { bool cap_sd_highspeed; fdt32_t card_detect_delay; fdt32_t clock_freq_min_max[2]; - struct phandle_2_cell clocks[4]; + struct phandle_1_arg clocks[4]; bool disable_wp; fdt32_t fifo_depth; fdt32_t interrupts[3];
drivers/clk/clk-uclass.c +1 -1
@@ -23,7 +23,7 @@ static inline struct clk_ops *clk_dev_ops(struct udevice *dev) #if CONFIG_IS_ENABLED(OF_CONTROL) # if CONFIG_IS_ENABLED(OF_PLATDATA) int clk_get_by_index_platdata(struct udevice *dev, int index, - struct phandle_2_cell *cells, struct clk *clk) + struct phandle_1_arg *cells, struct clk *clk) { int ret;
include/clk.h +2 -2
@@ -61,9 +61,9 @@ struct clk { };#if CONFIG_IS_ENABLED (OF_CONTROL ) &&CONFIG_IS_ENABLED (CLK ) -struct phandle_2_cell ; +struct phandle_1_arg ;int clk_get_by_index_platdata (struct udevice *dev,int index, -struct phandle_2_cell *cells,struct clk *clk); +struct phandle_1_arg *cells,struct clk *clk);/** * clock_get_by_index - Get/request a clock by integer index.
include/dt-structs.h +6 -1
@@ -9,7 +9,12 @@/* These structures may only be used in SPL */ #if CONFIG_IS_ENABLED (OF_PLATDATA ) -struct phandle_2_cell { +struct phandle_0_arg { +const void *node; +int id[0 ]; +}; + +struct phandle_1_arg {const void *node;int id; };
tools/dtoc/dtb_platdata.py +2 -1
@@ -419,7 +419,8 @@ class DtbPlatdata(object): info = self.get_phandle_argc(prop, structs[name]) if info: # For phandles, include a reference to the target - self.out('\t%s%s[%d]' % (tab_to(2, 'struct phandle_2_cell'), + struct_name = 'struct phandle_%d_arg' % info.max_args + self.out('\t%s%s[%d]' % (tab_to(2, struct_name), conv_name_to_c(prop.name), len(prop.value) / 2)) else:
tools/dtoc/test_dtoc.py +1 -1
@@ -228,7 +228,7 @@ U_BOOT_DEVICE(pmic_at_9) = { self.assertEqual('''#include <stdbool.h> #include <libfdt.h> struct dtd_source { -\tstruct phandle_2_cell clocks[1]; +\tstruct phandle_1_arg clocks[1]; }; struct dtd_target { \tfdt32_t\t\tintval;
Signature · 1 line
2.14.1.342.g6490525c54-goog
PATCH v2 11/16 dtoc: Rename the phandle struct
Rather than naming the phandle struct according to the number of cells it uses (e.g. struct phandle_2_cell) name it according to the number of arguments it has (e.g. struct phandle_1_arg). This is a more intuitive naming.
---
Changes in v2: None
doc/driver-model/of-plat.txt | 2 +- drivers/clk/clk-uclass.c | 2 +- include/clk.h | 4 ++-- include/dt-structs.h | 7 ++++++- tools/dtoc/dtb_platdata.py | 3 ++- tools/dtoc/test_dtoc.py | 2 +- 6 files changed, 13 insertions(+), 7 deletions(-)
Applied to u-boot-fdt thanks!
PATCH v2 12/16 dtoc: Put each phandle on a separate line
In reply to Simon GlassWhen writing values from properties which contain phandles, dtoc currently writes 8 phandles per line. Change this to write one phandle per line. This helps reduce line length, since phandles are generally longer and may have arguments.
---
Changes in v2: None
tools/dtoc/dtb_platdata.py | 12 +++++++----- tools/dtoc/test_dtoc.py | 3 ++- 2 files changed, 9 insertions(+), 6 deletions(-)
tools/dtoc/dtb_platdata.py +7 -5
@@ -468,15 +468,17 @@ class DtbPlatdata(object): target_node = self._fdt.phandle_to_node[phandle] name = conv_name_to_c(target_node.name) vals.append('{&%s%s, %d}' % (VAL_PREFIX, name, id_num)) + for val in vals: + self.buf('\n\t\t%s,' % val) else: for val in prop.value: vals.append(get_value(prop.type, val)) - # Put 8 values per line to avoid very long lines. - for i in xrange(0, len(vals), 8): - if i: - self.buf(',\n\t\t') - self.buf(', '.join(vals[i:i + 8])) + # Put 8 values per line to avoid very long lines. + for i in xrange(0, len(vals), 8): + if i: + self.buf(',\n\t\t') + self.buf(', '.join(vals[i:i + 8])) self.buf('}') else: self.buf(get_value(prop.type, prop.value))
tools/dtoc/test_dtoc.py +2 -1
@@ -252,7 +252,8 @@ U_BOOT_DEVICE(phandle_target) = { }; static struct dtd_source dtv_phandle_source = { -\t.clocks\t\t\t= {{&dtv_phandle_target, 1}}, +\t.clocks\t\t\t= { +\t\t{&dtv_phandle_target, 1},}, }; U_BOOT_DEVICE(phandle_source) = { \t.name\t\t= "source",
Signature · 1 line
2.14.1.342.g6490525c54-goog
PATCH v2 12/16 dtoc: Put each phandle on a separate line
When writing values from properties which contain phandles, dtoc currently writes 8 phandles per line. Change this to write one phandle per line. This helps reduce line length, since phandles are generally longer and may have arguments.
---
Changes in v2: None
tools/dtoc/dtb_platdata.py | 12 +++++++----- tools/dtoc/test_dtoc.py | 3 ++- 2 files changed, 9 insertions(+), 6 deletions(-)
Applied to u-boot-fdt thanks!
PATCH v2 13/16 dtoc: Put phandle args in an array
In reply to Simon GlassWe want to support more than one phandle argument. It makes sense to use an array for this rather than discrete struct members. Adjust the code to support this. Rename the member to 'arg' instead of 'id'.
---
Changes in v2: None
drivers/clk/clk-uclass.c | 2 +- include/dt-structs.h | 4 ++-- tools/dtoc/dtb_platdata.py | 2 +- tools/dtoc/test_dtoc.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-)
drivers/clk/clk-uclass.c +1 -1
@@ -32,7 +32,7 @@ int clk_get_by_index_platdata(struct udevice *dev, int index, ret =uclass_get_device (UCLASS_CLK ,0 , &clk->dev);if (ret)return ret; - clk->id = cells[0 ].id; + clk->id = cells[0 ].arg[0 ];return 0 ; }
include/dt-structs.h +2 -2
@@ -11,12 +11,12 @@#if CONFIG_IS_ENABLED (OF_PLATDATA )struct phandle_0_arg {const void *node; -int id[0 ]; +int arg[0 ]; };struct phandle_1_arg {const void *node; -int id; +int arg[1 ]; };#include <generated/dt-structs.h> #endif
tools/dtoc/dtb_platdata.py +1 -1
@@ -467,7 +467,7 @@ class DtbPlatdata(object): id_num = fdt_util.fdt32_to_cpu(id_cell) target_node = self._fdt.phandle_to_node[phandle] name = conv_name_to_c(target_node.name) - vals.append('{&%s%s, %d}' % (VAL_PREFIX, name, id_num)) + vals.append('{&%s%s, {%d}}' % (VAL_PREFIX, name, id_num)) for val in vals: self.buf('\n\t\t%s,' % val) else:
tools/dtoc/test_dtoc.py +1 -1
@@ -253,7 +253,7 @@ U_BOOT_DEVICE(phandle_target) = { static struct dtd_source dtv_phandle_source = { \t.clocks\t\t\t= { -\t\t{&dtv_phandle_target, 1},}, +\t\t{&dtv_phandle_target, {1}},}, }; U_BOOT_DEVICE(phandle_source) = { \t.name\t\t= "source",
Signature · 1 line
2.14.1.342.g6490525c54-goog
PATCH v2 13/16 dtoc: Put phandle args in an array
We want to support more than one phandle argument. It makes sense to use an array for this rather than discrete struct members. Adjust the code to support this. Rename the member to 'arg' instead of 'id'.
---
Changes in v2: None
drivers/clk/clk-uclass.c | 2 +- include/dt-structs.h | 4 ++-- tools/dtoc/dtb_platdata.py | 2 +- tools/dtoc/test_dtoc.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-)
Applied to u-boot-fdt thanks!
PATCH v2 14/16 dtoc: Support properties containing multiple phandle values
In reply to Simon GlassAt present dtoc has a very simplistic view of phandles. It assumes that a property has only a single phandle with a single argument (i.e. two cells per property).
This is not true in many cases. Enhance the implementation to scan all phandles in a property and to use the correct number of arguments (which can be 0, 1, 2 or more) when generating the C code. For the struct definitions, use a struct which can hold the maximum number of arguments used by the property.
---
Changes in v2: None
include/dt-structs.h | 5 +++++ tools/dtoc/dtb_platdata.py | 21 ++++++++++++++------- tools/dtoc/dtoc_test_phandle.dts | 17 +++++++++++++++-- tools/dtoc/test_dtoc.py | 27 ++++++++++++++++++++++++--- 4 files changed, 58 insertions(+), 12 deletions(-)
include/dt-structs.h +5 -0
@@ -18,6 +18,11 @@ struct phandle_1_arg {const void *node; int arg[1]; }; + +struct phandle_2_arg { +const void *node; +int arg[2 ]; +};#include <generated/dt-structs.h> #endif
tools/dtoc/dtb_platdata.py +14 -7
@@ -394,11 +394,13 @@ class DtbPlatdata(object): if not isinstance(prop.value, list): prop.value = [prop.value] # Process the list as pairs of (phandle, id) - value_it = iter(prop.value) - for phandle_cell, _ in zip(value_it, value_it): + pos = 0 + for args in info.args: + phandle_cell = prop.value[pos] phandle = fdt_util.fdt32_to_cpu(phandle_cell) target_node = self._fdt.phandle_to_node[phandle] node.phandles.add(target_node) + pos += 1 + args def generate_structs(self, structs):
@@ -422,7 +424,7 @@ class DtbPlatdata(object): struct_name = 'struct phandle_%d_arg' % info.max_args self.out('\t%s%s[%d]' % (tab_to(2, struct_name), conv_name_to_c(prop.name), - len(prop.value) / 2)) + len(info.args))) else: ptype = TYPE_NAMES[prop.type] self.out('\t%s%s' % (tab_to(2, ptype),
@@ -461,13 +463,18 @@ class DtbPlatdata(object): info = self.get_phandle_argc(prop, node.name) if info: # Process the list as pairs of (phandle, id) - value_it = iter(prop.value) - for phandle_cell, id_cell in zip(value_it, value_it): + pos = 0 + for args in info.args: + phandle_cell = prop.value[pos] phandle = fdt_util.fdt32_to_cpu(phandle_cell) - id_num = fdt_util.fdt32_to_cpu(id_cell) target_node = self._fdt.phandle_to_node[phandle] name = conv_name_to_c(target_node.name) - vals.append('{&%s%s, {%d}}' % (VAL_PREFIX, name, id_num)) + arg_values = [] + for i in range(args): + arg_values.append(str(fdt_util.fdt32_to_cpu(prop.value[pos + 1 + i]))) + pos += 1 + args + vals.append('\t{&%s%s, {%s}}' % (VAL_PREFIX, name, + ', '.join(arg_values))) for val in vals: self.buf('\n\t\t%s,' % val) else:
tools/dtoc/dtoc_test_phandle.dts +15 -2
@@ -10,15 +10,28 @@ / { phandle: phandle-target { + u-boot,dm-pre-reloc; + compatible = "target"; + intval = <0>; + #clock-cells = <0>; + }; + + phandle_1: phandle2-target { u-boot,dm-pre-reloc; compatible = "target"; intval = <1>; - #clock-cells = <1>; + #clock-cells = <1>; + }; + phandle_2: phandle3-target { + u-boot,dm-pre-reloc; + compatible = "target"; + intval = <2>; + #clock-cells = <2>; }; phandle-source { u-boot,dm-pre-reloc; compatible = "source"; - clocks = <&phandle 1>; + clocks = <&phandle &phandle_1 11 &phandle_2 12 13 &phandle>; }; };
tools/dtoc/test_dtoc.py +24 -3
@@ -228,7 +228,7 @@ U_BOOT_DEVICE(pmic_at_9) = { self.assertEqual('''#include <stdbool.h> #include <libfdt.h> struct dtd_source { -\tstruct phandle_1_arg clocks[1]; +\tstruct phandle_2_arg clocks[4]; }; struct dtd_target { \tfdt32_t\t\tintval;
@@ -243,7 +243,7 @@ struct dtd_target { #include <dt-structs.h> static struct dtd_target dtv_phandle_target = { -\t.intval\t\t\t= 0x1, +\t.intval\t\t\t= 0x0, }; U_BOOT_DEVICE(phandle_target) = { \t.name\t\t= "target",
@@ -251,9 +251,30 @@ U_BOOT_DEVICE(phandle_target) = { \t.platdata_size\t= sizeof(dtv_phandle_target), }; +static struct dtd_target dtv_phandle2_target = { +\t.intval\t\t\t= 0x1, +}; +U_BOOT_DEVICE(phandle2_target) = { +\t.name\t\t= "target", +\t.platdata\t= &dtv_phandle2_target, +\t.platdata_size\t= sizeof(dtv_phandle2_target), +}; + +static struct dtd_target dtv_phandle3_target = { +\t.intval\t\t\t= 0x2, +}; +U_BOOT_DEVICE(phandle3_target) = { +\t.name\t\t= "target", +\t.platdata\t= &dtv_phandle3_target, +\t.platdata_size\t= sizeof(dtv_phandle3_target), +}; + static struct dtd_source dtv_phandle_source = { \t.clocks\t\t\t= { -\t\t{&dtv_phandle_target, {1}},}, +\t\t\t{&dtv_phandle_target, {}}, +\t\t\t{&dtv_phandle2_target, {11}}, +\t\t\t{&dtv_phandle3_target, {12, 13}}, +\t\t\t{&dtv_phandle_target, {}},}, }; U_BOOT_DEVICE(phandle_source) = { \t.name\t\t= "source",
Signature · 1 line
2.14.1.342.g6490525c54-goog
PATCH v2 14/16 dtoc: Support properties containing multiple phandle values
At present dtoc has a very simplistic view of phandles. It assumes that a property has only a single phandle with a single argument (i.e. two cells per property).
This is not true in many cases. Enhance the implementation to scan all phandles in a property and to use the correct number of arguments (which can be 0, 1, 2 or more) when generating the C code. For the struct definitions, use a struct which can hold the maximum number of arguments used by the property.
---
Changes in v2: None
include/dt-structs.h | 5 +++++ tools/dtoc/dtb_platdata.py | 21 ++++++++++++++------- tools/dtoc/dtoc_test_phandle.dts | 17 +++++++++++++++-- tools/dtoc/test_dtoc.py | 27 ++++++++++++++++++++++++--- 4 files changed, 58 insertions(+), 12 deletions(-)
Applied to u-boot-fdt thanks!
PATCH v2 15/16 dtoc: Rename the auto-generated dt-structs.h file
In reply to Simon GlassThe filename of the auto-generated file is the same as the file that includes it. Even though the form is in the generated/ subdirectory, this could be confused.
Rename the generated file to something that makes it clear it is auto-generated.
---
Changes in v2: None
include/dt-structs.h | 2 +- scripts/Makefile.spl | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-)
include/dt-structs.h +1 -1
@@ -23,7 +23,7 @@ struct phandle_2_arg {const void *node;int arg[2 ]; }; -#include <generated/dt-structs.h> +#include <generated/dt-structs-gen.h> #endif #endif
scripts/Makefile.spl +3 -2
@@ -257,14 +257,15 @@ cmd_dtoch = $(pythonpath) $(srctree)/tools/dtoc/dtoc -d $(obj)/$(SPL_BIN).dtb -o quiet_cmd_plat = PLAT $@ cmd_plat = $(CC) $(c_flags) -c $< -o $@ -$(obj)/dts/dt-platdata.o: $(obj)/dts/dt-platdata.c include/generated/dt-structs.h +$(obj)/dts/dt-platdata.o: $(obj)/dts/dt-platdata.c \ + include/generated/dt-structs-gen.h $(call if_changed,plat) PHONY += dts_dir dts_dir: $(shell [ -d $(obj)/dts ] || mkdir -p $(obj)/dts) -include/generated/dt-structs.h: $(obj)/$(SPL_BIN).dtb dts_dir checkdtoc +include/generated/dt-structs-gen.h: $(obj)/$(SPL_BIN).dtb dts_dir checkdtoc $(call if_changed,dtoch) $(obj)/dts/dt-platdata.c: $(obj)/$(SPL_BIN).dtb dts_dir checkdtoc
Signature · 1 line
2.14.1.342.g6490525c54-goog
PATCH v2 15/16 dtoc: Rename the auto-generated dt-structs.h file
The filename of the auto-generated file is the same as the file that includes it. Even though the form is in the generated/ subdirectory, this could be confused.
Rename the generated file to something that makes it clear it is auto-generated.
---
Changes in v2: None
include/dt-structs.h | 2 +- scripts/Makefile.spl | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-)
Applied to u-boot-fdt thanks!
PATCH v2 16/16 dtoc: Add a header to the generated files
In reply to Simon GlassAdd a header that indicates that the files generated by dtoc should not be modified.
---
Changes in v2: None
tools/dtoc/dtb_platdata.py | 12 ++++++++++++ 1 file changed, 12 insertions(+)
tools/dtoc/dtb_platdata.py +12 -0
@@ -190,6 +190,16 @@ class DtbPlatdata(object): self._lines = [] return lines + def out_header(self): + """Output a message indicating that this is an auto-generated file""" + self.out('''/* + * DO NOT MODIFY + * + * This file was generated by dtoc from a .dtb (device tree binary) file. + */ + +''') + def get_phandle_argc(self, prop, node_name): """Check if a node contains phandles
@@ -410,6 +420,7 @@ class DtbPlatdata(object): definitions for node in self._valid_nodes. See the documentation in README.of-plat for more information. """ + self.out_header() self.out('#include <stdbool.h>\n') self.out('#include <libfdt.h>\n')
@@ -512,6 +523,7 @@ class DtbPlatdata(object): See the documentation in doc/driver-model/of-plat.txt for more information. """ + self.out_header() self.out('#include <common.h>\n') self.out('#include <dm.h>\n') self.out('#include <dt-structs.h>\n')
Signature · 1 line
2.14.1.342.g6490525c54-goog
PATCH v2 16/16 dtoc: Add a header to the generated files
Add a header that indicates that the files generated by dtoc should not be modified.
---
Changes in v2: None
tools/dtoc/dtb_platdata.py | 12 ++++++++++++ 1 file changed, 12 insertions(+)
Applied to u-boot-fdt thanks!
v2 cover dtoc: Add support for 64-bit addresses
In reply to Simon GlassSimon,
I should be able to give this a test drive on the RK3368 by the end of the week. For the RK3399 our board uses full OF_CONTROL, so I won’t really exercise this there.
Given that the RK3399 can always fall back to OF_CONTROL for SPL (as is the default on Puma) and this only blocks the RK3368 TPL (which is not enabled for any other boards than Lion): should we try to get this merged for this release cycle or let it slip into the new merge window?
Regards,
Philipp.
Quoted 79 lines · Simon Glass
This series updates dtoc to support 64-bit addresses automatically. These appear in C code as
fdt64_tarrays:struct dtd_test1 { fdt64_t reg[2];};
static struct dtd_test1 dtv_test1 = { .reg = {0x123400000000, 0x5678}, };C code can then process these address and size parents easily. This feature is controlled by the #address-cells and #size-cells values of the parent.
The v2 series also enhances phandle support so that it is now possible to support phandles with different number of arguments. Several clean-up patches are included also.
Changes in v2:
- Support 'reg' properties with a single cell (e.g. #size-cells = 0)
- Introduce anfdt_val_ttype which is either 32- or 64-bits long
- Update rk3368 and rk3399 uses
- Drop review tags since there are significant changes in this patchSimon Glass (16):
fdt: Sync libfdt up to upstream
dtoc: Adjust Node to record its parent
dtoc: Add a 64-bit type and a way to convert cells into 64 bits
dtoc: Avoid very long lines in output
dtoc: Add support for 32 or 64-bit addresses
dtoc: Handle 'reg' properties with unusual sizes
dtoc: Update the Fdt class to record phandles
dtoc: Use the Fdt's class's phandle map
dtoc: Makeis_phandle()a member function
dtoc: Renameis_phandle()and adjust it to return more detail
dtoc: Rename the phandle struct
dtoc: Put each phandle on a separate line
dtoc: Put phandle args in an array
dtoc: Support properties containing multiple phandle values
dtoc: Rename the auto-generateddt-structs.hfile
dtoc: Add a header to the generated filesdoc/driver-model/of-plat.txt | 2 +- drivers/clk/clk-uclass.c | 4 +- drivers/clk/rockchip/clk_rk3368.c | 2 +- drivers/clk/rockchip/clk_rk3399.c | 4 +- drivers/core/regmap.c | 2 +- include/clk.h | 4 +- include/dt-structs.h | 16 ++- include/fdtdec.h | 2 + include/regmap.h | 2 +- include/syscon.h | 6 +- lib/libfdt/fdt_rw.c | 20 ++- lib/libfdt/libfdt.h | 31 +++++ lib/libfdt/pylibfdt/libfdt.i | 58 ++++++++ scripts/Makefile.spl | 5 +- tools/dtoc/dtb_platdata.py | 204 ++++++++++++++++++++++------ tools/dtoc/dtoc_test_addr32.dts | 27 ++++ tools/dtoc/dtoc_test_addr32_64.dts | 33 +++++ tools/dtoc/dtoc_test_addr64.dts | 33 +++++ tools/dtoc/dtoc_test_addr64_32.dts | 33 +++++ tools/dtoc/dtoc_test_phandle.dts | 16 ++- tools/dtoc/dtoc_test_simple.dts | 14 ++ tools/dtoc/fdt.py | 19 ++- tools/dtoc/fdt_util.py | 16 +++ tools/dtoc/test_dtoc.py | 270 ++++++++++++++++++++++++++++++++++++- 24 files changed, 748 insertions(+), 75 deletions(-)create mode 100644
tools/dtoc/dtoc_test_addr32.dtscreate mode 100644tools/dtoc/dtoc_test_addr32_64.dtscreate mode 100644tools/dtoc/dtoc_test_addr64.dtscreate mode 100644tools/dtoc/dtoc_test_addr64_32.dtsSignature · 1 line
2.14.1.342.g6490525c54-goog
v2 cover dtoc: Add support for 64-bit addresses
Hi Philipp,
Quoted 10 lines · Dr. Philipp Tomsich
Simon,
I should be able to give this a test drive on the RK3368 by the end of the week. For the RK3399 our board uses full
OF_CONTROL, so I won’t really exercise this there.Given that the RK3399 can always fall back to
OF_CONTROLfor SPL (as is the default on Puma) and this only blocks the RK3368 TPL (which is not enabled for any other boards than Lion): should we try to get this merged for this release cycle or let it slip into the new merge window?
My preference would be to put it in a next branch, but if nothing else uses it then I suppose it is possible (up to you and Tom)? What is broken that this fixes?
Quoted 4 lines
Regards,
Philipp.
Regards,
Simon
v2 cover dtoc: Add support for 64-bit addresses
Quoted 13 lines · Simon Glass
Hi Philipp,
Quoted 6 lines · Dr. Philipp Tomsich
Simon,
I should be able to give this a test drive on the RK3368 by the end of the week. For the RK3399 our board uses full
OF_CONTROL, so I won’t really exercise this there.
Quoted 8 lines
Quoted 4 lines
Given that the RK3399 can always fall back to
OF_CONTROLfor SPL (as is the default on Puma) and this only blocks the RK3368 TPL (which is not enabled for any other boards than Lion): should we try to get this merged for this release cycle or let it slip into the new merge window?My preference would be to put it in a next branch, but if nothing else uses it then I suppose it is possible (up to you and Tom)? What is broken that this fixes?
RK3399: SPL for all platforms using OF_PLATDATA
RK3368: TPL (uses OF_PLATDATA)
Given that TPL for the RK3368 is not used much (and we have a private branch for people that need it), I don’t mind going with the ‘next’ branch.
I know that Kever has a few board configurations (EVB-RK3399, Firefly-RK3399) that are affected, but I’d rather see these moved to OF_CONTROL instead of OF_PLATDATA.
Regards,
Philipp.
v2 cover dtoc: Add support for 64-bit addresses
Hi Philipp,
Quoted 25 lines · Dr. Philipp Tomsich
Quoted 13 lines · Simon Glass
Hi Philipp,
Quoted 6 lines · Dr. Philipp Tomsich
Simon,
I should be able to give this a test drive on the RK3368 by the end of the week. For the RK3399 our board uses full
OF_CONTROL, so I won’t really exercise this there.Quoted 8 lines
Quoted 4 lines
Given that the RK3399 can always fall back to
OF_CONTROLfor SPL (as is the default on Puma) and this only blocks the RK3368 TPL (which is not enabled for any other boards than Lion): should we try to get this merged for this release cycle or let it slip into the new merge window?My preference would be to put it in a next branch, but if nothing else uses it then I suppose it is possible (up to you and Tom)? What is broken that this fixes?
RK3399: SPL for all platforms using
OF_PLATDATA
RK3368: TPL (usesOF_PLATDATA)
Quoted 6 lines
Given that TPL for the RK3368 is not used much (and we have a private branch for people that need it), I don’t mind going with the ‘next’ branch.
I know that Kever has a few board configurations (EVB-RK3399, Firefly-RK3399) that are affected, but I’d rather see these moved to
OF_CONTROLinstead ofOF_PLATDATA.
Yes, I see OF_PLATDATA as an extreme measure to be used when we really have to.
Regards
Simon
v2 cover dtoc: Add support for 64-bit addresses
In reply to Simon GlassHi Simon,
Thanks for your patches, It works very good. I have test the patch
set on firefly-rk3399,
and the SPL works with OF_PLATDATA after I fix issue in clk(Philipp has point out) driver,
sdram driver and sdhci driver, I will send out my fix later.
Pls add my test tag for this patch set.
Thanks,
- Kever
Quoted 74 lines · Simon Glass
This series updates dtoc to support 64-bit addresses automatically. These appear in C code as
fdt64_tarrays:struct dtd_test1 { fdt64_t reg[2];};
static struct dtd_test1 dtv_test1 = { .reg = {0x123400000000, 0x5678}, };C code can then process these address and size parents easily. This feature is controlled by the #address-cells and #size-cells values of the parent.
The v2 series also enhances phandle support so that it is now possible to support phandles with different number of arguments. Several clean-up patches are included also.
Changes in v2:
- Support 'reg' properties with a single cell (e.g. #size-cells = 0)
- Introduce anfdt_val_ttype which is either 32- or 64-bits long
- Update rk3368 and rk3399 uses
- Drop review tags since there are significant changes in this patchSimon Glass (16):
fdt: Sync libfdt up to upstream
dtoc: Adjust Node to record its parent
dtoc: Add a 64-bit type and a way to convert cells into 64 bits
dtoc: Avoid very long lines in output
dtoc: Add support for 32 or 64-bit addresses
dtoc: Handle 'reg' properties with unusual sizes
dtoc: Update the Fdt class to record phandles
dtoc: Use the Fdt's class's phandle map
dtoc: Makeis_phandle()a member function
dtoc: Renameis_phandle()and adjust it to return more detail
dtoc: Rename the phandle struct
dtoc: Put each phandle on a separate line
dtoc: Put phandle args in an array
dtoc: Support properties containing multiple phandle values
dtoc: Rename the auto-generateddt-structs.hfile
dtoc: Add a header to the generated filesdoc/driver-model/of-plat.txt | 2 +- drivers/clk/clk-uclass.c | 4 +- drivers/clk/rockchip/clk_rk3368.c | 2 +- drivers/clk/rockchip/clk_rk3399.c | 4 +- drivers/core/regmap.c | 2 +- include/clk.h | 4 +- include/dt-structs.h | 16 ++- include/fdtdec.h | 2 + include/regmap.h | 2 +- include/syscon.h | 6 +- lib/libfdt/fdt_rw.c | 20 ++- lib/libfdt/libfdt.h | 31 +++++ lib/libfdt/pylibfdt/libfdt.i | 58 ++++++++ scripts/Makefile.spl | 5 +- tools/dtoc/dtb_platdata.py | 204 ++++++++++++++++++++++------ tools/dtoc/dtoc_test_addr32.dts | 27 ++++ tools/dtoc/dtoc_test_addr32_64.dts | 33 +++++ tools/dtoc/dtoc_test_addr64.dts | 33 +++++ tools/dtoc/dtoc_test_addr64_32.dts | 33 +++++ tools/dtoc/dtoc_test_phandle.dts | 16 ++- tools/dtoc/dtoc_test_simple.dts | 14 ++ tools/dtoc/fdt.py | 19 ++- tools/dtoc/fdt_util.py | 16 +++ tools/dtoc/test_dtoc.py | 270 ++++++++++++++++++++++++++++++++++++- 24 files changed, 748 insertions(+), 75 deletions(-)create mode 100644
tools/dtoc/dtoc_test_addr32.dtscreate mode 100644tools/dtoc/dtoc_test_addr32_64.dtscreate mode 100644tools/dtoc/dtoc_test_addr64.dtscreate mode 100644tools/dtoc/dtoc_test_addr64_32.dts