Commit 4f8d22b1 authored by Yang Yingliang's avatar Yang Yingliang Committed by Yuntao Liu
Browse files

irqchip/mbigen: add support for a MBIGEN generating SPIs

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8NULW


CVE: N/A

-------------------------------------------------

Now with
50528752 ("irqchip/gic-v3: Add support for Message Based Interrupts as an MSI controller"),
we can support MBIGEN to generate message based SPIs by writing GICD_SETSPIR.

The first 64-pins of each MBIGEN chip is used to generate SPIs, and each
MBIGEN chip has several MBIGEN nodes, every node has 128 pins for generating
LPIs. The total pins are: 64(SPIs) + 128 * node_nr(LPIs). So we can translate
the pin index in a unified way in mbigen_domain_translate().

Add TYPE and VEC registers that used by generating SPIs, the driver can
access them when MBIGEN is used to generate SPIs.

Also Add Config IRQ_MBIGEN_ENABLE_SPIs to control whether to enable SPIs
generation by MBIGEN

Signed-off-by: default avatarYang Yingliang <yangyingliang@huawei.com>
Signed-off-by: default avatarYuntao Liu <liuyuntao12@huawei.com>
parent 117e4eb6
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -6626,6 +6626,7 @@ CONFIG_ARM_GIC_V3_ITS=y
CONFIG_ARM_GIC_V3_ITS_PCI=y
# CONFIG_AL_FIC is not set
CONFIG_HISILICON_IRQ_MBIGEN=y
CONFIG_IRQ_MBIGEN_ENABLE_SPI=y
# CONFIG_XILINX_INTC is not set
CONFIG_PARTITION_PERCPU=y
CONFIG_QCOM_IRQ_COMBINER=y
+7 −0
Original line number Diff line number Diff line
@@ -159,6 +159,13 @@ config HISILICON_IRQ_MBIGEN
	select ARM_GIC_V3
	select ARM_GIC_V3_ITS

config IRQ_MBIGEN_ENABLE_SPI
	bool "MBIGEN enable generating SPIs"
	depends on HISILICON_IRQ_MBIGEN
	default n
	help
	  Use the first 64-pins of each MBIGEN chip to generate SPIs.

config IMGPDC_IRQ
	bool
	select GENERIC_IRQ_CHIP
+32 −1
Original line number Diff line number Diff line
@@ -53,6 +53,11 @@
 */
#define REG_MBIGEN_LPI_TYPE_OFFSET	0x0

#ifdef CONFIG_IRQ_MBIGEN_ENABLE_SPI
#define REG_MBIGEN_SPI_VEC_OFFSET	0x500
#define REG_MBIGEN_SPI_TYPE_OFFSET	0x400
#endif

/**
 * struct mbigen_device - holds the information of mbigen device.
 *
@@ -68,6 +73,11 @@ static inline unsigned int get_mbigen_vec_reg(irq_hw_number_t hwirq)
{
	unsigned int nid, pin;

#ifdef CONFIG_IRQ_MBIGEN_ENABLE_SPI
	if (hwirq < SPI_NUM_PER_MBIGEN_CHIP)
		return (hwirq * 4 + REG_MBIGEN_SPI_VEC_OFFSET);
#endif

	hwirq -= SPI_NUM_PER_MBIGEN_CHIP;
	nid = hwirq / IRQS_PER_MBIGEN_NODE + 1;
	pin = hwirq % IRQS_PER_MBIGEN_NODE;
@@ -81,6 +91,15 @@ static inline void get_mbigen_type_reg(irq_hw_number_t hwirq,
{
	unsigned int nid, irq_ofst, ofst;

#ifdef CONFIG_IRQ_MBIGEN_ENABLE_SPI
	if (hwirq < SPI_NUM_PER_MBIGEN_CHIP) {
		*mask = 1 << (hwirq % 32);
		ofst = hwirq / 32 * 4;
		*addr = ofst + REG_MBIGEN_SPI_TYPE_OFFSET;
		return;
	}
#endif

	hwirq -= SPI_NUM_PER_MBIGEN_CHIP;
	nid = hwirq / IRQS_PER_MBIGEN_NODE + 1;
	irq_ofst = hwirq % IRQS_PER_MBIGEN_NODE;
@@ -154,6 +173,14 @@ static void mbigen_write_msg(struct msi_desc *desc, struct msi_msg *msg)
		return;

	base += get_mbigen_vec_reg(d->hwirq);

#ifdef CONFIG_IRQ_MBIGEN_ENABLE_SPI
	if (d->hwirq < SPI_NUM_PER_MBIGEN_CHIP) {
		writel_relaxed(msg->data, base);
		return;
	}
#endif

	val = readl_relaxed(base);

	val &= ~(IRQ_EVENT_ID_MASK << IRQ_EVENT_ID_SHIFT);
@@ -174,8 +201,12 @@ static int mbigen_domain_translate(struct irq_domain *d,
		if (fwspec->param_count != 2)
			return -EINVAL;

#ifdef CONFIG_IRQ_MBIGEN_ENABLE_SPI
		if (fwspec->param[0] > MAXIMUM_IRQ_PIN_NUM)
#else
		if ((fwspec->param[0] > MAXIMUM_IRQ_PIN_NUM) ||
			(fwspec->param[0] < SPI_NUM_PER_MBIGEN_CHIP))
#endif
			return -EINVAL;
		else
			*hwirq = fwspec->param[0];