blob: 541a90798d423c103bb322ef132f03c18803b39f [file] [log] [blame]
Steven J. Hill30700332012-05-30 21:02:49 +00001/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
Qais Yousef44327232013-12-06 11:00:42 +00007 * Copyright (C) 2013 Imagination Technologies Ltd.
Steven J. Hill30700332012-05-30 21:02:49 +00008 */
9#include <linux/init.h>
Qais Yousef44327232013-12-06 11:00:42 +000010#include <linux/libfdt.h>
Steven J. Hill9b731002013-01-17 11:37:03 -060011#include <linux/of_platform.h>
12#include <linux/of_fdt.h>
13#include <linux/bootmem.h>
14
Rob Herring089a49b2013-09-07 14:58:54 -050015#include <asm/prom.h>
Qais Yousef44327232013-12-06 11:00:42 +000016#include <asm/fw/fw.h>
Rob Herring089a49b2013-09-07 14:58:54 -050017
Steven J. Hill9b731002013-01-17 11:37:03 -060018#include <asm/mips-boards/generic.h>
Steven J. Hill30700332012-05-30 21:02:49 +000019
Steven J. Hill30700332012-05-30 21:02:49 +000020const char *get_system_type(void)
21{
22 return "MIPS SEAD3";
23}
24
Qais Yousef44327232013-12-06 11:00:42 +000025static uint32_t get_memsize_from_cmdline(void)
26{
27 int memsize = 0;
28 char *p = arcs_cmdline;
29 char *s = "memsize=";
30
31 p = strstr(p, s);
32 if (p) {
33 p += strlen(s);
34 memsize = memparse(p, NULL);
35 }
36
37 return memsize;
38}
39
40static uint32_t get_memsize_from_env(void)
41{
42 int memsize = 0;
43 char *p;
44
45 p = fw_getenv("memsize");
46 if (p)
47 memsize = memparse(p, NULL);
48
49 return memsize;
50}
51
52static uint32_t get_memsize(void)
53{
54 uint32_t memsize;
55
56 memsize = get_memsize_from_cmdline();
57 if (memsize)
58 return memsize;
59
60 return get_memsize_from_env();
61}
62
63static void __init parse_memsize_param(void)
64{
65 int offset;
66 const uint64_t *prop_value;
67 int prop_len;
68 uint32_t memsize = get_memsize();
69
70 if (!memsize)
71 return;
72
73 offset = fdt_path_offset(&__dtb_start, "/memory");
74 if (offset > 0) {
75 uint64_t new_value;
76 /*
77 * reg contains 2 32-bits BE values, offset and size. We just
78 * want to replace the size value without affecting the offset
79 */
80 prop_value = fdt_getprop(&__dtb_start, offset, "reg", &prop_len);
81 new_value = be64_to_cpu(*prop_value);
82 new_value = (new_value & ~0xffffffffllu) | memsize;
83 fdt_setprop_inplace_u64(&__dtb_start, offset, "reg", new_value);
84 }
85}
86
Steven J. Hill30700332012-05-30 21:02:49 +000087void __init plat_mem_setup(void)
88{
Qais Yousef44327232013-12-06 11:00:42 +000089 /* allow command line/bootloader env to override memory size in DT */
90 parse_memsize_param();
91
Steven J. Hill9b731002013-01-17 11:37:03 -060092 /*
93 * Load the builtin devicetree. This causes the chosen node to be
94 * parsed resulting in our memory appearing
95 */
96 __dt_setup_arch(&__dtb_start);
97}
98
99void __init device_tree_init(void)
100{
101 unsigned long base, size;
102
103 if (!initial_boot_params)
104 return;
105
106 base = virt_to_phys((void *)initial_boot_params);
107 size = be32_to_cpu(initial_boot_params->totalsize);
108
109 /* Before we do anything, lets reserve the dt blob */
110 reserve_bootmem(base, size, BOOTMEM_DEFAULT);
111
112 unflatten_device_tree();
Steven J. Hill30700332012-05-30 21:02:49 +0000113}
Qais Yousef187e7c52013-12-06 11:00:44 +0000114
115static int __init customize_machine(void)
116{
117 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
118 return 0;
119}
120arch_initcall(customize_machine);