// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * CoreNet Coherency Fabric error reporting
 *
 * Copyright 2014 Freescale Semiconductor Inc.
 */

#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/property.h>

enum ccf_version {
	CCF1,
	CCF2,
};

struct ccf_info {
	enum ccf_version version;
	int err_reg_offs;
	bool has_brr;
};

static const struct ccf_info ccf1_info = {
	.version = CCF1,
	.err_reg_offs = 0xa00,
	.has_brr = false,
};

static const struct ccf_info ccf2_info = {
	.version = CCF2,
	.err_reg_offs = 0xe40,
	.has_brr = true,
};

/*
 * This register is present but not documented, with different values for
 * IP_ID, on other chips with fsl,corenet2-cf such as t4240 and b4860.
 */
#define CCF_BRR			0xbf8
#define CCF_BRR_IPID		0xffff0000
#define CCF_BRR_IPID_T1040	0x09310000

static const struct of_device_id ccf_matches[] = {
	{
		.compatible = "fsl,corenet1-cf",
		.data = &ccf1_info,
	},
	{
		.compatible = "fsl,corenet2-cf",
		.data = &ccf2_info,
	},
	{}
};
MODULE_DEVICE_TABLE(of, ccf_matches);

struct ccf_err_regs {
	u32 errdet;		/* 0x00 Error Detect Register */
	/* 0x04 Error Enable (ccf1)/Disable (ccf2) Register */
	u32 errdis;
	/* 0x08 Error Interrupt Enable Register (ccf2 only) */
	u32 errinten;
	u32 cecar;		/* 0x0c Error Capture Attribute Register */
	u32 cecaddrh;		/* 0x10 Error Capture Address High */
	u32 cecaddrl;		/* 0x14 Error Capture Address Low */
	u32 cecar2;		/* 0x18 Error Capture Attribute Register 2 */
};

/* LAE/CV also valid for errdis and errinten */
#define ERRDET_LAE		(1 << 0)  /* Local Access Error */
#define ERRDET_CV		(1 << 1)  /* Coherency Violation */
#define ERRDET_UTID		(1 << 2)  /* Unavailable Target ID (t1040) */
#define ERRDET_MCST		(1 << 3)  /* Multicast Stash (t1040) */
#define ERRDET_CTYPE_SHIFT	26	  /* Capture Type (ccf2 only) */
#define ERRDET_CTYPE_MASK	(0x1f << ERRDET_CTYPE_SHIFT)
#define ERRDET_CAP		(1 << 31) /* Capture Valid (ccf2 only) */

#define CECAR_VAL		(1 << 0)  /* Valid (ccf1 only) */
#define CECAR_UVT		(1 << 15) /* Unavailable target ID (ccf1) */
#define CECAR_SRCID_SHIFT_CCF1	24
#define CECAR_SRCID_MASK_CCF1	(0xff << CECAR_SRCID_SHIFT_CCF1)
#define CECAR_SRCID_SHIFT_CCF2	18
#define CECAR_SRCID_MASK_CCF2	(0xff << CECAR_SRCID_SHIFT_CCF2)

#define CECADDRH_ADDRH		0xff

struct ccf_private {
	const struct ccf_info *info;
	struct device *dev;
	void __iomem *regs;
	struct ccf_err_regs __iomem *err_regs;
	bool t1040;
};

static irqreturn_t ccf_irq(int irq, void *dev_id)
{
	struct ccf_private *ccf = dev_id;
	static DEFINE_RATELIMIT_STATE(ratelimit, DEFAULT_RATELIMIT_INTERVAL,
				      DEFAULT_RATELIMIT_BURST);
	u32 errdet, cecar, cecar2;
	u64 addr;
	u32 src_id;
	bool uvt = false;
	bool cap_valid = false;

	errdet = ioread32be(&ccf->err_regs->errdet);
	cecar = ioread32be(&ccf->err_regs->cecar);
	cecar2 = ioread32be(&ccf->err_regs->cecar2);
	addr = ioread32be(&ccf->err_regs->cecaddrl);
	addr |= ((u64)(ioread32be(&ccf->err_regs->cecaddrh) &
		       CECADDRH_ADDRH)) << 32;

	if (!__ratelimit(&ratelimit))
		goto out;

	switch (ccf->info->version) {
	case CCF1:
		if (cecar & CECAR_VAL) {
			if (cecar & CECAR_UVT)
				uvt = true;

			src_id = (cecar & CECAR_SRCID_MASK_CCF1) >>
				 CECAR_SRCID_SHIFT_CCF1;
			cap_valid = true;
		}

		break;
	case CCF2:
		if (errdet & ERRDET_CAP) {
			src_id = (cecar & CECAR_SRCID_MASK_CCF2) >>
				 CECAR_SRCID_SHIFT_CCF2;
			cap_valid = true;
		}

		break;
	}

	dev_crit(ccf->dev, "errdet 0x%08x cecar 0x%08x cecar2 0x%08x\n",
		 errdet, cecar, cecar2);

	if (errdet & ERRDET_LAE) {
		if (uvt)
			dev_crit(ccf->dev, "LAW Unavailable Target ID\n");
		else
			dev_crit(ccf->dev, "Local Access Window Error\n");
	}

	if (errdet & ERRDET_CV)
		dev_crit(ccf->dev, "Coherency Violation\n");

	if (errdet & ERRDET_UTID)
		dev_crit(ccf->dev, "Unavailable Target ID\n");

	if (errdet & ERRDET_MCST)
		dev_crit(ccf->dev, "Multicast Stash\n");

	if (cap_valid) {
		dev_crit(ccf->dev, "address 0x%09llx, src id 0x%x\n",
			 addr, src_id);
	}

out:
	iowrite32be(errdet, &ccf->err_regs->errdet);
	return errdet ? IRQ_HANDLED : IRQ_NONE;
}

static int ccf_probe(struct platform_device *pdev)
{
	struct ccf_private *ccf;
	u32 errinten;
	int ret, irq;

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

	ccf->regs = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(ccf->regs))
		return PTR_ERR(ccf->regs);

	ccf->dev = &pdev->dev;
	ccf->info = device_get_match_data(&pdev->dev);
	ccf->err_regs = ccf->regs + ccf->info->err_reg_offs;

	if (ccf->info->has_brr) {
		u32 brr = ioread32be(ccf->regs + CCF_BRR);

		if ((brr & CCF_BRR_IPID) == CCF_BRR_IPID_T1040)
			ccf->t1040 = true;
	}

	dev_set_drvdata(&pdev->dev, ccf);

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	ret = devm_request_irq(&pdev->dev, irq, ccf_irq, 0, pdev->name, ccf);
	if (ret) {
		dev_err(&pdev->dev, "%s: can't request irq\n", __func__);
		return ret;
	}

	errinten = ERRDET_LAE | ERRDET_CV;
	if (ccf->t1040)
		errinten |= ERRDET_UTID | ERRDET_MCST;

	switch (ccf->info->version) {
	case CCF1:
		/* On CCF1 this register enables rather than disables. */
		iowrite32be(errinten, &ccf->err_regs->errdis);
		break;

	case CCF2:
		iowrite32be(0, &ccf->err_regs->errdis);
		iowrite32be(errinten, &ccf->err_regs->errinten);
		break;
	}

	return 0;
}

static void ccf_remove(struct platform_device *pdev)
{
	struct ccf_private *ccf = dev_get_drvdata(&pdev->dev);

	switch (ccf->info->version) {
	case CCF1:
		iowrite32be(0, &ccf->err_regs->errdis);
		break;

	case CCF2:
		/*
		 * We clear errdis on ccf1 because that's the only way to
		 * disable interrupts, but on ccf2 there's no need to disable
		 * detection.
		 */
		iowrite32be(0, &ccf->err_regs->errinten);
		break;
	}
}

static struct platform_driver ccf_driver = {
	.driver = {
		.name = KBUILD_MODNAME,
		.of_match_table = ccf_matches,
	},
	.probe = ccf_probe,
	.remove_new = ccf_remove,
};

module_platform_driver(ccf_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Freescale Semiconductor");
MODULE_DESCRIPTION("Freescale CoreNet Coherency Fabric error reporting");
