summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/mach-mpc85xx/fdt.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/mach-mpc85xx/fdt.c')
-rw-r--r--arch/powerpc/mach-mpc85xx/fdt.c154
1 files changed, 154 insertions, 0 deletions
diff --git a/arch/powerpc/mach-mpc85xx/fdt.c b/arch/powerpc/mach-mpc85xx/fdt.c
new file mode 100644
index 0000000000..de0114ad64
--- /dev/null
+++ b/arch/powerpc/mach-mpc85xx/fdt.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2013 GE Intelligent Platforms, Inc.
+ * Copyright 2007-2011 Freescale Semiconductor, Inc.
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Based on U-Boot arch/powerpc/cpu/mpc85xx/fdt.c and
+ * common/fdt_support.c - version git-2b26201.
+ */
+#include <common.h>
+#include <init.h>
+#include <errno.h>
+#include <environment.h>
+#include <asm/processor.h>
+#include <mach/clock.h>
+#include <of.h>
+
+static void of_setup_crypto_node(void *blob)
+{
+ struct device_node *crypto_node;
+
+ crypto_node = of_find_compatible_node(blob, NULL, "fsl,sec2.0");
+ if (crypto_node == NULL)
+ return;
+
+ of_delete_node(crypto_node);
+}
+
+/* These properties specify whether the hardware supports the stashing
+ * of buffer descriptors in L2 cache.
+ */
+static void fdt_add_enet_stashing(void *fdt)
+{
+ struct device_node *node;
+
+ node = of_find_compatible_node(fdt, NULL, "gianfar");
+ while (node) {
+ of_set_property(node, "bd-stash", NULL, 0, 1);
+ of_property_write_u32(node, "rx-stash-len", 96);
+ of_property_write_u32(node, "rx-stash-idx", 0);
+ node = of_find_compatible_node(node, NULL, "gianfar");
+ }
+
+ node = of_find_compatible_node(fdt, NULL, "fsl,etsec2");
+ while (node) {
+ of_set_property(node, "bd-stash", NULL, 0, 1);
+ of_property_write_u32(node, "rx-stash-len", 96);
+ of_property_write_u32(node, "rx-stash-idx", 0);
+ node = of_find_compatible_node(node, NULL, "fsl,etsec2");
+ }
+}
+
+static int fdt_stdout_setup(struct device_node *blob)
+{
+ struct device_node *node, *alias;
+ char sername[9] = { 0 };
+ const char *prop;
+ struct console_device *cdev;
+ int len;
+
+ node = of_create_node(blob, "/chosen");
+ if (node == NULL) {
+ pr_err("%s: could not open /chosen node\n", __func__);
+ goto error;
+ }
+
+ cdev = console_get_first_active();
+ if (cdev)
+ sprintf(sername, "serial%d", cdev->dev->id);
+ else
+ sprintf(sername, "serial%d", 0);
+
+ alias = of_find_node_by_path_from(blob, "/aliases");
+ if (!alias) {
+ pr_err("%s: could not get aliases node.\n", __func__);
+ goto error;
+ }
+ prop = of_get_property(alias, sername, &len);
+ of_set_property(node, "linux,stdout-path", prop, len, 1);
+
+ return 0;
+error:
+ return -ENODEV;
+}
+
+static int fdt_cpu_setup(struct device_node *blob, void *unused)
+{
+ struct device_node *node;
+ struct sys_info sysinfo;
+
+ /* delete crypto node if not on an E-processor */
+ if (!IS_E_PROCESSOR(get_svr()))
+ of_setup_crypto_node(blob);
+
+ fdt_add_enet_stashing(blob);
+ fsl_get_sys_info(&sysinfo);
+
+ node = of_find_node_by_type(blob, "cpu");
+ while (node) {
+ const uint32_t *reg;
+
+ of_property_write_u32(node, "timebase-frequency",
+ fsl_get_timebase_clock());
+ of_property_write_u32(node, "bus-frequency",
+ sysinfo.freqSystemBus);
+ reg = of_get_property(node, "reg", NULL);
+ of_property_write_u32(node, "clock-frequency",
+ sysinfo.freqProcessor[*reg]);
+ node = of_find_node_by_type(node, "cpu");
+ }
+
+ node = of_find_node_by_type(blob, "soc");
+ if (node)
+ of_property_write_u32(node, "bus-frequency",
+ sysinfo.freqSystemBus);
+
+ node = of_find_compatible_node(blob, NULL, "fsl,elbc");
+ if (node)
+ of_property_write_u32(node, "bus-frequency",
+ sysinfo.freqLocalBus);
+
+ node = of_find_compatible_node(blob, NULL, "ns16550");
+ while (node) {
+ of_property_write_u32(node, "clock-frequency",
+ sysinfo.freqSystemBus);
+ node = of_find_compatible_node(node, NULL, "ns16550");
+ }
+
+ node = of_find_compatible_node(blob, NULL, "fsl,mpic");
+ if (node)
+ of_property_write_u32(node, "clock-frequency",
+ sysinfo.freqSystemBus);
+
+ fdt_stdout_setup(blob);
+
+ return 0;
+}
+
+static int of_register_mpc85xx_fixup(void)
+{
+ return of_register_fixup(fdt_cpu_setup, NULL);
+}
+late_initcall(of_register_mpc85xx_fixup);