// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2016 Socionext Inc.
 *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 */

#include <cpu_func.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/printk.h>
#include <linux/psci.h>
#include <linux/sizes.h>
#include <asm/processor.h>
#include <asm/psci.h>
#include <asm/secure.h>
#include <asm/system.h>

#include "../debug.h"
#include "../soc-info.h"
#include "arm-mpcore.h"
#include "cache-uniphier.h"

#define UNIPHIER_SMPCTRL_ROM_RSV2	0x59801208

void uniphier_smp_trampoline(void);
void uniphier_smp_trampoline_end(void);
u32 uniphier_smp_booted[CONFIG_ARMV7_PSCI_NR_CPUS];

static int uniphier_get_nr_cpus(void)
{
	switch (uniphier_get_soc_id()) {
	case UNIPHIER_PRO4_ID:
	case UNIPHIER_PRO5_ID:
		return 2;
	case UNIPHIER_PXS2_ID:
	case UNIPHIER_LD6B_ID:
		return 4;
	default:
		return 1;
	}
}

static void uniphier_smp_kick_all_cpus(void)
{
	const u32 target_ways = BIT(0);
	size_t trmp_size;
	u32 trmp_src = (unsigned long)uniphier_smp_trampoline;
	u32 trmp_src_end = (unsigned long)uniphier_smp_trampoline_end;
	u32 trmp_dest, trmp_dest_end;
	int nr_cpus, i;
	int timeout = 1000;

	nr_cpus = uniphier_get_nr_cpus();
	if (nr_cpus == 1)
		return;

	for (i = 0; i < nr_cpus; i++)	/* lock ways for all CPUs */
		uniphier_cache_set_active_ways(i, 0);
	uniphier_cache_inv_way(target_ways);
	uniphier_cache_enable();

	/* copy trampoline code */
	uniphier_cache_prefetch_range(trmp_src, trmp_src_end, target_ways);

	trmp_size = trmp_src_end - trmp_src;

	trmp_dest = trmp_src & (SZ_64K - 1);
	trmp_dest += SZ_1M - SZ_64K * 2;

	trmp_dest_end = trmp_dest + trmp_size;

	uniphier_cache_touch_range(trmp_dest, trmp_dest_end, target_ways);

	writel(trmp_dest, UNIPHIER_SMPCTRL_ROM_RSV2);

	asm("dsb	ishst\n" /* Ensure the write to ROM_RSV2 is visible */
	    "sev"); /* Bring up all secondary CPUs from Boot ROM into U-Boot */

	while (--timeout) {
		int all_booted = 1;

		for (i = 1; i < nr_cpus; i++)
			if (!uniphier_smp_booted[i])
				all_booted = 0;
		if (all_booted)
			break;
		udelay(1);

		/* barrier here because uniphier_smp_booted[] may be updated */
		cpu_relax();
	}

	if (!timeout)
		pr_warn("warning: some of secondary CPUs may not boot\n");

	uniphier_cache_disable();
}

void psci_board_init(void)
{
	unsigned long scu_base;
	u32 scu_ctrl, tmp;

	asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (scu_base));

	scu_ctrl = readl(scu_base + 0x30);
	if (!(scu_ctrl & 1))
		writel(scu_ctrl | 0x1, scu_base + 0x30);

	scu_ctrl = readl(scu_base + SCU_CTRL);
	scu_ctrl |= SCU_ENABLE | SCU_STANDBY_ENABLE;
	writel(scu_ctrl, scu_base + SCU_CTRL);

	tmp = readl(scu_base + SCU_SNSAC);
	tmp |= 0xfff;
	writel(tmp, scu_base + SCU_SNSAC);

	uniphier_smp_kick_all_cpus();
}

void psci_arch_init(void)
{
	u32 actlr;

	asm("mrc p15, 0, %0, c1, c0, 1" : "=r" (actlr));
	actlr |= 0x41;		/* set SMP and FW bits */
	asm("mcr p15, 0, %0, c1, c0, 1" : : "r" (actlr));
}

u32 uniphier_psci_holding_pen_release __secure_data = 0xffffffff;

s32 __secure psci_cpu_on(u32 function_id, u32 cpuid, u32 entry_point,
			 u32 context_id)
{
	u32 cpu = cpuid & 0xff;

	debug_puts("[U-Boot PSCI]  psci_cpu_on: cpuid=");
	debug_puth(cpuid);
	debug_puts(", entry_point=");
	debug_puth(entry_point);
	debug_puts(", context_id=");
	debug_puth(context_id);
	debug_puts("\n");

	psci_save(cpu, entry_point, context_id);

	/* We assume D-cache is off, so do not call flush_dcache() here */
	uniphier_psci_holding_pen_release = cpu;

	/* Send an event to wake up the secondary CPU. */
	asm("dsb	ishst\n"
	    "sev");

	return PSCI_RET_SUCCESS;
}

void __secure psci_system_reset(void)
{
	reset_cpu();
}
