/*
 * Copyright(c) 2015 EZchip Technologies.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * The full GNU General Public License is included in this distribution in
 * the file called "COPYING".
 */

#include <linux/smp.h>
#include <linux/of_fdt.h>
#include <linux/io.h>
#include <linux/irqdomain.h>
#include <asm/irq.h>
#include <plat/ctop.h>
#include <plat/smp.h>
#include <plat/mtm.h>

#define NPS_DEFAULT_MSID	0x34
#define NPS_MTM_CPU_CFG		0x90

static char smp_cpuinfo_buf[128] = {"Extn [EZNPS-SMP]\t: On\n"};

/* Get cpu map from device tree */
static int __init eznps_get_map(const char *name, struct cpumask *cpumask)
{
	unsigned long dt_root = of_get_flat_dt_root();
	const char *buf;

	buf = of_get_flat_dt_prop(dt_root, name, NULL);
	if (!buf)
		return 1;

	cpulist_parse(buf, cpumask);

	return 0;
}

/* Update board cpu maps */
static void __init eznps_init_cpumasks(void)
{
	struct cpumask cpumask;

	if (eznps_get_map("present-cpus", &cpumask)) {
		pr_err("Failed to get present-cpus from dtb");
		return;
	}
	init_cpu_present(&cpumask);

	if (eznps_get_map("possible-cpus", &cpumask)) {
		pr_err("Failed to get possible-cpus from dtb");
		return;
	}
	init_cpu_possible(&cpumask);
}

static void eznps_init_core(unsigned int cpu)
{
	u32 sync_value;
	struct nps_host_reg_aux_hw_comply hw_comply;
	struct nps_host_reg_aux_lpc lpc;

	if (NPS_CPU_TO_THREAD_NUM(cpu) != 0)
		return;

	hw_comply.value = read_aux_reg(CTOP_AUX_HW_COMPLY);
	hw_comply.me  = 1;
	hw_comply.le  = 1;
	hw_comply.te  = 1;
	write_aux_reg(CTOP_AUX_HW_COMPLY, hw_comply.value);

	/* Enable MMU clock */
	lpc.mep = 1;
	write_aux_reg(CTOP_AUX_LPC, lpc.value);

	/* Boot CPU only */
	if (!cpu) {
		/* Write to general purpose register in CRG */
		sync_value = ioread32be(REG_GEN_PURP_0);
		sync_value |= NPS_CRG_SYNC_BIT;
		iowrite32be(sync_value, REG_GEN_PURP_0);
	}
}

/*
 * Master kick starting another CPU
 */
static void __init eznps_smp_wakeup_cpu(int cpu, unsigned long pc)
{
	struct nps_host_reg_mtm_cpu_cfg cpu_cfg;

	if (mtm_enable_thread(cpu) == 0)
		return;

	/* set PC, dmsid, and start CPU */
	cpu_cfg.value = (u32)res_service;
	cpu_cfg.dmsid = NPS_DEFAULT_MSID;
	cpu_cfg.cs = 1;
	iowrite32be(cpu_cfg.value, nps_mtm_reg_addr(cpu, NPS_MTM_CPU_CFG));
}

static void eznps_ipi_send(int cpu)
{
	struct global_id gid;
	struct {
		union {
			struct {
				u32 num:8, cluster:8, core:8, thread:8;
			};
			u32 value;
		};
	} ipi;

	gid.value = cpu;
	ipi.thread = get_thread(gid);
	ipi.core = gid.core;
	ipi.cluster = nps_cluster_logic_to_phys(gid.cluster);
	ipi.num = NPS_IPI_IRQ;

	__asm__ __volatile__(
	"	mov r3, %0\n"
	"	.word %1\n"
	:
	: "r"(ipi.value), "i"(CTOP_INST_ASRI_0_R3)
	: "r3");
}

static void eznps_init_per_cpu(int cpu)
{
	smp_ipi_irq_setup(cpu, NPS_IPI_IRQ);

	eznps_init_core(cpu);
	mtm_enable_core(cpu);
}

struct plat_smp_ops plat_smp_ops = {
	.info		= smp_cpuinfo_buf,
	.init_early_smp	= eznps_init_cpumasks,
	.cpu_kick	= eznps_smp_wakeup_cpu,
	.ipi_send	= eznps_ipi_send,
	.init_per_cpu	= eznps_init_per_cpu,
};
