// SPDX-License-Identifier: GPL-2.0
/*
 * Driver for Xilinx TMR Manager IP.
 *
 * Copyright (C) 2022 Advanced Micro Devices, Inc.
 *
 * Description:
 * This driver is developed for TMR Manager,The Triple Modular Redundancy(TMR)
 * Manager is responsible for handling the TMR subsystem state, including
 * fault detection and error recovery. The core is triplicated in each of
 * the sub-blocks in the TMR subsystem, and provides majority voting of
 * its internal state provides soft error detection, correction and
 * recovery.
 */

#include <asm/xilinx_mb_manager.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>

/* TMR Manager Register offsets */
#define XTMR_MANAGER_CR_OFFSET		0x0
#define XTMR_MANAGER_FFR_OFFSET		0x4
#define XTMR_MANAGER_CMR0_OFFSET	0x8
#define XTMR_MANAGER_CMR1_OFFSET	0xC
#define XTMR_MANAGER_BDIR_OFFSET	0x10
#define XTMR_MANAGER_SEMIMR_OFFSET	0x1C

/* Register Bitmasks/shifts */
#define XTMR_MANAGER_CR_MAGIC1_MASK	GENMASK(7, 0)
#define XTMR_MANAGER_CR_MAGIC2_MASK	GENMASK(15, 8)
#define XTMR_MANAGER_CR_RIR_MASK	BIT(16)
#define XTMR_MANAGER_FFR_LM12_MASK	BIT(0)
#define XTMR_MANAGER_FFR_LM13_MASK	BIT(1)
#define XTMR_MANAGER_FFR_LM23_MASK	BIT(2)

#define XTMR_MANAGER_CR_MAGIC2_SHIFT	4
#define XTMR_MANAGER_CR_RIR_SHIFT	16
#define XTMR_MANAGER_CR_BB_SHIFT	18

#define XTMR_MANAGER_MAGIC1_MAX_VAL	255

/**
 * struct xtmr_manager_dev - Driver data for TMR Manager
 * @regs: device physical base address
 * @cr_val: control register value
 * @magic1: Magic 1 hardware configuration value
 * @err_cnt: error statistics count
 * @phys_baseaddr: Physical base address
 */
struct xtmr_manager_dev {
	void __iomem *regs;
	u32 cr_val;
	u32 magic1;
	u32 err_cnt;
	resource_size_t phys_baseaddr;
};

/* IO accessors */
static inline void xtmr_manager_write(struct xtmr_manager_dev *xtmr_manager,
				      u32 addr, u32 value)
{
	iowrite32(value, xtmr_manager->regs + addr);
}

static inline u32 xtmr_manager_read(struct xtmr_manager_dev *xtmr_manager,
				    u32 addr)
{
	return ioread32(xtmr_manager->regs + addr);
}

static void xmb_manager_reset_handler(struct xtmr_manager_dev *xtmr_manager)
{
	/* Clear the FFR Register contents as a part of recovery process. */
	xtmr_manager_write(xtmr_manager, XTMR_MANAGER_FFR_OFFSET, 0);
}

static void xmb_manager_update_errcnt(struct xtmr_manager_dev *xtmr_manager)
{
	xtmr_manager->err_cnt++;
}

static ssize_t errcnt_show(struct device *dev, struct device_attribute *attr,
			   char *buf)
{
	struct xtmr_manager_dev *xtmr_manager = dev_get_drvdata(dev);

	return sysfs_emit(buf, "%x\n", xtmr_manager->err_cnt);
}
static DEVICE_ATTR_RO(errcnt);

static ssize_t dis_block_break_store(struct device *dev,
				     struct device_attribute *attr,
				     const char *buf, size_t size)
{
	struct xtmr_manager_dev *xtmr_manager = dev_get_drvdata(dev);
	int ret;
	long value;

	ret = kstrtoul(buf, 16, &value);
	if (ret)
		return ret;

	/* unblock the break signal*/
	xtmr_manager->cr_val &= ~(1 << XTMR_MANAGER_CR_BB_SHIFT);
	xtmr_manager_write(xtmr_manager, XTMR_MANAGER_CR_OFFSET,
			   xtmr_manager->cr_val);
	return size;
}
static DEVICE_ATTR_WO(dis_block_break);

static struct attribute *xtmr_manager_dev_attrs[] = {
	&dev_attr_dis_block_break.attr,
	&dev_attr_errcnt.attr,
	NULL,
};
ATTRIBUTE_GROUPS(xtmr_manager_dev);

static void xtmr_manager_init(struct xtmr_manager_dev *xtmr_manager)
{
	/* Clear the SEM interrupt mask register to disable the interrupt */
	xtmr_manager_write(xtmr_manager, XTMR_MANAGER_SEMIMR_OFFSET, 0);

	/* Allow recovery reset by default */
	xtmr_manager->cr_val = (1 << XTMR_MANAGER_CR_RIR_SHIFT) |
				xtmr_manager->magic1;
	xtmr_manager_write(xtmr_manager, XTMR_MANAGER_CR_OFFSET,
			   xtmr_manager->cr_val);
	/*
	 * Configure Break Delay Initialization Register to zero so that
	 * break occurs immediately
	 */
	xtmr_manager_write(xtmr_manager, XTMR_MANAGER_BDIR_OFFSET, 0);

	/*
	 * To come out of break handler need to block the break signal
	 * in the tmr manager, update the xtmr_manager cr_val for the same
	 */
	xtmr_manager->cr_val |= (1 << XTMR_MANAGER_CR_BB_SHIFT);

	/*
	 * When the break vector gets asserted because of error injection,
	 * the break signal must be blocked before exiting from the
	 * break handler, Below api updates the TMR manager address and
	 * control register and error counter callback arguments,
	 * which will be used by the break handler to block the
	 * break and call the callback function.
	 */
	xmb_manager_register(xtmr_manager->phys_baseaddr, xtmr_manager->cr_val,
			     (void *)xmb_manager_update_errcnt,
			     xtmr_manager, (void *)xmb_manager_reset_handler);
}

/**
 * xtmr_manager_probe - Driver probe function
 * @pdev: Pointer to the platform_device structure
 *
 * This is the driver probe routine. It does all the memory
 * allocation for the device.
 *
 * Return: 0 on success and failure value on error
 */
static int xtmr_manager_probe(struct platform_device *pdev)
{
	struct xtmr_manager_dev *xtmr_manager;
	struct resource *res;
	int err;

	xtmr_manager = devm_kzalloc(&pdev->dev, sizeof(*xtmr_manager),
				    GFP_KERNEL);
	if (!xtmr_manager)
		return -ENOMEM;

	xtmr_manager->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
	if (IS_ERR(xtmr_manager->regs))
		return PTR_ERR(xtmr_manager->regs);

	xtmr_manager->phys_baseaddr = res->start;

	err = of_property_read_u32(pdev->dev.of_node, "xlnx,magic1",
				   &xtmr_manager->magic1);
	if (err < 0) {
		dev_err(&pdev->dev, "unable to read xlnx,magic1 property");
		return err;
	}

	if (xtmr_manager->magic1 > XTMR_MANAGER_MAGIC1_MAX_VAL) {
		dev_err(&pdev->dev, "invalid xlnx,magic1 property value");
		return -EINVAL;
	}

	/* Initialize TMR Manager */
	xtmr_manager_init(xtmr_manager);

	platform_set_drvdata(pdev, xtmr_manager);

	return 0;
}

static const struct of_device_id xtmr_manager_of_match[] = {
	{
		.compatible = "xlnx,tmr-manager-1.0",
	},
	{ /* end of table */ }
};
MODULE_DEVICE_TABLE(of, xtmr_manager_of_match);

static struct platform_driver xtmr_manager_driver = {
	.driver = {
		.name = "xilinx-tmr_manager",
		.of_match_table = xtmr_manager_of_match,
		.dev_groups = xtmr_manager_dev_groups,
	},
	.probe = xtmr_manager_probe,
};
module_platform_driver(xtmr_manager_driver);

MODULE_AUTHOR("Advanced Micro Devices, Inc");
MODULE_DESCRIPTION("Xilinx TMR Manager Driver");
MODULE_LICENSE("GPL");
