Commit | Line | Data |
---|---|---|
3070033a SH |
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. | |
44327236 | 7 | * Copyright (C) 2013 Imagination Technologies Ltd. |
3070033a SH |
8 | */ |
9 | #include <linux/init.h> | |
44327236 | 10 | #include <linux/libfdt.h> |
9b731009 | 11 | #include <linux/of_fdt.h> |
9b731009 | 12 | |
089a49b6 | 13 | #include <asm/prom.h> |
44327236 | 14 | #include <asm/fw/fw.h> |
089a49b6 | 15 | |
9b731009 | 16 | #include <asm/mips-boards/generic.h> |
3070033a | 17 | |
3070033a SH |
18 | const char *get_system_type(void) |
19 | { | |
20 | return "MIPS SEAD3"; | |
21 | } | |
22 | ||
44327236 QY |
23 | static uint32_t get_memsize_from_cmdline(void) |
24 | { | |
25 | int memsize = 0; | |
26 | char *p = arcs_cmdline; | |
27 | char *s = "memsize="; | |
28 | ||
29 | p = strstr(p, s); | |
30 | if (p) { | |
31 | p += strlen(s); | |
32 | memsize = memparse(p, NULL); | |
33 | } | |
34 | ||
35 | return memsize; | |
36 | } | |
37 | ||
38 | static uint32_t get_memsize_from_env(void) | |
39 | { | |
40 | int memsize = 0; | |
41 | char *p; | |
42 | ||
43 | p = fw_getenv("memsize"); | |
44 | if (p) | |
45 | memsize = memparse(p, NULL); | |
46 | ||
47 | return memsize; | |
48 | } | |
49 | ||
50 | static uint32_t get_memsize(void) | |
51 | { | |
52 | uint32_t memsize; | |
53 | ||
54 | memsize = get_memsize_from_cmdline(); | |
55 | if (memsize) | |
56 | return memsize; | |
57 | ||
58 | return get_memsize_from_env(); | |
59 | } | |
60 | ||
61 | static void __init parse_memsize_param(void) | |
62 | { | |
63 | int offset; | |
64 | const uint64_t *prop_value; | |
65 | int prop_len; | |
66 | uint32_t memsize = get_memsize(); | |
67 | ||
68 | if (!memsize) | |
69 | return; | |
70 | ||
0cdde839 | 71 | offset = fdt_path_offset(__dtb_start, "/memory"); |
44327236 QY |
72 | if (offset > 0) { |
73 | uint64_t new_value; | |
74 | /* | |
75 | * reg contains 2 32-bits BE values, offset and size. We just | |
76 | * want to replace the size value without affecting the offset | |
77 | */ | |
0cdde839 | 78 | prop_value = fdt_getprop(__dtb_start, offset, "reg", &prop_len); |
44327236 QY |
79 | new_value = be64_to_cpu(*prop_value); |
80 | new_value = (new_value & ~0xffffffffllu) | memsize; | |
0cdde839 | 81 | fdt_setprop_inplace_u64(__dtb_start, offset, "reg", new_value); |
44327236 QY |
82 | } |
83 | } | |
84 | ||
5e7c1c91 MR |
85 | void __init *plat_get_fdt(void) |
86 | { | |
87 | return (void *)__dtb_start; | |
88 | } | |
89 | ||
3070033a SH |
90 | void __init plat_mem_setup(void) |
91 | { | |
44327236 QY |
92 | /* allow command line/bootloader env to override memory size in DT */ |
93 | parse_memsize_param(); | |
94 | ||
9b731009 SH |
95 | /* |
96 | * Load the builtin devicetree. This causes the chosen node to be | |
97 | * parsed resulting in our memory appearing | |
98 | */ | |
0cdde839 | 99 | __dt_setup_arch(__dtb_start); |
9b731009 SH |
100 | } |
101 | ||
102 | void __init device_tree_init(void) | |
103 | { | |
9b731009 SH |
104 | if (!initial_boot_params) |
105 | return; | |
106 | ||
7e8a2762 | 107 | unflatten_and_copy_device_tree(); |
3070033a | 108 | } |