Unverified Commit 5cab1e7e authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!3974 Add support for mbigen to generate SPIs

Merge Pull Request from: @ci-robot 
 
PR sync from: Yuntao Liu <liuyuntao12@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/DG6OVJ5ZY2SUDVZOZMWFMZ6H76GMOOEZ/ 
enable MBIGEN to generate SPIs

Yang Yingliang (3):
  irqchip/mbigen: rename register marcros
  irqchip/mbigen: add support for a MBIGEN generating SPIs
  dt-bindings/irqchip/mbigen: add example of MBIGEN generate SPIs


-- 
2.34.1
 
https://gitee.com/openeuler/kernel/issues/I8NULW 
 
Link:https://gitee.com/openeuler/kernel/pulls/3974

 

Reviewed-by: default avatarZhang Jianhua <chris.zjh@huawei.com>
Reviewed-by: default avatarLiu Chao <liuchao173@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parents cad90c54 eef0dce2
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@ Hisilicon designed mbigen to collect and generate interrupt.


Non-pci devices can connect to mbigen and generate the
interrupt by writing ITS register.
interrupt by writing GICD or ITS register.

The mbigen chip and devices connect to mbigen have the following properties:

@@ -64,6 +64,13 @@ Examples:
				num-pins = <2>;
				#interrupt-cells = <2>;
			};

			mbigen_spi_example:spi_example {
				interrupt-controller;
				msi-parent = <&gic>;
				num-pins = <2>;
				#interrupt-cells = <2>;
			};
	};

Devices connect to mbigen required properties:
@@ -82,3 +89,11 @@ Examples:
		interrupts =	<656 1>,
				<657 1>;
	};

	spi_example: spi0@0 {
		compatible = "spi,example";
		reg = <0 0 0 0>;
		interrupt-parent = <&mbigen_spi_example>;
		interrupts = <13 4>,
			     <14 4>;
	};
+1 −0
Original line number Diff line number Diff line
@@ -6629,6 +6629,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
+42 −11
Original line number Diff line number Diff line
@@ -19,14 +19,14 @@
/* Interrupt numbers per mbigen node supported */
#define IRQS_PER_MBIGEN_NODE		128

/* 64 irqs (Pin0-pin63) are reserved for each mbigen chip */
#define RESERVED_IRQ_PER_MBIGEN_CHIP	64
/* 64 irqs (Pin0-pin63) are used for SPIs on each mbigen chip */
#define SPI_NUM_PER_MBIGEN_CHIP		64

/* The maximum IRQ pin number of mbigen chip(start from 0) */
#define MAXIMUM_IRQ_PIN_NUM		1407

/*
 * In mbigen vector register
 * In mbigen lpi vector register
 * bit[21:12]:	event id value
 * bit[11:0]:	device id
 */
@@ -37,7 +37,7 @@
#define MBIGEN_NODE_OFFSET		0x1000

/* offset of vector register in mbigen node */
#define REG_MBIGEN_VEC_OFFSET		0x200
#define REG_MBIGEN_LPI_VEC_OFFSET	0x200

/*
 * offset of clear register in mbigen node
@@ -51,7 +51,12 @@
 * This register is used to configure interrupt
 * trigger type
 */
#define REG_MBIGEN_TYPE_OFFSET		0x0
#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,12 +73,17 @@ static inline unsigned int get_mbigen_vec_reg(irq_hw_number_t hwirq)
{
	unsigned int nid, pin;

	hwirq -= RESERVED_IRQ_PER_MBIGEN_CHIP;
#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;

	return pin * 4 + nid * MBIGEN_NODE_OFFSET
			+ REG_MBIGEN_VEC_OFFSET;
			+ REG_MBIGEN_LPI_VEC_OFFSET;
}

static inline void get_mbigen_type_reg(irq_hw_number_t hwirq,
@@ -81,7 +91,16 @@ static inline void get_mbigen_type_reg(irq_hw_number_t hwirq,
{
	unsigned int nid, irq_ofst, ofst;

	hwirq -= RESERVED_IRQ_PER_MBIGEN_CHIP;
#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;

@@ -89,7 +108,7 @@ static inline void get_mbigen_type_reg(irq_hw_number_t hwirq,
	ofst = irq_ofst / 32 * 4;

	*addr = ofst + nid * MBIGEN_NODE_OFFSET
		+ REG_MBIGEN_TYPE_OFFSET;
		+ REG_MBIGEN_LPI_TYPE_OFFSET;
}

static inline void get_mbigen_clear_reg(irq_hw_number_t hwirq,
@@ -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] < RESERVED_IRQ_PER_MBIGEN_CHIP))
			(fwspec->param[0] < SPI_NUM_PER_MBIGEN_CHIP))
#endif
			return -EINVAL;
		else
			*hwirq = fwspec->param[0];