/*
 *  linux/arch/arm/mach-vexpress/platsmp.c
 *
 *  Copyright (C) 2002 ARM Ltd.
 *  All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/smp.h>
#include <linux/io.h>
#include <linux/of_fdt.h>
#include <linux/vexpress.h>

#include <asm/smp_scu.h>
#include <asm/hardware/gic.h>
#include <asm/mach/map.h>

#include <mach/motherboard.h>

#include <plat/platsmp.h>

#include "core.h"

#if defined(CONFIG_OF)

static enum {
	GENERIC_SCU,
	CORTEX_A9_SCU,
} vexpress_dt_scu __initdata = GENERIC_SCU;

static struct map_desc vexpress_dt_cortex_a9_scu_map __initdata = {
	.virtual	= V2T_PERIPH,
	/* .pfn	set in vexpress_dt_init_cortex_a9_scu() */
	.length		= SZ_128,
	.type		= MT_DEVICE,
};

static void *vexpress_dt_cortex_a9_scu_base __initdata;

const static char *vexpress_dt_cortex_a9_match[] __initconst = {
	"arm,cortex-a5-scu",
	"arm,cortex-a9-scu",
	NULL
};

static int __init vexpress_dt_find_scu(unsigned long node,
		const char *uname, int depth, void *data)
{
	if (of_flat_dt_match(node, vexpress_dt_cortex_a9_match)) {
		phys_addr_t phys_addr;
		__be32 *reg = of_get_flat_dt_prop(node, "reg", NULL);

		if (WARN_ON(!reg))
			return -EINVAL;

		phys_addr = be32_to_cpup(reg);
		vexpress_dt_scu = CORTEX_A9_SCU;

		vexpress_dt_cortex_a9_scu_map.pfn = __phys_to_pfn(phys_addr);
		iotable_init(&vexpress_dt_cortex_a9_scu_map, 1);
		vexpress_dt_cortex_a9_scu_base = ioremap(phys_addr, SZ_256);
		if (WARN_ON(!vexpress_dt_cortex_a9_scu_base))
			return -EFAULT;
	}

	return 0;
}

void __init vexpress_dt_smp_map_io(void)
{
	if (initial_boot_params)
		WARN_ON(of_scan_flat_dt(vexpress_dt_find_scu, NULL));
}

static int __init vexpress_dt_cpus_num(unsigned long node, const char *uname,
		int depth, void *data)
{
	static int prev_depth = -1;
	static int nr_cpus = -1;

	if (prev_depth > depth && nr_cpus > 0)
		return nr_cpus;

	if (nr_cpus < 0 && strcmp(uname, "cpus") == 0)
		nr_cpus = 0;

	if (nr_cpus >= 0) {
		const char *device_type = of_get_flat_dt_prop(node,
				"device_type", NULL);

		if (device_type && strcmp(device_type, "cpu") == 0)
			nr_cpus++;
	}

	prev_depth = depth;

	return 0;
}

static void __init vexpress_dt_smp_init_cpus(void)
{
	int ncores = 0, i;

	switch (vexpress_dt_scu) {
	case GENERIC_SCU:
		ncores = of_scan_flat_dt(vexpress_dt_cpus_num, NULL);
		break;
	case CORTEX_A9_SCU:
		ncores = scu_get_core_count(vexpress_dt_cortex_a9_scu_base);
		break;
	default:
		WARN_ON(1);
		break;
	}

	if (ncores < 2)
		return;

	if (ncores > nr_cpu_ids) {
		pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
				ncores, nr_cpu_ids);
		ncores = nr_cpu_ids;
	}

	for (i = 0; i < ncores; ++i)
		set_cpu_possible(i, true);

	set_smp_cross_call(gic_raise_softirq);
}

static void __init vexpress_dt_smp_prepare_cpus(unsigned int max_cpus)
{
	int i;

	switch (vexpress_dt_scu) {
	case GENERIC_SCU:
		for (i = 0; i < max_cpus; i++)
			set_cpu_present(i, true);
		break;
	case CORTEX_A9_SCU:
		scu_enable(vexpress_dt_cortex_a9_scu_base);
		break;
	default:
		WARN_ON(1);
		break;
	}
}

#else

static void __init vexpress_dt_smp_init_cpus(void)
{
	WARN_ON(1);
}

void __init vexpress_dt_smp_prepare_cpus(unsigned int max_cpus)
{
	WARN_ON(1);
}

#endif

/*
 * Initialise the CPU possible map early - this describes the CPUs
 * which may be present or become present in the system.
 */
static void __init vexpress_smp_init_cpus(void)
{
	if (ct_desc)
		ct_desc->init_cpu_map();
	else
		vexpress_dt_smp_init_cpus();

}

static void __init vexpress_smp_prepare_cpus(unsigned int max_cpus)
{
	/*
	 * Initialise the present map, which describes the set of CPUs
	 * actually populated at the present time.
	 */
	if (ct_desc)
		ct_desc->smp_enable(max_cpus);
	else
		vexpress_dt_smp_prepare_cpus(max_cpus);

	/*
	 * Write the address of secondary startup into the
	 * system-wide flags register. The boot monitor waits
	 * until it receives a soft interrupt, and then the
	 * secondary CPU branches to this address.
	 */
	vexpress_flags_set(virt_to_phys(versatile_secondary_startup));
}

struct smp_operations __initdata vexpress_smp_ops = {
	.smp_init_cpus		= vexpress_smp_init_cpus,
	.smp_prepare_cpus	= vexpress_smp_prepare_cpus,
	.smp_secondary_init	= versatile_secondary_init,
	.smp_boot_secondary	= versatile_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
	.cpu_die		= vexpress_cpu_die,
#endif
};
