Skip to contentSkip to conversation

dtoc: Add support for 64-bit addresses

PATCH Superseded Simon Glass 4 participants 40 messages Aug 29, 2017 – Sep 15, 2017

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

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
#1 lore raw

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
index 80a3212141..3dc775261f 100644
@@ -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
index f3f9cad184..6af94cb3f7 100644
@@ -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
#2 lore raw

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!

#3 lore raw

PATCH v2 2/16 dtoc: Adjust Node to record its parent

In reply to Simon Glass

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(-)
tools/dtoc/fdt.py +7 -5
index 63a32ea2d7..49409a62ec 100644
@@ -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
#4 lore raw

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!

#5 lore raw

PATCH v2 3/16 dtoc: Add a 64-bit type and a way to convert cells into 64 bits

In reply to Simon Glass

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(-)
tools/dtoc/dtb_platdata.py +3 -0
index 041a33188f..4a1162a9fa 100644
@@ -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
index 49409a62ec..ffd42ce541 100644
@@ -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
index b9dfae8d0e..bec6ee947a 100644
@@ -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
#6 lore raw

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!

#7 lore raw

PATCH v2 4/16 dtoc: Avoid very long lines in output

In reply to Simon Glass

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(-)
tools/dtoc/dtb_platdata.py +6 -1
index 4a1162a9fa..3243bccfe8 100644
@@ -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
index 8b95c4124f..5040f23325 100644
@@ -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
#8 lore raw

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!

#9 lore raw

PATCH v2 5/16 dtoc: Add support for 32 or 64-bit addresses

In reply to 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_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
index 2be1f572d7..0160d50c03 100644
@@ -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
index 3edafea140..0de3db620d 100644
@@ -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
index d4e16a27ef..0f1d30820c 100644
@@ -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
index 4a0947c626..1ba02be8e1 100644
@@ -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
index 1eed94e47a..493a5d8eff 100644
@@ -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
index 34842aa470..5d52b1cc3c 100644
@@ -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
new file mode 100644
index 0000000000..bcfdcae10b
@@ -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
new file mode 100644
index 0000000000..1c96243310
@@ -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
new file mode 100644
index 0000000000..4c0ad0ec36
@@ -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
new file mode 100644
index 0000000000..c36f6b726e
@@ -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
index bec6ee947a..338d47a5e1 100644
@@ -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
#10 lore raw

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_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'.

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_t type.

See below.

Quoted 45 lines

---

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
index 2be1f572d7..0160d50c03 100644
@@ -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
index 3edafea140..0de3db620d 100644

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
index d4e16a27ef..0f1d30820c 100644
@@ -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
index 4a0947c626..1ba02be8e1 100644
@@ -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
index 1eed94e47a..493a5d8eff 100644
@@ -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
index 34842aa470..5d52b1cc3c 100644
@@ -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
index 3243bccfe8..0c719310b1 100644
@@ -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
new file mode 100644
index 0000000000..bcfdcae10b
@@ -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
new file mode 100644
index 0000000000..1c96243310
@@ -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
new file mode 100644
index 0000000000..4c0ad0ec36
@@ -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
new file mode 100644
index 0000000000..c36f6b726e
@@ -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
index bec6ee947a..338d47a5e1 100644
@@ -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
index 5040f23325..09cfddaaaa 100644
@@ -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
#11 lore raw

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_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'.

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_t type.

See below.

Quoted 48 lines

---

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
index 2be1f572d7..0160d50c03 100644
@@ -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
index 3edafea140..0de3db620d 100644
@@ -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

#12 lore raw

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_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.

Quoted 36 lines
Quoted 4 lines

See below.

Quoted 27 lines

---

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

Applied to u-boot-fdt thanks!

#13 lore raw

PATCH v2 6/16 dtoc: Handle 'reg' properties with unusual sizes

In reply to Simon Glass

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(+)
tools/dtoc/dtoc_test_simple.dts +14 -0
index c736686263..6afe674b1f 100644
@@ -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
index 09cfddaaaa..62460acb7c 100644
@@ -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
#14 lore raw

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!

#15 lore raw

PATCH v2 7/16 dtoc: Update the Fdt class to record phandles

In reply to Simon Glass

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(+)
tools/dtoc/fdt.py +5 -0
index ffd42ce541..dbc338653b 100644
@@ -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
#16 lore raw

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!

#17 lore raw

PATCH v2 8/16 dtoc: Use the Fdt's class's phandle map

In reply to Simon Glass

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(-)
tools/dtoc/dtb_platdata.py +3 -13
index 0c719310b1..705ab27c86 100644
@@ -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
#18 lore raw

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!

#19 lore raw

PATCH v2 9/16 dtoc: Make is_phandle() a member function

In reply to Simon Glass

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(-)
tools/dtoc/dtb_platdata.py +18 -18
index 705ab27c86..a483d6c875 100644
@@ -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
#20 lore raw

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!

#21 lore raw

PATCH v2 10/16 dtoc: Rename is_phandle() and adjust it to return more detail

In reply to Simon Glass

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(-)
tools/dtoc/dtb_platdata.py +57 -22
index a483d6c875..001bc4ea66 100644
@@ -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
index e9828a695b..c0a602f296 100644
@@ -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
#22 lore raw

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!

#23 lore raw

PATCH v2 11/16 dtoc: Rename the phandle struct

In reply to Simon Glass

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(-)
doc/driver-model/of-plat.txt +1 -1
index 3ed8c759d6..732bc34f06 100644
@@ -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
index e68d9279b9..8b40326efa 100644
@@ -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
index c5988f78a8..e7ce3e8576 100644
@@ -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
index 0732c442ff..2ed997115a 100644
@@ -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
index 001bc4ea66..0234f71b76 100644
@@ -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
index 62460acb7c..23c4439ed9 100644
@@ -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
#24 lore raw

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!

#25 lore raw

PATCH v2 12/16 dtoc: Put each phandle on a separate line

In reply to Simon Glass

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(-)
tools/dtoc/dtb_platdata.py +7 -5
index 0234f71b76..c0a3ae692b 100644
@@ -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
index 23c4439ed9..aa617a649c 100644
@@ -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
#26 lore raw

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!

#27 lore raw

PATCH v2 13/16 dtoc: Put phandle args in an array

In reply to Simon Glass

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(-)
drivers/clk/clk-uclass.c +1 -1
index 8b40326efa..83ba13374c 100644
@@ -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
index 2ed997115a..9ab4e2524d 100644
@@ -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
index c0a3ae692b..1920a59f82 100644
@@ -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
index aa617a649c..fbae927cf8 100644
@@ -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
#28 lore raw

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!

#29 lore raw

PATCH v2 14/16 dtoc: Support properties containing multiple phandle values

In reply to Simon Glass

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(-)
include/dt-structs.h +5 -0
index 9ab4e2524d..76979e73e1 100644
@@ -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
index 1920a59f82..cfca45b0ac 100644
@@ -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
index c0a602f296..ba12b0fe65 100644
@@ -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
index fbae927cf8..cc009b2a25 100644
@@ -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
#30 lore raw

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!

#31 lore raw

PATCH v2 15/16 dtoc: Rename the auto-generated dt-structs.h file

In reply to Simon Glass

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(-)
include/dt-structs.h +1 -1
index 76979e73e1..c0f56951b5 100644
@@ -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
index dd8065d87d..b86ea76bab 100644
@@ -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
#32 lore raw

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!

#33 lore raw

PATCH v2 16/16 dtoc: Add a header to the generated files

In reply to Simon Glass

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(+)
tools/dtoc/dtb_platdata.py +12 -0
index cfca45b0ac..dc9c0d9f45 100644
@@ -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
#34 lore raw

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!

#35 lore raw

v2 cover dtoc: Add support for 64-bit addresses

In reply to Simon Glass

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_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_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
#36 lore raw

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_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?

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

#37 lore raw

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_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?

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.

#38 lore raw

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_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?

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)

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_CONTROL instead of OF_PLATDATA.

Yes, I see OF_PLATDATA as an extreme measure to be used when we really have to.

Regards
Simon

#39 lore raw

v2 cover dtoc: Add support for 64-bit addresses

In reply to Simon Glass

Hi 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_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