diff --git a/arch/ppc/include/asm/processor.h b/arch/ppc/include/asm/processor.h index 29e0622..04cfb60 100644 --- a/arch/ppc/include/asm/processor.h +++ b/arch/ppc/include/asm/processor.h @@ -845,6 +845,7 @@ /* Some parts define SVR[0:23] as the SOC version */ #define SVR_SOC_VER(svr) (((svr) >> 8) & 0xFFFFFF) /* SOC Version fields */ +#define IS_E_PROCESSOR(svr) ((svr) & 0x80000) /* * SVR_VER() Version Values diff --git a/arch/ppc/mach-mpc85xx/Makefile b/arch/ppc/mach-mpc85xx/Makefile index cc412c5..81d6853 100644 --- a/arch/ppc/mach-mpc85xx/Makefile +++ b/arch/ppc/mach-mpc85xx/Makefile @@ -5,4 +5,5 @@ obj-y += speed.o obj-y +=time.o obj-$(CONFIG_MP) += mp.o +obj-$(CONFIG_OFTREE) += fdt.o obj-$(CONFIG_DRIVER_NET_GIANFAR) += eth-devices.o diff --git a/arch/ppc/mach-mpc85xx/fdt.c b/arch/ppc/mach-mpc85xx/fdt.c new file mode 100644 index 0000000..4feae44 --- /dev/null +++ b/arch/ppc/mach-mpc85xx/fdt.c @@ -0,0 +1,146 @@ +/* + * Copyright 2013 GE Intelligent Platforms, Inc. + * Copyright 2007-2011 Freescale Semiconductor, Inc. + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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 +#include +#include +#include +#include +#include +#include + +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"); + } +} + +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; + } + + for_each_console(cdev) + if ((cdev->f_active & (CONSOLE_STDIN | CONSOLE_STDOUT))) + break; + 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) +{ + 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"); + } + + fdt_stdout_setup(blob); + + return 0; +} + +static int of_register_mpc85xx_fixup(void) +{ + return of_register_fixup(fdt_cpu_setup); +} +late_initcall(of_register_mpc85xx_fixup); diff --git a/net/eth.c b/net/eth.c index e94689a..e5d6a35 100644 --- a/net/eth.c +++ b/net/eth.c @@ -273,7 +273,7 @@ return 0; } -#ifdef CONFIG_OFDEVICE +#ifdef CONFIG_OFTREE static int eth_of_fixup(struct device_node *root) { struct eth_device *edev; @@ -285,21 +285,23 @@ * find a nodepath for and which has a valid mac address. */ list_for_each_entry(edev, &netdev_list, list) { - if (!edev->nodepath) { - dev_dbg(&edev->dev, "%s: no node to fixup\n", __func__); - continue; - } - if (!is_valid_ether_addr(edev->ethaddr)) { - dev_dbg(&edev->dev, "%s: no valid mac address, cannot fixup\n", - __func__); + dev_dbg(&edev->dev, + "%s: no valid mac address, cannot fixup\n", + __func__); continue; } - node = of_find_node_by_path_from(root, edev->nodepath); + if (edev->nodepath) { + node = of_find_node_by_path_from(root, edev->nodepath); + } else { + char eth[12]; + sprintf(eth, "ethernet%d", edev->dev.id); + node = of_find_node_by_alias(root, eth); + } + if (!node) { - dev_dbg(&edev->dev, "%s: fixup node %s not found\n", - __func__, edev->nodepath); + dev_dbg(&edev->dev, "%s: no node to fixup\n", __func__); continue; }