[U-Boot-Users] [PATCH] RFC: generic property fixup mechanism for LIBFDT

Bartlomiej Sieka tur at semihalf.com
Wed Aug 22 13:54:25 CEST 2007


On Fri, Aug 03, 2007 at 08:25:56AM -0600, Grant Likely wrote:
[...]
> > +static int fdt_set_tbfreq(void *fdt, int nodeoffset, const char *name, bd_t *bd)
> > +{
> > +       u32 tmp;
> > +       /*
> > +        * Create or update the property.
> > +        */
> > +       tmp = cpu_to_be32(OF_TBCLK);
> > +       return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
> > +}
> > +
> > +static int fdt_set_busfreq(void *fdt, int nodeoffset, const char *name,
> > +                               bd_t *bd)
> > +{
> > +       u32 tmp;
> > +       /*
> > +        * Create or update the property.
> > +        */
> > +       tmp = cpu_to_be32(bd->bi_busfreq);
> > +       return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
> > +}
> > +
> > +static int fdt_set_clockfreq(void *fdt, int nodeoffset, const char *name,
> > +                               bd_t *bd)
> > +{
> > +       u32 tmp;
> > +       /*
> > +        * Create or update the property.
> > +        */
> > +       tmp = cpu_to_be32(bd->bi_intfreq);
> > +       return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
> > +}
> > +
> > +static int fdt_set_ipbusfreq(void *fdt, int nodeoffset, const char *name,
> > +                               bd_t *bd)
> > +{
> > +       u32 tmp;
> > +       /*
> > +        * Create or update the property.
> > +        */
> > +       tmp = cpu_to_be32(bd->bi_ipbfreq);
> > +       return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
> > +}
> 
> These 4 functions are pretty close to identical (except for the
> parameter to cpu_to_be32()).  Surely there is a more compact way to do
> this.  In addition, these function don't really contain anything that
> screams out "5xxx only!".  Can this be common support code usable by
> all boards?

Please see the patch below for a more generic approach to property fixups.
The patch updates mpc5xxx-related code, but I've looked at mpc83xx fixups
and it seems like they can be adapted to this approach as well.

I am interested in the comments people might have before proceeding further
(i.e., getting rid of OF_FLAT_TREE in mpc5xxx).

Regards,
Bartlomiej


diff --git a/cpu/mpc5xxx/cpu.c b/cpu/mpc5xxx/cpu.c
index 1eac2bb..1e661c2 100644
--- a/cpu/mpc5xxx/cpu.c
+++ b/cpu/mpc5xxx/cpu.c
@@ -33,6 +33,9 @@
 
 #if defined(CONFIG_OF_FLAT_TREE)
 #include <ft_build.h>
+#elif defined(CONFIG_OF_LIBFDT)
+#include <libfdt.h>
+#include <libfdt_env.h>
 #endif
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -109,9 +112,81 @@ unsigned long get_tbclk (void)
 	return (tbclk);
 }
 
+#if defined(CONFIG_OF_LIBFDT)
 /* ------------------------------------------------------------------------- */
-
-#ifdef CONFIG_OF_FLAT_TREE
+/*
+ * Fixups to the fdt.
+ */
+void
+ft_cpu_setup(void *blob, bd_t *bd)
+{
+	u32 tbfreq;
+	u32 busfreq;
+	u32 intfreq;
+	u32 ipbfreq;
+
+	/* fixup properties */
+	fdt_fixup_props_t fixup_props[] = {
+		{	"/cpus/" OF_CPU,
+			"timebase-frequency",
+			NULL,	/* to be set manually */
+			0,	/* to be set manually */
+			1
+		},
+		{	"/cpus/" OF_CPU,
+			"bus-frequency",
+			NULL,	/* to be set manually */
+			0,	/* to be set manually */
+			1
+		},
+		{	"/cpus/" OF_CPU,
+			"clock-frequency",
+			NULL,	/* to be set manually */
+			0,	/* to be set manually */
+			1
+		},
+		{	"/" OF_SOC,
+			"bus-frequency",
+			NULL,	/* to be set manually */
+			0,	/* to be set manually */
+			1
+		},
+		{	"/" OF_SOC "/ethernet at 3000",
+			"mac-address",
+			bd->bi_enetaddr,
+			6,
+			0
+		},
+		{	"/" OF_SOC "/ethernet at 3000",
+			"local-mac-address",
+			bd->bi_enetaddr,
+			6,
+			0
+		}
+	};
+
+	/* manually set members that can't be initialized in the definition */
+	tbfreq = cpu_to_be32(OF_TBCLK);
+	fixup_props[0].val = &tbfreq;
+	fixup_props[0].len = sizeof(tbfreq);
+
+	busfreq = cpu_to_be32(bd->bi_busfreq);
+	fixup_props[1].val = &busfreq;
+	fixup_props[1].len = sizeof(busfreq);
+
+	intfreq = cpu_to_be32(bd->bi_intfreq);
+	fixup_props[2].val = &intfreq;
+	fixup_props[2].len = sizeof(intfreq);
+
+	ipbfreq = cpu_to_be32(bd->bi_ipbfreq);
+	fixup_props[3].val = &ipbfreq;
+	fixup_props[3].len = sizeof(ipbfreq);
+
+
+	fdt_fixup_props(blob, fixup_props,
+			sizeof(fixup_props) / sizeof(fixup_props[0]));
+}
+#elif defined(CONFIG_OF_FLAT_TREE)
 void
 ft_cpu_setup(void *blob, bd_t *bd)
 {
diff --git a/include/libfdt.h b/include/libfdt.h
index 340e89d..065c580 100644
--- a/include/libfdt.h
+++ b/include/libfdt.h
@@ -23,6 +23,17 @@
 #include <fdt.h>
 #include <libfdt_env.h>
 
+
+/* Structure describing property to be fixed-up in cpu-specific code */
+typedef struct {
+        char *node;
+        char *prop;
+        void *val;
+        int len;        /* sizeof(val) */
+        char create;    /* whether to create non-existing properties */
+} fdt_fixup_props_t;
+
+
 #define FDT_FIRST_SUPPORTED_VERSION	0x10
 #define FDT_LAST_SUPPORTED_VERSION	0x11
 
@@ -145,6 +156,7 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
 			    const char *name, int namelen);
 int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
 int fdt_del_node(void *fdt, int nodeoffset);
+void fdt_fixup_props(void *blob, fdt_fixup_props_t fixup_props[], int count);
 
 /* Extra functions */
 const char *fdt_strerror(int errval);
diff --git a/libfdt/fdt_rw.c b/libfdt/fdt_rw.c
index 693bfe4..572a4e6 100644
--- a/libfdt/fdt_rw.c
+++ b/libfdt/fdt_rw.c
@@ -19,6 +19,8 @@
 #include "config.h"
 #if CONFIG_OF_LIBFDT
 
+#include <common.h>
+
 #include "libfdt_env.h"
 
 #include <fdt.h>
@@ -295,4 +297,40 @@ int fdt_pack(void *fdt)
 	return 0;
 }
 
+
+/*
+ * Function fixes up properties in passed 'blob'. It uses the array
+ * 'fixup_props' to take the description of properites to be fixed up, and
+ * processes 'count' elements from this array.
+ */
+void fdt_fixup_props(void *blob, fdt_fixup_props_t fixup_props[], int count)
+{
+	int nodeoffset;
+	int err;
+	int j;
+
+	for (j = 0; j < count; j++) {
+		nodeoffset = fdt_find_node_by_path(blob, fixup_props[j].node);
+		if (nodeoffset >= 0) {
+			if (fixup_props[j].create ||
+				fdt_get_property(blob, nodeoffset,
+					fixup_props[j].prop, 0))
+				err = fdt_setprop(blob, nodeoffset,
+							fixup_props[j].prop,
+							fixup_props[j].val,
+							fixup_props[j].len);
+			else
+				err = 0;
+			if (err < 0)
+				debug("Problem setting %s = %s: %s\n",
+					fixup_props[j].node,
+					fixup_props[j].prop,
+					fdt_strerror(err));
+
+		} else
+			debug("Couldn't find %s: %s\n",
+				fixup_props[j].node,
+				fdt_strerror(nodeoffset));
+	}
+}
 #endif /* CONFIG_OF_LIBFDT */




More information about the U-Boot mailing list