// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
 * Copyright (C) 2014 Oleksij Rempel <linux@rempel-privat.de>
 *	Add Alphascale ASM9260 support.
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/irqchip.h>
#include <linux/irqdomain.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/stmp_device.h>
#include <asm/exception.h>

#include "alphascale_asm9260-icoll.h"

/*
 * this device provide 4 offsets for each register:
 * 0x0 - plain read write mode
 * 0x4 - set mode, OR logic.
 * 0x8 - clr mode, XOR logic.
 * 0xc - togle mode.
 */
#define SET_REG 4
#define CLR_REG 8

#define HW_ICOLL_VECTOR				0x0000
#define HW_ICOLL_LEVELACK			0x0010
#define HW_ICOLL_CTRL				0x0020
#define HW_ICOLL_STAT_OFFSET			0x0070
#define HW_ICOLL_INTERRUPT0			0x0120
#define HW_ICOLL_INTERRUPTn(n)			((n) * 0x10)
#define BM_ICOLL_INTR_ENABLE			BIT(2)
#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0	0x1

#define ICOLL_NUM_IRQS		128

enum icoll_type {
	ICOLL,
	ASM9260_ICOLL,
};

struct icoll_priv {
	void __iomem *vector;
	void __iomem *levelack;
	void __iomem *ctrl;
	void __iomem *stat;
	void __iomem *intr;
	void __iomem *clear;
	enum icoll_type type;
};

static struct icoll_priv icoll_priv;
static struct irq_domain *icoll_domain;

/* calculate bit offset depending on number of interrupt per register */
static u32 icoll_intr_bitshift(struct irq_data *d, u32 bit)
{
	/*
	 * mask lower part of hwirq to convert it
	 * in 0, 1, 2 or 3 and then multiply it by 8 (or shift by 3)
	 */
	return bit << ((d->hwirq & 3) << 3);
}

/* calculate mem offset depending on number of interrupt per register */
static void __iomem *icoll_intr_reg(struct irq_data *d)
{
	/* offset = hwirq / intr_per_reg * 0x10 */
	return icoll_priv.intr + ((d->hwirq >> 2) * 0x10);
}

static void icoll_ack_irq(struct irq_data *d)
{
	/*
	 * The Interrupt Collector is able to prioritize irqs.
	 * Currently only level 0 is used. So acking can use
	 * BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 unconditionally.
	 */
	__raw_writel(BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0,
			icoll_priv.levelack);
}

static void icoll_mask_irq(struct irq_data *d)
{
	__raw_writel(BM_ICOLL_INTR_ENABLE,
			icoll_priv.intr + CLR_REG + HW_ICOLL_INTERRUPTn(d->hwirq));
}

static void icoll_unmask_irq(struct irq_data *d)
{
	__raw_writel(BM_ICOLL_INTR_ENABLE,
			icoll_priv.intr + SET_REG + HW_ICOLL_INTERRUPTn(d->hwirq));
}

static void asm9260_mask_irq(struct irq_data *d)
{
	__raw_writel(icoll_intr_bitshift(d, BM_ICOLL_INTR_ENABLE),
			icoll_intr_reg(d) + CLR_REG);
}

static void asm9260_unmask_irq(struct irq_data *d)
{
	__raw_writel(ASM9260_BM_CLEAR_BIT(d->hwirq),
		     icoll_priv.clear +
		     ASM9260_HW_ICOLL_CLEARn(d->hwirq));

	__raw_writel(icoll_intr_bitshift(d, BM_ICOLL_INTR_ENABLE),
			icoll_intr_reg(d) + SET_REG);
}

static struct irq_chip mxs_icoll_chip = {
	.irq_ack = icoll_ack_irq,
	.irq_mask = icoll_mask_irq,
	.irq_unmask = icoll_unmask_irq,
	.flags = IRQCHIP_MASK_ON_SUSPEND |
		 IRQCHIP_SKIP_SET_WAKE,
};

static struct irq_chip asm9260_icoll_chip = {
	.irq_ack = icoll_ack_irq,
	.irq_mask = asm9260_mask_irq,
	.irq_unmask = asm9260_unmask_irq,
	.flags = IRQCHIP_MASK_ON_SUSPEND |
		 IRQCHIP_SKIP_SET_WAKE,
};

asmlinkage void __exception_irq_entry icoll_handle_irq(struct pt_regs *regs)
{
	u32 irqnr;

	irqnr = __raw_readl(icoll_priv.stat);
	__raw_writel(irqnr, icoll_priv.vector);
	handle_domain_irq(icoll_domain, irqnr, regs);
}

static int icoll_irq_domain_map(struct irq_domain *d, unsigned int virq,
				irq_hw_number_t hw)
{
	struct irq_chip *chip;

	if (icoll_priv.type == ICOLL)
		chip = &mxs_icoll_chip;
	else
		chip = &asm9260_icoll_chip;

	irq_set_chip_and_handler(virq, chip, handle_level_irq);

	return 0;
}

static const struct irq_domain_ops icoll_irq_domain_ops = {
	.map = icoll_irq_domain_map,
	.xlate = irq_domain_xlate_onecell,
};

static void __init icoll_add_domain(struct device_node *np,
			  int num)
{
	icoll_domain = irq_domain_add_linear(np, num,
					     &icoll_irq_domain_ops, NULL);

	if (!icoll_domain)
		panic("%pOF: unable to create irq domain", np);
}

static void __iomem * __init icoll_init_iobase(struct device_node *np)
{
	void __iomem *icoll_base;

	icoll_base = of_io_request_and_map(np, 0, np->name);
	if (IS_ERR(icoll_base))
		panic("%pOF: unable to map resource", np);
	return icoll_base;
}

static int __init icoll_of_init(struct device_node *np,
			  struct device_node *interrupt_parent)
{
	void __iomem *icoll_base;

	icoll_priv.type = ICOLL;

	icoll_base		= icoll_init_iobase(np);
	icoll_priv.vector	= icoll_base + HW_ICOLL_VECTOR;
	icoll_priv.levelack	= icoll_base + HW_ICOLL_LEVELACK;
	icoll_priv.ctrl		= icoll_base + HW_ICOLL_CTRL;
	icoll_priv.stat		= icoll_base + HW_ICOLL_STAT_OFFSET;
	icoll_priv.intr		= icoll_base + HW_ICOLL_INTERRUPT0;
	icoll_priv.clear	= NULL;

	/*
	 * Interrupt Collector reset, which initializes the priority
	 * for each irq to level 0.
	 */
	stmp_reset_block(icoll_priv.ctrl);

	icoll_add_domain(np, ICOLL_NUM_IRQS);

	return 0;
}
IRQCHIP_DECLARE(mxs, "fsl,icoll", icoll_of_init);

static int __init asm9260_of_init(struct device_node *np,
			  struct device_node *interrupt_parent)
{
	void __iomem *icoll_base;
	int i;

	icoll_priv.type = ASM9260_ICOLL;

	icoll_base = icoll_init_iobase(np);
	icoll_priv.vector	= icoll_base + ASM9260_HW_ICOLL_VECTOR;
	icoll_priv.levelack	= icoll_base + ASM9260_HW_ICOLL_LEVELACK;
	icoll_priv.ctrl		= icoll_base + ASM9260_HW_ICOLL_CTRL;
	icoll_priv.stat		= icoll_base + ASM9260_HW_ICOLL_STAT_OFFSET;
	icoll_priv.intr		= icoll_base + ASM9260_HW_ICOLL_INTERRUPT0;
	icoll_priv.clear	= icoll_base + ASM9260_HW_ICOLL_CLEAR0;

	writel_relaxed(ASM9260_BM_CTRL_IRQ_ENABLE,
			icoll_priv.ctrl);
	/*
	 * ASM9260 don't provide reset bit. So, we need to set level 0
	 * manually.
	 */
	for (i = 0; i < 16 * 0x10; i += 0x10)
		writel(0, icoll_priv.intr + i);

	icoll_add_domain(np, ASM9260_NUM_IRQS);
	set_handle_irq(icoll_handle_irq);

	return 0;
}
IRQCHIP_DECLARE(asm9260, "alphascale,asm9260-icoll", asm9260_of_init);
