Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes...
[sfrench/cifs-2.6.git] / arch / mips / powertv / memory.c
1 /*
2  * Carsten Langgaard, carstenl@mips.com
3  * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
4  * Portions copyright (C) 2009 Cisco Systems, Inc.
5  *
6  *  This program is free software; you can distribute it and/or modify it
7  *  under the terms of the GNU General Public License (Version 2) as
8  *  published by the Free Software Foundation.
9  *
10  *  This program is distributed in the hope it will be useful, but WITHOUT
11  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  *  for more details.
14  *
15  *  You should have received a copy of the GNU General Public License along
16  *  with this program; if not, write to the Free Software Foundation, Inc.,
17  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
18  *
19  * Apparently originally from arch/mips/malta-memory.c. Modified to work
20  * with the PowerTV bootloader.
21  */
22 #include <linux/init.h>
23 #include <linux/mm.h>
24 #include <linux/bootmem.h>
25 #include <linux/pfn.h>
26 #include <linux/string.h>
27
28 #include <asm/bootinfo.h>
29 #include <asm/page.h>
30 #include <asm/sections.h>
31
32 #include <asm/mips-boards/prom.h>
33
34 #include "init.h"
35
36 /* Memory constants */
37 #define KIBIBYTE(n)             ((n) * 1024)    /* Number of kibibytes */
38 #define MEBIBYTE(n)             ((n) * KIBIBYTE(1024)) /* Number of mebibytes */
39 #define DEFAULT_MEMSIZE         MEBIBYTE(256)   /* If no memsize provided */
40 #define LOW_MEM_MAX             MEBIBYTE(252)   /* Max usable low mem */
41 #define RES_BOOTLDR_MEMSIZE     MEBIBYTE(1)     /* Memory reserved for bldr */
42 #define BOOT_MEM_SIZE           KIBIBYTE(256)   /* Memory reserved for bldr */
43 #define PHYS_MEM_START          0x10000000      /* Start of physical memory */
44
45 unsigned long ptv_memsize;
46
47 char __initdata cmdline[COMMAND_LINE_SIZE];
48
49 void __init prom_meminit(void)
50 {
51         char *memsize_str;
52         unsigned long memsize = 0;
53         unsigned int physend;
54         char *ptr;
55         int low_mem;
56         int high_mem;
57
58         /* Check the command line first for a memsize directive */
59         strcpy(cmdline, arcs_cmdline);
60         ptr = strstr(cmdline, "memsize=");
61         if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' '))
62                 ptr = strstr(ptr, " memsize=");
63
64         if (ptr) {
65                 memsize = memparse(ptr + 8, &ptr);
66         } else {
67                 /* otherwise look in the environment */
68                 memsize_str = prom_getenv("memsize");
69
70                 if (memsize_str != NULL) {
71                         pr_info("prom memsize = %s\n", memsize_str);
72                         memsize = simple_strtol(memsize_str, NULL, 0);
73                 }
74
75                 if (memsize == 0) {
76                         if (_prom_memsize != 0) {
77                                 memsize = _prom_memsize;
78                                 pr_info("_prom_memsize = 0x%lx\n", memsize);
79                                 /* add in memory that the bootloader doesn't
80                                  * report */
81                                 memsize += BOOT_MEM_SIZE;
82                         } else {
83                                 memsize = DEFAULT_MEMSIZE;
84                                 pr_info("Memsize not passed by bootloader, "
85                                         "defaulting to 0x%lx\n", memsize);
86                         }
87                 }
88         }
89
90         /* Store memsize for diagnostic purposes */
91         ptv_memsize = memsize;
92
93         physend = PFN_ALIGN(&_end) - 0x80000000;
94         if (memsize > LOW_MEM_MAX) {
95                 low_mem = LOW_MEM_MAX;
96                 high_mem = memsize - low_mem;
97         } else {
98                 low_mem = memsize;
99                 high_mem = 0;
100         }
101
102 /*
103  * TODO: We will use the hard code for memory configuration until
104  * the bootloader releases their device tree to us.
105  */
106         /*
107          * Add the memory reserved for use by the bootloader to the
108          * memory map.
109          */
110         add_memory_region(PHYS_MEM_START, RES_BOOTLDR_MEMSIZE,
111                 BOOT_MEM_RESERVED);
112 #ifdef CONFIG_HIGHMEM_256_128
113         /*
114          * Add memory in low for general use by the kernel and its friends
115          * (like drivers, applications, etc).
116          */
117         add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE,
118                 LOW_MEM_MAX - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM);
119         /*
120          * Add the memory reserved for reset vector.
121          */
122         add_memory_region(0x1fc00000, MEBIBYTE(4), BOOT_MEM_RESERVED);
123         /*
124          * Add the memory reserved.
125          */
126         add_memory_region(0x20000000, MEBIBYTE(1024 + 75), BOOT_MEM_RESERVED);
127         /*
128          * Add memory in high for general use by the kernel and its friends
129          * (like drivers, applications, etc).
130          *
131          * 75MB is reserved for devices which are using the memory in high.
132          */
133         add_memory_region(0x60000000 + MEBIBYTE(75), MEBIBYTE(128 - 75),
134                 BOOT_MEM_RAM);
135 #elif defined CONFIG_HIGHMEM_128_128
136         /*
137          * Add memory in low for general use by the kernel and its friends
138          * (like drivers, applications, etc).
139          */
140         add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE,
141                 MEBIBYTE(128) - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM);
142         /*
143          * Add the memory reserved.
144          */
145         add_memory_region(PHYS_MEM_START + MEBIBYTE(128),
146                 MEBIBYTE(128 + 1024 + 75), BOOT_MEM_RESERVED);
147         /*
148          * Add memory in high for general use by the kernel and its friends
149          * (like drivers, applications, etc).
150          *
151          * 75MB is reserved for devices which are using the memory in high.
152          */
153         add_memory_region(0x60000000 + MEBIBYTE(75), MEBIBYTE(128 - 75),
154                 BOOT_MEM_RAM);
155 #else
156         /* Add low memory regions for either:
157          *   - no-highmemory configuration case -OR-
158          *   - highmemory "HIGHMEM_LOWBANK_ONLY" case
159          */
160         /*
161          * Add memory for general use by the kernel and its friends
162          * (like drivers, applications, etc).
163          */
164         add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE,
165                 low_mem - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM);
166         /*
167          * Add the memory reserved for reset vector.
168          */
169         add_memory_region(0x1fc00000, MEBIBYTE(4), BOOT_MEM_RESERVED);
170 #endif
171 }
172
173 void __init prom_free_prom_memory(void)
174 {
175         unsigned long addr;
176         int i;
177
178         for (i = 0; i < boot_mem_map.nr_map; i++) {
179                 if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
180                         continue;
181
182                 addr = boot_mem_map.map[i].addr;
183                 free_init_pages("prom memory",
184                                 addr, addr + boot_mem_map.map[i].size);
185         }
186 }