/*
 *  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 <asm/smp_scu.h>
#include <asm/hardware/gic.h>
#include <asm/mach/map.h>

#include <mach/motherboard.h>

#include "core.h"

extern void versatile_secondary_startup(void);

#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.
 */
void __init smp_init_cpus(void)
{
	if (ct_desc)
		ct_desc->init_cpu_map();
	else
		vexpress_dt_smp_init_cpus();

}

void __init platform_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.
	 */
	v2m_flags_set(virt_to_phys(versatile_secondary_startup));
}
