// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/module.h>
#include <linux/irqdomain.h>
#include <linux/irqchip.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <asm/irq.h>

#define INTC_IRQS		64

#define CK_INTC_ICR		0x00
#define CK_INTC_PEN31_00	0x14
#define CK_INTC_PEN63_32	0x2c
#define CK_INTC_NEN31_00	0x10
#define CK_INTC_NEN63_32	0x28
#define CK_INTC_SOURCE		0x40
#define CK_INTC_DUAL_BASE	0x100

#define GX_INTC_PEN31_00	0x00
#define GX_INTC_PEN63_32	0x04
#define GX_INTC_NEN31_00	0x40
#define GX_INTC_NEN63_32	0x44
#define GX_INTC_NMASK31_00	0x50
#define GX_INTC_NMASK63_32	0x54
#define GX_INTC_SOURCE		0x60

static void __iomem *reg_base;
static struct irq_domain *root_domain;

static int nr_irq = INTC_IRQS;

/*
 * When controller support pulse signal, the PEN_reg will hold on signal
 * without software trigger.
 *
 * So, to support pulse signal we need to clear IFR_reg and the address of
 * IFR_offset is NEN_offset - 8.
 */
static void irq_ck_mask_set_bit(struct irq_data *d)
{
	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
	struct irq_chip_type *ct = irq_data_get_chip_type(d);
	unsigned long ifr = ct->regs.mask - 8;
	u32 mask = d->mask;

	irq_gc_lock(gc);
	*ct->mask_cache |= mask;
	irq_reg_writel(gc, *ct->mask_cache, ct->regs.mask);
	irq_reg_writel(gc, irq_reg_readl(gc, ifr) & ~mask, ifr);
	irq_gc_unlock(gc);
}

static void __init ck_set_gc(struct device_node *node, void __iomem *reg_base,
			     u32 mask_reg, u32 irq_base)
{
	struct irq_chip_generic *gc;

	gc = irq_get_domain_generic_chip(root_domain, irq_base);
	gc->reg_base = reg_base;
	gc->chip_types[0].regs.mask = mask_reg;
	gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
	gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;

	if (of_find_property(node, "csky,support-pulse-signal", NULL))
		gc->chip_types[0].chip.irq_unmask = irq_ck_mask_set_bit;
}

static inline u32 build_channel_val(u32 idx, u32 magic)
{
	u32 res;

	/*
	 * Set the same index for each channel
	 */
	res = idx | (idx << 8) | (idx << 16) | (idx << 24);

	/*
	 * Set the channel magic number in descending order.
	 * The magic is 0x00010203 for ck-intc
	 * The magic is 0x03020100 for gx6605s-intc
	 */
	return res | magic;
}

static inline void setup_irq_channel(u32 magic, void __iomem *reg_addr)
{
	u32 i;

	/* Setup 64 channel slots */
	for (i = 0; i < INTC_IRQS; i += 4)
		writel(build_channel_val(i, magic), reg_addr + i);
}

static int __init
ck_intc_init_comm(struct device_node *node, struct device_node *parent)
{
	int ret;

	if (parent) {
		pr_err("C-SKY Intc not a root irq controller\n");
		return -EINVAL;
	}

	reg_base = of_iomap(node, 0);
	if (!reg_base) {
		pr_err("C-SKY Intc unable to map: %p.\n", node);
		return -EINVAL;
	}

	root_domain = irq_domain_add_linear(node, nr_irq,
					    &irq_generic_chip_ops, NULL);
	if (!root_domain) {
		pr_err("C-SKY Intc irq_domain_add failed.\n");
		return -ENOMEM;
	}

	ret = irq_alloc_domain_generic_chips(root_domain, 32, 1,
			"csky_intc", handle_level_irq,
			IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN, 0, 0);
	if (ret) {
		pr_err("C-SKY Intc irq_alloc_gc failed.\n");
		return -ENOMEM;
	}

	return 0;
}

static inline bool handle_irq_perbit(struct pt_regs *regs, u32 hwirq,
				     u32 irq_base)
{
	if (hwirq == 0)
		return 0;

	generic_handle_domain_irq(root_domain, irq_base + __fls(hwirq));

	return 1;
}

/* gx6605s 64 irqs interrupt controller */
static void gx_irq_handler(struct pt_regs *regs)
{
	bool ret;

retry:
	ret = handle_irq_perbit(regs,
			readl(reg_base + GX_INTC_PEN63_32), 32);
	if (ret)
		goto retry;

	ret = handle_irq_perbit(regs,
			readl(reg_base + GX_INTC_PEN31_00), 0);
	if (ret)
		goto retry;
}

static int __init
gx_intc_init(struct device_node *node, struct device_node *parent)
{
	int ret;

	ret = ck_intc_init_comm(node, parent);
	if (ret)
		return ret;

	/*
	 * Initial enable reg to disable all interrupts
	 */
	writel(0x0, reg_base + GX_INTC_NEN31_00);
	writel(0x0, reg_base + GX_INTC_NEN63_32);

	/*
	 * Initial mask reg with all unmasked, because we only use enable reg
	 */
	writel(0x0, reg_base + GX_INTC_NMASK31_00);
	writel(0x0, reg_base + GX_INTC_NMASK63_32);

	setup_irq_channel(0x03020100, reg_base + GX_INTC_SOURCE);

	ck_set_gc(node, reg_base, GX_INTC_NEN31_00, 0);
	ck_set_gc(node, reg_base, GX_INTC_NEN63_32, 32);

	set_handle_irq(gx_irq_handler);

	return 0;
}
IRQCHIP_DECLARE(csky_gx6605s_intc, "csky,gx6605s-intc", gx_intc_init);

/*
 * C-SKY simple 64 irqs interrupt controller, dual-together could support 128
 * irqs.
 */
static void ck_irq_handler(struct pt_regs *regs)
{
	bool ret;
	void __iomem *reg_pen_lo = reg_base + CK_INTC_PEN31_00;
	void __iomem *reg_pen_hi = reg_base + CK_INTC_PEN63_32;

retry:
	/* handle 0 - 63 irqs */
	ret = handle_irq_perbit(regs, readl(reg_pen_hi), 32);
	if (ret)
		goto retry;

	ret = handle_irq_perbit(regs, readl(reg_pen_lo), 0);
	if (ret)
		goto retry;

	if (nr_irq == INTC_IRQS)
		return;

	/* handle 64 - 127 irqs */
	ret = handle_irq_perbit(regs,
			readl(reg_pen_hi + CK_INTC_DUAL_BASE), 96);
	if (ret)
		goto retry;

	ret = handle_irq_perbit(regs,
			readl(reg_pen_lo + CK_INTC_DUAL_BASE), 64);
	if (ret)
		goto retry;
}

static int __init
ck_intc_init(struct device_node *node, struct device_node *parent)
{
	int ret;

	ret = ck_intc_init_comm(node, parent);
	if (ret)
		return ret;

	/* Initial enable reg to disable all interrupts */
	writel(0, reg_base + CK_INTC_NEN31_00);
	writel(0, reg_base + CK_INTC_NEN63_32);

	/* Enable irq intc */
	writel(BIT(31), reg_base + CK_INTC_ICR);

	ck_set_gc(node, reg_base, CK_INTC_NEN31_00, 0);
	ck_set_gc(node, reg_base, CK_INTC_NEN63_32, 32);

	setup_irq_channel(0x00010203, reg_base + CK_INTC_SOURCE);

	set_handle_irq(ck_irq_handler);

	return 0;
}
IRQCHIP_DECLARE(ck_intc, "csky,apb-intc", ck_intc_init);

static int __init
ck_dual_intc_init(struct device_node *node, struct device_node *parent)
{
	int ret;

	/* dual-apb-intc up to 128 irq sources*/
	nr_irq = INTC_IRQS * 2;

	ret = ck_intc_init(node, parent);
	if (ret)
		return ret;

	/* Initial enable reg to disable all interrupts */
	writel(0, reg_base + CK_INTC_NEN31_00 + CK_INTC_DUAL_BASE);
	writel(0, reg_base + CK_INTC_NEN63_32 + CK_INTC_DUAL_BASE);

	ck_set_gc(node, reg_base + CK_INTC_DUAL_BASE, CK_INTC_NEN31_00, 64);
	ck_set_gc(node, reg_base + CK_INTC_DUAL_BASE, CK_INTC_NEN63_32, 96);

	setup_irq_channel(0x00010203,
			  reg_base + CK_INTC_SOURCE + CK_INTC_DUAL_BASE);

	return 0;
}
IRQCHIP_DECLARE(ck_dual_intc, "csky,dual-apb-intc", ck_dual_intc_init);
