a499f9940fd7e3a3b15ca5ae48edec5e251e94e0
[firefly-linux-kernel-4.4.55.git] / arch / mips / mti-sead3 / sead3-setup.c
1 /*
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.
7  * Copyright (C) 2013 Imagination Technologies Ltd.
8  */
9 #include <linux/init.h>
10 #include <linux/libfdt.h>
11 #include <linux/of_platform.h>
12 #include <linux/of_fdt.h>
13 #include <linux/bootmem.h>
14
15 #include <asm/prom.h>
16 #include <asm/fw/fw.h>
17
18 #include <asm/mips-boards/generic.h>
19
20 const char *get_system_type(void)
21 {
22         return "MIPS SEAD3";
23 }
24
25 static 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
40 static 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
52 static 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
63 static 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
87 void __init plat_mem_setup(void)
88 {
89         /* allow command line/bootloader env to override memory size in DT */
90         parse_memsize_param();
91
92         /*
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
99 void __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();
113 }