/*
 * Copyright (c) 2021-2022, NVIDIA Corporation. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include <errno.h>

#include <arch.h>
#include <arch_helpers.h>
#include <drivers/arm/gic600ae_fmu.h>
#include <drivers/delay_timer.h>
#include <lib/mmio.h>

#define GICFMU_IDLE_TIMEOUT_US		U(2000000)

/* Macro to write 32-bit FMU registers */
#define GIC_FMU_WRITE_32(base, reg, val) \
	do { \
		/* \
		 * This register receives the unlock key that is required for \
		 * writes to FMU registers to be successful. \
		 */ \
		mmio_write_32(base + GICFMU_KEY, 0xBE); \
		/* Perform the actual write */ \
		mmio_write_32((base) + (reg), (val)); \
	} while (false)

/* Macro to write 64-bit FMU registers */
#define GIC_FMU_WRITE_64(base, reg, n, val) \
	do { \
		/* \
		 * This register receives the unlock key that is required for \
		 * writes to FMU registers to be successful. \
		 */ \
		mmio_write_32(base + GICFMU_KEY, 0xBE); \
		/* \
		 * APB bus is 32-bit wide; so split the 64-bit write into \
		 * two 32-bit writes \
		 */ \
		mmio_write_32((base) + reg##_LO + (n * 64), (val)); \
		mmio_write_32((base) + reg##_HI + (n * 64), (val)); \
	} while (false)

/* Helper function to wait until FMU is ready to accept the next command */
static void wait_until_fmu_is_idle(uintptr_t base)
{
	uint32_t timeout_count = GICFMU_IDLE_TIMEOUT_US;
	uint64_t status;

	/* wait until status is 'busy' */
	do {
		status = (gic_fmu_read_status(base) & BIT(0));

		if (timeout_count-- == 0U) {
			ERROR("GIC600 AE FMU is not responding\n");
			panic();
		}

		udelay(1U);

	} while (status == U(0));
}

#define GIC_FMU_WRITE_ON_IDLE_32(base, reg, val) \
	do { \
		/* Wait until FMU is ready */ \
		wait_until_fmu_is_idle(base); \
		/* Actual register write */ \
		GIC_FMU_WRITE_32(base, reg, val); \
		/* Wait until FMU is ready */ \
		wait_until_fmu_is_idle(base); \
	} while (false)

#define GIC_FMU_WRITE_ON_IDLE_64(base, reg, n, val) \
	do { \
		/* Wait until FMU is ready */ \
		wait_until_fmu_is_idle(base); \
		/* Actual register write */ \
		GIC_FMU_WRITE_64(base, reg, n, val); \
		/* Wait until FMU is ready */ \
		wait_until_fmu_is_idle(base); \
	} while (false)

/*******************************************************************************
 * GIC FMU functions for accessing the Fault Management Unit registers
 ******************************************************************************/

/*
 * Accessors to read the Error Record Feature Register bits corresponding
 * to an error record 'n'
 */
uint64_t gic_fmu_read_errfr(uintptr_t base, unsigned int n)
{
	/*
	 * APB bus is 32-bit wide; so split the 64-bit read into
	 * two 32-bit reads
	 */
	uint64_t reg_val = (uint64_t)mmio_read_32(base + GICFMU_ERRFR_LO + n * 64U);

	reg_val |= ((uint64_t)mmio_read_32(base + GICFMU_ERRFR_HI + n * 64U) << 32);
	return reg_val;
}

/*
 * Accessors to read the Error Record Control Register bits corresponding
 * to an error record 'n'
 */
uint64_t gic_fmu_read_errctlr(uintptr_t base, unsigned int n)
{
	/*
	 * APB bus is 32-bit wide; so split the 64-bit read into
	 * two 32-bit reads
	 */
	uint64_t reg_val = (uint64_t)mmio_read_32(base + GICFMU_ERRCTLR_LO + n * 64U);

	reg_val |= ((uint64_t)mmio_read_32(base + GICFMU_ERRCTLR_HI + n * 64U) << 32);
	return reg_val;
}

/*
 * Accessors to read the Error Record Primary Status Register bits
 * corresponding to an error record 'n'
 */
uint64_t gic_fmu_read_errstatus(uintptr_t base, unsigned int n)
{
	/*
	 * APB bus is 32-bit wide; so split the 64-bit read into
	 * two 32-bit reads
	 */
	uint64_t reg_val = (uint64_t)mmio_read_32(base + GICFMU_ERRSTATUS_LO + n * 64U);

	reg_val |= ((uint64_t)mmio_read_32(base + GICFMU_ERRSTATUS_HI + n * 64U) << 32);
	return reg_val;
}

/*
 * Accessors to read the Error Group Status Register
 */
uint64_t gic_fmu_read_errgsr(uintptr_t base)
{
	/*
	 * APB bus is 32-bit wide; so split the 64-bit read into
	 * two 32-bit reads
	 */
	uint64_t reg_val = (uint64_t)mmio_read_32(base + GICFMU_ERRGSR_LO);

	reg_val |= ((uint64_t)mmio_read_32(base + GICFMU_ERRGSR_HI) << 32);
	return reg_val;
}

/*
 * Accessors to read the Ping Control Register
 */
uint32_t gic_fmu_read_pingctlr(uintptr_t base)
{
	return mmio_read_32(base + GICFMU_PINGCTLR);
}

/*
 * Accessors to read the Ping Now Register
 */
uint32_t gic_fmu_read_pingnow(uintptr_t base)
{
	return mmio_read_32(base + GICFMU_PINGNOW);
}

/*
 * Accessors to read the Ping Mask Register
 */
uint64_t gic_fmu_read_pingmask(uintptr_t base)
{
	/*
	 * APB bus is 32-bit wide; so split the 64-bit read into
	 * two 32-bit reads
	 */
	uint64_t reg_val = (uint64_t)mmio_read_32(base + GICFMU_PINGMASK_LO);

	reg_val |= ((uint64_t)mmio_read_32(base + GICFMU_PINGMASK_HI) << 32);
	return reg_val;
}

/*
 * Accessors to read the FMU Status Register
 */
uint32_t gic_fmu_read_status(uintptr_t base)
{
	return mmio_read_32(base + GICFMU_STATUS);
}

/*
 * Accessors to read the Error Record ID Register
 */
uint32_t gic_fmu_read_erridr(uintptr_t base)
{
	return mmio_read_32(base + GICFMU_ERRIDR);
}

/*
 * Accessors to write a 64 bit value to the Error Record Control Register
 */
void gic_fmu_write_errctlr(uintptr_t base, unsigned int n, uint64_t val)
{
	GIC_FMU_WRITE_64(base, GICFMU_ERRCTLR, n, val);
}

/*
 * Accessors to write a 64 bit value to the Error Record Primary Status
 * Register
 */
void gic_fmu_write_errstatus(uintptr_t base, unsigned int n, uint64_t val)
{
	/* Wait until FMU is ready before writing */
	GIC_FMU_WRITE_ON_IDLE_64(base, GICFMU_ERRSTATUS, n, val);
}

/*
 * Accessors to write a 32 bit value to the Ping Control Register
 */
void gic_fmu_write_pingctlr(uintptr_t base, uint32_t val)
{
	GIC_FMU_WRITE_32(base, GICFMU_PINGCTLR, val);
}

/*
 * Accessors to write a 32 bit value to the Ping Now Register
 */
void gic_fmu_write_pingnow(uintptr_t base, uint32_t val)
{
	/* Wait until FMU is ready before writing */
	GIC_FMU_WRITE_ON_IDLE_32(base, GICFMU_PINGNOW, val);
}

/*
 * Accessors to write a 32 bit value to the Safety Mechanism Enable Register
 */
void gic_fmu_write_smen(uintptr_t base, uint32_t val)
{
	/* Wait until FMU is ready before writing */
	GIC_FMU_WRITE_ON_IDLE_32(base, GICFMU_SMEN, val);
}

/*
 * Accessors to write a 32 bit value to the Safety Mechanism Inject Error
 * Register
 */
void gic_fmu_write_sminjerr(uintptr_t base, uint32_t val)
{
	/* Wait until FMU is ready before writing */
	GIC_FMU_WRITE_ON_IDLE_32(base, GICFMU_SMINJERR, val);
}

/*
 * Accessors to write a 64 bit value to the Ping Mask Register
 */
void gic_fmu_write_pingmask(uintptr_t base, uint64_t val)
{
	GIC_FMU_WRITE_64(base, GICFMU_PINGMASK, 0, val);
}

/*
 * Helper function to disable all safety mechanisms for a given block
 */
void gic_fmu_disable_all_sm_blkid(uintptr_t base, unsigned int blkid)
{
	uint32_t smen, max_smid = U(0);

	/* Sanity check block ID */
	assert((blkid >= FMU_BLK_GICD) && (blkid <= FMU_BLK_PPI31));

	/* Find the max safety mechanism ID for the block */
	switch (blkid) {
	case FMU_BLK_GICD:
		max_smid = FMU_SMID_GICD_MAX;
		break;

	case FMU_BLK_SPICOL:
		max_smid = FMU_SMID_SPICOL_MAX;
		break;

	case FMU_BLK_WAKERQ:
		max_smid = FMU_SMID_WAKERQ_MAX;
		break;

	case FMU_BLK_ITS0...FMU_BLK_ITS7:
		max_smid = FMU_SMID_ITS_MAX;
		break;

	case FMU_BLK_PPI0...FMU_BLK_PPI31:
		max_smid = FMU_SMID_PPI_MAX;
		break;

	default:
		assert(false);
		break;
	}

	/* Disable all Safety Mechanisms for a given block id */
	for (unsigned int i = 0U; i < max_smid; i++) {
		smen = (blkid << FMU_SMEN_BLK_SHIFT) | (i << FMU_SMEN_SMID_SHIFT);
		gic_fmu_write_smen(base, smen);
	}
}
