// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2013 Linaro Ltd.
 * Copyright (c) 2013 HiSilicon Limited.
 */

#include <linux/cpu.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <asm/cacheflush.h>
#include <asm/smp_plat.h>
#include "core.h"

/* Sysctrl registers in Hi3620 SoC */
#define SCISOEN				0xc0
#define SCISODIS			0xc4
#define SCPERPWREN			0xd0
#define SCPERPWRDIS			0xd4
#define SCCPUCOREEN			0xf4
#define SCCPUCOREDIS			0xf8
#define SCPERCTRL0			0x200
#define SCCPURSTEN			0x410
#define SCCPURSTDIS			0x414

/*
 * bit definition in SCISOEN/SCPERPWREN/...
 *
 * CPU2_ISO_CTRL	(1 << 5)
 * CPU3_ISO_CTRL	(1 << 6)
 * ...
 */
#define CPU2_ISO_CTRL			(1 << 5)

/*
 * bit definition in SCPERCTRL0
 *
 * CPU0_WFI_MASK_CFG	(1 << 28)
 * CPU1_WFI_MASK_CFG	(1 << 29)
 * ...
 */
#define CPU0_WFI_MASK_CFG		(1 << 28)

/*
 * bit definition in SCCPURSTEN/...
 *
 * CPU0_SRST_REQ_EN	(1 << 0)
 * CPU1_SRST_REQ_EN	(1 << 1)
 * ...
 */
#define CPU0_HPM_SRST_REQ_EN		(1 << 22)
#define CPU0_DBG_SRST_REQ_EN		(1 << 12)
#define CPU0_NEON_SRST_REQ_EN		(1 << 4)
#define CPU0_SRST_REQ_EN		(1 << 0)

#define HIX5HD2_PERI_CRG20		0x50
#define CRG20_CPU1_RESET		(1 << 17)

#define HIX5HD2_PERI_PMC0		0x1000
#define PMC0_CPU1_WAIT_MTCOMS_ACK	(1 << 8)
#define PMC0_CPU1_PMC_ENABLE		(1 << 7)
#define PMC0_CPU1_POWERDOWN		(1 << 3)

#define HIP01_PERI9                    0x50
#define PERI9_CPU1_RESET               (1 << 1)

enum {
	HI3620_CTRL,
	ERROR_CTRL,
};

static void __iomem *ctrl_base;
static int id;

static void set_cpu_hi3620(int cpu, bool enable)
{
	u32 val = 0;

	if (enable) {
		/* MTCMOS set */
		if ((cpu == 2) || (cpu == 3))
			writel_relaxed(CPU2_ISO_CTRL << (cpu - 2),
				       ctrl_base + SCPERPWREN);
		udelay(100);

		/* Enable core */
		writel_relaxed(0x01 << cpu, ctrl_base + SCCPUCOREEN);

		/* unreset */
		val = CPU0_DBG_SRST_REQ_EN | CPU0_NEON_SRST_REQ_EN
			| CPU0_SRST_REQ_EN;
		writel_relaxed(val << cpu, ctrl_base + SCCPURSTDIS);
		/* reset */
		val |= CPU0_HPM_SRST_REQ_EN;
		writel_relaxed(val << cpu, ctrl_base + SCCPURSTEN);

		/* ISO disable */
		if ((cpu == 2) || (cpu == 3))
			writel_relaxed(CPU2_ISO_CTRL << (cpu - 2),
				       ctrl_base + SCISODIS);
		udelay(1);

		/* WFI Mask */
		val = readl_relaxed(ctrl_base + SCPERCTRL0);
		val &= ~(CPU0_WFI_MASK_CFG << cpu);
		writel_relaxed(val, ctrl_base + SCPERCTRL0);

		/* Unreset */
		val = CPU0_DBG_SRST_REQ_EN | CPU0_NEON_SRST_REQ_EN
			| CPU0_SRST_REQ_EN | CPU0_HPM_SRST_REQ_EN;
		writel_relaxed(val << cpu, ctrl_base + SCCPURSTDIS);
	} else {
		/* wfi mask */
		val = readl_relaxed(ctrl_base + SCPERCTRL0);
		val |= (CPU0_WFI_MASK_CFG << cpu);
		writel_relaxed(val, ctrl_base + SCPERCTRL0);

		/* disable core*/
		writel_relaxed(0x01 << cpu, ctrl_base + SCCPUCOREDIS);

		if ((cpu == 2) || (cpu == 3)) {
			/* iso enable */
			writel_relaxed(CPU2_ISO_CTRL << (cpu - 2),
				       ctrl_base + SCISOEN);
			udelay(1);
		}

		/* reset */
		val = CPU0_DBG_SRST_REQ_EN | CPU0_NEON_SRST_REQ_EN
			| CPU0_SRST_REQ_EN | CPU0_HPM_SRST_REQ_EN;
		writel_relaxed(val << cpu, ctrl_base + SCCPURSTEN);

		if ((cpu == 2) || (cpu == 3)) {
			/* MTCMOS unset */
			writel_relaxed(CPU2_ISO_CTRL << (cpu - 2),
				       ctrl_base + SCPERPWRDIS);
			udelay(100);
		}
	}
}

static int hi3xxx_hotplug_init(void)
{
	struct device_node *node;

	node = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl");
	if (!node) {
		id = ERROR_CTRL;
		return -ENOENT;
	}

	ctrl_base = of_iomap(node, 0);
	of_node_put(node);
	if (!ctrl_base) {
		id = ERROR_CTRL;
		return -ENOMEM;
	}

	id = HI3620_CTRL;
	return 0;
}

void hi3xxx_set_cpu(int cpu, bool enable)
{
	if (!ctrl_base) {
		if (hi3xxx_hotplug_init() < 0)
			return;
	}

	if (id == HI3620_CTRL)
		set_cpu_hi3620(cpu, enable);
}

static bool hix5hd2_hotplug_init(void)
{
	struct device_node *np;

	np = of_find_compatible_node(NULL, NULL, "hisilicon,cpuctrl");
	if (!np)
		return false;

	ctrl_base = of_iomap(np, 0);
	of_node_put(np);
	if (!ctrl_base)
		return false;

	return true;
}

void hix5hd2_set_cpu(int cpu, bool enable)
{
	u32 val = 0;

	if (!ctrl_base)
		if (!hix5hd2_hotplug_init())
			BUG();

	if (enable) {
		/* power on cpu1 */
		val = readl_relaxed(ctrl_base + HIX5HD2_PERI_PMC0);
		val &= ~(PMC0_CPU1_WAIT_MTCOMS_ACK | PMC0_CPU1_POWERDOWN);
		val |= PMC0_CPU1_PMC_ENABLE;
		writel_relaxed(val, ctrl_base + HIX5HD2_PERI_PMC0);
		/* unreset */
		val = readl_relaxed(ctrl_base + HIX5HD2_PERI_CRG20);
		val &= ~CRG20_CPU1_RESET;
		writel_relaxed(val, ctrl_base + HIX5HD2_PERI_CRG20);
	} else {
		/* power down cpu1 */
		val = readl_relaxed(ctrl_base + HIX5HD2_PERI_PMC0);
		val |= PMC0_CPU1_PMC_ENABLE | PMC0_CPU1_POWERDOWN;
		val &= ~PMC0_CPU1_WAIT_MTCOMS_ACK;
		writel_relaxed(val, ctrl_base + HIX5HD2_PERI_PMC0);

		/* reset */
		val = readl_relaxed(ctrl_base + HIX5HD2_PERI_CRG20);
		val |= CRG20_CPU1_RESET;
		writel_relaxed(val, ctrl_base + HIX5HD2_PERI_CRG20);
	}
}

void hip01_set_cpu(int cpu, bool enable)
{
	unsigned int temp;
	struct device_node *np;

	if (!ctrl_base) {
		np = of_find_compatible_node(NULL, NULL, "hisilicon,hip01-sysctrl");
		BUG_ON(!np);
		ctrl_base = of_iomap(np, 0);
		of_node_put(np);
		BUG_ON(!ctrl_base);
	}

	if (enable) {
		/* reset on CPU1  */
		temp = readl_relaxed(ctrl_base + HIP01_PERI9);
		temp |= PERI9_CPU1_RESET;
		writel_relaxed(temp, ctrl_base + HIP01_PERI9);

		udelay(50);

		/* unreset on CPU1 */
		temp = readl_relaxed(ctrl_base + HIP01_PERI9);
		temp &= ~PERI9_CPU1_RESET;
		writel_relaxed(temp, ctrl_base + HIP01_PERI9);
	}
}

static inline void cpu_enter_lowpower(void)
{
	unsigned int v;

	flush_cache_all();

	/*
	 * Turn off coherency and L1 D-cache
	 */
	asm volatile(
	"	mrc	p15, 0, %0, c1, c0, 1\n"
	"	bic	%0, %0, #0x40\n"
	"	mcr	p15, 0, %0, c1, c0, 1\n"
	"	mrc	p15, 0, %0, c1, c0, 0\n"
	"	bic	%0, %0, #0x04\n"
	"	mcr	p15, 0, %0, c1, c0, 0\n"
	  : "=&r" (v)
	  : "r" (0)
	  : "cc");
}

#ifdef CONFIG_HOTPLUG_CPU
void hi3xxx_cpu_die(unsigned int cpu)
{
	cpu_enter_lowpower();
	hi3xxx_set_cpu_jump(cpu, phys_to_virt(0));
	cpu_do_idle();

	/* We should have never returned from idle */
	panic("cpu %d unexpectedly exit from shutdown\n", cpu);
}

int hi3xxx_cpu_kill(unsigned int cpu)
{
	unsigned long timeout = jiffies + msecs_to_jiffies(50);

	while (hi3xxx_get_cpu_jump(cpu))
		if (time_after(jiffies, timeout))
			return 0;
	hi3xxx_set_cpu(cpu, false);
	return 1;
}

void hix5hd2_cpu_die(unsigned int cpu)
{
	flush_cache_all();
	hix5hd2_set_cpu(cpu, false);
}
#endif
