/*
 * Copyright 2023 NXP
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief Driver for NXP's IRQ_STEER IP.
 *
 * Below you may find some useful information that will help you better understand how the
 * driver works. The ">" sign is used to mark ideas that are considered important and should
 * be taken note of.
 *
 * 1) What is the IRQ_STEER IP?
 *	- in Zephyr terminology, the IRQ_STEER can be considered an interrupt aggregator. As such,
 *	its main goal is to multiplex multiple interrupt lines into a single/multiple ones.
 *
 * 2) How does the IRQ_STEER IP work?
 *	- below you may find a diagram meant to give you an intuition regarding the IP's structure
 *	and how it works (all of the information below is applicable to i.MX8MP but it can be
 *	extended to any NXP SoC using the IRQ_STEER IP):
 *
 *                 SYSTEM_INTID[0:159]
 *                        |
 *      MASK[0:4]------   |
 *                    |   |
 *                  +------+
 *                  |      |
 *                  |32 AND|
 *                  |      |
 *                  +------+
 *                        |
 *      SET[0:4]------    |
 *                   |    |
 *                  +------+
 *                  |      |
 *                  |32 OR |
 *                  |      |
 *                  +------+
 *                     |__________ STATUS[0:4]
 *                     |
 *                  +------+
 *                  |GROUP |
 *                  |  BY  |
 *                  |  64  |
 *                  +------+
 *                   |  | |
 *      _____________|  | |________________
 *      |               |                 |
 * MASTER_IN[0]    MASTER_IN[1]      MASTER_IN[2]
 *      |               |                 |
 *      |               |                 |
 *      |_____________  |  _______________|
 *                   |  | |
 *                  +------+
 *                  |      |
 *                  | AND  | ---------- MINTDIS[0:2]
 *                  |      |
 *                  +------+
 *                   |  | |
 *      _____________|  | |________________
 *      |               |                 |
 * MASTER_OUT[0]  MASTER_OUT[1]      MASTER_OUT[2]
 *
 *	- initially, all SYSTEM_INTID are grouped by 32 => 5 groups.
 *
 *	> each of these groups is controlled by a MASK, SET and STATUS index as follows:
 *
 *		MASK/SET/STATUS[0] => SYSTEM_INTID[159:128]
 *		MASK/SET/STATUS[1] => SYSTEM_INTID[127:96]
 *		MASK/SET/STATUS[2] => SYSTEM_INTID[95:64]
 *		MASK/SET/STATUS[3] => SYSTEM_INTID[63:32]
 *		MASK/SET/STATUS[4] => SYSTEM_INTID[31:0]
 *
 *      > after that, all SYSTEM_INTID are grouped by 64 as follows:
 *
 *		SYSTEM_INTID[159:96] => MASTER_IN[2]
 *              SYSTEM_INTID[95:32] => MASTER_IN[1]
 *              SYSTEM_INTID[31:0] => MASTER_IN[0]
 *
 *      note: MASTER_IN[0] is only responsible for 32 interrupts
 *
 *      > the value of MASTER_IN[x] is obtained by OR'ing the input interrupt lines.
 *
 *      > the value of MASTER_OUT[x] is obtained by AND'ing MASTER_IN[x] with !MINTDIS[x].
 *
 *      - whenever a SYSTEM_INTID is asserted, its corresponding MASTER_OUT signal will also
 *	be asserted, thus signaling the target processor.
 *
 *	> please note the difference between an IRQ_STEER channel and an IRQ_STEER master output.
 *	An IRQ_STEER channel refers to an IRQ_STEER instance (e.g: the DSP uses IRQ_STEER channel
 *	0 a.k.a instance 0). An IRQ_STEER channel has multiple master outputs. For example, in
 *	the case of i.MX8MP each IRQ_STEER channel has 3 master outputs since an IRQ_STEER channel
 *	routes 160 interrupts (32 for first master output, 64 for second master output, and 64 for
 *	the third master output).
 *
 * 3) Using Zephyr's multi-level interrupt support
 *	- since Zephyr supports organizing interrupts on multiple levels, we can use this to
 *	separate the interrupts in 2 levels:
 *		1) LEVEL 1 INTERRUPTS
 *			- these are the interrupts that go directly to the processor (for example,
 *			on i.MX8MP the MU can directly assert the DSP's interrupt line 7)
 *
 *		2) LEVEL 2 INTERRUPTS
 *			- these interrupts go through IRQ_STEER and are signaled by a single
 *			processor interrupt line.
 *			- e.g: for i.MX8MP, INTID 34 (SDMA3) goes through IRQ_STEER and is signaled
 *			to the DSP by INTID 20 which is a direct interrupt (or LEVEL 1 interrupt).
 *
 *	- the following diagram (1) shows the interrupt organization on i.MX8MP:
 *	                                                        +------------+
 *								|            |
 *	      SYSTEM_INTID[31:0] ------ IRQ_STEER_MASTER_0 ----	| 19         |
 *								|            |
 *	      SYSTEM_INTID[95:32] ----- IRQ_STEER_MASTER_1 ----	| 20  DSP    |
 *								|            |
 *	      SYSTEM_INTID[159:96] ---- IRQ_STEER_MASTER_2 ----	| 21         |
 *								|            |
 *								+------------+
 *
 *	- as such, asserting a system interrupt will lead to asserting its corresponding DSP
 *	interrupt line (for example, if system interrupt 34 is asserted, that would lead to
 *	interrupt 20 being asserted)
 *
 *	- in the above diagram, SYSTEM_INTID[x] are LEVEL 2 interrupts, while 19, 20, and 21 are
 *	LEVEL 1 interrupts.
 *
 *	- INTID 19 is the parent of SYSTEM_INTID[31:0] and so on.
 *
 *	> before going into how the INTIDs are encoded, we need to distinguish between 3 types of
 *	INTIDs:
 *		1) System INTIDs
 *			- these are the values that can be found in NXP's TRMs for different
 *			SoCs (usually they have the same IDs as the GIC SPIs)
 *			- for example, INTID 34 is a system INTID for SDMA3 (i.MX8MP).
 *
 *		2) Zephyr INTIDs
 *			- these are the Zephyr-specific encodings of the system INTIDs.
 *			- these are used to encode multi-level interrupts (for more information
 *			please see [1])
 *			> if you need to register an interrupt dynamically, you need to use this
 *			encoding when specifying the interrupt.
 *
 *		3) DTS INTIDs
 *			- these are the encodings of the system INTIDs used in the DTS.
 *			- all of these INTIDs are relative to IRQ_STEER's MASTER_OUTs.
 *
 *	> encoding an INTID:
 *		1) SYSTEM INTID => ZEPHYR INTID
 *			- the following steps need to be performed:
 *
 *				a) Find out which IRQ_STEER MASTER
 *				is in charge of aggregating this interrupt.
 *					* for instance, SYSTEM_INTID 34 (SDMA3 on i.MX8MP) is
 *					aggregated by MASTER 1 as depicted in diagram (1).
 *
 *				b) After finding the MASTER aggregator, you need
 *				to find the corresponding parent interrupt.
 *					* for example, SYSTEM_INTID 34 (SDMA3 on i.MX8MP) is
 *					aggregated by MASTER 1, which has the parent INTID 20
 *					as depicted in diagram (1) => PARENT_INTID(34) = 20.
 *
 *				c) Find the INTID relative to the MASTER aggregator. This is done
 *				by subtracting the number of interrupts each of the previous
 *				master aggregators is in charge of. If the master aggregator is
 *				MASTER 0 then RELATIVE_INTID=SYSTEM_INTID.
 *					* for example, SYSTEM_ID 34 is aggregated by MASTER 1.
 *					As such, we need to subtract 32 from 34 (because the
 *					previous master - MASTER 0 - is in charge of aggregating
 *					32 interrupts) => RELATIVE_INTID(34) = 2.
 *
 *					* generally speaking, RELATIVE_INTID can be computed using
 *					the following formula (assuming SYSTEM_INTID belongs to
 *					MASTER y):
 *						RELATIVE_INTID(x) = x -
 *							\sum{i=0}^{y - 1} GET_MASTER_INT_NUM(i)
 *					where:
 *						1) GET_MASTER_INT_NUM(x) computes the number of
 *						interrupts master x aggregates
 *						2) x is the system interrupt
 *
 *					* to make sure your computation is correct use the
 *					following restriction:
 *						0 <= RELATIVE_INTID(x) < GET_MASTER_INT_NUM(y)
 *
 *				d) To the obtained RELATIVE_INTID you need to add the value of 1,
 *				left shift the result by the number of bits used to encode the
 *				level 1 interrupts (see [1] for details) and OR the parent ID.
 *					* for example, RELATIVE_INTID(34) = 2 (i.MX8MP),
 *					PARENT_INTID(34) = 20 => ZEPHYR_INTID = ((2 + 1) << 8) | 20
 *
 *					* generally speaking, ZEPHYR_INTID can be computed using
 *					the following formula:
 *						ZEPHYR_INTID(x) = ((RELATIVE_INTID(x) + 1) <<
 *						NUM_LVL1_BITS) | PARENT_INTID(x)
 *					where:
 *						1) RELATIVE_INTID(x) computes the relative INTID
 *						of system interrupt x (step c).
 *
 *						2) NUM_LVL1_BITS is the number of bits used to
 *						encode level 1 interrupts.
 *
 *						3) PARENT_INTID(x) computes the parent INTID of a
 *						system interrupt x (step b)
 *
 *			- all of these steps are performed by to_zephyr_irq().
 *			> for interrupts aggregated by MASTER 0 you may skip step c) as
 *			RELATIVE_INTID(x) = x.
 *
 *		2) SYSTEM INTID => DTS INTID
 *			- for this you just have to compute RELATIVE_INTID as described above in
 *			step c).
 *			- for example, if an IP uses INTID 34 you'd write its interrupts property
 *			as follows (i.MX8MP):
 *				interrupts = <&master1 2>;
 *
 * 4) Notes and comments
 *	> PLEASE DON'T MISTAKE THE ZEPHYR MULTI-LEVEL INTERRUPT ORGANIZATION WITH THE XTENSA ONE.
 *	THEY ARE DIFFERENT THINGS.
 *
 * [1]: https://docs.zephyrproject.org/latest/kernel/services/interrupts.html#multi-level-interrupt-handling
 */

#include <zephyr/device.h>
#include <zephyr/irq.h>
#include <fsl_irqsteer.h>
#include <zephyr/cache.h>

#include "sw_isr_common.h"

/* used for driver binding */
#define DT_DRV_COMPAT nxp_irqsteer_intc

/* macros used for DTS parsing */
#define _IRQSTEER_REGISTER_DISPATCHER(node_id)				\
	IRQ_CONNECT(DT_IRQN(node_id),					\
		    DT_IRQ(node_id, priority),				\
		    irqsteer_isr_dispatcher,				\
		    &dispatchers[DT_REG_ADDR(node_id)],			\
		    0)

#define _IRQSTEER_DECLARE_DISPATCHER(node_id)				\
{									\
	.dev = DEVICE_DT_GET(DT_PARENT(node_id)),			\
	.master_index = DT_REG_ADDR(node_id),				\
	.irq = DT_IRQN(node_id),					\
}

#define IRQSTEER_DECLARE_DISPATCHERS(parent_id)\
	DT_FOREACH_CHILD_STATUS_OKAY_SEP(parent_id, _IRQSTEER_DECLARE_DISPATCHER, (,))

#define IRQSTEER_REGISTER_DISPATCHERS(parent_id)\
	DT_FOREACH_CHILD_STATUS_OKAY_SEP(parent_id, _IRQSTEER_REGISTER_DISPATCHER, (;))

/* utility macros */
#define UINT_TO_IRQSTEER(x) ((IRQSTEER_Type *)(x))

struct irqsteer_config {
	uint32_t regmap_phys;
	uint32_t regmap_size;
	struct irqsteer_dispatcher *dispatchers;
};

struct irqsteer_dispatcher {
	const struct device *dev;
	/* which set of interrupts is the dispatcher in charge of? */
	uint32_t master_index;
	/* which interrupt line is the dispatcher tied to? */
	uint32_t irq;
};

static struct irqsteer_dispatcher dispatchers[] = {
	IRQSTEER_DECLARE_DISPATCHERS(DT_NODELABEL(irqsteer))
};

/* used to convert system INTID to zephyr INTID */
static int to_zephyr_irq(uint32_t regmap, uint32_t irq,
			 struct irqsteer_dispatcher *dispatcher)
{
	int i, idx;

	idx = irq;

	for (i = dispatcher->master_index - 1; i >= 0; i--) {
		idx -= IRQSTEER_GetMasterIrqCount(UINT_TO_IRQSTEER(regmap), i);
	}

	return irq_to_level_2(idx) | dispatcher->irq;
}

/* used to convert master-relative INTID to system INTID */
static int to_system_irq(uint32_t regmap, int irq, int master_index)
{
	int i;

	for (i = master_index - 1; i >= 0; i--) {
		irq += IRQSTEER_GetMasterIrqCount(UINT_TO_IRQSTEER(regmap), i);
	}

	return irq;
}

/* used to convert zephyr INTID to system INTID */
static int from_zephyr_irq(uint32_t regmap, uint32_t irq, uint32_t master_index)
{
	int i, idx;

	idx = irq;

	for (i = 0; i < master_index; i++) {
		idx += IRQSTEER_GetMasterIrqCount(UINT_TO_IRQSTEER(regmap), i);
	}

	return idx;
}

void z_soc_irq_enable_disable(uint32_t irq, bool enable)
{
	uint32_t parent_irq;
	int i, system_irq, level2_irq;
	const struct irqsteer_config *cfg;

	if (irq_get_level(irq) == 1) {
		/* LEVEL 1 interrupts are DSP direct */
		if (enable) {
			xtensa_irq_enable(XTENSA_IRQ_NUMBER(irq));
		} else {
			xtensa_irq_disable(XTENSA_IRQ_NUMBER(irq));
		}
		return;
	}

	parent_irq = irq_parent_level_2(irq);
	level2_irq = irq_from_level_2(irq);

	/* find dispatcher responsible for this interrupt */
	for (i = 0; i < ARRAY_SIZE(dispatchers); i++) {
		if (dispatchers[i].irq != parent_irq) {
			continue;
		}

		cfg = dispatchers[i].dev->config;

		system_irq = from_zephyr_irq(cfg->regmap_phys, level2_irq,
					     dispatchers[i].master_index);

		if (enable) {
			IRQSTEER_EnableInterrupt(UINT_TO_IRQSTEER(cfg->regmap_phys),
						 system_irq);
		} else {
			IRQSTEER_DisableInterrupt(UINT_TO_IRQSTEER(cfg->regmap_phys),
						  system_irq);
		}

		return;
	}
}

void z_soc_irq_enable(uint32_t irq)
{
	z_soc_irq_enable_disable(irq, true);
}

void z_soc_irq_disable(uint32_t irq)
{
	z_soc_irq_enable_disable(irq, false);
}

int z_soc_irq_is_enabled(unsigned int irq)
{
	uint32_t parent_irq;
	int i, system_irq, level2_irq;
	const struct irqsteer_config *cfg;

	if (irq_get_level(irq) == 1) {
		/* LEVEL 1 interrupts are DSP direct */
		return xtensa_irq_is_enabled(XTENSA_IRQ_NUMBER(irq));
	}

	parent_irq = irq_parent_level_2(irq);
	level2_irq = irq_from_level_2(irq);

	/* find dispatcher responsible for this interrupt */
	for (i = 0; i < ARRAY_SIZE(dispatchers); i++) {
		if (dispatchers[i].irq != parent_irq) {
			continue;
		}

		cfg = dispatchers[i].dev->config;

		system_irq = from_zephyr_irq(cfg->regmap_phys, level2_irq,
					     dispatchers[i].master_index);

		return IRQSTEER_InterruptIsEnabled(UINT_TO_IRQSTEER(cfg->regmap_phys), system_irq);
	}

	return false;
}


static void irqsteer_isr_dispatcher(const void *data)
{
	struct irqsteer_dispatcher *dispatcher;
	const struct irqsteer_config *cfg;
	uint32_t table_idx;
	int system_irq, zephyr_irq, i;
	uint64_t status;

	dispatcher = (struct irqsteer_dispatcher *)data;
	cfg = dispatcher->dev->config;

	/* fetch master interrupts status */
	status = IRQSTEER_GetMasterInterruptsStatus(UINT_TO_IRQSTEER(cfg->regmap_phys),
						    dispatcher->master_index);

	for (i = 0; status; i++) {
		/* if bit 0 is set then that means relative INTID i is asserted */
		if (status & 1) {
			/* convert master-relative INTID to a system INTID */
			system_irq = to_system_irq(cfg->regmap_phys, i,
						   dispatcher->master_index);

			/* convert system INTID to a Zephyr INTID */
			zephyr_irq = to_zephyr_irq(cfg->regmap_phys, system_irq, dispatcher);

			/* compute index in the SW ISR table */
			table_idx = z_get_sw_isr_table_idx(zephyr_irq);

			/* call child's ISR */
			_sw_isr_table[table_idx].isr(_sw_isr_table[table_idx].arg);
		}

		status >>= 1;
	}
}

static void irqsteer_enable_dispatchers(const struct device *dev)
{
	int i;
	struct irqsteer_dispatcher *dispatcher;
	const struct irqsteer_config *cfg;

	cfg = dev->config;

	for (i = 0; i < ARRAY_SIZE(dispatchers); i++) {
		dispatcher = &dispatchers[i];

		IRQSTEER_EnableMasterInterrupt(UINT_TO_IRQSTEER(cfg->regmap_phys),
					       dispatcher->irq);

		xtensa_irq_enable(XTENSA_IRQ_NUMBER(dispatcher->irq));
	}
}

static int irqsteer_init(const struct device *dev)
{
	IRQSTEER_REGISTER_DISPATCHERS(DT_NODELABEL(irqsteer));

	/* enable all dispatchers */
	irqsteer_enable_dispatchers(dev);

	return 0;
}


/* TODO: do we need to add support for MMU-based SoCs? */
static struct irqsteer_config irqsteer_config = {
	.regmap_phys = DT_REG_ADDR(DT_NODELABEL(irqsteer)),
	.regmap_size = DT_REG_SIZE(DT_NODELABEL(irqsteer)),
	.dispatchers = dispatchers,
};

/* assumption: only 1 IRQ_STEER instance */
DEVICE_DT_INST_DEFINE(0,
		      &irqsteer_init,
		      NULL,
		      NULL, &irqsteer_config,
		      PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY,
		      NULL);
