/*
 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <arch_helpers.h>
#include <assert.h>
#include <debug.h>
#include <delay_timer.h>
#include <endian.h>
#include <errno.h>
#include <gicv2.h>
#include <mmio.h>
#include <platform.h>
#include <psci.h>
#include "platform_def.h"

#define LS_SCFG_BASE			0x01570000
/* register to store warm boot entry, big endian, higher 32bit */
#define LS_SCFG_SCRATCHRW0_OFFSET	     0x600
/* register to store warm boot entry, big endian, lower 32bit */
#define LS_SCFG_SCRATCHRW1_OFFSET	     0x604
#define LS_SCFG_COREBCR_OFFSET		     0x680

#define LS_DCFG_BASE			0x01EE0000
#define LS_DCFG_RSTCR_OFFSET		     0x0B0
#define LS_DCFG_RSTRQMR1_OFFSET		     0x0C0
#define LS_DCFG_BRR_OFFSET		     0x0E4

#define LS_SCFG_CORE0_SFT_RST_OFFSET		0x130
#define LS_SCFG_CORE1_SFT_RST_OFFSET		0x134
#define LS_SCFG_CORE2_SFT_RST_OFFSET		0x138
#define LS_SCFG_CORE3_SFT_RST_OFFSET		0x13C

#define LS_SCFG_CORESRENCR_OFFSET		0x204

#define LS_SCFG_RVBAR0_0_OFFSET			0x220
#define LS_SCFG_RVBAR0_1_OFFSET			0x224

#define LS_SCFG_RVBAR1_0_OFFSET			0x228
#define LS_SCFG_RVBAR1_1_OFFSET			0x22C

#define LS_SCFG_RVBAR2_0_OFFSET			0x230
#define LS_SCFG_RVBAR2_1_OFFSET			0x234

#define LS_SCFG_RVBAR3_0_OFFSET			0x238
#define LS_SCFG_RVBAR3_1_OFFSET			0x23C

/* the entry for core warm boot */
static uintptr_t warmboot_entry;

/* warm reset single core */
static void ls1043_reset_core(int core_pos)
{
	assert(core_pos >= 0 && core_pos < PLATFORM_CORE_COUNT);

	/* set 0 in RVBAR, boot from bootrom at 0x0 */
	mmio_write_32(LS_SCFG_BASE + LS_SCFG_RVBAR0_0_OFFSET + core_pos * 8,
		      0);
	mmio_write_32(LS_SCFG_BASE + LS_SCFG_RVBAR0_1_OFFSET + core_pos * 8,
		      0);

	dsb();
	/* enable core soft reset */
	mmio_write_32(LS_SCFG_BASE + LS_SCFG_CORESRENCR_OFFSET,
		      htobe32(1 << 31));
	dsb();
	isb();
	/* reset core */
	mmio_write_32(LS_SCFG_BASE + LS_SCFG_CORE0_SFT_RST_OFFSET +
			core_pos * 4, htobe32(1 << 31));
	mdelay(10);
}

static void __dead2 ls1043_system_reset(void)
{
	/* clear reset request mask bits */
	mmio_write_32(LS_DCFG_BASE + LS_DCFG_RSTRQMR1_OFFSET, 0);

	/* set reset request bit */
	mmio_write_32(LS_DCFG_BASE + LS_DCFG_RSTCR_OFFSET,
		      htobe32((uint32_t)0x2));

	/* system will reset; if fail, enter wfi */
	dsb();
	isb();
	wfi();

	panic();
}


static int ls1043_pwr_domain_on(u_register_t mpidr)
{
	int core_pos = plat_core_pos_by_mpidr(mpidr);
	uint32_t core_mask, brr;

	assert(core_pos >= 0 && core_pos < PLATFORM_CORE_COUNT);
	core_mask = 1 << core_pos;

	/* set warm boot entry */
	mmio_write_32(LS_SCFG_BASE + LS_SCFG_SCRATCHRW0_OFFSET,
		htobe32((uint32_t)(warmboot_entry >> 32)));

	mmio_write_32(LS_SCFG_BASE + LS_SCFG_SCRATCHRW1_OFFSET,
		htobe32((uint32_t)warmboot_entry));

	dsb();

	brr = be32toh(mmio_read_32(LS_DCFG_BASE + LS_DCFG_BRR_OFFSET));
	if (brr & core_mask) {
		/* core has been released, must reset it to restart */
		ls1043_reset_core(core_pos);

		/* set bit in core boot control register to enable boot */
		mmio_write_32(LS_SCFG_BASE + LS_SCFG_COREBCR_OFFSET,
			htobe32(core_mask));

	} else {
		/* set bit in core boot control register to enable boot */
		mmio_write_32(LS_SCFG_BASE + LS_SCFG_COREBCR_OFFSET,
			htobe32(core_mask));

		/* release core */
		mmio_write_32(LS_DCFG_BASE + LS_DCFG_BRR_OFFSET,
			      htobe32(brr | core_mask));
	}

	mdelay(20);

	/* wake core in case it is in wfe */
	dsb();
	isb();
	sev();

	return PSCI_E_SUCCESS;
}

static void ls1043_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
	/* Per cpu gic distributor setup */
	gicv2_pcpu_distif_init();

	/* Enable the gic CPU interface */
	gicv2_cpuif_enable();
}

static void ls1043_pwr_domain_off(const psci_power_state_t *target_state)
{
	/* Disable the gic CPU interface */
	gicv2_cpuif_disable();
}

static plat_psci_ops_t ls1043_psci_pm_ops = {
	.system_reset = ls1043_system_reset,
	.pwr_domain_on = ls1043_pwr_domain_on,
	.pwr_domain_on_finish = ls1043_pwr_domain_on_finish,
	.pwr_domain_off = ls1043_pwr_domain_off,
};

int plat_setup_psci_ops(uintptr_t sec_entrypoint,
			const plat_psci_ops_t **psci_ops)
{
	warmboot_entry = sec_entrypoint;
	*psci_ops = &ls1043_psci_pm_ops;
	return 0;
}
