diff options
Diffstat (limited to 'cpu/mpc83xx')
-rw-r--r-- | cpu/mpc83xx/cpu.c | 184 |
1 files changed, 183 insertions, 1 deletions
diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c index e4bc405..e934ba6 100644 --- a/cpu/mpc83xx/cpu.c +++ b/cpu/mpc83xx/cpu.c @@ -30,8 +30,14 @@ #include <watchdog.h> #include <command.h> #include <mpc83xx.h> -#include <ft_build.h> #include <asm/processor.h> +#if defined(CONFIG_OF_FLAT_TREE) +#include <ft_build.h> +#endif +#if defined(CONFIG_OF_LIBFDT) +#include <libfdt.h> +#include <libfdt_env.h> +#endif DECLARE_GLOBAL_DATA_PTR; @@ -291,6 +297,182 @@ void watchdog_reset (void) } #endif +#if defined(CONFIG_OF_LIBFDT) + +/* + * "Setter" functions used to add/modify FDT entries. + */ +static int fdt_set_eth0(void *fdt, int nodeoffset, const char *name, bd_t *bd) +{ + /* + * Fix it up if it exists, don't create it if it doesn't exist. + */ + if (fdt_get_property(fdt, nodeoffset, name, 0)) { + return fdt_setprop(fdt, nodeoffset, name, bd->bi_enetaddr, 6); + } + return -FDT_ERR_NOTFOUND; +} +#ifdef CONFIG_HAS_ETH1 +/* second onboard ethernet port */ +static int fdt_set_eth1(void *fdt, int nodeoffset, const char *name, bd_t *bd) +{ + /* + * Fix it up if it exists, don't create it if it doesn't exist. + */ + if (fdt_get_property(fdt, nodeoffset, name, 0)) { + return fdt_setprop(fdt, nodeoffset, name, bd->bi_enet1addr, 6); + } + return -FDT_ERR_NOTFOUND; +} +#endif +#ifdef CONFIG_HAS_ETH2 +/* third onboard ethernet port */ +static int fdt_set_eth2(void *fdt, int nodeoffset, const char *name, bd_t *bd) +{ + /* + * Fix it up if it exists, don't create it if it doesn't exist. + */ + if (fdt_get_property(fdt, nodeoffset, name, 0)) { + return fdt_setprop(fdt, nodeoffset, name, bd->bi_enet2addr, 6); + } + return -FDT_ERR_NOTFOUND; +} +#endif +#ifdef CONFIG_HAS_ETH3 +/* fourth onboard ethernet port */ +static int fdt_set_eth3(void *fdt, int nodeoffset, const char *name, bd_t *bd) +{ + /* + * Fix it up if it exists, don't create it if it doesn't exist. + */ + if (fdt_get_property(fdt, nodeoffset, name, 0)) { + return fdt_setprop(fdt, nodeoffset, name, bd->bi_enet3addr, 6); + } + return -FDT_ERR_NOTFOUND; +} +#endif + +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)); +} + +/* + * Fixups to the fdt. If "create" is TRUE, the node is created + * unconditionally. If "create" is FALSE, the node is updated + * only if it already exists. + */ +static const struct { + char *node; + char *prop; + int (*set_fn)(void *fdt, int nodeoffset, const char *name, bd_t *bd); +} fixup_props[] = { + { "/cpus/" OF_CPU, + "bus-frequency", + fdt_set_busfreq + }, + { "/cpus/" OF_SOC, + "bus-frequency", + fdt_set_busfreq + }, + { "/" OF_SOC "/serial@4500/", + "clock-frequency", + fdt_set_busfreq + }, + { "/" OF_SOC "/serial@4600/", + "clock-frequency", + fdt_set_busfreq + }, +#ifdef CONFIG_MPC83XX_TSEC1 + { "/" OF_SOC "/ethernet@24000, + "mac-address", + fdt_set_eth0 + }, + { "/" OF_SOC "/ethernet@24000, + "local-mac-address", + fdt_set_eth0 + }, +#endif +#ifdef CONFIG_MPC83XX_TSEC2 + { "/" OF_SOC "/ethernet@25000, + "mac-address", + fdt_set_eth1 + }, + { "/" OF_SOC "/ethernet@25000, + "local-mac-address", + fdt_set_eth1 + }, +#endif +#ifdef CONFIG_UEC_ETH1 +#if CFG_UEC1_UCC_NUM == 0 /* UCC1 */ + { "/" OF_QE "/ucc@2000/mac-address", + "mac-address", + fdt_set_eth0 + }, + { "/" OF_QE "/ucc@2000/mac-address", + "local-mac-address", + fdt_set_eth0 + }, +#elif CFG_UEC1_UCC_NUM == 2 /* UCC3 */ + { "/" OF_QE "/ucc@2200/mac-address", + "mac-address", + fdt_set_eth0 + }, + { "/" OF_QE "/ucc@2200/mac-address", + "local-mac-address", + fdt_set_eth0 + }, +#endif +#endif +#ifdef CONFIG_UEC_ETH2 +#if CFG_UEC2_UCC_NUM == 1 /* UCC2 */ + { "/" OF_QE "/ucc@3000/mac-address", + "mac-address", + fdt_set_eth1 + }, + { "/" OF_QE "/ucc@3000/mac-address", + "local-mac-address", + fdt_set_eth1 + }, +#elif CFG_UEC1_UCC_NUM == 3 /* UCC4 */ + { "/" OF_QE "/ucc@3200/mac-address", + "mac-address", + fdt_set_eth1 + }, + { "/" OF_QE "/ucc@3200/mac-address", + "local-mac-address", + fdt_set_eth1 + }, +#endif +#endif +}; + +void +ft_cpu_setup(void *blob, bd_t *bd) +{ + int nodeoffset; + int err; + int j; + + for (j = 0; j < (sizeof(fixup_props) / sizeof(fixup_props[0])); j++) { + nodeoffset = fdt_path_offset(fdt, fixup_props[j].node); + if (nodeoffset >= 0) { + err = (*fixup_props[j].set_fn)(blob, nodeoffset, fixup_props[j].prop, bd); + if (err < 0) + printf("set_fn/libfdt: %s %s returned %s\n", + fixup_props[j].node, + fixup_props[j].prop, + fdt_strerror(err)); + } + } +} +#endif + #if defined(CONFIG_OF_FLAT_TREE) void ft_cpu_setup(void *blob, bd_t *bd) |