diff options
Diffstat (limited to 'arch/arm/boards/raspberry-pi/rpi-common.c')
-rw-r--r-- | arch/arm/boards/raspberry-pi/rpi-common.c | 86 |
1 files changed, 82 insertions, 4 deletions
diff --git a/arch/arm/boards/raspberry-pi/rpi-common.c b/arch/arm/boards/raspberry-pi/rpi-common.c index b5d16a15ca..60cea7f8e9 100644 --- a/arch/arm/boards/raspberry-pi/rpi-common.c +++ b/arch/arm/boards/raspberry-pi/rpi-common.c @@ -16,21 +16,28 @@ #include <common.h> #include <init.h> #include <fs.h> +#include <of.h> #include <linux/stat.h> #include <linux/clk.h> #include <linux/clkdev.h> #include <envfs.h> #include <malloc.h> +#include <libfile.h> #include <gpio.h> #include <net.h> #include <led.h> #include <asm/armlinux.h> +#include <asm/barebox-arm.h> #include <generated/mach-types.h> +#include <linux/sizes.h> +#include <globalvar.h> #include <mach/core.h> #include <mach/mbox.h> +#include <mach/platform.h> #include "rpi.h" +#include "lowlevel.h" struct msg_get_arm_mem { struct bcm2835_mbox_hdr hdr; @@ -314,10 +321,6 @@ static int rpi_clock_init(void) } postconsole_initcall(rpi_clock_init); -#define BCM2835_PL011_BASE 0x20201000 -#define BCM2836_PL011_BASE 0x3f201000 -#define BCM2836_MINIUART_BASE 0x3f215040 - static int rpi_console_clock_init(void) { struct clk *clk; @@ -370,12 +373,87 @@ static int rpi_env_init(void) return 0; } +/* Extract /chosen/bootargs from the VideoCore FDT into vc.bootargs + * global variable. */ +static int rpi_vc_fdt_bootargs(void *fdt) +{ + int ret = 0; + struct device_node *root = NULL, *node; + const char *cmdline; + + root = of_unflatten_dtb(fdt); + if (IS_ERR(root)) { + ret = PTR_ERR(root); + root = NULL; + goto out; + } + + node = of_find_node_by_path_from(root, "/chosen"); + if (!node) { + pr_err("no /chosen node\n"); + ret = -ENOENT; + goto out; + } + + cmdline = of_get_property(node, "bootargs", NULL); + if (!cmdline) { + pr_err("no bootargs property in the /chosen node\n"); + ret = -ENOENT; + goto out; + } + + globalvar_add_simple("vc.bootargs", cmdline); + +out: + if (root) + of_delete_node(root); + + return ret; +} + +static void rpi_vc_fdt(void) +{ + void *saved_vc_fdt; + struct fdt_header *oftree; + unsigned long magic, size; + int ret; + + /* VideoCore FDT was copied in PBL just above Barebox memory */ + saved_vc_fdt = (void *)(arm_mem_endmem_get()); + + oftree = saved_vc_fdt; + magic = be32_to_cpu(oftree->magic); + if (magic != FDT_MAGIC) { + pr_err("videocore fdt saved in pbl has invalid magic\n"); + + if (magic == VIDEOCORE_FDT_ERROR) { + pr_err("there was an error copying fdt in pbl: %d\n", + be32_to_cpu(oftree->totalsize)); + } + return; + } + + size = be32_to_cpu(oftree->totalsize); + if (write_file("/vc.dtb", saved_vc_fdt, size)) { + pr_err("failed to save videocore fdt to a file\n"); + return; + } + + ret = rpi_vc_fdt_bootargs(saved_vc_fdt); + if (ret) { + pr_err("failed to extract bootargs from videocore fdt: %d\n", + ret); + return; + } +} + static int rpi_devices_init(void) { rpi_model_init(); bcm2835_register_fb(); armlinux_set_architecture(MACH_TYPE_BCM2708); rpi_env_init(); + rpi_vc_fdt(); return 0; } late_initcall(rpi_devices_init); |