cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Adventurer
Adventurer
356 Views
Registered: ‎04-06-2012

AXI Interrupt Controller not working in Linux

Jump to solution

Hello,

I have a system that requires more than 2 i2c buses, so I have added axi_iic cores to my block design since the zynq-7000 only has 2 i2c controllers in the PS. Each axi_iic devices requires an interrupt to be connected to the PL-PS port (IRQF2P). I've figured out how to map the IRQ through the device tree, but it turns out it wasn't required as the device tree builder maps it properly. Thus, all I needed to do was to enable the CONFIG_I2C_XILINX=y option in the kernel config. My first tests went fine as I only used 1 axi_iic core, and the interrupt of the axi_iic core was mapped directly into the PS. Here is the output of /proc/interrupts:

root@red-pitaya:/proc# cat /proc/interrupts
CPU0 CPU1
16: 0 0 GIC-0 27 Edge gt
17: 0 0 GIC-0 43 Level ttc_clockevent
18: 1523 1552 GIC-0 29 Edge twd
19: 0 0 GIC-0 37 Level arm-pmu
20: 0 0 GIC-0 38 Level arm-pmu
21: 43 0 GIC-0 39 Level f8007100.adc
23: 0 0 GIC-0 57 Level cdns-i2c
25: 0 0 GIC-0 35 Level f800c000.ocmc
26: 191 0 GIC-0 59 Level xuartps
27: 5 0 GIC-0 58 Level e0006000.spi
28: 157 0 GIC-0 54 Level eth0
29: 3494 0 GIC-0 56 Level mmc0
30: 0 0 GIC-0 45 Level f8003000.dmac
31: 0 0 GIC-0 46 Level f8003000.dmac
32: 0 0 GIC-0 47 Level f8003000.dmac
33: 0 0 GIC-0 48 Level f8003000.dmac
34: 0 0 GIC-0 49 Level f8003000.dmac
35: 0 0 GIC-0 72 Level f8003000.dmac
36: 0 0 GIC-0 73 Level f8003000.dmac
37: 0 0 GIC-0 74 Level f8003000.dmac
38: 0 0 GIC-0 75 Level f8003000.dmac
39: 0 0 GIC-0 40 Level f8007000.devcfg
45: 0 0 GIC-0 41 Edge f8005000.watchdog
46: 0 0 GIC-0 61 Level 41600000.i2c
IPI1: 0 0 Timer broadcast interrupts
IPI2: 968 1892 Rescheduling interrupts
IPI3: 3 3 Function call interrupts
IPI4: 0 0 CPU stop interrupts
IPI5: 0 0 IRQ work interrupts
IPI6: 0 0 completion interrupts
Err: 0

Here is the (very simple) PL connection schematic:

diagram.png

 

Since I require 18 axi_iic devices and the IRQF2P port only has 16 bits, I know I have to use an axi_intr module. So far, I'm still using a single axi_iic module, so I don't even have to do any signal concatenation. The only difference is that the interrupt output of the axi_iic block goes into my axi_intr, and its irq output goes into the IRQF2P port. I've also enabled the axi_intr driver by using CONFIG_XILINX_INTC=y in my kernel config file. It seems like something is broken, as I don't see any interrupt being registered:

root@red-pitaya:~# cat /proc/interrupts
CPU0 CPU1
16: 0 0 GIC-0 27 Edge gt
17: 0 0 GIC-0 43 Level ttc_clockevent
18: 1576 1660 GIC-0 29 Edge twd
19: 0 0 GIC-0 37 Level arm-pmu
20: 0 0 GIC-0 38 Level arm-pmu
21: 43 0 GIC-0 39 Level f8007100.adc
23: 0 0 GIC-0 57 Level cdns-i2c
25: 0 0 GIC-0 35 Level f800c000.ocmc
26: 215 0 GIC-0 59 Level xuartps
27: 5 0 GIC-0 58 Level e0006000.spi
28: 105 0 GIC-0 54 Level eth0
29: 4244 0 GIC-0 56 Level mmc0
30: 0 0 GIC-0 45 Level f8003000.dmac
31: 0 0 GIC-0 46 Level f8003000.dmac
32: 0 0 GIC-0 47 Level f8003000.dmac
33: 0 0 GIC-0 48 Level f8003000.dmac
34: 0 0 GIC-0 49 Level f8003000.dmac
35: 0 0 GIC-0 72 Level f8003000.dmac
36: 0 0 GIC-0 73 Level f8003000.dmac
37: 0 0 GIC-0 74 Level f8003000.dmac
38: 0 0 GIC-0 75 Level f8003000.dmac
39: 0 0 GIC-0 40 Level f8007000.devcfg
45: 0 0 GIC-0 41 Edge f8005000.watchdog
IPI1: 0 0 Timer broadcast interrupts
IPI2: 1177 1794 Rescheduling interrupts
IPI3: 4 1 Function call interrupts
IPI4: 0 0 CPU stop interrupts
IPI5: 0 0 IRQ work interrupts
IPI6: 0 0 completion interrupts
Err: 0

My PL connections are done like so:

diagram.png

I've tried enabling the "Cascade Mode Master" option of the AXI Interrupt Controller, but it did not change anything. The irq output is configured to be high level active, which is compatible with the IRQ_F2P port. In fact, my axi_iic_0 block also had a high level active interrupt output and it worked fine when it went directly into the IRQ_F2P port.

Here are some relevant excerpts from the decompiled device tree. Everything seems to be binded properly. The "interrupts" line of the axi interrupt controller corresponds to the proper IRQ number. In fact, when my axi_iic block was hooked directly into the IRQ_F2P port, it had the same "interrupts" line (and it worked fine). I can also see that the AXI controller appears to be mapped to the GIC properly. Also, the axi controller has a reference to the driver that gets compiled when using CONFIG_XILINX_INTC=y driver, which is what we want.

 

		interrupt-controller@f8f01000 {
			compatible = "arm,cortex-a9-gic";
			#interrupt-cells = <0x3>;
			interrupt-controller;
			reg = <0xf8f01000 0x1000 0xf8f00100 0x100>;
			num_cpus = <0x2>;
			num_interrupts = <0x60>;
			phandle = <0x4>;
		};

... (skipping lines)

		interrupt-controller@41800000 {
			#interrupt-cells = <0x2>;
			clock-names = "s_axi_aclk";
			clocks = <0x6>;
			compatible = "xlnx,axi-intc-4.1", "xlnx,xps-intc-1.00.a";
			interrupt-controller;
			interrupt-names = "irq";
			interrupt-parent = <0x4>;
			interrupts = <0x0 0x1d 0x4>;
			reg = <0x41800000 0x10000>;
			xlnx,kind-of-intr = <0x0>;
			xlnx,num-intr-inputs = <0x1>;
			phandle = <0x7>;
		};
... (skipping lines)

		i2c@41600000 {
			#address-cells = <0x1>;
			#size-cells = <0x0>;
			clock-names = "s_axi_aclk";
			clocks = <0x6>;
			compatible = "xlnx,axi-iic-2.0", "xlnx,xps-iic-2.00.a";
			interrupt-names = "iic2intc_irpt";
			interrupt-parent = <0x7>;
			interrupts = <0x0 0x2>;
			reg = <0x41600000 0x10000>;

			ds1682@6b {
				compatible = "dallas,ds1682";
				reg = <0x6b>;
			};
		};

 

 

According to the forum posts I've found, using the axi_intc module to increase the amount of available PL->PS interrupts is pretty standard and pretty much "plug and play". I know for a fact my issue comes from this module, as I can communicate with my i2c chip through the axi_iic module when I don't use the axi_intr block. Would someone be kind enough to tell me what's wrong, or at least give me some pointers?

My next steps will be to add a ILA to see if there are any interrupt activity in the PL, and also add debugging printed messages into the xlnx,xps-intc-1.00.a driver to see if it gets probed properly.

0 Kudos
1 Solution

Accepted Solutions
Highlighted
Adventurer
Adventurer
323 Views
Registered: ‎04-06-2012

Turns out everything was working, but the project Makefile had a sensibility list error that had the effect of not recompiling the linux kernel after I modified the config to add CONFIG_XILINX_INTC. After making sure my kernel config change was applied, I tested again and I could communicate with the i2c device when using the AXI Interrupt Controller.

Even if it turns out I had no design issues, I will not delete this thread since it might help somebody that is trying to get the axi interrupt controller to work in linux.

View solution in original post

0 Kudos
1 Reply
Highlighted
Adventurer
Adventurer
324 Views
Registered: ‎04-06-2012

Turns out everything was working, but the project Makefile had a sensibility list error that had the effect of not recompiling the linux kernel after I modified the config to add CONFIG_XILINX_INTC. After making sure my kernel config change was applied, I tested again and I could communicate with the i2c device when using the AXI Interrupt Controller.

Even if it turns out I had no design issues, I will not delete this thread since it might help somebody that is trying to get the axi interrupt controller to work in linux.

View solution in original post

0 Kudos