// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2019, Rick Chen <rick@andestech.com>
 *
 * U-Boot syscon driver for Andes' PLICSW
 * The PLICSW block is an Andes-specific design for software interrupts,
 * contains memory-mapped priority, enable, claim and pending registers
 * similar to RISC-V PLIC.
 */

#include <common.h>
#include <dm.h>
#include <asm/global_data.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)	((ulong)(base) + 0x1000)
/* enable register */
#define ENABLE_REG(base, hart)	((ulong)(base) + 0x2000 + (hart) * 0x80)
/* claim register */
#define CLAIM_REG(base, hart)	((ulong)(base) + 0x200004 + (hart) * 0x1000)
/* priority register */
#define PRIORITY_REG(base)	((ulong)(base) + PLICSW_PRIORITY_BASE)

/* Bit 0 of PLIC-SW pending array is hardwired to zero, so we start from bit 1 */
#define FIRST_AVAILABLE_BIT	0x2
#define SEND_IPI_TO_HART(hart)	(FIRST_AVAILABLE_BIT << (hart))
#define PLICSW_PRIORITY_BASE        0x4
#define PLICSW_INTERRUPT_PER_HART   0x1

DECLARE_GLOBAL_DATA_PTR;

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

	en = FIRST_AVAILABLE_BIT << hart;
	writel(en, (void __iomem *)ENABLE_REG(gd->arch.plicsw, hart));

	return 0;
}

static void init_priority_ipi(int hart_num)
{
    uint32_t *priority = (void *)PRIORITY_REG(gd->arch.plicsw);

    for (int i = 0; i < hart_num * PLICSW_INTERRUPT_PER_HART; i++) {
        writel(1, &priority[i]);
    }

    return;
}

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

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

	ret = uclass_find_first_device(UCLASS_CPU, &dev);
	if (ret)
		return ret;
	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_enabled(node))
			continue;

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

	init_priority_ipi(hart_num);
	return 0;
}

int riscv_send_ipi(int hart)
{
	unsigned int ipi = SEND_IPI_TO_HART(hart);

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

	return 0;
}

int riscv_clear_ipi(int hart)
{
	u32 source_id;

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

	return 0;
}

int riscv_get_ipi(int hart, int *pending)
{
	unsigned int ipi = SEND_IPI_TO_HART(hart);

	*pending = readl((void __iomem *)PENDING_REG(gd->arch.plicsw));
	*pending = !!(*pending & ipi);

	return 0;
}

static const struct udevice_id andes_plicsw_ids[] = {
	{ .compatible = "andestech,plicsw", .data = RISCV_SYSCON_PLICSW },
	{ }
};

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