[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