/*
 * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
 * reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the NetLogic
 * license below:
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <linux/kernel.h>
#include <linux/of_fdt.h>
#include <linux/memblock.h>

#include <asm/idle.h>
#include <asm/reboot.h>
#include <asm/time.h>
#include <asm/bootinfo.h>

#include <asm/netlogic/haldefs.h>
#include <asm/netlogic/common.h>

#include <asm/netlogic/xlp-hal/iomap.h>
#include <asm/netlogic/xlp-hal/xlp.h>
#include <asm/netlogic/xlp-hal/sys.h>

uint64_t nlm_io_base;
struct nlm_soc_info nlm_nodes[NLM_NR_NODES];
cpumask_t nlm_cpumask = CPU_MASK_CPU0;
unsigned int nlm_threads_per_core;

static void nlm_linux_exit(void)
{
	uint64_t sysbase = nlm_get_node(0)->sysbase;

	if (cpu_is_xlp9xx())
		nlm_write_sys_reg(sysbase, SYS_9XX_CHIP_RESET, 1);
	else
		nlm_write_sys_reg(sysbase, SYS_CHIP_RESET, 1);
	for ( ; ; )
		cpu_wait();
}

static void nlm_fixup_mem(void)
{
	const int pref_backup = 512;
	struct memblock_region *mem;

	for_each_mem_region(mem) {
		memblock_remove(mem->base + mem->size - pref_backup,
			pref_backup);
	}
}

static void __init xlp_init_mem_from_bars(void)
{
	uint64_t map[16];
	int i, n;

	n = nlm_get_dram_map(-1, map, ARRAY_SIZE(map));	/* -1 : all nodes */
	for (i = 0; i < n; i += 2) {
		/* exclude 0x1000_0000-0x2000_0000, u-boot device */
		if (map[i] <= 0x10000000 && map[i+1] > 0x10000000)
			map[i+1] = 0x10000000;
		if (map[i] > 0x10000000 && map[i] < 0x20000000)
			map[i] = 0x20000000;

		memblock_add(map[i], map[i+1] - map[i]);
	}
}

void __init plat_mem_setup(void)
{
#ifdef CONFIG_SMP
	nlm_wakeup_secondary_cpus();

	/* update TLB size after waking up threads */
	current_cpu_data.tlbsize = ((read_c0_config6() >> 16) & 0xffff) + 1;

	register_smp_ops(&nlm_smp_ops);
#endif
	_machine_restart = (void (*)(char *))nlm_linux_exit;
	_machine_halt	= nlm_linux_exit;
	pm_power_off	= nlm_linux_exit;

	/* memory and bootargs from DT */
	xlp_early_init_devtree();

	if (memblock_end_of_DRAM() == 0) {
		pr_info("Using DRAM BARs for memory map.\n");
		xlp_init_mem_from_bars();
	}
	/* Calculate and setup wired entries for mapped kernel */
	nlm_fixup_mem();
}

const char *get_system_type(void)
{
	switch (read_c0_prid() & PRID_IMP_MASK) {
	case PRID_IMP_NETLOGIC_XLP9XX:
	case PRID_IMP_NETLOGIC_XLP5XX:
	case PRID_IMP_NETLOGIC_XLP2XX:
		return "Broadcom XLPII Series";
	default:
		return "Netlogic XLP Series";
	}
}

void xlp_mmu_init(void)
{
	u32 conf4;

	if (cpu_is_xlpii()) {
		/* XLPII series has extended pagesize in config 4 */
		conf4 = read_c0_config4() & ~0x1f00u;
		write_c0_config4(conf4 | ((PAGE_SHIFT - 10) / 2 << 8));
	} else {
		/* enable extended TLB and Large Fixed TLB */
		write_c0_config6(read_c0_config6() | 0x24);

		/* set page mask of extended Fixed TLB in config7 */
		write_c0_config7(PM_DEFAULT_MASK >>
			(13 + (ffz(PM_DEFAULT_MASK >> 13) / 2)));
	}
}

void nlm_percpu_init(int hwcpuid)
{
}

void __init prom_init(void)
{
	void *reset_vec;

	nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE);
	nlm_init_boot_cpu();
	xlp_mmu_init();
	nlm_node_init(0);
	xlp_dt_init((void *)(long)fw_arg0);

	/* Update reset entry point with CPU init code */
	reset_vec = (void *)CKSEG1ADDR(RESET_VEC_PHYS);
	memset(reset_vec, 0, RESET_VEC_SIZE);
	memcpy(reset_vec, (void *)nlm_reset_entry,
			(nlm_reset_entry_end - nlm_reset_entry));

#ifdef CONFIG_SMP
	cpumask_setall(&nlm_cpumask);
#endif
}
