/*1* Carsten Langgaard, [email protected]2* Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.3* Portions copyright (C) 2009 Cisco Systems, Inc.4*5* This program is free software; you can distribute it and/or modify it6* under the terms of the GNU General Public License (Version 2) as7* published by the Free Software Foundation.8*9* This program is distributed in the hope it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* for more details.13*14* You should have received a copy of the GNU General Public License along15* with this program; if not, write to the Free Software Foundation, Inc.,16* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.17*18* Apparently originally from arch/mips/malta-memory.c. Modified to work19* with the PowerTV bootloader.20*/21#include <linux/init.h>22#include <linux/mm.h>23#include <linux/bootmem.h>24#include <linux/pfn.h>25#include <linux/string.h>2627#include <asm/bootinfo.h>28#include <asm/page.h>29#include <asm/sections.h>3031#include <asm/mips-boards/prom.h>32#include <asm/mach-powertv/asic.h>33#include <asm/mach-powertv/ioremap.h>3435#include "init.h"3637/* Memory constants */38#define KIBIBYTE(n) ((n) * 1024) /* Number of kibibytes */39#define MEBIBYTE(n) ((n) * KIBIBYTE(1024)) /* Number of mebibytes */40#define DEFAULT_MEMSIZE MEBIBYTE(128) /* If no memsize provided */4142#define BLDR_SIZE KIBIBYTE(256) /* Memory reserved for bldr */43#define RV_SIZE MEBIBYTE(4) /* Size of reset vector */4445#define LOW_MEM_END 0x20000000 /* Highest low memory address */46#define BLDR_ALIAS 0x10000000 /* Bootloader address */47#define RV_PHYS 0x1fc00000 /* Reset vector address */48#define LOW_RAM_END RV_PHYS /* End of real RAM in low mem */4950/*51* Very low-level conversion from processor physical address to device52* DMA address for the first bank of memory.53*/54#define PHYS_TO_DMA(paddr) ((paddr) + (CONFIG_LOW_RAM_DMA - LOW_RAM_ALIAS))5556unsigned long ptv_memsize;5758/*59* struct low_mem_reserved - Items in low memory that are reserved60* @start: Physical address of item61* @size: Size, in bytes, of this item62* @is_aliased: True if this is RAM aliased from another location. If false,63* it is something other than aliased RAM and the RAM in the64* unaliased address is still visible outside of low memory.65*/66struct low_mem_reserved {67phys_addr_t start;68phys_addr_t size;69bool is_aliased;70};7172/*73* Must be in ascending address order74*/75struct low_mem_reserved low_mem_reserved[] = {76{BLDR_ALIAS, BLDR_SIZE, true}, /* Bootloader RAM */77{RV_PHYS, RV_SIZE, false}, /* Reset vector */78};7980/*81* struct mem_layout - layout of a piece of the system RAM82* @phys: Physical address of the start of this piece of RAM. This is the83* address at which both the processor and I/O devices see the84* RAM.85* @alias: Alias of this piece of memory in order to make it appear in86* the low memory part of the processor's address space. I/O87* devices don't see anything here.88* @size: Size, in bytes, of this piece of RAM89*/90struct mem_layout {91phys_addr_t phys;92phys_addr_t alias;93phys_addr_t size;94};9596/*97* struct mem_layout_list - list descriptor for layouts of system RAM pieces98* @family: Specifies the family being described99* @n: Number of &struct mem_layout elements100* @layout: Pointer to the list of &mem_layout structures101*/102struct mem_layout_list {103enum family_type family;104size_t n;105struct mem_layout *layout;106};107108static struct mem_layout f1500_layout[] = {109{0x20000000, 0x10000000, MEBIBYTE(256)},110};111112static struct mem_layout f4500_layout[] = {113{0x40000000, 0x10000000, MEBIBYTE(256)},114{0x20000000, 0x20000000, MEBIBYTE(32)},115};116117static struct mem_layout f8500_layout[] = {118{0x40000000, 0x10000000, MEBIBYTE(256)},119{0x20000000, 0x20000000, MEBIBYTE(32)},120{0x30000000, 0x30000000, MEBIBYTE(32)},121};122123static struct mem_layout fx600_layout[] = {124{0x20000000, 0x10000000, MEBIBYTE(256)},125{0x60000000, 0x60000000, MEBIBYTE(128)},126};127128static struct mem_layout_list layout_list[] = {129{FAMILY_1500, ARRAY_SIZE(f1500_layout), f1500_layout},130{FAMILY_1500VZE, ARRAY_SIZE(f1500_layout), f1500_layout},131{FAMILY_1500VZF, ARRAY_SIZE(f1500_layout), f1500_layout},132{FAMILY_4500, ARRAY_SIZE(f4500_layout), f4500_layout},133{FAMILY_8500, ARRAY_SIZE(f8500_layout), f8500_layout},134{FAMILY_8500RNG, ARRAY_SIZE(f8500_layout), f8500_layout},135{FAMILY_4600, ARRAY_SIZE(fx600_layout), fx600_layout},136{FAMILY_4600VZA, ARRAY_SIZE(fx600_layout), fx600_layout},137{FAMILY_8600, ARRAY_SIZE(fx600_layout), fx600_layout},138{FAMILY_8600VZB, ARRAY_SIZE(fx600_layout), fx600_layout},139};140141/* If we can't determine the layout, use this */142static struct mem_layout default_layout[] = {143{0x20000000, 0x10000000, MEBIBYTE(128)},144};145146/**147* register_non_ram - register low memory not available for RAM usage148*/149static __init void register_non_ram(void)150{151int i;152153for (i = 0; i < ARRAY_SIZE(low_mem_reserved); i++)154add_memory_region(low_mem_reserved[i].start,155low_mem_reserved[i].size, BOOT_MEM_RESERVED);156}157158/**159* get_memsize - get the size of memory as a single bank160*/161static phys_addr_t get_memsize(void)162{163static char cmdline[COMMAND_LINE_SIZE] __initdata;164phys_addr_t memsize = 0;165char *memsize_str;166char *ptr;167168/* Check the command line first for a memsize directive */169strcpy(cmdline, arcs_cmdline);170ptr = strstr(cmdline, "memsize=");171if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' '))172ptr = strstr(ptr, " memsize=");173174if (ptr) {175memsize = memparse(ptr + 8, &ptr);176} else {177/* otherwise look in the environment */178memsize_str = prom_getenv("memsize");179180if (memsize_str != NULL) {181pr_info("prom memsize = %s\n", memsize_str);182memsize = simple_strtol(memsize_str, NULL, 0);183}184185if (memsize == 0) {186if (_prom_memsize != 0) {187memsize = _prom_memsize;188pr_info("_prom_memsize = 0x%x\n", memsize);189/* add in memory that the bootloader doesn't190* report */191memsize += BLDR_SIZE;192} else {193memsize = DEFAULT_MEMSIZE;194pr_info("Memsize not passed by bootloader, "195"defaulting to 0x%x\n", memsize);196}197}198}199200return memsize;201}202203/**204* register_low_ram - register an aliased section of RAM205* @p: Alias address of memory206* @n: Number of bytes in this section of memory207*208* Returns the number of bytes registered209*210*/211static __init phys_addr_t register_low_ram(phys_addr_t p, phys_addr_t n)212{213phys_addr_t s;214int i;215phys_addr_t orig_n;216217orig_n = n;218219BUG_ON(p + n > RV_PHYS);220221for (i = 0; n != 0 && i < ARRAY_SIZE(low_mem_reserved); i++) {222phys_addr_t start;223phys_addr_t size;224225start = low_mem_reserved[i].start;226size = low_mem_reserved[i].size;227228/* Handle memory before this low memory section */229if (p < start) {230phys_addr_t s;231s = min(n, start - p);232add_memory_region(p, s, BOOT_MEM_RAM);233p += s;234n -= s;235}236237/* Handle the low memory section itself. If it's aliased,238* we reduce the number of byes left, but if not, the RAM239* is available elsewhere and we don't reduce the number of240* bytes remaining. */241if (p == start) {242if (low_mem_reserved[i].is_aliased) {243s = min(n, size);244n -= s;245p += s;246} else247p += n;248}249}250251return orig_n - n;252}253254/*255* register_ram - register real RAM256* @p: Address of memory as seen by devices257* @alias: If the memory is seen at an additional address by the processor,258* this will be the address, otherwise it is the same as @p.259* @n: Number of bytes in this section of memory260*/261static __init void register_ram(phys_addr_t p, phys_addr_t alias,262phys_addr_t n)263{264/*265* If some or all of this memory has an alias, break it into the266* aliased and non-aliased portion.267*/268if (p != alias) {269phys_addr_t alias_size;270phys_addr_t registered;271272alias_size = min(n, LOW_RAM_END - alias);273registered = register_low_ram(alias, alias_size);274ioremap_add_map(alias, p, n);275n -= registered;276p += registered;277}278279#ifdef CONFIG_HIGHMEM280if (n != 0) {281add_memory_region(p, n, BOOT_MEM_RAM);282ioremap_add_map(p, p, n);283}284#endif285}286287/**288* register_address_space - register things in the address space289* @memsize: Number of bytes of RAM installed290*291* Takes the given number of bytes of RAM and registers as many of the regions,292* or partial regions, as it can. So, the default configuration might have293* two regions with 256 MiB each. If the memsize passed in on the command line294* is 384 MiB, it will register the first region with 256 MiB and the second295* with 128 MiB.296*/297static __init void register_address_space(phys_addr_t memsize)298{299int i;300phys_addr_t size;301size_t n;302struct mem_layout *layout;303enum family_type family;304305/*306* Register all of the things that aren't available to the kernel as307* memory.308*/309register_non_ram();310311/* Find the appropriate memory description */312family = platform_get_family();313314for (i = 0; i < ARRAY_SIZE(layout_list); i++) {315if (layout_list[i].family == family)316break;317}318319if (i == ARRAY_SIZE(layout_list)) {320n = ARRAY_SIZE(default_layout);321layout = default_layout;322} else {323n = layout_list[i].n;324layout = layout_list[i].layout;325}326327for (i = 0; memsize != 0 && i < n; i++) {328size = min(memsize, layout[i].size);329register_ram(layout[i].phys, layout[i].alias, size);330memsize -= size;331}332}333334void __init prom_meminit(void)335{336ptv_memsize = get_memsize();337register_address_space(ptv_memsize);338}339340void __init prom_free_prom_memory(void)341{342unsigned long addr;343int i;344345for (i = 0; i < boot_mem_map.nr_map; i++) {346if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)347continue;348349addr = boot_mem_map.map[i].addr;350free_init_pages("prom memory",351addr, addr + boot_mem_map.map[i].size);352}353}354355356