/*
 *  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.h>
#include <linux/of_fdt.h>
#include <linux/vexpress.h>

#include <asm/mcpm.h>
#include <asm/smp_scu.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);
}

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
};

bool __init vexpress_smp_init_ops(void)
{
#ifdef CONFIG_MCPM
	/*
	 * The best way to detect a multi-cluster configuration at the moment
	 * is to look for the presence of a CCI in the system.
	 * Override the default vexpress_smp_ops if so.
	 */
	struct device_node *node;
	node = of_find_compatible_node(NULL, NULL, "arm,cci-400");
	if (node && of_device_is_available(node)) {
		mcpm_smp_set_ops();
		return true;
	}
#endif
	return false;
}
