/* arch/arm/mach-msm/memory.c
 *
 * Copyright (C) 2007 Google, Inc.
 * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#include <linux/mm.h>
#include <linux/mm_types.h>
#include <linux/bootmem.h>
#include <linux/module.h>
#include <linux/memory_alloc.h>
#include <linux/memblock.h>
#include <asm/pgtable.h>
#include <asm/io.h>
#include <asm/mach/map.h>
#include <asm/cacheflush.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
#include <mach/msm_memtypes.h>
#include <mach/memory.h>
#include <linux/hardirq.h>
#if defined(CONFIG_MSM_NPA_REMOTE)
#include "npa_remote.h"
#include <linux/completion.h>
#include <linux/err.h>
#endif
#include <linux/android_pmem.h>
#include <mach/msm_iomap.h>
#include <mach/socinfo.h>
#include <linux/sched.h>
#include <linux/of_fdt.h>

/* fixme */
#include <asm/tlbflush.h>
#include <../../mm/mm.h>
#include <linux/fmem.h>

#if defined(CONFIG_ARCH_MSM7X27)
static void *strongly_ordered_page;
static char strongly_ordered_mem[PAGE_SIZE*2-4];

void __init map_page_strongly_ordered(void)
{
	long unsigned int phys;
	struct map_desc map[1];

	if (strongly_ordered_page)
		return;

	strongly_ordered_page = (void*)PFN_ALIGN((int)&strongly_ordered_mem);
	phys = __pa(strongly_ordered_page);

	map[0].pfn = __phys_to_pfn(phys);
	map[0].virtual = MSM_STRONGLY_ORDERED_PAGE;
	map[0].length = PAGE_SIZE;
	map[0].type = MT_MEMORY_SO;
	iotable_init(map, ARRAY_SIZE(map));

	printk(KERN_ALERT "Initialized strongly ordered page successfully\n");
}
#else
void map_page_strongly_ordered(void) { }
#endif

#if defined(CONFIG_ARCH_MSM7X27)
void write_to_strongly_ordered_memory(void)
{
	*(int *)MSM_STRONGLY_ORDERED_PAGE = 0;
}
#else
void write_to_strongly_ordered_memory(void) { }
#endif
EXPORT_SYMBOL(write_to_strongly_ordered_memory);

/* These cache related routines make the assumption (if outer cache is
 * available) that the associated physical memory is contiguous.
 * They will operate on all (L1 and L2 if present) caches.
 */
void clean_and_invalidate_caches(unsigned long vstart,
	unsigned long length, unsigned long pstart)
{
	dmac_flush_range((void *)vstart, (void *) (vstart + length));
	outer_flush_range(pstart, pstart + length);
}

void clean_caches(unsigned long vstart,
	unsigned long length, unsigned long pstart)
{
	dmac_clean_range((void *)vstart, (void *) (vstart + length));
	outer_clean_range(pstart, pstart + length);
}

void invalidate_caches(unsigned long vstart,
	unsigned long length, unsigned long pstart)
{
	dmac_inv_range((void *)vstart, (void *) (vstart + length));
	outer_inv_range(pstart, pstart + length);
}

void * __init alloc_bootmem_aligned(unsigned long size, unsigned long alignment)
{
	void *unused_addr = NULL;
	unsigned long addr, tmp_size, unused_size;

	/* Allocate maximum size needed, see where it ends up.
	 * Then free it -- in this path there are no other allocators
	 * so we can depend on getting the same address back
	 * when we allocate a smaller piece that is aligned
	 * at the end (if necessary) and the piece we really want,
	 * then free the unused first piece.
	 */

	tmp_size = size + alignment - PAGE_SIZE;
	addr = (unsigned long)alloc_bootmem(tmp_size);
	free_bootmem(__pa(addr), tmp_size);

	unused_size = alignment - (addr % alignment);
	if (unused_size)
		unused_addr = alloc_bootmem(unused_size);

	addr = (unsigned long)alloc_bootmem(size);
	if (unused_size)
		free_bootmem(__pa(unused_addr), unused_size);

	return (void *)addr;
}

int (*change_memory_power)(u64, u64, int);

int platform_physical_remove_pages(u64 start, u64 size)
{
	if (!change_memory_power)
		return 0;
	return change_memory_power(start, size, MEMORY_DEEP_POWERDOWN);
}

int platform_physical_active_pages(u64 start, u64 size)
{
	if (!change_memory_power)
		return 0;
	return change_memory_power(start, size, MEMORY_ACTIVE);
}

int platform_physical_low_power_pages(u64 start, u64 size)
{
	if (!change_memory_power)
		return 0;
	return change_memory_power(start, size, MEMORY_SELF_REFRESH);
}

char *memtype_name[] = {
	"SMI_KERNEL",
	"SMI",
	"EBI0",
	"EBI1"
};

struct reserve_info *reserve_info;

/**
 * calculate_reserve_limits() - calculate reserve limits for all
 * memtypes
 *
 * for each memtype in the reserve_info->memtype_reserve_table, sets
 * the `limit' field to the largest size of any memblock of that
 * memtype.
 */
static void __init calculate_reserve_limits(void)
{
	struct memblock_region *mr;
	int memtype;
	struct memtype_reserve *mt;

	for_each_memblock(memory, mr) {
		memtype = reserve_info->paddr_to_memtype(mr->base);
		if (memtype == MEMTYPE_NONE) {
			pr_warning("unknown memory type for region at %lx\n",
				(long unsigned int)mr->base);
			continue;
		}
		mt = &reserve_info->memtype_reserve_table[memtype];
		mt->limit = max_t(unsigned long, mt->limit, mr->size);
	}
}

static void __init adjust_reserve_sizes(void)
{
	int i;
	struct memtype_reserve *mt;

	mt = &reserve_info->memtype_reserve_table[0];
	for (i = 0; i < MEMTYPE_MAX; i++, mt++) {
		if (mt->flags & MEMTYPE_FLAGS_1M_ALIGN)
			mt->size = (mt->size + SECTION_SIZE - 1) & SECTION_MASK;
		if (mt->size > mt->limit) {
			pr_warning("%lx size for %s too large, setting to %lx\n",
				mt->size, memtype_name[i], mt->limit);
			mt->size = mt->limit;
		}
	}
}

static void __init reserve_memory_for_mempools(void)
{
	int memtype, memreg_type;
	struct memtype_reserve *mt;
	struct memblock_region *mr, *mr_candidate = NULL;
	int ret;

	mt = &reserve_info->memtype_reserve_table[0];
	for (memtype = 0; memtype < MEMTYPE_MAX; memtype++, mt++) {
		if (mt->flags & MEMTYPE_FLAGS_FIXED || !mt->size)
			continue;

		/* Choose the memory block with the highest physical
		 * address which is large enough, so that we will not
		 * take memory from the lowest memory bank which the kernel
		 * is in (and cause boot problems) and so that we might
		 * be able to steal memory that would otherwise become
		 * highmem.
		 */
		for_each_memblock(memory, mr) {
			memreg_type =
				reserve_info->paddr_to_memtype(mr->base);
			if (memtype != memreg_type)
				continue;
			if (mr->size >= mt->size
				&& (mr_candidate == NULL
					|| mr->base > mr_candidate->base))
				mr_candidate = mr;
		}
		BUG_ON(mr_candidate == NULL);
		/* bump mt up against the top of the region */
		mt->start = mr_candidate->base + mr_candidate->size - mt->size;
		ret = memblock_remove(mt->start, mt->size);
		BUG_ON(ret);
	}
}

static void __init initialize_mempools(void)
{
	struct mem_pool *mpool;
	int memtype;
	struct memtype_reserve *mt;

	mt = &reserve_info->memtype_reserve_table[0];
	for (memtype = 0; memtype < MEMTYPE_MAX; memtype++, mt++) {
		if (!mt->size)
			continue;
		mpool = initialize_memory_pool(mt->start, mt->size, memtype);
		if (!mpool)
			pr_warning("failed to create %s mempool\n",
				memtype_name[memtype]);
	}
}

#define  MAX_FIXED_AREA_SIZE 0x11000000

void __init msm_reserve(void)
{
	unsigned long msm_fixed_area_size;
	unsigned long msm_fixed_area_start;

	memory_pool_init();
	if (reserve_info->calculate_reserve_sizes)
		reserve_info->calculate_reserve_sizes();

	msm_fixed_area_size = reserve_info->fixed_area_size;
	msm_fixed_area_start = reserve_info->fixed_area_start;
	if (msm_fixed_area_size)
		if (msm_fixed_area_start > reserve_info->low_unstable_address
			- MAX_FIXED_AREA_SIZE)
			reserve_info->low_unstable_address =
			msm_fixed_area_start;

	calculate_reserve_limits();
	adjust_reserve_sizes();
	reserve_memory_for_mempools();
	initialize_mempools();
}

static int get_ebi_memtype(void)
{
	/* on 7x30 and 8x55 "EBI1 kernel PMEM" is really on EBI0 */
	if (cpu_is_msm7x30() || cpu_is_msm8x55())
		return MEMTYPE_EBI0;
	return MEMTYPE_EBI1;
}

void *allocate_contiguous_ebi(unsigned long size,
	unsigned long align, int cached)
{
	return allocate_contiguous_memory(size, get_ebi_memtype(),
		align, cached);
}
EXPORT_SYMBOL(allocate_contiguous_ebi);

unsigned long allocate_contiguous_ebi_nomap(unsigned long size,
	unsigned long align)
{
	return _allocate_contiguous_memory_nomap(size, get_ebi_memtype(),
		align, __builtin_return_address(0));
}
EXPORT_SYMBOL(allocate_contiguous_ebi_nomap);

unsigned int msm_ttbr0;

void store_ttbr0(void)
{
	/* Store TTBR0 for post-mortem debugging purposes. */
	asm("mrc p15, 0, %0, c2, c0, 0\n"
		: "=r" (msm_ttbr0));
}

int request_fmem_c_region(void *unused)
{
	return fmem_set_state(FMEM_C_STATE);
}

int release_fmem_c_region(void *unused)
{
	return fmem_set_state(FMEM_T_STATE);
}

static char * const memtype_names[] = {
	[MEMTYPE_SMI_KERNEL] = "SMI_KERNEL",
	[MEMTYPE_SMI]	= "SMI",
	[MEMTYPE_EBI0] = "EBI0",
	[MEMTYPE_EBI1] = "EBI1",
};

int msm_get_memory_type_from_name(const char *memtype_name)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(memtype_names); i++) {
		if (memtype_names[i] &&
		    strcmp(memtype_name, memtype_names[i]) == 0)
			return i;
	}

	pr_err("Could not find memory type %s\n", memtype_name);
	return -EINVAL;
}

static int reserve_memory_type(const char *mem_name,
				struct memtype_reserve *reserve_table,
				int size)
{
	int ret = msm_get_memory_type_from_name(mem_name);

	if (ret >= 0) {
		reserve_table[ret].size += size;
		ret = 0;
	}
	return ret;
}

static int __init check_for_compat(unsigned long node)
{
	char **start = __compat_exports_start;

	for ( ; start < __compat_exports_end; start++)
		if (of_flat_dt_is_compatible(node, *start))
			return 1;

	return 0;
}

int __init dt_scan_for_memory_reserve(unsigned long node, const char *uname,
		int depth, void *data)
{
	char *memory_name_prop;
	unsigned int *memory_remove_prop;
	unsigned long memory_name_prop_length;
	unsigned long memory_remove_prop_length;
	unsigned long memory_size_prop_length;
	unsigned int *memory_size_prop;
	unsigned int memory_size;
	unsigned int memory_start;
	int ret;

	memory_name_prop = of_get_flat_dt_prop(node,
						"qcom,memory-reservation-type",
						&memory_name_prop_length);
	memory_remove_prop = of_get_flat_dt_prop(node,
						"qcom,memblock-remove",
						&memory_remove_prop_length);

	if (memory_name_prop || memory_remove_prop) {
		if (!check_for_compat(node))
			goto out;
	} else {
		goto out;
	}

	if (memory_name_prop) {
		if (strnlen(memory_name_prop, memory_name_prop_length) == 0) {
			WARN(1, "Memory name was malformed\n");
			goto mem_remove;
		}

		memory_size_prop = of_get_flat_dt_prop(node,
						"qcom,memory-reservation-size",
						&memory_size_prop_length);

		if (memory_size_prop &&
		    (memory_size_prop_length == sizeof(unsigned int))) {
			memory_size = be32_to_cpu(*memory_size_prop);

			if (reserve_memory_type(memory_name_prop,
						data, memory_size) == 0)
				pr_info("%s reserved %s size %x\n",
					uname, memory_name_prop, memory_size);
			else
				WARN(1, "Node %s reserve failed\n",
						uname);
		} else {
			WARN(1, "Node %s specified bad/nonexistent size\n",
					uname);
		}
	}

mem_remove:

	if (memory_remove_prop) {
		if (memory_remove_prop_length != (2*sizeof(unsigned int))) {
			WARN(1, "Memory remove malformed\n");
			goto out;
		}

		memory_start = be32_to_cpu(memory_remove_prop[0]);
		memory_size = be32_to_cpu(memory_remove_prop[1]);

		ret = memblock_remove(memory_start, memory_size);
		if (ret)
			WARN(1, "Failed to remove memory %x-%x\n",
				memory_start, memory_start+memory_size);
		else
			pr_info("Node %s removed memory %x-%x\n", uname,
				memory_start, memory_start+memory_size);
	}

out:
	return 0;
}

/* This function scans the device tree to populate the memory hole table */
int __init dt_scan_for_memory_hole(unsigned long node, const char *uname,
		int depth, void *data)
{
	unsigned int *memory_remove_prop;
	unsigned long memory_remove_prop_length;
	unsigned long hole_start;
	unsigned long hole_size;

	memory_remove_prop = of_get_flat_dt_prop(node,
						"qcom,memblock-remove",
						&memory_remove_prop_length);

	if (memory_remove_prop) {
		if (!check_for_compat(node))
			goto out;
	} else {
		goto out;
	}

	if (memory_remove_prop) {
		if (memory_remove_prop_length != (2*sizeof(unsigned int))) {
			WARN(1, "Memory remove malformed\n");
			goto out;
		}

		hole_start = be32_to_cpu(memory_remove_prop[0]);
		hole_size = be32_to_cpu(memory_remove_prop[1]);

		if (hole_start + hole_size <= MAX_HOLE_ADDRESS) {
			if (memory_hole_start == 0 && memory_hole_end == 0) {
				memory_hole_start = hole_start;
				memory_hole_end = hole_start + hole_size;
			} else if ((memory_hole_end - memory_hole_start)
							<= hole_size) {
				memory_hole_start = hole_start;
				memory_hole_end = hole_start + hole_size;
			}
		}
		adjust_meminfo(hole_start, hole_size);
	}

out:
	return 0;
}

/*
 * Split the memory bank to reflect the hole, if present,
 * using the start and end of the memory hole.
 */
void adjust_meminfo(unsigned long start, unsigned long size)
{
	int i, j;

	for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
		struct membank *bank = &meminfo.bank[j];
		*bank = meminfo.bank[i];

		if (((start + size) <= (bank->start + bank->size)) &&
			(start >= bank->start)) {
			memmove(bank + 1, bank,
				(meminfo.nr_banks - i) * sizeof(*bank));
			meminfo.nr_banks++;
			i++;
			bank[1].size -= (start + size);
			bank[1].start = (start + size);
			bank[1].highmem = 0;
			j++;
			bank->size = start - bank->start;
		}
		j++;
	}
}
unsigned long get_ddr_size(void)
{
	unsigned int i;
	unsigned long ret = 0;

	for (i = 0; i < meminfo.nr_banks; i++)
		ret += meminfo.bank[i].size;

	return ret;
}

/* Provide a string that anonymous device tree allocations (those not
 * directly associated with any driver) can use for their "compatible"
 * field */
EXPORT_COMPAT("qcom,msm-contig-mem");
