/**
 * Copyright (C) ARM Limited 2013-2014. 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.
 *
 */

#if GATOR_IKS_SUPPORT

#include <linux/of.h>
#include <asm/bL_switcher.h>
#include <asm/smp_plat.h>
#include <trace/events/power_cpu_migrate.h>

static bool map_cpuids;
static int mpidr_cpuids[NR_CPUS];
static const struct gator_cpu *mpidr_cpus[NR_CPUS];
static int __lcpu_to_pcpu[NR_CPUS];

static const struct gator_cpu *gator_find_cpu_by_dt_name(const char *const name)
{
	int i;

	for (i = 0; gator_cpus[i].cpuid != 0; ++i) {
		const struct gator_cpu *const gator_cpu = &gator_cpus[i];

		if (gator_cpu->dt_name != NULL && strcmp(gator_cpu->dt_name, name) == 0)
			return gator_cpu;
	}

	return NULL;
}

static void calc_first_cluster_size(void)
{
	int len;
	const u32 *val;
	const char *compatible;
	struct device_node *cn = NULL;
	int mpidr_cpuids_count = 0;

	/* Zero is a valid cpuid, so initialize the array to 0xff's */
	memset(&mpidr_cpuids, 0xff, sizeof(mpidr_cpuids));
	memset(&mpidr_cpus, 0, sizeof(mpidr_cpus));

	while ((cn = of_find_node_by_type(cn, "cpu"))) {
		BUG_ON(mpidr_cpuids_count >= NR_CPUS);

		val = of_get_property(cn, "reg", &len);
		if (!val || len != 4) {
			pr_err("%s missing reg property\n", cn->full_name);
			continue;
		}
		compatible = of_get_property(cn, "compatible", NULL);
		if (compatible == NULL) {
			pr_err("%s missing compatible property\n", cn->full_name);
			continue;
		}

		mpidr_cpuids[mpidr_cpuids_count] = be32_to_cpup(val);
		mpidr_cpus[mpidr_cpuids_count] = gator_find_cpu_by_dt_name(compatible);
		++mpidr_cpuids_count;
	}

	map_cpuids = (mpidr_cpuids_count == nr_cpu_ids);
}

static int linearize_mpidr(int mpidr)
{
	int i;

	for (i = 0; i < nr_cpu_ids; ++i) {
		if (mpidr_cpuids[i] == mpidr)
			return i;
	}

	BUG();
}

int lcpu_to_pcpu(const int lcpu)
{
	int pcpu;

	if (!map_cpuids)
		return lcpu;

	BUG_ON(lcpu >= nr_cpu_ids || lcpu < 0);
	pcpu = __lcpu_to_pcpu[lcpu];
	BUG_ON(pcpu >= nr_cpu_ids || pcpu < 0);
	return pcpu;
}

int pcpu_to_lcpu(const int pcpu)
{
	int lcpu;

	if (!map_cpuids)
		return pcpu;

	BUG_ON(pcpu >= nr_cpu_ids || pcpu < 0);
	for (lcpu = 0; lcpu < nr_cpu_ids; ++lcpu) {
		if (__lcpu_to_pcpu[lcpu] == pcpu) {
			BUG_ON(lcpu >= nr_cpu_ids || lcpu < 0);
			return lcpu;
		}
	}
	BUG();
}

static void gator_update_cpu_mapping(u32 cpu_hwid)
{
	int lcpu = smp_processor_id();
	int pcpu = linearize_mpidr(cpu_hwid & MPIDR_HWID_BITMASK);

	BUG_ON(lcpu >= nr_cpu_ids || lcpu < 0);
	BUG_ON(pcpu >= nr_cpu_ids || pcpu < 0);
	__lcpu_to_pcpu[lcpu] = pcpu;
}

GATOR_DEFINE_PROBE(cpu_migrate_begin, TP_PROTO(u64 timestamp, u32 cpu_hwid))
{
	const int cpu = get_physical_cpu();

	gator_timer_offline((void *)1);
	gator_timer_offline_dispatch(cpu, true);
}

GATOR_DEFINE_PROBE(cpu_migrate_finish, TP_PROTO(u64 timestamp, u32 cpu_hwid))
{
	int cpu;

	gator_update_cpu_mapping(cpu_hwid);

	/* get_physical_cpu must be called after gator_update_cpu_mapping */
	cpu = get_physical_cpu();
	gator_timer_online_dispatch(cpu, true);
	gator_timer_online((void *)1);
}

GATOR_DEFINE_PROBE(cpu_migrate_current, TP_PROTO(u64 timestamp, u32 cpu_hwid))
{
	gator_update_cpu_mapping(cpu_hwid);
}

static void gator_send_iks_core_names(void)
{
	int cpu;
	/* Send the cpu names */
	preempt_disable();
	for (cpu = 0; cpu < nr_cpu_ids; ++cpu) {
		if (mpidr_cpus[cpu] != NULL)
			gator_send_core_name(cpu, mpidr_cpus[cpu]->cpuid);
	}
	preempt_enable();
}

static int gator_migrate_start(void)
{
	int retval = 0;

	if (!map_cpuids)
		return retval;

	if (retval == 0)
		retval = GATOR_REGISTER_TRACE(cpu_migrate_begin);
	if (retval == 0)
		retval = GATOR_REGISTER_TRACE(cpu_migrate_finish);
	if (retval == 0)
		retval = GATOR_REGISTER_TRACE(cpu_migrate_current);
	if (retval == 0) {
		/* Initialize the logical to physical cpu mapping */
		memset(&__lcpu_to_pcpu, 0xff, sizeof(__lcpu_to_pcpu));
		bL_switcher_trace_trigger();
	}
	return retval;
}

static void gator_migrate_stop(void)
{
	if (!map_cpuids)
		return;

	GATOR_UNREGISTER_TRACE(cpu_migrate_current);
	GATOR_UNREGISTER_TRACE(cpu_migrate_finish);
	GATOR_UNREGISTER_TRACE(cpu_migrate_begin);
}

#else

#define calc_first_cluster_size()
#define gator_send_iks_core_names()
#define gator_migrate_start() 0
#define gator_migrate_stop()

#endif
