// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2019, Rick Chen <rick@andestech.com>
 *
 * U-Boot syscon driver for Andes's Platform Level Interrupt Controller (PLIC).
 * The PLIC block holds memory-mapped claim and pending registers
 * associated with software interrupt.
 */

#include <common.h>
#include <dm.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <dm/uclass-internal.h>
#include <regmap.h>
#include <syscon.h>
#include <asm/io.h>
#include <asm/syscon.h>
#include <cpu.h>
#include <linux/err.h>

/* pending register */
#define PENDING_REG(base, hart)	((ulong)(base) + 0x1000 + ((hart) / 4) * 4)
/* enable register */
#define ENABLE_REG(base, hart)	((ulong)(base) + 0x2000 + (hart) * 0x80)
/* claim register */
#define CLAIM_REG(base, hart)	((ulong)(base) + 0x200004 + (hart) * 0x1000)

#define ENABLE_HART_IPI         (0x80808080)
#define SEND_IPI_TO_HART(hart)  (0x80 >> (hart))

DECLARE_GLOBAL_DATA_PTR;

static int enable_ipi(int hart)
{
	unsigned int en;

	en = ENABLE_HART_IPI >> hart;
	writel(en, (void __iomem *)ENABLE_REG(gd->arch.plic, hart));

	return 0;
}

int riscv_init_ipi(void)
{
	int ret;
	long *base = syscon_get_first_range(RISCV_SYSCON_PLIC);
	ofnode node;
	struct udevice *dev;
	u32 reg;

	if (IS_ERR(base))
		return PTR_ERR(base);
	gd->arch.plic = base;

	ret = uclass_find_first_device(UCLASS_CPU, &dev);
	if (ret)
		return ret;
	else if (!dev)
		return -ENODEV;

	ofnode_for_each_subnode(node, dev_ofnode(dev->parent)) {
		const char *device_type;

		device_type = ofnode_read_string(node, "device_type");
		if (!device_type)
			continue;

		if (strcmp(device_type, "cpu"))
			continue;

		/* skip if hart is marked as not available */
		if (!ofnode_is_available(node))
			continue;

		/* read hart ID of CPU */
		ret = ofnode_read_u32(node, "reg", &reg);
		if (ret == 0)
			enable_ipi(reg);
	}

	return 0;
}

int riscv_send_ipi(int hart)
{
	unsigned int ipi = (SEND_IPI_TO_HART(hart) << (8 * gd->arch.boot_hart));

	writel(ipi, (void __iomem *)PENDING_REG(gd->arch.plic,
				gd->arch.boot_hart));

	return 0;
}

int riscv_clear_ipi(int hart)
{
	u32 source_id;

	source_id = readl((void __iomem *)CLAIM_REG(gd->arch.plic, hart));
	writel(source_id, (void __iomem *)CLAIM_REG(gd->arch.plic, hart));

	return 0;
}

int riscv_get_ipi(int hart, int *pending)
{
	*pending = readl((void __iomem *)PENDING_REG(gd->arch.plic,
						     gd->arch.boot_hart));
	*pending = !!(*pending & SEND_IPI_TO_HART(hart));

	return 0;
}

static const struct udevice_id andes_plic_ids[] = {
	{ .compatible = "riscv,plic1", .data = RISCV_SYSCON_PLIC },
	{ }
};

U_BOOT_DRIVER(andes_plic) = {
	.name		= "andes_plic",
	.id		= UCLASS_SYSCON,
	.of_match	= andes_plic_ids,
	.flags		= DM_FLAG_PRE_RELOC,
};
