// SPDX-License-Identifier: GPL-2.0-only
/*
 * Freescale MU used as MSI controller
 *
 * Copyright (c) 2018 Pengutronix, Oleksij Rempel <o.rempel@pengutronix.de>
 * Copyright 2022 NXP
 *	Frank Li <Frank.Li@nxp.com>
 *	Peng Fan <peng.fan@nxp.com>
 *
 * Based on drivers/mailbox/imx-mailbox.c
 */

#include <linux/clk.h>
#include <linux/irq.h>
#include <linux/irqchip.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/irqdomain.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/msi.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/pm_runtime.h>
#include <linux/pm_domain.h>
#include <linux/spinlock.h>

#define IMX_MU_CHANS            4

enum imx_mu_xcr {
	IMX_MU_GIER,
	IMX_MU_GCR,
	IMX_MU_TCR,
	IMX_MU_RCR,
	IMX_MU_xCR_MAX,
};

enum imx_mu_xsr {
	IMX_MU_SR,
	IMX_MU_GSR,
	IMX_MU_TSR,
	IMX_MU_RSR,
	IMX_MU_xSR_MAX
};

enum imx_mu_type {
	IMX_MU_V2 = BIT(1),
};

/* Receive Interrupt Enable */
#define IMX_MU_xCR_RIEn(data, x) ((data->cfg->type) & IMX_MU_V2 ? BIT(x) : BIT(24 + (3 - (x))))
#define IMX_MU_xSR_RFn(data, x) ((data->cfg->type) & IMX_MU_V2 ? BIT(x) : BIT(24 + (3 - (x))))

struct imx_mu_dcfg {
	enum imx_mu_type type;
	u32     xTR;            /* Transmit Register0 */
	u32     xRR;            /* Receive Register0 */
	u32     xSR[IMX_MU_xSR_MAX];         /* Status Registers */
	u32     xCR[IMX_MU_xCR_MAX];         /* Control Registers */
};

struct imx_mu_msi {
	raw_spinlock_t			lock;
	struct irq_domain		*msi_domain;
	void __iomem			*regs;
	phys_addr_t			msiir_addr;
	const struct imx_mu_dcfg	*cfg;
	unsigned long			used;
	struct clk			*clk;
};

static void imx_mu_write(struct imx_mu_msi *msi_data, u32 val, u32 offs)
{
	iowrite32(val, msi_data->regs + offs);
}

static u32 imx_mu_read(struct imx_mu_msi *msi_data, u32 offs)
{
	return ioread32(msi_data->regs + offs);
}

static u32 imx_mu_xcr_rmw(struct imx_mu_msi *msi_data, enum imx_mu_xcr type, u32 set, u32 clr)
{
	unsigned long flags;
	u32 val;

	raw_spin_lock_irqsave(&msi_data->lock, flags);
	val = imx_mu_read(msi_data, msi_data->cfg->xCR[type]);
	val &= ~clr;
	val |= set;
	imx_mu_write(msi_data, val, msi_data->cfg->xCR[type]);
	raw_spin_unlock_irqrestore(&msi_data->lock, flags);

	return val;
}

static void imx_mu_msi_parent_mask_irq(struct irq_data *data)
{
	struct imx_mu_msi *msi_data = irq_data_get_irq_chip_data(data);

	imx_mu_xcr_rmw(msi_data, IMX_MU_RCR, 0, IMX_MU_xCR_RIEn(msi_data, data->hwirq));
}

static void imx_mu_msi_parent_unmask_irq(struct irq_data *data)
{
	struct imx_mu_msi *msi_data = irq_data_get_irq_chip_data(data);

	imx_mu_xcr_rmw(msi_data, IMX_MU_RCR, IMX_MU_xCR_RIEn(msi_data, data->hwirq), 0);
}

static void imx_mu_msi_parent_ack_irq(struct irq_data *data)
{
	struct imx_mu_msi *msi_data = irq_data_get_irq_chip_data(data);

	imx_mu_read(msi_data, msi_data->cfg->xRR + data->hwirq * 4);
}

static struct irq_chip imx_mu_msi_irq_chip = {
	.name = "MU-MSI",
	.irq_ack = irq_chip_ack_parent,
};

static struct msi_domain_ops imx_mu_msi_irq_ops = {
};

static struct msi_domain_info imx_mu_msi_domain_info = {
	.flags	= (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS),
	.ops	= &imx_mu_msi_irq_ops,
	.chip	= &imx_mu_msi_irq_chip,
};

static void imx_mu_msi_parent_compose_msg(struct irq_data *data,
					  struct msi_msg *msg)
{
	struct imx_mu_msi *msi_data = irq_data_get_irq_chip_data(data);
	u64 addr = msi_data->msiir_addr + 4 * data->hwirq;

	msg->address_hi = upper_32_bits(addr);
	msg->address_lo = lower_32_bits(addr);
	msg->data = data->hwirq;
}

static int imx_mu_msi_parent_set_affinity(struct irq_data *irq_data,
				   const struct cpumask *mask, bool force)
{
	return -EINVAL;
}

static struct irq_chip imx_mu_msi_parent_chip = {
	.name		= "MU",
	.irq_mask	= imx_mu_msi_parent_mask_irq,
	.irq_unmask	= imx_mu_msi_parent_unmask_irq,
	.irq_ack	= imx_mu_msi_parent_ack_irq,
	.irq_compose_msi_msg	= imx_mu_msi_parent_compose_msg,
	.irq_set_affinity = imx_mu_msi_parent_set_affinity,
};

static int imx_mu_msi_domain_irq_alloc(struct irq_domain *domain,
					unsigned int virq,
					unsigned int nr_irqs,
					void *args)
{
	struct imx_mu_msi *msi_data = domain->host_data;
	unsigned long flags;
	int pos, err = 0;

	WARN_ON(nr_irqs != 1);

	raw_spin_lock_irqsave(&msi_data->lock, flags);
	pos = find_first_zero_bit(&msi_data->used, IMX_MU_CHANS);
	if (pos < IMX_MU_CHANS)
		__set_bit(pos, &msi_data->used);
	else
		err = -ENOSPC;
	raw_spin_unlock_irqrestore(&msi_data->lock, flags);

	if (err)
		return err;

	irq_domain_set_info(domain, virq, pos,
			    &imx_mu_msi_parent_chip, msi_data,
			    handle_edge_irq, NULL, NULL);
	return 0;
}

static void imx_mu_msi_domain_irq_free(struct irq_domain *domain,
				       unsigned int virq, unsigned int nr_irqs)
{
	struct irq_data *d = irq_domain_get_irq_data(domain, virq);
	struct imx_mu_msi *msi_data = irq_data_get_irq_chip_data(d);
	unsigned long flags;

	raw_spin_lock_irqsave(&msi_data->lock, flags);
	__clear_bit(d->hwirq, &msi_data->used);
	raw_spin_unlock_irqrestore(&msi_data->lock, flags);
}

static const struct irq_domain_ops imx_mu_msi_domain_ops = {
	.alloc	= imx_mu_msi_domain_irq_alloc,
	.free	= imx_mu_msi_domain_irq_free,
};

static void imx_mu_msi_irq_handler(struct irq_desc *desc)
{
	struct imx_mu_msi *msi_data = irq_desc_get_handler_data(desc);
	struct irq_chip *chip = irq_desc_get_chip(desc);
	u32 status;
	int i;

	status = imx_mu_read(msi_data, msi_data->cfg->xSR[IMX_MU_RSR]);

	chained_irq_enter(chip, desc);
	for (i = 0; i < IMX_MU_CHANS; i++) {
		if (status & IMX_MU_xSR_RFn(msi_data, i))
			generic_handle_domain_irq(msi_data->msi_domain, i);
	}
	chained_irq_exit(chip, desc);
}

static int imx_mu_msi_domains_init(struct imx_mu_msi *msi_data, struct device *dev)
{
	struct fwnode_handle *fwnodes = dev_fwnode(dev);
	struct irq_domain *parent;

	/* Initialize MSI domain parent */
	parent = irq_domain_create_linear(fwnodes,
					    IMX_MU_CHANS,
					    &imx_mu_msi_domain_ops,
					    msi_data);
	if (!parent) {
		dev_err(dev, "failed to create IRQ domain\n");
		return -ENOMEM;
	}

	irq_domain_update_bus_token(parent, DOMAIN_BUS_NEXUS);

	msi_data->msi_domain = platform_msi_create_irq_domain(fwnodes,
					&imx_mu_msi_domain_info,
					parent);

	if (!msi_data->msi_domain) {
		dev_err(dev, "failed to create MSI domain\n");
		irq_domain_remove(parent);
		return -ENOMEM;
	}

	irq_domain_set_pm_device(msi_data->msi_domain, dev);

	return 0;
}

/* Register offset of different version MU IP */
static const struct imx_mu_dcfg imx_mu_cfg_imx6sx = {
	.type	= 0,
	.xTR    = 0x0,
	.xRR    = 0x10,
	.xSR    = {
			[IMX_MU_SR]  = 0x20,
			[IMX_MU_GSR] = 0x20,
			[IMX_MU_TSR] = 0x20,
			[IMX_MU_RSR] = 0x20,
		  },
	.xCR    = {
			[IMX_MU_GIER] = 0x24,
			[IMX_MU_GCR]  = 0x24,
			[IMX_MU_TCR]  = 0x24,
			[IMX_MU_RCR]  = 0x24,
		  },
};

static const struct imx_mu_dcfg imx_mu_cfg_imx7ulp = {
	.type	= 0,
	.xTR    = 0x20,
	.xRR    = 0x40,
	.xSR    = {
			[IMX_MU_SR]  = 0x60,
			[IMX_MU_GSR] = 0x60,
			[IMX_MU_TSR] = 0x60,
			[IMX_MU_RSR] = 0x60,
		  },
	.xCR    = {
			[IMX_MU_GIER] = 0x64,
			[IMX_MU_GCR]  = 0x64,
			[IMX_MU_TCR]  = 0x64,
			[IMX_MU_RCR]  = 0x64,
		  },
};

static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp = {
	.type   = IMX_MU_V2,
	.xTR    = 0x200,
	.xRR    = 0x280,
	.xSR    = {
			[IMX_MU_SR]  = 0xC,
			[IMX_MU_GSR] = 0x118,
			[IMX_MU_TSR] = 0x124,
			[IMX_MU_RSR] = 0x12C,
		  },
	.xCR    = {
			[IMX_MU_GIER] = 0x110,
			[IMX_MU_GCR]  = 0x114,
			[IMX_MU_TCR]  = 0x120,
			[IMX_MU_RCR]  = 0x128
		  },
};

static int __init imx_mu_of_init(struct device_node *dn,
				 struct device_node *parent,
				 const struct imx_mu_dcfg *cfg)
{
	struct platform_device *pdev = of_find_device_by_node(dn);
	struct device_link *pd_link_a;
	struct device_link *pd_link_b;
	struct imx_mu_msi *msi_data;
	struct resource *res;
	struct device *pd_a;
	struct device *pd_b;
	struct device *dev;
	int ret;
	int irq;

	dev = &pdev->dev;

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

	msi_data->cfg = cfg;

	msi_data->regs = devm_platform_ioremap_resource_byname(pdev, "processor-a-side");
	if (IS_ERR(msi_data->regs)) {
		dev_err(&pdev->dev, "failed to initialize 'regs'\n");
		return PTR_ERR(msi_data->regs);
	}

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "processor-b-side");
	if (!res)
		return -EIO;

	msi_data->msiir_addr = res->start + msi_data->cfg->xTR;

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

	platform_set_drvdata(pdev, msi_data);

	msi_data->clk = devm_clk_get(dev, NULL);
	if (IS_ERR(msi_data->clk))
		return PTR_ERR(msi_data->clk);

	pd_a = dev_pm_domain_attach_by_name(dev, "processor-a-side");
	if (IS_ERR(pd_a))
		return PTR_ERR(pd_a);

	pd_b = dev_pm_domain_attach_by_name(dev, "processor-b-side");
	if (IS_ERR(pd_b))
		return PTR_ERR(pd_b);

	pd_link_a = device_link_add(dev, pd_a,
			DL_FLAG_STATELESS |
			DL_FLAG_PM_RUNTIME |
			DL_FLAG_RPM_ACTIVE);

	if (!pd_link_a) {
		dev_err(dev, "Failed to add device_link to mu a.\n");
		goto err_pd_a;
	}

	pd_link_b = device_link_add(dev, pd_b,
			DL_FLAG_STATELESS |
			DL_FLAG_PM_RUNTIME |
			DL_FLAG_RPM_ACTIVE);


	if (!pd_link_b) {
		dev_err(dev, "Failed to add device_link to mu a.\n");
		goto err_pd_b;
	}

	ret = imx_mu_msi_domains_init(msi_data, dev);
	if (ret)
		goto err_dm_init;

	pm_runtime_enable(dev);

	irq_set_chained_handler_and_data(irq,
					 imx_mu_msi_irq_handler,
					 msi_data);

	return 0;

err_dm_init:
	device_link_remove(dev,	pd_b);
err_pd_b:
	device_link_remove(dev, pd_a);
err_pd_a:
	return -EINVAL;
}

static int __maybe_unused imx_mu_runtime_suspend(struct device *dev)
{
	struct imx_mu_msi *priv = dev_get_drvdata(dev);

	clk_disable_unprepare(priv->clk);

	return 0;
}

static int __maybe_unused imx_mu_runtime_resume(struct device *dev)
{
	struct imx_mu_msi *priv = dev_get_drvdata(dev);
	int ret;

	ret = clk_prepare_enable(priv->clk);
	if (ret)
		dev_err(dev, "failed to enable clock\n");

	return ret;
}

static const struct dev_pm_ops imx_mu_pm_ops = {
	SET_RUNTIME_PM_OPS(imx_mu_runtime_suspend,
			   imx_mu_runtime_resume, NULL)
};

static int __init imx_mu_imx7ulp_of_init(struct device_node *dn,
					 struct device_node *parent)
{
	return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx7ulp);
}

static int __init imx_mu_imx6sx_of_init(struct device_node *dn,
					struct device_node *parent)
{
	return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx6sx);
}

static int __init imx_mu_imx8ulp_of_init(struct device_node *dn,
					 struct device_node *parent)
{
	return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx8ulp);
}

IRQCHIP_PLATFORM_DRIVER_BEGIN(imx_mu_msi)
IRQCHIP_MATCH("fsl,imx7ulp-mu-msi", imx_mu_imx7ulp_of_init)
IRQCHIP_MATCH("fsl,imx6sx-mu-msi", imx_mu_imx6sx_of_init)
IRQCHIP_MATCH("fsl,imx8ulp-mu-msi", imx_mu_imx8ulp_of_init)
IRQCHIP_PLATFORM_DRIVER_END(imx_mu_msi, .pm = &imx_mu_pm_ops)


MODULE_AUTHOR("Frank Li <Frank.Li@nxp.com>");
MODULE_DESCRIPTION("Freescale MU MSI controller driver");
MODULE_LICENSE("GPL");
