/*
 * Copyright 2014 Linaro Ltd.
 * Copyright (C) 2014 ZTE Corporation.
 *
 * 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/delay.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/jiffies.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/smp.h>

#include <asm/cacheflush.h>
#include <asm/cp15.h>
#include <asm/fncpy.h>
#include <asm/proc-fns.h>
#include <asm/smp_scu.h>
#include <asm/smp_plat.h>

#include "core.h"

#define AON_SYS_CTRL_RESERVED1		0xa8

#define BUS_MATRIX_REMAP_CONFIG		0x00

#define PCU_CPU0_CTRL			0x00
#define PCU_CPU1_CTRL			0x04
#define PCU_CPU1_ST			0x0c
#define PCU_GLOBAL_CTRL			0x14
#define PCU_EXPEND_CONTROL		0x34

#define ZX_IRAM_BASE			0x00200000

static void __iomem *pcu_base;
static void __iomem *matrix_base;
static void __iomem *scu_base;

void __init zx_smp_prepare_cpus(unsigned int max_cpus)
{
	struct device_node *np;
	unsigned long base = 0;
	void __iomem *aonsysctrl_base;
	void __iomem *sys_iram;

	base = scu_a9_get_base();
	scu_base = ioremap(base, SZ_256);
	if (!scu_base) {
		pr_err("%s: failed to map scu\n", __func__);
		return;
	}

	scu_enable(scu_base);

	np = of_find_compatible_node(NULL, NULL, "zte,sysctrl");
	if (!np) {
		pr_err("%s: failed to find sysctrl node\n", __func__);
		return;
	}

	aonsysctrl_base = of_iomap(np, 0);
	if (!aonsysctrl_base) {
		pr_err("%s: failed to map aonsysctrl\n", __func__);
		of_node_put(np);
		return;
	}

	/*
	 * Write the address of secondary startup into the
	 * system-wide flags register. The BootMonitor waits
	 * until it receives a soft interrupt, and then the
	 * secondary CPU branches to this address.
	 */
	__raw_writel(__pa_symbol(zx_secondary_startup),
		     aonsysctrl_base + AON_SYS_CTRL_RESERVED1);

	iounmap(aonsysctrl_base);
	of_node_put(np);

	np = of_find_compatible_node(NULL, NULL, "zte,zx296702-pcu");
	pcu_base = of_iomap(np, 0);
	of_node_put(np);
	WARN_ON(!pcu_base);

	np = of_find_compatible_node(NULL, NULL, "zte,zx-bus-matrix");
	matrix_base = of_iomap(np, 0);
	of_node_put(np);
	WARN_ON(!matrix_base);

	/* Map the first 4 KB IRAM for suspend usage */
	sys_iram = __arm_ioremap_exec(ZX_IRAM_BASE, PAGE_SIZE, false);
	zx_secondary_startup_pa = __pa_symbol(zx_secondary_startup);
	fncpy(sys_iram, &zx_resume_jump, zx_suspend_iram_sz);
}

static int zx_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
	static bool first_boot = true;

	if (first_boot) {
		arch_send_wakeup_ipi_mask(cpumask_of(cpu));
		first_boot = false;
		return 0;
	}

	/* Swap the base address mapping between IRAM and IROM */
	writel_relaxed(0x1, matrix_base + BUS_MATRIX_REMAP_CONFIG);

	/* Power on CPU1 */
	writel_relaxed(0x0, pcu_base + PCU_CPU1_CTRL);

	/* Wait for power on ack */
	while (readl_relaxed(pcu_base + PCU_CPU1_ST) & 0x4)
		cpu_relax();

	/* Swap back the mapping of IRAM and IROM */
	writel_relaxed(0x0, matrix_base + BUS_MATRIX_REMAP_CONFIG);

	return 0;
}

#ifdef CONFIG_HOTPLUG_CPU
static inline void cpu_enter_lowpower(void)
{
	unsigned int v;

	asm volatile(
		"mcr	p15, 0, %1, c7, c5, 0\n"
	"	mcr	p15, 0, %1, c7, c10, 4\n"
	/*
	 * Turn off coherency
	 */
	"	mrc	p15, 0, %0, c1, c0, 1\n"
	"	bic	%0, %0, %3\n"
	"	mcr	p15, 0, %0, c1, c0, 1\n"
	"	mrc	p15, 0, %0, c1, c0, 0\n"
	"	bic	%0, %0, %2\n"
	"	mcr	p15, 0, %0, c1, c0, 0\n"
	  : "=&r" (v)
	  : "r" (0), "Ir" (CR_C), "Ir" (0x40)
	  : "cc");
}

static int zx_cpu_kill(unsigned int cpu)
{
	unsigned long timeout = jiffies + msecs_to_jiffies(2000);

	writel_relaxed(0x2, pcu_base + PCU_CPU1_CTRL);

	while ((readl_relaxed(pcu_base + PCU_CPU1_ST) & 0x3) != 0x0) {
		if (time_after(jiffies, timeout)) {
			pr_err("*** cpu1 poweroff timeout\n");
			break;
		}
	}
	return 1;
}

static void zx_cpu_die(unsigned int cpu)
{
	scu_power_mode(scu_base, SCU_PM_POWEROFF);
	cpu_enter_lowpower();

	while (1)
		cpu_do_idle();
}
#endif

static void zx_secondary_init(unsigned int cpu)
{
	scu_power_mode(scu_base, SCU_PM_NORMAL);
}

static const struct smp_operations zx_smp_ops __initconst = {
	.smp_prepare_cpus	= zx_smp_prepare_cpus,
	.smp_secondary_init	= zx_secondary_init,
	.smp_boot_secondary	= zx_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
	.cpu_kill		= zx_cpu_kill,
	.cpu_die		= zx_cpu_die,
#endif
};

CPU_METHOD_OF_DECLARE(zx_smp, "zte,zx296702-smp", &zx_smp_ops);
