/**
 * Copyright (C) ARM Limited 2013. 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
	for (cpu = 0; cpu < nr_cpu_ids; ++cpu) {
		if (mpidr_cpus[cpu] != NULL) {
			gator_send_core_name(cpu, mpidr_cpus[cpu]->cpuid, mpidr_cpus[cpu]);
		}
	}
}

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
